@nicia-ai/typegraph 0.65.0 → 0.66.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 (196) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/{atomic-mutation-program-BznZQ06C.d.ts → atomic-mutation-program-BhP75Qn0.d.ts} +1 -1
  3. package/dist/{atomic-mutation-program-Bfu5z-je.d.cts → atomic-mutation-program-DMdmc4s0.d.cts} +1 -1
  4. package/dist/backend/drizzle/engine/index.cjs +13 -13
  5. package/dist/backend/drizzle/engine/index.d.cts +9 -9
  6. package/dist/backend/drizzle/engine/index.d.ts +9 -9
  7. package/dist/backend/drizzle/engine/index.js +8 -8
  8. package/dist/backend/drizzle/indexes.d.cts +1 -1
  9. package/dist/backend/drizzle/indexes.d.ts +1 -1
  10. package/dist/backend/index.cjs +91 -91
  11. package/dist/backend/index.d.cts +7 -7
  12. package/dist/backend/index.d.ts +7 -7
  13. package/dist/backend/index.js +8 -8
  14. package/dist/backend/postgres/index.cjs +23 -23
  15. package/dist/backend/postgres/index.d.cts +8 -8
  16. package/dist/backend/postgres/index.d.ts +8 -8
  17. package/dist/backend/postgres/index.js +8 -8
  18. package/dist/backend/postgres/pglite-store.cjs +1 -1
  19. package/dist/backend/postgres/pglite-store.d.cts +6 -6
  20. package/dist/backend/postgres/pglite-store.d.ts +6 -6
  21. package/dist/backend/postgres/pglite-store.js +1 -1
  22. package/dist/backend/postgres/pglite.cjs +10 -10
  23. package/dist/backend/postgres/pglite.d.cts +3 -3
  24. package/dist/backend/postgres/pglite.d.ts +3 -3
  25. package/dist/backend/postgres/pglite.js +9 -9
  26. package/dist/backend/sqlite/index.cjs +21 -21
  27. package/dist/backend/sqlite/index.d.cts +7 -7
  28. package/dist/backend/sqlite/index.d.ts +7 -7
  29. package/dist/backend/sqlite/index.js +8 -8
  30. package/dist/backend/sqlite/libsql.cjs +14 -14
  31. package/dist/backend/sqlite/libsql.d.cts +3 -3
  32. package/dist/backend/sqlite/libsql.d.ts +3 -3
  33. package/dist/backend/sqlite/libsql.js +8 -8
  34. package/dist/backend/sqlite/local-store.cjs +1 -1
  35. package/dist/backend/sqlite/local-store.d.cts +6 -6
  36. package/dist/backend/sqlite/local-store.d.ts +6 -6
  37. package/dist/backend/sqlite/local-store.js +1 -1
  38. package/dist/backend/sqlite/local.cjs +10 -10
  39. package/dist/backend/sqlite/local.d.cts +3 -3
  40. package/dist/backend/sqlite/local.d.ts +3 -3
  41. package/dist/backend/sqlite/local.js +9 -9
  42. package/dist/{chunk-337ONI2I.js → chunk-3SUZXB5X.js} +146 -80
  43. package/dist/chunk-3SUZXB5X.js.map +1 -0
  44. package/dist/{chunk-4VTCIEK3.js → chunk-4TQOIBWH.js} +3 -3
  45. package/dist/{chunk-4VTCIEK3.js.map → chunk-4TQOIBWH.js.map} +1 -1
  46. package/dist/{chunk-JRWKRBI5.cjs → chunk-5JOCIMQ3.cjs} +6 -6
  47. package/dist/{chunk-JRWKRBI5.cjs.map → chunk-5JOCIMQ3.cjs.map} +1 -1
  48. package/dist/{chunk-BWQA3POT.cjs → chunk-6B3LQUYG.cjs} +206 -138
  49. package/dist/chunk-6B3LQUYG.cjs.map +1 -0
  50. package/dist/{chunk-RQPCUHIH.js → chunk-6ECNYQDW.js} +3 -3
  51. package/dist/{chunk-RQPCUHIH.js.map → chunk-6ECNYQDW.js.map} +1 -1
  52. package/dist/{chunk-OLB75LRQ.js → chunk-6GKKAQMW.js} +5 -5
  53. package/dist/{chunk-OLB75LRQ.js.map → chunk-6GKKAQMW.js.map} +1 -1
  54. package/dist/{chunk-OC5ROP7V.cjs → chunk-6JRVV2SS.cjs} +8 -2
  55. package/dist/chunk-6JRVV2SS.cjs.map +1 -0
  56. package/dist/{chunk-JERQGJKG.cjs → chunk-732VS5PW.cjs} +18 -18
  57. package/dist/{chunk-JERQGJKG.cjs.map → chunk-732VS5PW.cjs.map} +1 -1
  58. package/dist/{chunk-DSX3P4S5.cjs → chunk-76OB5RSH.cjs} +6 -6
  59. package/dist/{chunk-DSX3P4S5.cjs.map → chunk-76OB5RSH.cjs.map} +1 -1
  60. package/dist/{chunk-DHRLOQLQ.cjs → chunk-7LQTDGV5.cjs} +11 -11
  61. package/dist/{chunk-DHRLOQLQ.cjs.map → chunk-7LQTDGV5.cjs.map} +1 -1
  62. package/dist/{chunk-Q25QYSOH.js → chunk-7YJHUY4T.js} +9 -9
  63. package/dist/{chunk-Q25QYSOH.js.map → chunk-7YJHUY4T.js.map} +1 -1
  64. package/dist/{chunk-BBOMNH44.js → chunk-BABP4D5B.js} +3 -3
  65. package/dist/{chunk-BBOMNH44.js.map → chunk-BABP4D5B.js.map} +1 -1
  66. package/dist/{chunk-EVGZ2TRQ.js → chunk-BE75G3M5.js} +3 -3
  67. package/dist/{chunk-EVGZ2TRQ.js.map → chunk-BE75G3M5.js.map} +1 -1
  68. package/dist/{chunk-FXGZT3WO.cjs → chunk-BX42F7IJ.cjs} +41 -41
  69. package/dist/{chunk-FXGZT3WO.cjs.map → chunk-BX42F7IJ.cjs.map} +1 -1
  70. package/dist/{chunk-VROJKWZ7.js → chunk-C3HNC3S6.js} +5 -5
  71. package/dist/{chunk-VROJKWZ7.js.map → chunk-C3HNC3S6.js.map} +1 -1
  72. package/dist/{chunk-G6T23JU7.js → chunk-CDKNGCE7.js} +3 -3
  73. package/dist/{chunk-G6T23JU7.js.map → chunk-CDKNGCE7.js.map} +1 -1
  74. package/dist/{chunk-BNTJ5YFO.cjs → chunk-EACDHXJL.cjs} +4 -4
  75. package/dist/{chunk-BNTJ5YFO.cjs.map → chunk-EACDHXJL.cjs.map} +1 -1
  76. package/dist/{chunk-SNDJUTMB.cjs → chunk-EBQX7MYL.cjs} +72 -72
  77. package/dist/{chunk-SNDJUTMB.cjs.map → chunk-EBQX7MYL.cjs.map} +1 -1
  78. package/dist/{chunk-GKSAEUX6.js → chunk-FXOFJ4FS.js} +7 -7
  79. package/dist/{chunk-GKSAEUX6.js.map → chunk-FXOFJ4FS.js.map} +1 -1
  80. package/dist/{chunk-ZOWRACZQ.cjs → chunk-G7OKJDMG.cjs} +5 -5
  81. package/dist/{chunk-ZOWRACZQ.cjs.map → chunk-G7OKJDMG.cjs.map} +1 -1
  82. package/dist/{chunk-VZRXXABW.js → chunk-HSLP6CVG.js} +5 -5
  83. package/dist/{chunk-VZRXXABW.js.map → chunk-HSLP6CVG.js.map} +1 -1
  84. package/dist/{chunk-MKJPBSID.cjs → chunk-I7SBZJI2.cjs} +4 -4
  85. package/dist/{chunk-MKJPBSID.cjs.map → chunk-I7SBZJI2.cjs.map} +1 -1
  86. package/dist/{chunk-H346QK3V.cjs → chunk-K7YACILO.cjs} +9 -9
  87. package/dist/{chunk-H346QK3V.cjs.map → chunk-K7YACILO.cjs.map} +1 -1
  88. package/dist/{chunk-L2GBVYRU.cjs → chunk-MGCPSR4C.cjs} +11 -11
  89. package/dist/{chunk-L2GBVYRU.cjs.map → chunk-MGCPSR4C.cjs.map} +1 -1
  90. package/dist/{chunk-KDNRACRG.cjs → chunk-MRUOOAIQ.cjs} +4 -4
  91. package/dist/{chunk-KDNRACRG.cjs.map → chunk-MRUOOAIQ.cjs.map} +1 -1
  92. package/dist/{chunk-PFXNQFFY.js → chunk-MUEPEWMQ.js} +67 -8
  93. package/dist/chunk-MUEPEWMQ.js.map +1 -0
  94. package/dist/{chunk-HTSJTWUT.js → chunk-OF63ZHSD.js} +4 -4
  95. package/dist/{chunk-HTSJTWUT.js.map → chunk-OF63ZHSD.js.map} +1 -1
  96. package/dist/{chunk-NGA3THGU.cjs → chunk-QR7W37HG.cjs} +14 -14
  97. package/dist/{chunk-NGA3THGU.cjs.map → chunk-QR7W37HG.cjs.map} +1 -1
  98. package/dist/{chunk-QFEO4M5W.js → chunk-RTPMG6LQ.js} +11 -11
  99. package/dist/{chunk-QFEO4M5W.js.map → chunk-RTPMG6LQ.js.map} +1 -1
  100. package/dist/{chunk-PFD4NUYV.js → chunk-SSDHR2C2.js} +3 -3
  101. package/dist/{chunk-PFD4NUYV.js.map → chunk-SSDHR2C2.js.map} +1 -1
  102. package/dist/{chunk-THK3SCQA.js → chunk-SYXTWPX6.js} +5 -5
  103. package/dist/{chunk-THK3SCQA.js.map → chunk-SYXTWPX6.js.map} +1 -1
  104. package/dist/{chunk-XSLQYGNR.cjs → chunk-T3VU3YRQ.cjs} +69 -69
  105. package/dist/{chunk-XSLQYGNR.cjs.map → chunk-T3VU3YRQ.cjs.map} +1 -1
  106. package/dist/{chunk-MIBWA6HX.js → chunk-TR7QTODF.js} +213 -33
  107. package/dist/chunk-TR7QTODF.js.map +1 -0
  108. package/dist/{chunk-AD3NLSV5.js → chunk-TU22BFMP.js} +8 -2
  109. package/dist/chunk-TU22BFMP.js.map +1 -0
  110. package/dist/{chunk-WTMSUIRO.js → chunk-UFKYMQJ5.js} +3 -3
  111. package/dist/{chunk-WTMSUIRO.js.map → chunk-UFKYMQJ5.js.map} +1 -1
  112. package/dist/{chunk-35LDKSMM.cjs → chunk-VNJMM2QQ.cjs} +30 -30
  113. package/dist/{chunk-35LDKSMM.cjs.map → chunk-VNJMM2QQ.cjs.map} +1 -1
  114. package/dist/{chunk-53ZEBIMD.js → chunk-WB55URNM.js} +6 -6
  115. package/dist/{chunk-53ZEBIMD.js.map → chunk-WB55URNM.js.map} +1 -1
  116. package/dist/{chunk-D2JPOFRZ.cjs → chunk-WY3IFEKV.cjs} +191 -191
  117. package/dist/{chunk-D2JPOFRZ.cjs.map → chunk-WY3IFEKV.cjs.map} +1 -1
  118. package/dist/{chunk-3KWF25MF.cjs → chunk-XQNKN3UF.cjs} +305 -246
  119. package/dist/chunk-XQNKN3UF.cjs.map +1 -0
  120. package/dist/{chunk-3RSFLZ7A.cjs → chunk-Y4X6ODVY.cjs} +943 -763
  121. package/dist/chunk-Y4X6ODVY.cjs.map +1 -0
  122. package/dist/core/index.d.cts +3 -3
  123. package/dist/core/index.d.ts +3 -3
  124. package/dist/{ddl-DvW9aobX.d.ts → ddl-2q7xLM1X.d.ts} +3 -3
  125. package/dist/{ddl-BjuXbPfw.d.cts → ddl-D_09BfbN.d.cts} +3 -3
  126. package/dist/graph-extension/index.d.cts +2 -2
  127. package/dist/graph-extension/index.d.ts +2 -2
  128. package/dist/graph-merge/index.cjs +156 -156
  129. package/dist/graph-merge/index.d.cts +7 -7
  130. package/dist/graph-merge/index.d.ts +7 -7
  131. package/dist/graph-merge/index.js +14 -14
  132. package/dist/{graph-templates-1vMqlPsu.d.cts → graph-templates-B5Q7oYAA.d.cts} +2 -2
  133. package/dist/{graph-templates-Y52w16dH.d.ts → graph-templates-D9N-Z9kw.d.ts} +2 -2
  134. package/dist/index.cjs +99 -99
  135. package/dist/index.d.cts +10 -10
  136. package/dist/index.d.ts +10 -10
  137. package/dist/index.js +18 -18
  138. package/dist/indexes/index.d.cts +4 -4
  139. package/dist/indexes/index.d.ts +4 -4
  140. package/dist/{ingestion-import-target-CCKeXZbW.d.ts → ingestion-import-target-B8EU6ug2.d.ts} +1 -1
  141. package/dist/{ingestion-import-target-774QRgkF.d.cts → ingestion-import-target-C5sHNFJF.d.cts} +1 -1
  142. package/dist/interchange/index.cjs +34 -34
  143. package/dist/interchange/index.d.cts +7 -7
  144. package/dist/interchange/index.d.ts +7 -7
  145. package/dist/interchange/index.js +11 -11
  146. package/dist/{local-store-impl-3E4VLFCI.cjs → local-store-impl-J6TJG45N.cjs} +22 -22
  147. package/dist/{local-store-impl-3E4VLFCI.cjs.map → local-store-impl-J6TJG45N.cjs.map} +1 -1
  148. package/dist/{local-store-impl-DFKS7QTV.js → local-store-impl-XKWR46WQ.js} +18 -18
  149. package/dist/{local-store-impl-DFKS7QTV.js.map → local-store-impl-XKWR46WQ.js.map} +1 -1
  150. package/dist/{pglite-store-impl-T75O3LVQ.cjs → pglite-store-impl-KXD5VWC5.cjs} +22 -22
  151. package/dist/{pglite-store-impl-T75O3LVQ.cjs.map → pglite-store-impl-KXD5VWC5.cjs.map} +1 -1
  152. package/dist/{pglite-store-impl-N63GGBU2.js → pglite-store-impl-LRZ4TO3H.js} +18 -18
  153. package/dist/{pglite-store-impl-N63GGBU2.js.map → pglite-store-impl-LRZ4TO3H.js.map} +1 -1
  154. package/dist/{postgres-2FYdVYCm.d.cts → postgres-BIm6TDfF.d.cts} +3 -3
  155. package/dist/{postgres-C9gitL71.d.ts → postgres-CRRB2qzy.d.ts} +3 -3
  156. package/dist/{postgres-BONrXHb4.d.cts → postgres-DOBXcZVg.d.cts} +1 -1
  157. package/dist/{postgres-DAFRdnTr.d.ts → postgres-DhZixg92.d.ts} +1 -1
  158. package/dist/{profile-Bmcg07Ki.d.cts → profile-CjAffcQt.d.cts} +2 -2
  159. package/dist/{profile-CAD65CqS.d.ts → profile-DVd70NA-.d.ts} +2 -2
  160. package/dist/profiler/index.d.cts +8 -8
  161. package/dist/profiler/index.d.ts +8 -8
  162. package/dist/provenance/index.cjs +22 -22
  163. package/dist/provenance/index.d.cts +6 -6
  164. package/dist/provenance/index.d.ts +6 -6
  165. package/dist/provenance/index.js +6 -6
  166. package/dist/{repair-validity-windows-CinP91t7.d.cts → repair-validity-windows-CpP_GpIx.d.cts} +1 -1
  167. package/dist/{repair-validity-windows-BJz4nffP.d.ts → repair-validity-windows-lfe275bY.d.ts} +1 -1
  168. package/dist/{resolve-DgOSlXx_.d.ts → resolve-CoYqHqno.d.cts} +7 -2
  169. package/dist/{resolve-DQXSEN_A.d.cts → resolve-DV0Iposp.d.ts} +7 -2
  170. package/dist/schema/index.cjs +37 -37
  171. package/dist/schema/index.d.cts +7 -7
  172. package/dist/schema/index.d.ts +7 -7
  173. package/dist/schema/index.js +7 -7
  174. package/dist/{searchable-DMdCwkXO.d.cts → searchable-C7Xt6g45.d.cts} +1 -1
  175. package/dist/{searchable-BPRF0Bah.d.ts → searchable-KKXrPet3.d.ts} +1 -1
  176. package/dist/{sqlite-DcDAAYow.d.ts → sqlite-BNwQ5pd7.d.ts} +3 -3
  177. package/dist/{sqlite-DgbYa-1Y.d.cts → sqlite-BkQM9ZeI.d.cts} +1 -1
  178. package/dist/{sqlite-UlG5prJQ.d.ts → sqlite-CcCSeXGg.d.ts} +1 -1
  179. package/dist/{sqlite-Co_uIpfs.d.cts → sqlite-DX9H3L7z.d.cts} +3 -3
  180. package/dist/{store-HxoFyQMu.d.cts → store-3nfPQK5j.d.cts} +30 -7
  181. package/dist/{store-C9T1c9Az.d.ts → store-C8ZPl7OW.d.ts} +30 -7
  182. package/dist/{types-CRCyg1fJ.d.cts → types-BynPp5kU.d.cts} +18 -2
  183. package/dist/{types-CRCyg1fJ.d.ts → types-BynPp5kU.d.ts} +18 -2
  184. package/dist/{types-Dg_prBqC.d.ts → types-C9YwrkSe.d.ts} +1 -1
  185. package/dist/{types-B5AUesS1.d.cts → types-JG-4CG6P.d.cts} +1 -1
  186. package/dist/{where-gRyc3jj_.d.cts → where-D1gBDqQ_.d.cts} +1 -1
  187. package/dist/{where-D-NDKMPw.d.ts → where-D2GqMFp-.d.ts} +1 -1
  188. package/package.json +1 -1
  189. package/dist/chunk-337ONI2I.js.map +0 -1
  190. package/dist/chunk-3KWF25MF.cjs.map +0 -1
  191. package/dist/chunk-3RSFLZ7A.cjs.map +0 -1
  192. package/dist/chunk-AD3NLSV5.js.map +0 -1
  193. package/dist/chunk-BWQA3POT.cjs.map +0 -1
  194. package/dist/chunk-MIBWA6HX.js.map +0 -1
  195. package/dist/chunk-OC5ROP7V.cjs.map +0 -1
  196. package/dist/chunk-PFXNQFFY.js.map +0 -1
@@ -1,10 +1,10 @@
1
1
  'use strict';
2
2
 
3
3
  var chunkQCD5JKU4_cjs = require('./chunk-QCD5JKU4.cjs');
4
- var chunk3KWF25MF_cjs = require('./chunk-3KWF25MF.cjs');
4
+ var chunkXQNKN3UF_cjs = require('./chunk-XQNKN3UF.cjs');
5
5
  var chunkCBHZX3G5_cjs = require('./chunk-CBHZX3G5.cjs');
6
- var chunkMKJPBSID_cjs = require('./chunk-MKJPBSID.cjs');
7
- var chunkOC5ROP7V_cjs = require('./chunk-OC5ROP7V.cjs');
6
+ var chunkI7SBZJI2_cjs = require('./chunk-I7SBZJI2.cjs');
7
+ var chunk6JRVV2SS_cjs = require('./chunk-6JRVV2SS.cjs');
8
8
  var chunk7XYPLAPL_cjs = require('./chunk-7XYPLAPL.cjs');
9
9
  var module$1 = require('module');
10
10
  var Database = require('better-sqlite3');
@@ -16,26 +16,26 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
16
16
 
17
17
  var Database__default = /*#__PURE__*/_interopDefault(Database);
18
18
 
19
- var nodeRequire = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunk-JERQGJKG.cjs', document.baseURI).href)));
19
+ var nodeRequire = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunk-732VS5PW.cjs', document.baseURI).href)));
20
20
  function installLocalSqliteBaseSchema(sqlite, tables2, fulltextStrategy) {
21
- if (chunk3KWF25MF_cjs.CURRENT_BASE_SCHEMA_VERSION !== 3) {
21
+ if (chunkXQNKN3UF_cjs.CURRENT_BASE_SCHEMA_VERSION !== 3) {
22
22
  throw new chunk7XYPLAPL_cjs.CompilerInvariantError(
23
23
  "The synchronous managed SQLite installation path only implements base-schema v1 through v3 adoption.",
24
- { currentVersion: chunk3KWF25MF_cjs.CURRENT_BASE_SCHEMA_VERSION }
24
+ { currentVersion: chunkXQNKN3UF_cjs.CURRENT_BASE_SCHEMA_VERSION }
25
25
  );
26
26
  }
27
- const installationSql = chunk3KWF25MF_cjs.generateSqliteMigrationSQL(tables2, fulltextStrategy);
27
+ const installationSql = chunkXQNKN3UF_cjs.generateSqliteMigrationSQL(tables2, fulltextStrategy);
28
28
  try {
29
29
  sqlite.exec(installationSql);
30
30
  } catch (error) {
31
- if (!chunkOC5ROP7V_cjs.isSqliteMissingEdgeMatchIdentityColumnError(error)) throw error;
31
+ if (!chunk6JRVV2SS_cjs.isSqliteMissingEdgeMatchIdentityColumnError(error)) throw error;
32
32
  const edgeTableName = drizzleOrm.getTableName(tables2.edges);
33
33
  for (let attempt = 0; attempt < 3; attempt += 1) {
34
- const rows = sqlite.prepare(`PRAGMA table_info(${chunk3KWF25MF_cjs.quoteDdlIdentifier(edgeTableName)})`).all();
34
+ const rows = sqlite.prepare(`PRAGMA table_info(${chunkXQNKN3UF_cjs.quoteDdlIdentifier(edgeTableName)})`).all();
35
35
  const columns = new Set(
36
36
  rows.flatMap((row) => typeof row.name === "string" ? [row.name] : [])
37
37
  );
38
- const adoptionSql = chunk3KWF25MF_cjs.planSqliteEdgeMatchIdentityAdoption(
38
+ const adoptionSql = chunkXQNKN3UF_cjs.planSqliteEdgeMatchIdentityAdoption(
39
39
  edgeTableName,
40
40
  columns
41
41
  );
@@ -43,7 +43,7 @@ function installLocalSqliteBaseSchema(sqlite, tables2, fulltextStrategy) {
43
43
  sqlite.exec([...adoptionSql, installationSql].join("\n"));
44
44
  return;
45
45
  } catch (repairError) {
46
- if (attempt === 2 || !chunkOC5ROP7V_cjs.isSqliteDuplicateEdgeMatchIdentityColumnError(repairError)) {
46
+ if (attempt === 2 || !chunk6JRVV2SS_cjs.isSqliteDuplicateEdgeMatchIdentityColumnError(repairError)) {
47
47
  throw repairError;
48
48
  }
49
49
  }
@@ -162,16 +162,16 @@ function applyConnectionPragmas(sqlite, pragmas) {
162
162
  }
163
163
  }
164
164
  function createLocalSqliteBackend(options = {}) {
165
- chunk3KWF25MF_cjs.assertNoLegacyTransactionCapability(options.capabilities);
165
+ chunkXQNKN3UF_cjs.assertNoLegacyTransactionCapability(options.capabilities);
166
166
  const path = options.path ?? ":memory:";
167
- const tables2 = options.tables ?? chunk3KWF25MF_cjs.tables2;
167
+ const tables2 = options.tables ?? chunkXQNKN3UF_cjs.tables2;
168
168
  const sqlite = createDatabase(path);
169
169
  try {
170
170
  applyConnectionPragmas(sqlite, options.pragmas);
171
171
  const hasSqliteVec = tryLoadSqliteVec(sqlite);
172
172
  const db = betterSqlite3.drizzle(sqlite);
173
173
  installLocalSqliteBaseSchema(sqlite, tables2, options.fulltext);
174
- const backend = chunk3KWF25MF_cjs.createSqliteBackend(db, {
174
+ const backend = chunkXQNKN3UF_cjs.createSqliteBackend(db, {
175
175
  ...options.schemaProvisioning === void 0 ? {} : { schemaProvisioning: options.schemaProvisioning },
176
176
  executionProfile: {
177
177
  isSync: true
@@ -187,10 +187,10 @@ function createLocalSqliteBackend(options = {}) {
187
187
  }
188
188
  }
189
189
  });
190
- const managedBackend = chunkOC5ROP7V_cjs.wrapWithManagedClose(backend, () => {
190
+ const managedBackend = chunk6JRVV2SS_cjs.wrapWithManagedClose(backend, () => {
191
191
  sqlite.close();
192
192
  });
193
- return { backend: chunkMKJPBSID_cjs.markBundledRootAutocommitEligible(managedBackend), db };
193
+ return { backend: chunkI7SBZJI2_cjs.markBundledRootAutocommitEligible(managedBackend), db };
194
194
  } catch (error) {
195
195
  try {
196
196
  sqlite.close();
@@ -213,5 +213,5 @@ function tryLoadSqliteVec(sqlite) {
213
213
  }
214
214
 
215
215
  exports.createLocalSqliteBackend = createLocalSqliteBackend;
216
- //# sourceMappingURL=chunk-JERQGJKG.cjs.map
217
- //# sourceMappingURL=chunk-JERQGJKG.cjs.map
216
+ //# sourceMappingURL=chunk-732VS5PW.cjs.map
217
+ //# sourceMappingURL=chunk-732VS5PW.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/backend/sqlite/local.ts"],"names":["createRequire","tables","CURRENT_BASE_SCHEMA_VERSION","CompilerInvariantError","generateSqliteMigrationSQL","isSqliteMissingEdgeMatchIdentityColumnError","getTableName","quoteDdlIdentifier","planSqliteEdgeMatchIdentityAdoption","isSqliteDuplicateEdgeMatchIdentityColumnError","Database","ConfigurationError","DEFAULT_LOCAL_SQLITE_PRAGMAS","assertNoLegacyTransactionCapability","drizzle","createSqliteBackend","sqliteVecStrategy","wrapWithManagedClose","markBundledRootAutocommitEligible"],"mappings":"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","file":"chunk-JERQGJKG.cjs","sourcesContent":["/**\n * Local SQLite backend using better-sqlite3.\n *\n * This module depends on the `better-sqlite3` native addon and should only\n * be imported in Node.js environments. For bundler-friendly SQLite DDL\n * generation and Drizzle backend creation, import from `@nicia-ai/typegraph/adapters/drizzle/sqlite`.\n *\n * @example In-memory database (default)\n * ```typescript\n * import { createLocalSqliteBackend } from \"@nicia-ai/typegraph/adapters/drizzle/sqlite/local\";\n *\n * const { backend, db } = createLocalSqliteBackend();\n * const store = createStore(graph, backend);\n * ```\n *\n * @example File-based database for persistent local development\n * ```typescript\n * import { createLocalSqliteBackend } from \"@nicia-ai/typegraph/adapters/drizzle/sqlite/local\";\n *\n * const { backend, db } = createLocalSqliteBackend({ path: \"./dev.db\" });\n * const store = createStore(graph, backend);\n * ```\n */\nimport { createRequire } from \"node:module\";\n\nimport Database from \"better-sqlite3\";\nimport { getTableName } from \"drizzle-orm\";\nimport {\n type BetterSQLite3Database,\n drizzle,\n} from \"drizzle-orm/better-sqlite3\";\n\nimport { CompilerInvariantError, ConfigurationError } from \"../../errors\";\nimport { type FulltextStrategy } from \"../../query/dialect/fulltext-strategy\";\nimport { sqliteVecStrategy } from \"../../query/dialect/vector/sqlite-vec-strategy\";\nimport {\n isSqliteDuplicateEdgeMatchIdentityColumnError,\n isSqliteMissingEdgeMatchIdentityColumnError,\n} from \"../../utils/sql-errors\";\nimport { markBundledRootAutocommitEligible } from \"../capabilities/autocommit-single-statement\";\nimport { wrapWithManagedClose } from \"../derive-backend\";\nimport { CURRENT_BASE_SCHEMA_VERSION } from \"../drizzle/base-schema\";\nimport {\n generateSqliteMigrationSQL,\n planSqliteEdgeMatchIdentityAdoption,\n quoteDdlIdentifier,\n} from \"../drizzle/ddl\";\nimport { type AnySqliteDatabase } from \"../drizzle/execution\";\nexport type { AnySqliteDatabase } from \"../drizzle/execution\";\nimport { assertNoLegacyTransactionCapability } from \"../capabilities/declarations\";\nimport {\n createSqliteBackend,\n type SqliteTables,\n tables as defaultTables,\n} from \"../drizzle/sqlite\";\nimport {\n DEFAULT_LOCAL_SQLITE_PRAGMAS,\n type LocalSqliteJournalMode,\n type LocalSqlitePragmaOptions,\n type LocalSqliteSynchronousMode,\n} from \"./local-options\";\n\nexport {\n DEFAULT_LOCAL_SQLITE_PRAGMAS,\n type LocalSqliteJournalMode,\n type LocalSqlitePragmaOptions,\n type LocalSqliteSynchronousMode,\n} from \"./local-options\";\nimport {\n type AdapterBackend,\n type BundledBackendCapabilityOverrides,\n type SchemaProvisioning,\n} from \"../types\";\nexport type { BundledBackendCapabilityOverrides } from \"../types\";\nexport type {\n ContributionDiagnostic,\n ContributionDiagnosticState,\n ContributionRepairEntry,\n ContributionRepairResult,\n} from \"../types\";\n\nconst nodeRequire = createRequire(import.meta.url);\n\nfunction installLocalSqliteBaseSchema(\n sqlite: Database.Database,\n tables: SqliteTables,\n fulltextStrategy: FulltextStrategy | false | undefined,\n): void {\n // v2 (the fences relation) and v3 (the recorded-relations' and recorded\n // identity-assertions relation's `since_idx` indexes) need no adoption\n // logic beyond what `generateSqliteMigrationSQL` already emits: a\n // brand-new relation or index is fully covered by its own `CREATE TABLE\n // IF NOT EXISTS` / `CREATE INDEX IF NOT EXISTS`, on both a fresh database\n // and one that already has every OTHER base table or index. Only v1's\n // edge-match-identity `ADD COLUMN` migration — handled by the catch block\n // below — needed runtime introspection this synchronous path writes by\n // hand instead of running `BaseSchemaLifecycle`'s async state machine.\n if (CURRENT_BASE_SCHEMA_VERSION !== 3) {\n throw new CompilerInvariantError(\n \"The synchronous managed SQLite installation path only implements base-schema v1 through v3 adoption.\",\n { currentVersion: CURRENT_BASE_SCHEMA_VERSION },\n );\n }\n const installationSql = generateSqliteMigrationSQL(tables, fulltextStrategy);\n try {\n sqlite.exec(installationSql);\n } catch (error) {\n if (!isSqliteMissingEdgeMatchIdentityColumnError(error)) throw error;\n const edgeTableName = getTableName(tables.edges);\n for (let attempt = 0; attempt < 3; attempt += 1) {\n const rows = sqlite\n .prepare(`PRAGMA table_info(${quoteDdlIdentifier(edgeTableName)})`)\n .all() as readonly Readonly<{ name?: unknown }>[];\n const columns = new Set(\n rows.flatMap((row) => (typeof row.name === \"string\" ? [row.name] : [])),\n );\n const adoptionSql = planSqliteEdgeMatchIdentityAdoption(\n edgeTableName,\n columns,\n );\n try {\n sqlite.exec([...adoptionSql, installationSql].join(\"\\n\"));\n return;\n } catch (repairError) {\n if (\n attempt === 2 ||\n !isSqliteDuplicateEdgeMatchIdentityColumnError(repairError)\n ) {\n throw repairError;\n }\n }\n }\n throw new CompilerInvariantError(\n \"Local SQLite match-identity adoption exhausted its retry loop without returning or throwing.\",\n );\n }\n}\n\n// ============================================================\n// Native Addon Helpers\n// ============================================================\n\ntype NodeModuleVersionMismatch = Readonly<{\n compiled: number;\n required: number;\n}>;\n\nfunction getUnknownErrorMessage(error: unknown): string {\n if (error instanceof Error) return error.message;\n return String(error);\n}\n\nfunction parseNodeModuleVersionMismatchMessage(\n message: string,\n): NodeModuleVersionMismatch | undefined {\n const regexp =\n /NODE_MODULE_VERSION (?<compiled>\\d+)[\\s\\S]*?NODE_MODULE_VERSION (?<required>\\d+)/;\n const match = regexp.exec(message);\n if (!match?.groups) return undefined;\n\n const compiled = Number(match.groups[\"compiled\"]);\n const required = Number(match.groups[\"required\"]);\n\n if (!Number.isFinite(compiled) || !Number.isFinite(required))\n return undefined;\n\n return { compiled, required };\n}\n\nfunction createDatabase(path: string): Database.Database {\n try {\n return new Database(path);\n } catch (error) {\n const message = getUnknownErrorMessage(error);\n const mismatch = parseNodeModuleVersionMismatchMessage(message);\n if (!mismatch) throw error;\n\n throw new ConfigurationError(\n [\n \"Failed to load better-sqlite3 native addon.\",\n `It was compiled for NODE_MODULE_VERSION ${mismatch.compiled}, but this Node.js runtime requires ${mismatch.required}.`,\n \"This usually happens after switching Node versions without rebuilding native dependencies.\",\n \"Rebuild with: pnpm rebuild better-sqlite3 (or npm rebuild better-sqlite3).\",\n ].join(\" \"),\n {\n nodeVersion: process.version,\n nodeModuleVersion: process.versions.modules,\n compiledNodeModuleVersion: mismatch.compiled,\n requiredNodeModuleVersion: mismatch.required,\n },\n { cause: error },\n );\n }\n}\n\n// ============================================================\n// Types\n// ============================================================\n\nconst LOCAL_SQLITE_JOURNAL_MODES: readonly LocalSqliteJournalMode[] = [\n \"wal\",\n \"delete\",\n \"truncate\",\n \"persist\",\n \"memory\",\n \"off\",\n];\n\nconst LOCAL_SQLITE_SYNCHRONOUS_MODES: readonly LocalSqliteSynchronousMode[] = [\n \"off\",\n \"normal\",\n \"full\",\n \"extra\",\n];\n\nconst SQLITE_MAX_WAL_AUTOCHECKPOINT_PAGES = 2_147_483_647;\n\nfunction applyConnectionPragmas(\n sqlite: Database.Database,\n pragmas: LocalSqlitePragmaOptions | false | undefined,\n): void {\n if (pragmas === false) return;\n const resolved: Required<LocalSqlitePragmaOptions> = {\n ...DEFAULT_LOCAL_SQLITE_PRAGMAS,\n ...pragmas,\n };\n\n // Runtime guards mirror the compile-time unions: pragma values are spliced\n // into pragma statements, so reject anything outside the allowlists rather\n // than forwarding it to SQLite.\n if (!LOCAL_SQLITE_JOURNAL_MODES.includes(resolved.journalMode)) {\n throw new ConfigurationError(\n `Invalid journalMode pragma: ${resolved.journalMode}. ` +\n `Expected one of: ${LOCAL_SQLITE_JOURNAL_MODES.join(\", \")}.`,\n { journalMode: resolved.journalMode },\n );\n }\n if (!LOCAL_SQLITE_SYNCHRONOUS_MODES.includes(resolved.synchronous)) {\n throw new ConfigurationError(\n `Invalid synchronous pragma: ${resolved.synchronous}. ` +\n `Expected one of: ${LOCAL_SQLITE_SYNCHRONOUS_MODES.join(\", \")}.`,\n { synchronous: resolved.synchronous },\n );\n }\n if (\n !Number.isSafeInteger(resolved.busyTimeoutMs) ||\n resolved.busyTimeoutMs < 0\n ) {\n throw new ConfigurationError(\n `Invalid busyTimeoutMs pragma: ${String(resolved.busyTimeoutMs)}. ` +\n \"Expected a non-negative integer number of milliseconds.\",\n { busyTimeoutMs: resolved.busyTimeoutMs },\n );\n }\n if (\n resolved.cacheSizeKib !== undefined &&\n (!Number.isSafeInteger(resolved.cacheSizeKib) || resolved.cacheSizeKib >= 0)\n ) {\n throw new ConfigurationError(\n `Invalid cacheSizeKib pragma: ${String(resolved.cacheSizeKib)}. ` +\n \"Expected a negative safe integer — SQLite's own cache_size pragma \" +\n \"interprets a positive value as a page count, not KiB, so a caller \" +\n 'who passes e.g. 131072 meaning \"131072 KiB\" silently gets ' +\n \"131072 pages (~512MiB at the default 4KiB page size) instead.\",\n { cacheSizeKib: resolved.cacheSizeKib },\n );\n }\n if (\n resolved.mmapSizeBytes !== undefined &&\n (!Number.isSafeInteger(resolved.mmapSizeBytes) ||\n resolved.mmapSizeBytes < 0)\n ) {\n throw new ConfigurationError(\n `Invalid mmapSizeBytes pragma: ${String(resolved.mmapSizeBytes)}. ` +\n \"Expected a non-negative safe integer number of bytes.\",\n { mmapSizeBytes: resolved.mmapSizeBytes },\n );\n }\n if (\n resolved.walAutocheckpointPages !== undefined &&\n (!Number.isSafeInteger(resolved.walAutocheckpointPages) ||\n resolved.walAutocheckpointPages < 0 ||\n resolved.walAutocheckpointPages > SQLITE_MAX_WAL_AUTOCHECKPOINT_PAGES)\n ) {\n throw new ConfigurationError(\n `Invalid walAutocheckpointPages pragma: ${String(resolved.walAutocheckpointPages)}. ` +\n `Expected an integer between 0 and ${SQLITE_MAX_WAL_AUTOCHECKPOINT_PAGES} ` +\n \"WAL pages (0 disables automatic checkpointing entirely).\",\n { walAutocheckpointPages: resolved.walAutocheckpointPages },\n );\n }\n\n // \":memory:\" databases always journal in memory; SQLite answers the WAL\n // request with \"memory\" instead of erroring, so no special-casing needed.\n sqlite.pragma(`journal_mode = ${resolved.journalMode}`);\n sqlite.pragma(`synchronous = ${resolved.synchronous}`);\n sqlite.pragma(`busy_timeout = ${resolved.busyTimeoutMs}`);\n if (resolved.cacheSizeKib !== undefined) {\n sqlite.pragma(`cache_size = ${resolved.cacheSizeKib}`);\n }\n if (resolved.mmapSizeBytes !== undefined) {\n sqlite.pragma(`mmap_size = ${resolved.mmapSizeBytes}`);\n }\n if (resolved.walAutocheckpointPages !== undefined) {\n sqlite.pragma(`wal_autocheckpoint = ${resolved.walAutocheckpointPages}`);\n }\n}\n\n/**\n * Options for creating a local SQLite backend.\n */\nexport type LocalSqliteBackendOptions = Readonly<{\n schemaProvisioning?: SchemaProvisioning;\n /**\n * Path to the SQLite database file.\n * Defaults to \":memory:\" for an in-memory database.\n */\n path?: string;\n\n /**\n * Connection pragmas applied at open. Defaults to\n * {@link DEFAULT_LOCAL_SQLITE_PRAGMAS} (WAL, `synchronous=NORMAL`, 5s busy\n * timeout, and SQLite's own tiny built-in page cache / disabled mmap\n * left untouched). Individual values merge over the defaults; pass\n * `false` to skip pragma configuration entirely and keep the driver\n * defaults (rollback journal, `synchronous=FULL`, and better-sqlite3's\n * own 5s busy timeout from its `timeout` constructor option). Set\n * `cacheSizeKib`/`mmapSizeBytes` explicitly once a database's working\n * set is known to exceed SQLite's 2MiB default cache — otherwise every\n * query pays a fresh disk read per page past that tiny working set. Set\n * `walAutocheckpointPages` explicitly for a bulk-insert-heavy workload —\n * SQLite's own default checkpoints every ~4MiB of WAL growth, which gets\n * more expensive as the database file grows over a large load.\n */\n pragmas?: LocalSqlitePragmaOptions | false;\n\n /**\n * Custom table definitions.\n * Defaults to standard TypeGraph table names.\n */\n tables?: SqliteTables;\n\n /**\n * Override the fulltext strategy. Defaults to `fts5Strategy` (SQLite's\n * built-in FTS5 virtual table). Pass `false` to disable fulltext support\n * entirely — the backend then advertises no `capabilities.fulltext` and\n * omits the fulltext CRUD/search methods, and the managed installation\n * never creates the fulltext table. Forwarded to both the installation\n * DDL and `createSqliteBackend`.\n */\n fulltext?: FulltextStrategy | false;\n\n /**\n * Override specific backend capabilities — e.g. to simulate an engine-level\n * gap like missing SQL window functions in tests. Forwarded to\n * createSqliteBackend.\n */\n capabilities?: BundledBackendCapabilityOverrides;\n}>;\n\n/**\n * Result of creating a local SQLite backend.\n */\nexport type LocalSqliteBackendResult = Readonly<{\n /**\n * The GraphBackend instance for use with createStore.\n */\n backend: AdapterBackend<AnySqliteDatabase>;\n\n /**\n * The underlying Drizzle database instance.\n * Useful for direct SQL access or cleanup.\n */\n db: BetterSQLite3Database;\n}>;\n\n// ============================================================\n// Factory Function\n// ============================================================\n\n/**\n * Creates a SQLite backend with minimal configuration.\n *\n * This is a convenience function for local development and testing.\n * It handles database creation, schema migration, and backend setup.\n *\n * For production deployments or custom configurations, use createSqliteBackend\n * directly with your own Drizzle database instance.\n *\n * @param options - Configuration options\n * @returns Backend and database instances\n *\n * @example In-memory database (default)\n * ```typescript\n * const { backend } = createLocalSqliteBackend();\n * const store = createStore(graph, backend);\n * ```\n *\n * @example File-based database\n * ```typescript\n * const { backend, db } = createLocalSqliteBackend({ path: \"./data.db\" });\n * const store = createStore(graph, backend);\n * ```\n */\nexport function createLocalSqliteBackend(\n options: LocalSqliteBackendOptions = {},\n): LocalSqliteBackendResult {\n assertNoLegacyTransactionCapability(options.capabilities);\n const path = options.path ?? \":memory:\";\n const tables = options.tables ?? defaultTables;\n\n const sqlite = createDatabase(path);\n try {\n applyConnectionPragmas(sqlite, options.pragmas);\n\n // Best-effort: load sqlite-vec so embedding fields are persisted to\n // per-`(kind, field)` `vec0` storage. Without it, nodes with\n // `embedding()` fields validate and insert but their vectors are silently\n // dropped. When the user has installed sqlite-vec as a peer dep we load\n // it and wire the strategy; otherwise we proceed without vector support.\n const hasSqliteVec = tryLoadSqliteVec(sqlite);\n\n const db = drizzle(sqlite);\n\n // The managed factory owns a complete fresh installation, including the\n // deployment-wide base-schema marker consumed by verified/runtime-only\n // entrypoints. Raw generateSqliteDDL intentionally omits that marker.\n installLocalSqliteBaseSchema(sqlite, tables, options.fulltext);\n\n const backend = createSqliteBackend(db, {\n ...(options.schemaProvisioning === undefined ?\n {}\n : { schemaProvisioning: options.schemaProvisioning }),\n executionProfile: {\n isSync: true,\n },\n tables,\n ...(hasSqliteVec ? { vector: sqliteVecStrategy } : {}),\n ...(options.fulltext === undefined ? {} : { fulltext: options.fulltext }),\n capabilities: {\n ...options.capabilities,\n graphAnalytics: {\n supported:\n options.capabilities?.graphAnalytics?.supported ??\n options.capabilities?.execution?.interactiveTransactions !== false,\n mathFunctions:\n options.capabilities?.graphAnalytics?.mathFunctions ?? true,\n },\n },\n });\n const managedBackend = wrapWithManagedClose(backend, () => {\n sqlite.close();\n });\n\n return { backend: markBundledRootAutocommitEligible(managedBackend), db };\n } catch (error) {\n try {\n sqlite.close();\n } catch {\n // Preserve the provisioning error; a cleanup failure is secondary.\n }\n throw error;\n }\n}\n\nfunction tryLoadSqliteVec(sqlite: Database.Database): boolean {\n try {\n // `sqlite-vec` is an optional peer dep; resolved via createRequire so\n // bundlers don't mark it as a hard import. Node resolves the package\n // only when it's actually installed.\n const module_: unknown = nodeRequire(\"sqlite-vec\");\n if (\n typeof module_ === \"object\" &&\n module_ !== null &&\n \"load\" in module_ &&\n typeof module_.load === \"function\"\n ) {\n (module_ as { load: (db: Database.Database) => void }).load(sqlite);\n return true;\n }\n return false;\n } catch {\n return false;\n }\n}\nexport type { GraphIdentityConfig } from \"../../core/define-graph\";\n"]}
1
+ {"version":3,"sources":["../src/backend/sqlite/local.ts"],"names":["createRequire","tables","CURRENT_BASE_SCHEMA_VERSION","CompilerInvariantError","generateSqliteMigrationSQL","isSqliteMissingEdgeMatchIdentityColumnError","getTableName","quoteDdlIdentifier","planSqliteEdgeMatchIdentityAdoption","isSqliteDuplicateEdgeMatchIdentityColumnError","Database","ConfigurationError","DEFAULT_LOCAL_SQLITE_PRAGMAS","assertNoLegacyTransactionCapability","drizzle","createSqliteBackend","sqliteVecStrategy","wrapWithManagedClose","markBundledRootAutocommitEligible"],"mappings":"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","file":"chunk-732VS5PW.cjs","sourcesContent":["/**\n * Local SQLite backend using better-sqlite3.\n *\n * This module depends on the `better-sqlite3` native addon and should only\n * be imported in Node.js environments. For bundler-friendly SQLite DDL\n * generation and Drizzle backend creation, import from `@nicia-ai/typegraph/adapters/drizzle/sqlite`.\n *\n * @example In-memory database (default)\n * ```typescript\n * import { createLocalSqliteBackend } from \"@nicia-ai/typegraph/adapters/drizzle/sqlite/local\";\n *\n * const { backend, db } = createLocalSqliteBackend();\n * const store = createStore(graph, backend);\n * ```\n *\n * @example File-based database for persistent local development\n * ```typescript\n * import { createLocalSqliteBackend } from \"@nicia-ai/typegraph/adapters/drizzle/sqlite/local\";\n *\n * const { backend, db } = createLocalSqliteBackend({ path: \"./dev.db\" });\n * const store = createStore(graph, backend);\n * ```\n */\nimport { createRequire } from \"node:module\";\n\nimport Database from \"better-sqlite3\";\nimport { getTableName } from \"drizzle-orm\";\nimport {\n type BetterSQLite3Database,\n drizzle,\n} from \"drizzle-orm/better-sqlite3\";\n\nimport { CompilerInvariantError, ConfigurationError } from \"../../errors\";\nimport { type FulltextStrategy } from \"../../query/dialect/fulltext-strategy\";\nimport { sqliteVecStrategy } from \"../../query/dialect/vector/sqlite-vec-strategy\";\nimport {\n isSqliteDuplicateEdgeMatchIdentityColumnError,\n isSqliteMissingEdgeMatchIdentityColumnError,\n} from \"../../utils/sql-errors\";\nimport { markBundledRootAutocommitEligible } from \"../capabilities/autocommit-single-statement\";\nimport { wrapWithManagedClose } from \"../derive-backend\";\nimport { CURRENT_BASE_SCHEMA_VERSION } from \"../drizzle/base-schema\";\nimport {\n generateSqliteMigrationSQL,\n planSqliteEdgeMatchIdentityAdoption,\n quoteDdlIdentifier,\n} from \"../drizzle/ddl\";\nimport { type AnySqliteDatabase } from \"../drizzle/execution\";\nexport type { AnySqliteDatabase } from \"../drizzle/execution\";\nimport { assertNoLegacyTransactionCapability } from \"../capabilities/declarations\";\nimport {\n createSqliteBackend,\n type SqliteTables,\n tables as defaultTables,\n} from \"../drizzle/sqlite\";\nimport {\n DEFAULT_LOCAL_SQLITE_PRAGMAS,\n type LocalSqliteJournalMode,\n type LocalSqlitePragmaOptions,\n type LocalSqliteSynchronousMode,\n} from \"./local-options\";\n\nexport {\n DEFAULT_LOCAL_SQLITE_PRAGMAS,\n type LocalSqliteJournalMode,\n type LocalSqlitePragmaOptions,\n type LocalSqliteSynchronousMode,\n} from \"./local-options\";\nimport {\n type AdapterBackend,\n type BundledBackendCapabilityOverrides,\n type SchemaProvisioning,\n} from \"../types\";\nexport type { BundledBackendCapabilityOverrides } from \"../types\";\nexport type {\n ContributionDiagnostic,\n ContributionDiagnosticState,\n ContributionRepairEntry,\n ContributionRepairResult,\n} from \"../types\";\n\nconst nodeRequire = createRequire(import.meta.url);\n\nfunction installLocalSqliteBaseSchema(\n sqlite: Database.Database,\n tables: SqliteTables,\n fulltextStrategy: FulltextStrategy | false | undefined,\n): void {\n // v2 (the fences relation) and v3 (the recorded-relations' and recorded\n // identity-assertions relation's `since_idx` indexes) need no adoption\n // logic beyond what `generateSqliteMigrationSQL` already emits: a\n // brand-new relation or index is fully covered by its own `CREATE TABLE\n // IF NOT EXISTS` / `CREATE INDEX IF NOT EXISTS`, on both a fresh database\n // and one that already has every OTHER base table or index. Only v1's\n // edge-match-identity `ADD COLUMN` migration — handled by the catch block\n // below — needed runtime introspection this synchronous path writes by\n // hand instead of running `BaseSchemaLifecycle`'s async state machine.\n if (CURRENT_BASE_SCHEMA_VERSION !== 3) {\n throw new CompilerInvariantError(\n \"The synchronous managed SQLite installation path only implements base-schema v1 through v3 adoption.\",\n { currentVersion: CURRENT_BASE_SCHEMA_VERSION },\n );\n }\n const installationSql = generateSqliteMigrationSQL(tables, fulltextStrategy);\n try {\n sqlite.exec(installationSql);\n } catch (error) {\n if (!isSqliteMissingEdgeMatchIdentityColumnError(error)) throw error;\n const edgeTableName = getTableName(tables.edges);\n for (let attempt = 0; attempt < 3; attempt += 1) {\n const rows = sqlite\n .prepare(`PRAGMA table_info(${quoteDdlIdentifier(edgeTableName)})`)\n .all() as readonly Readonly<{ name?: unknown }>[];\n const columns = new Set(\n rows.flatMap((row) => (typeof row.name === \"string\" ? [row.name] : [])),\n );\n const adoptionSql = planSqliteEdgeMatchIdentityAdoption(\n edgeTableName,\n columns,\n );\n try {\n sqlite.exec([...adoptionSql, installationSql].join(\"\\n\"));\n return;\n } catch (repairError) {\n if (\n attempt === 2 ||\n !isSqliteDuplicateEdgeMatchIdentityColumnError(repairError)\n ) {\n throw repairError;\n }\n }\n }\n throw new CompilerInvariantError(\n \"Local SQLite match-identity adoption exhausted its retry loop without returning or throwing.\",\n );\n }\n}\n\n// ============================================================\n// Native Addon Helpers\n// ============================================================\n\ntype NodeModuleVersionMismatch = Readonly<{\n compiled: number;\n required: number;\n}>;\n\nfunction getUnknownErrorMessage(error: unknown): string {\n if (error instanceof Error) return error.message;\n return String(error);\n}\n\nfunction parseNodeModuleVersionMismatchMessage(\n message: string,\n): NodeModuleVersionMismatch | undefined {\n const regexp =\n /NODE_MODULE_VERSION (?<compiled>\\d+)[\\s\\S]*?NODE_MODULE_VERSION (?<required>\\d+)/;\n const match = regexp.exec(message);\n if (!match?.groups) return undefined;\n\n const compiled = Number(match.groups[\"compiled\"]);\n const required = Number(match.groups[\"required\"]);\n\n if (!Number.isFinite(compiled) || !Number.isFinite(required))\n return undefined;\n\n return { compiled, required };\n}\n\nfunction createDatabase(path: string): Database.Database {\n try {\n return new Database(path);\n } catch (error) {\n const message = getUnknownErrorMessage(error);\n const mismatch = parseNodeModuleVersionMismatchMessage(message);\n if (!mismatch) throw error;\n\n throw new ConfigurationError(\n [\n \"Failed to load better-sqlite3 native addon.\",\n `It was compiled for NODE_MODULE_VERSION ${mismatch.compiled}, but this Node.js runtime requires ${mismatch.required}.`,\n \"This usually happens after switching Node versions without rebuilding native dependencies.\",\n \"Rebuild with: pnpm rebuild better-sqlite3 (or npm rebuild better-sqlite3).\",\n ].join(\" \"),\n {\n nodeVersion: process.version,\n nodeModuleVersion: process.versions.modules,\n compiledNodeModuleVersion: mismatch.compiled,\n requiredNodeModuleVersion: mismatch.required,\n },\n { cause: error },\n );\n }\n}\n\n// ============================================================\n// Types\n// ============================================================\n\nconst LOCAL_SQLITE_JOURNAL_MODES: readonly LocalSqliteJournalMode[] = [\n \"wal\",\n \"delete\",\n \"truncate\",\n \"persist\",\n \"memory\",\n \"off\",\n];\n\nconst LOCAL_SQLITE_SYNCHRONOUS_MODES: readonly LocalSqliteSynchronousMode[] = [\n \"off\",\n \"normal\",\n \"full\",\n \"extra\",\n];\n\nconst SQLITE_MAX_WAL_AUTOCHECKPOINT_PAGES = 2_147_483_647;\n\nfunction applyConnectionPragmas(\n sqlite: Database.Database,\n pragmas: LocalSqlitePragmaOptions | false | undefined,\n): void {\n if (pragmas === false) return;\n const resolved: Required<LocalSqlitePragmaOptions> = {\n ...DEFAULT_LOCAL_SQLITE_PRAGMAS,\n ...pragmas,\n };\n\n // Runtime guards mirror the compile-time unions: pragma values are spliced\n // into pragma statements, so reject anything outside the allowlists rather\n // than forwarding it to SQLite.\n if (!LOCAL_SQLITE_JOURNAL_MODES.includes(resolved.journalMode)) {\n throw new ConfigurationError(\n `Invalid journalMode pragma: ${resolved.journalMode}. ` +\n `Expected one of: ${LOCAL_SQLITE_JOURNAL_MODES.join(\", \")}.`,\n { journalMode: resolved.journalMode },\n );\n }\n if (!LOCAL_SQLITE_SYNCHRONOUS_MODES.includes(resolved.synchronous)) {\n throw new ConfigurationError(\n `Invalid synchronous pragma: ${resolved.synchronous}. ` +\n `Expected one of: ${LOCAL_SQLITE_SYNCHRONOUS_MODES.join(\", \")}.`,\n { synchronous: resolved.synchronous },\n );\n }\n if (\n !Number.isSafeInteger(resolved.busyTimeoutMs) ||\n resolved.busyTimeoutMs < 0\n ) {\n throw new ConfigurationError(\n `Invalid busyTimeoutMs pragma: ${String(resolved.busyTimeoutMs)}. ` +\n \"Expected a non-negative integer number of milliseconds.\",\n { busyTimeoutMs: resolved.busyTimeoutMs },\n );\n }\n if (\n resolved.cacheSizeKib !== undefined &&\n (!Number.isSafeInteger(resolved.cacheSizeKib) || resolved.cacheSizeKib >= 0)\n ) {\n throw new ConfigurationError(\n `Invalid cacheSizeKib pragma: ${String(resolved.cacheSizeKib)}. ` +\n \"Expected a negative safe integer — SQLite's own cache_size pragma \" +\n \"interprets a positive value as a page count, not KiB, so a caller \" +\n 'who passes e.g. 131072 meaning \"131072 KiB\" silently gets ' +\n \"131072 pages (~512MiB at the default 4KiB page size) instead.\",\n { cacheSizeKib: resolved.cacheSizeKib },\n );\n }\n if (\n resolved.mmapSizeBytes !== undefined &&\n (!Number.isSafeInteger(resolved.mmapSizeBytes) ||\n resolved.mmapSizeBytes < 0)\n ) {\n throw new ConfigurationError(\n `Invalid mmapSizeBytes pragma: ${String(resolved.mmapSizeBytes)}. ` +\n \"Expected a non-negative safe integer number of bytes.\",\n { mmapSizeBytes: resolved.mmapSizeBytes },\n );\n }\n if (\n resolved.walAutocheckpointPages !== undefined &&\n (!Number.isSafeInteger(resolved.walAutocheckpointPages) ||\n resolved.walAutocheckpointPages < 0 ||\n resolved.walAutocheckpointPages > SQLITE_MAX_WAL_AUTOCHECKPOINT_PAGES)\n ) {\n throw new ConfigurationError(\n `Invalid walAutocheckpointPages pragma: ${String(resolved.walAutocheckpointPages)}. ` +\n `Expected an integer between 0 and ${SQLITE_MAX_WAL_AUTOCHECKPOINT_PAGES} ` +\n \"WAL pages (0 disables automatic checkpointing entirely).\",\n { walAutocheckpointPages: resolved.walAutocheckpointPages },\n );\n }\n\n // \":memory:\" databases always journal in memory; SQLite answers the WAL\n // request with \"memory\" instead of erroring, so no special-casing needed.\n sqlite.pragma(`journal_mode = ${resolved.journalMode}`);\n sqlite.pragma(`synchronous = ${resolved.synchronous}`);\n sqlite.pragma(`busy_timeout = ${resolved.busyTimeoutMs}`);\n if (resolved.cacheSizeKib !== undefined) {\n sqlite.pragma(`cache_size = ${resolved.cacheSizeKib}`);\n }\n if (resolved.mmapSizeBytes !== undefined) {\n sqlite.pragma(`mmap_size = ${resolved.mmapSizeBytes}`);\n }\n if (resolved.walAutocheckpointPages !== undefined) {\n sqlite.pragma(`wal_autocheckpoint = ${resolved.walAutocheckpointPages}`);\n }\n}\n\n/**\n * Options for creating a local SQLite backend.\n */\nexport type LocalSqliteBackendOptions = Readonly<{\n schemaProvisioning?: SchemaProvisioning;\n /**\n * Path to the SQLite database file.\n * Defaults to \":memory:\" for an in-memory database.\n */\n path?: string;\n\n /**\n * Connection pragmas applied at open. Defaults to\n * {@link DEFAULT_LOCAL_SQLITE_PRAGMAS} (WAL, `synchronous=NORMAL`, 5s busy\n * timeout, and SQLite's own tiny built-in page cache / disabled mmap\n * left untouched). Individual values merge over the defaults; pass\n * `false` to skip pragma configuration entirely and keep the driver\n * defaults (rollback journal, `synchronous=FULL`, and better-sqlite3's\n * own 5s busy timeout from its `timeout` constructor option). Set\n * `cacheSizeKib`/`mmapSizeBytes` explicitly once a database's working\n * set is known to exceed SQLite's 2MiB default cache — otherwise every\n * query pays a fresh disk read per page past that tiny working set. Set\n * `walAutocheckpointPages` explicitly for a bulk-insert-heavy workload —\n * SQLite's own default checkpoints every ~4MiB of WAL growth, which gets\n * more expensive as the database file grows over a large load.\n */\n pragmas?: LocalSqlitePragmaOptions | false;\n\n /**\n * Custom table definitions.\n * Defaults to standard TypeGraph table names.\n */\n tables?: SqliteTables;\n\n /**\n * Override the fulltext strategy. Defaults to `fts5Strategy` (SQLite's\n * built-in FTS5 virtual table). Pass `false` to disable fulltext support\n * entirely — the backend then advertises no `capabilities.fulltext` and\n * omits the fulltext CRUD/search methods, and the managed installation\n * never creates the fulltext table. Forwarded to both the installation\n * DDL and `createSqliteBackend`.\n */\n fulltext?: FulltextStrategy | false;\n\n /**\n * Override specific backend capabilities — e.g. to simulate an engine-level\n * gap like missing SQL window functions in tests. Forwarded to\n * createSqliteBackend.\n */\n capabilities?: BundledBackendCapabilityOverrides;\n}>;\n\n/**\n * Result of creating a local SQLite backend.\n */\nexport type LocalSqliteBackendResult = Readonly<{\n /**\n * The GraphBackend instance for use with createStore.\n */\n backend: AdapterBackend<AnySqliteDatabase>;\n\n /**\n * The underlying Drizzle database instance.\n * Useful for direct SQL access or cleanup.\n */\n db: BetterSQLite3Database;\n}>;\n\n// ============================================================\n// Factory Function\n// ============================================================\n\n/**\n * Creates a SQLite backend with minimal configuration.\n *\n * This is a convenience function for local development and testing.\n * It handles database creation, schema migration, and backend setup.\n *\n * For production deployments or custom configurations, use createSqliteBackend\n * directly with your own Drizzle database instance.\n *\n * @param options - Configuration options\n * @returns Backend and database instances\n *\n * @example In-memory database (default)\n * ```typescript\n * const { backend } = createLocalSqliteBackend();\n * const store = createStore(graph, backend);\n * ```\n *\n * @example File-based database\n * ```typescript\n * const { backend, db } = createLocalSqliteBackend({ path: \"./data.db\" });\n * const store = createStore(graph, backend);\n * ```\n */\nexport function createLocalSqliteBackend(\n options: LocalSqliteBackendOptions = {},\n): LocalSqliteBackendResult {\n assertNoLegacyTransactionCapability(options.capabilities);\n const path = options.path ?? \":memory:\";\n const tables = options.tables ?? defaultTables;\n\n const sqlite = createDatabase(path);\n try {\n applyConnectionPragmas(sqlite, options.pragmas);\n\n // Best-effort: load sqlite-vec so embedding fields are persisted to\n // per-`(kind, field)` `vec0` storage. Without it, nodes with\n // `embedding()` fields validate and insert but their vectors are silently\n // dropped. When the user has installed sqlite-vec as a peer dep we load\n // it and wire the strategy; otherwise we proceed without vector support.\n const hasSqliteVec = tryLoadSqliteVec(sqlite);\n\n const db = drizzle(sqlite);\n\n // The managed factory owns a complete fresh installation, including the\n // deployment-wide base-schema marker consumed by verified/runtime-only\n // entrypoints. Raw generateSqliteDDL intentionally omits that marker.\n installLocalSqliteBaseSchema(sqlite, tables, options.fulltext);\n\n const backend = createSqliteBackend(db, {\n ...(options.schemaProvisioning === undefined ?\n {}\n : { schemaProvisioning: options.schemaProvisioning }),\n executionProfile: {\n isSync: true,\n },\n tables,\n ...(hasSqliteVec ? { vector: sqliteVecStrategy } : {}),\n ...(options.fulltext === undefined ? {} : { fulltext: options.fulltext }),\n capabilities: {\n ...options.capabilities,\n graphAnalytics: {\n supported:\n options.capabilities?.graphAnalytics?.supported ??\n options.capabilities?.execution?.interactiveTransactions !== false,\n mathFunctions:\n options.capabilities?.graphAnalytics?.mathFunctions ?? true,\n },\n },\n });\n const managedBackend = wrapWithManagedClose(backend, () => {\n sqlite.close();\n });\n\n return { backend: markBundledRootAutocommitEligible(managedBackend), db };\n } catch (error) {\n try {\n sqlite.close();\n } catch {\n // Preserve the provisioning error; a cleanup failure is secondary.\n }\n throw error;\n }\n}\n\nfunction tryLoadSqliteVec(sqlite: Database.Database): boolean {\n try {\n // `sqlite-vec` is an optional peer dep; resolved via createRequire so\n // bundlers don't mark it as a hard import. Node resolves the package\n // only when it's actually installed.\n const module_: unknown = nodeRequire(\"sqlite-vec\");\n if (\n typeof module_ === \"object\" &&\n module_ !== null &&\n \"load\" in module_ &&\n typeof module_.load === \"function\"\n ) {\n (module_ as { load: (db: Database.Database) => void }).load(sqlite);\n return true;\n }\n return false;\n } catch {\n return false;\n }\n}\nexport type { GraphIdentityConfig } from \"../../core/define-graph\";\n"]}
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var chunkZOWRACZQ_cjs = require('./chunk-ZOWRACZQ.cjs');
4
- var chunkOC5ROP7V_cjs = require('./chunk-OC5ROP7V.cjs');
3
+ var chunkG7OKJDMG_cjs = require('./chunk-G7OKJDMG.cjs');
4
+ var chunk6JRVV2SS_cjs = require('./chunk-6JRVV2SS.cjs');
5
5
  var chunkL4L4AV6F_cjs = require('./chunk-L4L4AV6F.cjs');
6
6
  var chunkXPSPDFKO_cjs = require('./chunk-XPSPDFKO.cjs');
7
7
  var chunk7XYPLAPL_cjs = require('./chunk-7XYPLAPL.cjs');
@@ -166,7 +166,7 @@ function createSchemaVersionRowMapper(config) {
166
166
  graph_id: asString(row["graph_id"], "graph_id"),
167
167
  version: asNumber(row["version"], "version"),
168
168
  schema_hash: asString(row["schema_hash"], "schema_hash"),
169
- schema_doc: chunkOC5ROP7V_cjs.rowPropsToJsonText(config.normalizeJson(row["schema_doc"])),
169
+ schema_doc: chunk6JRVV2SS_cjs.rowPropsToJsonText(config.normalizeJson(row["schema_doc"])),
170
170
  created_at: normalizeRequiredRowTimestamp(
171
171
  row["created_at"],
172
172
  "created_at"
@@ -181,7 +181,7 @@ function buildHardDeleteUniquesByConcreteKind(uniquesTableName, params) {
181
181
  return chunkXPSPDFKO_cjs.sql`DELETE FROM ${chunkXPSPDFKO_cjs.sql.identifier(uniquesTableName)} WHERE ${chunkXPSPDFKO_cjs.sql.identifier("graph_id")} = ${params.graphId} AND ${chunkXPSPDFKO_cjs.sql.identifier("concrete_kind")} = ${params.concreteKind}`;
182
182
  }
183
183
  function buildHardDeleteEdgeClaimsByEdgeKind(edgeClaimsTableName, params) {
184
- const axes = chunkZOWRACZQ_cjs.edgeCardinalityAxesForKind(params.edgeKind).map(
184
+ const axes = chunkG7OKJDMG_cjs.edgeCardinalityAxesForKind(params.edgeKind).map(
185
185
  (axis) => chunkXPSPDFKO_cjs.sql`${axis}`
186
186
  );
187
187
  return chunkXPSPDFKO_cjs.sql`DELETE FROM ${chunkXPSPDFKO_cjs.sql.identifier(edgeClaimsTableName)} WHERE ${chunkXPSPDFKO_cjs.sql.identifier("graph_id")} = ${params.graphId} AND ${chunkXPSPDFKO_cjs.sql.identifier("axis")} IN (${chunkXPSPDFKO_cjs.sql.join(axes, chunkXPSPDFKO_cjs.sql`, `)})`;
@@ -204,5 +204,5 @@ exports.formatPostgresTimestamp = formatPostgresTimestamp;
204
204
  exports.normalizeRequiredRowTimestamp = normalizeRequiredRowTimestamp;
205
205
  exports.normalizeRowTimestamp = normalizeRowTimestamp;
206
206
  exports.nowIso = nowIso;
207
- //# sourceMappingURL=chunk-DSX3P4S5.cjs.map
208
- //# sourceMappingURL=chunk-DSX3P4S5.cjs.map
207
+ //# sourceMappingURL=chunk-76OB5RSH.cjs.map
208
+ //# sourceMappingURL=chunk-76OB5RSH.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/backend/row-mappers.ts","../src/store/claims/removal-sql.ts"],"names":["DatabaseOperationError","canonicalizeDatabaseTimestamp","rowPropsToJsonText","sql","edgeCardinalityAxesForKind"],"mappings":"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","file":"chunk-DSX3P4S5.cjs","sourcesContent":["/**\n * Shared database row-mapping utilities.\n */\n\nimport { DatabaseOperationError } from \"../errors\";\nimport { canonicalizeDatabaseTimestamp } from \"../utils/date\";\nimport {\n type EdgeRow,\n type NodeRow,\n rowPropsToJsonText,\n type SchemaVersionRow,\n type UniqueRow,\n} from \"./types\";\n\nfunction asString(value: unknown, field: string): string {\n if (typeof value !== \"string\") {\n throw new DatabaseOperationError(\n `Expected ${field} to be string, got ${typeof value}`,\n { operation: \"select\", entity: \"row\" },\n );\n }\n return value;\n}\n\nfunction asOptionalString(value: unknown, field: string): string | undefined {\n if (value === null || value === undefined) return undefined;\n return asString(value, field);\n}\n\nfunction asNumber(value: unknown, field: string): number {\n if (typeof value !== \"number\") {\n throw new DatabaseOperationError(\n `Expected ${field} to be number, got ${typeof value}`,\n { operation: \"select\", entity: \"row\" },\n );\n }\n return value;\n}\n\nexport function nowIso(): string {\n return new Date().toISOString();\n}\n\n/**\n * Formats PostgreSQL timestamps used by internal status-table adapters.\n * Row metadata uses the stricter {@link normalizeRowTimestamp} contract.\n */\nexport function formatPostgresTimestamp(value: unknown): string | undefined {\n if (value === null || value === undefined) return undefined;\n if (value instanceof Date) return value.toISOString();\n if (typeof value === \"string\") {\n if (value.includes(\"T\")) return value;\n const date = new Date(value);\n if (!Number.isNaN(date.getTime())) return date.toISOString();\n return value;\n }\n return undefined;\n}\n\n/**\n * Canonicalizes database-driver timestamp values at the row-mapping boundary.\n * Every store and compiled-query metadata projection uses this owner so driver\n * rendering differences cannot become public values.\n */\nexport function normalizeRowTimestamp(\n value: unknown,\n field: string,\n): string | undefined {\n if (value === null || value === undefined) return undefined;\n const canonical = canonicalizeDatabaseTimestamp(value);\n if (canonical === undefined) {\n throw new DatabaseOperationError(\n `Expected ${field} to be a database timestamp, got ${typeof value}`,\n { operation: \"select\", entity: \"row\" },\n );\n }\n return canonical;\n}\n\nexport function normalizeRequiredRowTimestamp(\n value: unknown,\n field: string,\n): string {\n const timestamp = normalizeRowTimestamp(value, field);\n if (timestamp === undefined) {\n throw new DatabaseOperationError(`Expected non-null ${field} timestamp`, {\n operation: \"select\",\n entity: \"row\",\n });\n }\n return timestamp;\n}\n\n/**\n * Coerce a fulltext relevance score to `number` at the backend\n * boundary. Postgres returns `numeric` as a string to preserve\n * precision; a custom `FulltextStrategy` on either dialect could\n * likewise yield a string. Shared so both backends enforce the same\n * `FulltextSearchResult.score: number` contract and reject garbage\n * loudly instead of propagating `NaN`.\n */\nexport function coerceNumericScore(value: number | string): number {\n if (typeof value === \"number\") return value;\n const parsed = Number.parseFloat(value);\n if (Number.isNaN(parsed)) {\n throw new TypeError(\n `Backend returned non-numeric fulltext score: ${JSON.stringify(value)}`,\n );\n }\n return parsed;\n}\n\n/**\n * Normalizes a JSON column that may be returned as a parsed object (JSONB)\n * or string. PostgreSQL drivers hand jsonb back already parsed — keep the\n * object instead of re-stringifying it, so the read path pays zero JSON\n * work per row (consumers normalize via rowPropsToObject /\n * rowPropsToJsonText at the point of use). SQLite text passes through.\n */\nfunction normalizeJsonColumn(value: unknown): string | Record<string, unknown> {\n if (typeof value === \"string\") return value;\n if (value !== null && typeof value === \"object\") {\n return value as Record<string, unknown>;\n }\n return JSON.stringify(value ?? {});\n}\n\n/**\n * Dialect-specific configuration for row mappers.\n *\n * Row mapper factories accept this config to produce dialect-appropriate\n * mappers. Timestamp normalization is dialect-independent and owned by\n * {@link normalizeRowTimestamp}; only JSON columns need dialect configuration.\n */\ntype DialectRowMapperConfig = Readonly<{\n normalizeJson: (value: unknown) => string | Record<string, unknown>;\n}>;\n\n/**\n * SQLite row mapper config. JSON is stored as TEXT.\n */\nexport const SQLITE_ROW_MAPPER_CONFIG: DialectRowMapperConfig = {\n normalizeJson: (value) => {\n if (typeof value !== \"string\") {\n throw new DatabaseOperationError(\n `Expected JSON column to be string, got ${typeof value}`,\n { operation: \"select\", entity: \"row\" },\n );\n }\n return value;\n },\n};\n\n/**\n * PostgreSQL row mapper config. JSONB is returned as parsed objects.\n */\nexport const POSTGRES_ROW_MAPPER_CONFIG: DialectRowMapperConfig = {\n normalizeJson: normalizeJsonColumn,\n};\n\n// Trust boundary: Drizzle raw SQL returns Record<string, unknown> rows.\n// The field access patterns below are intentional unsafe casts at the\n// database driver boundary where we know the column shapes.\n\nexport function createNodeRowMapper(\n config: DialectRowMapperConfig,\n): (row: Record<string, unknown>) => NodeRow {\n return (row) => ({\n graph_id: asString(row[\"graph_id\"], \"graph_id\"),\n kind: asString(row[\"kind\"], \"kind\"),\n id: asString(row[\"id\"], \"id\"),\n props: config.normalizeJson(row[\"props\"]),\n version: asNumber(row[\"version\"], \"version\"),\n valid_from: normalizeRowTimestamp(row[\"valid_from\"], \"valid_from\"),\n valid_to: normalizeRowTimestamp(row[\"valid_to\"], \"valid_to\"),\n created_at: normalizeRequiredRowTimestamp(row[\"created_at\"], \"created_at\"),\n updated_at: normalizeRequiredRowTimestamp(row[\"updated_at\"], \"updated_at\"),\n deleted_at: normalizeRowTimestamp(row[\"deleted_at\"], \"deleted_at\"),\n });\n}\n\nexport function createEdgeRowMapper(\n config: DialectRowMapperConfig,\n): (row: Record<string, unknown>) => EdgeRow {\n return (row) => {\n const matchIdentityName = asOptionalString(\n row[\"match_identity_name\"],\n \"match_identity_name\",\n );\n const matchIdentityKey = asOptionalString(\n row[\"match_identity_key\"],\n \"match_identity_key\",\n );\n return {\n graph_id: asString(row[\"graph_id\"], \"graph_id\"),\n id: asString(row[\"id\"], \"id\"),\n kind: asString(row[\"kind\"], \"kind\"),\n from_kind: asString(row[\"from_kind\"], \"from_kind\"),\n from_id: asString(row[\"from_id\"], \"from_id\"),\n to_kind: asString(row[\"to_kind\"], \"to_kind\"),\n to_id: asString(row[\"to_id\"], \"to_id\"),\n props: config.normalizeJson(row[\"props\"]),\n ...(matchIdentityName === undefined ?\n {}\n : { match_identity_name: matchIdentityName }),\n ...(matchIdentityKey === undefined ?\n {}\n : { match_identity_key: matchIdentityKey }),\n valid_from: normalizeRowTimestamp(row[\"valid_from\"], \"valid_from\"),\n valid_to: normalizeRowTimestamp(row[\"valid_to\"], \"valid_to\"),\n created_at: normalizeRequiredRowTimestamp(\n row[\"created_at\"],\n \"created_at\",\n ),\n updated_at: normalizeRequiredRowTimestamp(\n row[\"updated_at\"],\n \"updated_at\",\n ),\n deleted_at: normalizeRowTimestamp(row[\"deleted_at\"], \"deleted_at\"),\n };\n };\n}\n\nfunction mapUniqueRow(row: Record<string, unknown>): UniqueRow {\n return {\n graph_id: asString(row[\"graph_id\"], \"graph_id\"),\n node_kind: asString(row[\"node_kind\"], \"node_kind\"),\n constraint_name: asString(row[\"constraint_name\"], \"constraint_name\"),\n key: asString(row[\"key\"], \"key\"),\n node_id: asString(row[\"node_id\"], \"node_id\"),\n concrete_kind: asString(row[\"concrete_kind\"], \"concrete_kind\"),\n deleted_at: normalizeRowTimestamp(row[\"deleted_at\"], \"deleted_at\"),\n };\n}\n\nexport function createUniqueRowMapper(\n _config: DialectRowMapperConfig,\n): (row: Record<string, unknown>) => UniqueRow {\n return mapUniqueRow;\n}\n\nexport function createSchemaVersionRowMapper(\n config: DialectRowMapperConfig,\n): (row: Record<string, unknown>) => SchemaVersionRow {\n return (row) => {\n const isActiveValue = row[\"is_active\"];\n const isActive =\n isActiveValue === true || isActiveValue === 1 || isActiveValue === \"1\";\n\n return {\n graph_id: asString(row[\"graph_id\"], \"graph_id\"),\n version: asNumber(row[\"version\"], \"version\"),\n schema_hash: asString(row[\"schema_hash\"], \"schema_hash\"),\n schema_doc: rowPropsToJsonText(config.normalizeJson(row[\"schema_doc\"])),\n created_at: normalizeRequiredRowTimestamp(\n row[\"created_at\"],\n \"created_at\",\n ),\n is_active: isActive,\n };\n };\n}\n","/**\n * Statement builders for the claim relations' bulk-removal paths.\n *\n * These are statements over the claim relations — the uniqueness claims a\n * kind's nodes own, and the edge-cardinality claims an edge kind's edges\n * hold — so their owner is `src/store/claims/`, exactly like every other\n * claim decision. `edgeCardinalityAxesForKind` already lives here (see\n * `./edge-claims`), so this module reads it directly instead of reaching\n * back out to an adapter that reaches back in.\n *\n * `src/backend/drizzle/operations/uniques.ts` and\n * `src/backend/drizzle/operations/edge-claims.ts` re-export these three\n * builders from their previous addresses, so `CommonOperationStrategy` and\n * `operation-backend-core.ts` see no change: one owner, two addresses, no\n * duplicate.\n */\nimport type { HardDeleteUniquesByConcreteKindParams } from \"../../backend/types\";\nimport { sql as fragmentSql, type SqlFragment } from \"../../query/sql-fragment\";\nimport { edgeCardinalityAxesForKind } from \"./edge-claims\";\n\n/**\n * THE definition of \"the uniqueness claims nodes of this kind own\": every row\n * whose `concrete_kind` is the kind, at whatever axis the row sits on.\n *\n * Kind reaping is a different predicate from a lifecycle release — \"every claim\n * this kind's nodes own\" rather than \"this node's claim for one constraint and\n * key\" — and it is a hard delete rather than a tombstone, so it is its own\n * builder. It is nonetheless the ONLY spelling of that predicate: both the\n * `hardDeleteUniquesByConcreteKind` backend member and `materializeRemovals`'\n * removed-kind cleanup compile this fragment. Keying on `node_kind` instead\n * would leak a claim whose axis is a sibling kind, delete a surviving sibling's\n * claim when the removed kind IS the axis, and never match a claim whose axis\n * is not a kind at all.\n *\n * Takes the relation NAME rather than the Drizzle table so the store-side\n * caller, which knows only its configured table names, can build the same\n * statement; the fragment renders on either dialect.\n */\nexport function buildHardDeleteUniquesByConcreteKind(\n uniquesTableName: string,\n params: HardDeleteUniquesByConcreteKindParams,\n): SqlFragment {\n return fragmentSql`DELETE FROM ${fragmentSql.identifier(uniquesTableName)} WHERE ${fragmentSql.identifier(\"graph_id\")} = ${params.graphId} AND ${fragmentSql.identifier(\"concrete_kind\")} = ${params.concreteKind}`;\n}\n\n/**\n * THE definition of \"the cardinality claims an edge kind owns\": every row at\n * one of the kind's declared-cardinality axes.\n *\n * Keyed on the axis rather than on the holder's id because a removed kind's\n * edges are deleted in the same pass, which would leave a claim naming a row\n * that no longer exists — takeable, but never reaped. Takes the relation NAME\n * rather than the Drizzle table so `materializeRemovals`, which knows only its\n * configured table names, compiles the same statement.\n */\nexport function buildHardDeleteEdgeClaimsByEdgeKind(\n edgeClaimsTableName: string,\n params: Readonly<{ graphId: string; edgeKind: string }>,\n): SqlFragment {\n const axes = edgeCardinalityAxesForKind(params.edgeKind).map(\n (axis) => fragmentSql`${axis}`,\n );\n return fragmentSql`DELETE FROM ${fragmentSql.identifier(edgeClaimsTableName)} WHERE ${fragmentSql.identifier(\"graph_id\")} = ${params.graphId} AND ${fragmentSql.identifier(\"axis\")} IN (${fragmentSql.join(axes, fragmentSql`, `)})`;\n}\n\n/**\n * Housekeeping for node-kind removal: deletes every claim held by an edge whose\n * source or target has the removed kind.\n *\n * The holder ids are selected before those edges are deleted. Filtering claim\n * axes cannot express this ownership: an edge kind may connect several node\n * kinds, while its claim axis names only its cardinality and edge kind.\n */\nexport function buildHardDeleteEdgeClaimsByNodeKind(\n edgeClaimsTableName: string,\n edgesTableName: string,\n params: Readonly<{ graphId: string; nodeKind: string }>,\n): SqlFragment {\n return fragmentSql`DELETE FROM ${fragmentSql.identifier(edgeClaimsTableName)} WHERE ${fragmentSql.identifier(\"graph_id\")} = ${params.graphId} AND ${fragmentSql.identifier(\"edge_id\")} IN (SELECT ${fragmentSql.identifier(\"id\")} FROM ${fragmentSql.identifier(edgesTableName)} WHERE ${fragmentSql.identifier(\"graph_id\")} = ${params.graphId} AND (${fragmentSql.identifier(\"from_kind\")} = ${params.nodeKind} OR ${fragmentSql.identifier(\"to_kind\")} = ${params.nodeKind}))`;\n}\n"]}
1
+ {"version":3,"sources":["../src/backend/row-mappers.ts","../src/store/claims/removal-sql.ts"],"names":["DatabaseOperationError","canonicalizeDatabaseTimestamp","rowPropsToJsonText","sql","edgeCardinalityAxesForKind"],"mappings":"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","file":"chunk-76OB5RSH.cjs","sourcesContent":["/**\n * Shared database row-mapping utilities.\n */\n\nimport { DatabaseOperationError } from \"../errors\";\nimport { canonicalizeDatabaseTimestamp } from \"../utils/date\";\nimport {\n type EdgeRow,\n type NodeRow,\n rowPropsToJsonText,\n type SchemaVersionRow,\n type UniqueRow,\n} from \"./types\";\n\nfunction asString(value: unknown, field: string): string {\n if (typeof value !== \"string\") {\n throw new DatabaseOperationError(\n `Expected ${field} to be string, got ${typeof value}`,\n { operation: \"select\", entity: \"row\" },\n );\n }\n return value;\n}\n\nfunction asOptionalString(value: unknown, field: string): string | undefined {\n if (value === null || value === undefined) return undefined;\n return asString(value, field);\n}\n\nfunction asNumber(value: unknown, field: string): number {\n if (typeof value !== \"number\") {\n throw new DatabaseOperationError(\n `Expected ${field} to be number, got ${typeof value}`,\n { operation: \"select\", entity: \"row\" },\n );\n }\n return value;\n}\n\nexport function nowIso(): string {\n return new Date().toISOString();\n}\n\n/**\n * Formats PostgreSQL timestamps used by internal status-table adapters.\n * Row metadata uses the stricter {@link normalizeRowTimestamp} contract.\n */\nexport function formatPostgresTimestamp(value: unknown): string | undefined {\n if (value === null || value === undefined) return undefined;\n if (value instanceof Date) return value.toISOString();\n if (typeof value === \"string\") {\n if (value.includes(\"T\")) return value;\n const date = new Date(value);\n if (!Number.isNaN(date.getTime())) return date.toISOString();\n return value;\n }\n return undefined;\n}\n\n/**\n * Canonicalizes database-driver timestamp values at the row-mapping boundary.\n * Every store and compiled-query metadata projection uses this owner so driver\n * rendering differences cannot become public values.\n */\nexport function normalizeRowTimestamp(\n value: unknown,\n field: string,\n): string | undefined {\n if (value === null || value === undefined) return undefined;\n const canonical = canonicalizeDatabaseTimestamp(value);\n if (canonical === undefined) {\n throw new DatabaseOperationError(\n `Expected ${field} to be a database timestamp, got ${typeof value}`,\n { operation: \"select\", entity: \"row\" },\n );\n }\n return canonical;\n}\n\nexport function normalizeRequiredRowTimestamp(\n value: unknown,\n field: string,\n): string {\n const timestamp = normalizeRowTimestamp(value, field);\n if (timestamp === undefined) {\n throw new DatabaseOperationError(`Expected non-null ${field} timestamp`, {\n operation: \"select\",\n entity: \"row\",\n });\n }\n return timestamp;\n}\n\n/**\n * Coerce a fulltext relevance score to `number` at the backend\n * boundary. Postgres returns `numeric` as a string to preserve\n * precision; a custom `FulltextStrategy` on either dialect could\n * likewise yield a string. Shared so both backends enforce the same\n * `FulltextSearchResult.score: number` contract and reject garbage\n * loudly instead of propagating `NaN`.\n */\nexport function coerceNumericScore(value: number | string): number {\n if (typeof value === \"number\") return value;\n const parsed = Number.parseFloat(value);\n if (Number.isNaN(parsed)) {\n throw new TypeError(\n `Backend returned non-numeric fulltext score: ${JSON.stringify(value)}`,\n );\n }\n return parsed;\n}\n\n/**\n * Normalizes a JSON column that may be returned as a parsed object (JSONB)\n * or string. PostgreSQL drivers hand jsonb back already parsed — keep the\n * object instead of re-stringifying it, so the read path pays zero JSON\n * work per row (consumers normalize via rowPropsToObject /\n * rowPropsToJsonText at the point of use). SQLite text passes through.\n */\nfunction normalizeJsonColumn(value: unknown): string | Record<string, unknown> {\n if (typeof value === \"string\") return value;\n if (value !== null && typeof value === \"object\") {\n return value as Record<string, unknown>;\n }\n return JSON.stringify(value ?? {});\n}\n\n/**\n * Dialect-specific configuration for row mappers.\n *\n * Row mapper factories accept this config to produce dialect-appropriate\n * mappers. Timestamp normalization is dialect-independent and owned by\n * {@link normalizeRowTimestamp}; only JSON columns need dialect configuration.\n */\ntype DialectRowMapperConfig = Readonly<{\n normalizeJson: (value: unknown) => string | Record<string, unknown>;\n}>;\n\n/**\n * SQLite row mapper config. JSON is stored as TEXT.\n */\nexport const SQLITE_ROW_MAPPER_CONFIG: DialectRowMapperConfig = {\n normalizeJson: (value) => {\n if (typeof value !== \"string\") {\n throw new DatabaseOperationError(\n `Expected JSON column to be string, got ${typeof value}`,\n { operation: \"select\", entity: \"row\" },\n );\n }\n return value;\n },\n};\n\n/**\n * PostgreSQL row mapper config. JSONB is returned as parsed objects.\n */\nexport const POSTGRES_ROW_MAPPER_CONFIG: DialectRowMapperConfig = {\n normalizeJson: normalizeJsonColumn,\n};\n\n// Trust boundary: Drizzle raw SQL returns Record<string, unknown> rows.\n// The field access patterns below are intentional unsafe casts at the\n// database driver boundary where we know the column shapes.\n\nexport function createNodeRowMapper(\n config: DialectRowMapperConfig,\n): (row: Record<string, unknown>) => NodeRow {\n return (row) => ({\n graph_id: asString(row[\"graph_id\"], \"graph_id\"),\n kind: asString(row[\"kind\"], \"kind\"),\n id: asString(row[\"id\"], \"id\"),\n props: config.normalizeJson(row[\"props\"]),\n version: asNumber(row[\"version\"], \"version\"),\n valid_from: normalizeRowTimestamp(row[\"valid_from\"], \"valid_from\"),\n valid_to: normalizeRowTimestamp(row[\"valid_to\"], \"valid_to\"),\n created_at: normalizeRequiredRowTimestamp(row[\"created_at\"], \"created_at\"),\n updated_at: normalizeRequiredRowTimestamp(row[\"updated_at\"], \"updated_at\"),\n deleted_at: normalizeRowTimestamp(row[\"deleted_at\"], \"deleted_at\"),\n });\n}\n\nexport function createEdgeRowMapper(\n config: DialectRowMapperConfig,\n): (row: Record<string, unknown>) => EdgeRow {\n return (row) => {\n const matchIdentityName = asOptionalString(\n row[\"match_identity_name\"],\n \"match_identity_name\",\n );\n const matchIdentityKey = asOptionalString(\n row[\"match_identity_key\"],\n \"match_identity_key\",\n );\n return {\n graph_id: asString(row[\"graph_id\"], \"graph_id\"),\n id: asString(row[\"id\"], \"id\"),\n kind: asString(row[\"kind\"], \"kind\"),\n from_kind: asString(row[\"from_kind\"], \"from_kind\"),\n from_id: asString(row[\"from_id\"], \"from_id\"),\n to_kind: asString(row[\"to_kind\"], \"to_kind\"),\n to_id: asString(row[\"to_id\"], \"to_id\"),\n props: config.normalizeJson(row[\"props\"]),\n ...(matchIdentityName === undefined ?\n {}\n : { match_identity_name: matchIdentityName }),\n ...(matchIdentityKey === undefined ?\n {}\n : { match_identity_key: matchIdentityKey }),\n valid_from: normalizeRowTimestamp(row[\"valid_from\"], \"valid_from\"),\n valid_to: normalizeRowTimestamp(row[\"valid_to\"], \"valid_to\"),\n created_at: normalizeRequiredRowTimestamp(\n row[\"created_at\"],\n \"created_at\",\n ),\n updated_at: normalizeRequiredRowTimestamp(\n row[\"updated_at\"],\n \"updated_at\",\n ),\n deleted_at: normalizeRowTimestamp(row[\"deleted_at\"], \"deleted_at\"),\n };\n };\n}\n\nfunction mapUniqueRow(row: Record<string, unknown>): UniqueRow {\n return {\n graph_id: asString(row[\"graph_id\"], \"graph_id\"),\n node_kind: asString(row[\"node_kind\"], \"node_kind\"),\n constraint_name: asString(row[\"constraint_name\"], \"constraint_name\"),\n key: asString(row[\"key\"], \"key\"),\n node_id: asString(row[\"node_id\"], \"node_id\"),\n concrete_kind: asString(row[\"concrete_kind\"], \"concrete_kind\"),\n deleted_at: normalizeRowTimestamp(row[\"deleted_at\"], \"deleted_at\"),\n };\n}\n\nexport function createUniqueRowMapper(\n _config: DialectRowMapperConfig,\n): (row: Record<string, unknown>) => UniqueRow {\n return mapUniqueRow;\n}\n\nexport function createSchemaVersionRowMapper(\n config: DialectRowMapperConfig,\n): (row: Record<string, unknown>) => SchemaVersionRow {\n return (row) => {\n const isActiveValue = row[\"is_active\"];\n const isActive =\n isActiveValue === true || isActiveValue === 1 || isActiveValue === \"1\";\n\n return {\n graph_id: asString(row[\"graph_id\"], \"graph_id\"),\n version: asNumber(row[\"version\"], \"version\"),\n schema_hash: asString(row[\"schema_hash\"], \"schema_hash\"),\n schema_doc: rowPropsToJsonText(config.normalizeJson(row[\"schema_doc\"])),\n created_at: normalizeRequiredRowTimestamp(\n row[\"created_at\"],\n \"created_at\",\n ),\n is_active: isActive,\n };\n };\n}\n","/**\n * Statement builders for the claim relations' bulk-removal paths.\n *\n * These are statements over the claim relations — the uniqueness claims a\n * kind's nodes own, and the edge-cardinality claims an edge kind's edges\n * hold — so their owner is `src/store/claims/`, exactly like every other\n * claim decision. `edgeCardinalityAxesForKind` already lives here (see\n * `./edge-claims`), so this module reads it directly instead of reaching\n * back out to an adapter that reaches back in.\n *\n * `src/backend/drizzle/operations/uniques.ts` and\n * `src/backend/drizzle/operations/edge-claims.ts` re-export these three\n * builders from their previous addresses, so `CommonOperationStrategy` and\n * `operation-backend-core.ts` see no change: one owner, two addresses, no\n * duplicate.\n */\nimport type { HardDeleteUniquesByConcreteKindParams } from \"../../backend/types\";\nimport { sql as fragmentSql, type SqlFragment } from \"../../query/sql-fragment\";\nimport { edgeCardinalityAxesForKind } from \"./edge-claims\";\n\n/**\n * THE definition of \"the uniqueness claims nodes of this kind own\": every row\n * whose `concrete_kind` is the kind, at whatever axis the row sits on.\n *\n * Kind reaping is a different predicate from a lifecycle release — \"every claim\n * this kind's nodes own\" rather than \"this node's claim for one constraint and\n * key\" — and it is a hard delete rather than a tombstone, so it is its own\n * builder. It is nonetheless the ONLY spelling of that predicate: both the\n * `hardDeleteUniquesByConcreteKind` backend member and `materializeRemovals`'\n * removed-kind cleanup compile this fragment. Keying on `node_kind` instead\n * would leak a claim whose axis is a sibling kind, delete a surviving sibling's\n * claim when the removed kind IS the axis, and never match a claim whose axis\n * is not a kind at all.\n *\n * Takes the relation NAME rather than the Drizzle table so the store-side\n * caller, which knows only its configured table names, can build the same\n * statement; the fragment renders on either dialect.\n */\nexport function buildHardDeleteUniquesByConcreteKind(\n uniquesTableName: string,\n params: HardDeleteUniquesByConcreteKindParams,\n): SqlFragment {\n return fragmentSql`DELETE FROM ${fragmentSql.identifier(uniquesTableName)} WHERE ${fragmentSql.identifier(\"graph_id\")} = ${params.graphId} AND ${fragmentSql.identifier(\"concrete_kind\")} = ${params.concreteKind}`;\n}\n\n/**\n * THE definition of \"the cardinality claims an edge kind owns\": every row at\n * one of the kind's declared-cardinality axes.\n *\n * Keyed on the axis rather than on the holder's id because a removed kind's\n * edges are deleted in the same pass, which would leave a claim naming a row\n * that no longer exists — takeable, but never reaped. Takes the relation NAME\n * rather than the Drizzle table so `materializeRemovals`, which knows only its\n * configured table names, compiles the same statement.\n */\nexport function buildHardDeleteEdgeClaimsByEdgeKind(\n edgeClaimsTableName: string,\n params: Readonly<{ graphId: string; edgeKind: string }>,\n): SqlFragment {\n const axes = edgeCardinalityAxesForKind(params.edgeKind).map(\n (axis) => fragmentSql`${axis}`,\n );\n return fragmentSql`DELETE FROM ${fragmentSql.identifier(edgeClaimsTableName)} WHERE ${fragmentSql.identifier(\"graph_id\")} = ${params.graphId} AND ${fragmentSql.identifier(\"axis\")} IN (${fragmentSql.join(axes, fragmentSql`, `)})`;\n}\n\n/**\n * Housekeeping for node-kind removal: deletes every claim held by an edge whose\n * source or target has the removed kind.\n *\n * The holder ids are selected before those edges are deleted. Filtering claim\n * axes cannot express this ownership: an edge kind may connect several node\n * kinds, while its claim axis names only its cardinality and edge kind.\n */\nexport function buildHardDeleteEdgeClaimsByNodeKind(\n edgeClaimsTableName: string,\n edgesTableName: string,\n params: Readonly<{ graphId: string; nodeKind: string }>,\n): SqlFragment {\n return fragmentSql`DELETE FROM ${fragmentSql.identifier(edgeClaimsTableName)} WHERE ${fragmentSql.identifier(\"graph_id\")} = ${params.graphId} AND ${fragmentSql.identifier(\"edge_id\")} IN (SELECT ${fragmentSql.identifier(\"id\")} FROM ${fragmentSql.identifier(edgesTableName)} WHERE ${fragmentSql.identifier(\"graph_id\")} = ${params.graphId} AND (${fragmentSql.identifier(\"from_kind\")} = ${params.nodeKind} OR ${fragmentSql.identifier(\"to_kind\")} = ${params.nodeKind}))`;\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkOC5ROP7V_cjs = require('./chunk-OC5ROP7V.cjs');
3
+ var chunk6JRVV2SS_cjs = require('./chunk-6JRVV2SS.cjs');
4
4
  var chunkBXHAPCQG_cjs = require('./chunk-BXHAPCQG.cjs');
5
5
  var chunk7XYPLAPL_cjs = require('./chunk-7XYPLAPL.cjs');
6
6
 
@@ -125,25 +125,25 @@ function requireExtras(definition, verdict, operation, refuse) {
125
125
  );
126
126
  }
127
127
  function claimsVerdict(backend) {
128
- return resolveBundle(backend, chunkOC5ROP7V_cjs.CLAIMS);
128
+ return resolveBundle(backend, chunk6JRVV2SS_cjs.CLAIMS);
129
129
  }
130
130
  function uniqueSidecarBatchVerdict(backend) {
131
- return resolveBundle(backend, chunkOC5ROP7V_cjs.UNIQUE_SIDECAR_BATCH);
131
+ return resolveBundle(backend, chunk6JRVV2SS_cjs.UNIQUE_SIDECAR_BATCH);
132
132
  }
133
133
  function batchPointReadVerdict(backend) {
134
- return resolveBundle(backend, chunkOC5ROP7V_cjs.BATCH_POINT_READ);
134
+ return resolveBundle(backend, chunk6JRVV2SS_cjs.BATCH_POINT_READ);
135
135
  }
136
136
  function endpointSetReadVerdict(backend) {
137
- return resolveBundle(backend, chunkOC5ROP7V_cjs.ENDPOINT_SET_READ);
137
+ return resolveBundle(backend, chunk6JRVV2SS_cjs.ENDPOINT_SET_READ);
138
138
  }
139
139
  function statementExecutionVerdict(backend) {
140
- return resolveBundle(backend, chunkOC5ROP7V_cjs.STATEMENT_EXECUTION);
140
+ return resolveBundle(backend, chunk6JRVV2SS_cjs.STATEMENT_EXECUTION);
141
141
  }
142
142
  function contributionHealthVerdict(backend) {
143
- return resolveBundle(backend, chunkOC5ROP7V_cjs.CONTRIBUTION_HEALTH);
143
+ return resolveBundle(backend, chunk6JRVV2SS_cjs.CONTRIBUTION_HEALTH);
144
144
  }
145
145
  function recordedRevisionOriginsVerdict(backend) {
146
- return resolveBundle(backend, chunkOC5ROP7V_cjs.RECORDED_REVISION_ORIGINS);
146
+ return resolveBundle(backend, chunk6JRVV2SS_cjs.RECORDED_REVISION_ORIGINS);
147
147
  }
148
148
  var CLAIMS_VERDICT_THUNKS = /* @__PURE__ */ new WeakMap();
149
149
  function createClaimsVerdictThunk(backend) {
@@ -153,7 +153,7 @@ function createClaimsVerdictThunk(backend) {
153
153
  const thunk = () => {
154
154
  if (memo === void 0) {
155
155
  try {
156
- memo = { state: "resolved", verdict: resolveBundle(backend, chunkOC5ROP7V_cjs.CLAIMS) };
156
+ memo = { state: "resolved", verdict: resolveBundle(backend, chunk6JRVV2SS_cjs.CLAIMS) };
157
157
  } catch (error) {
158
158
  memo = { state: "thrown", error };
159
159
  throw error;
@@ -202,5 +202,5 @@ exports.requireExtras = requireExtras;
202
202
  exports.resolveBundle = resolveBundle;
203
203
  exports.statementExecutionVerdict = statementExecutionVerdict;
204
204
  exports.uniqueSidecarBatchVerdict = uniqueSidecarBatchVerdict;
205
- //# sourceMappingURL=chunk-DHRLOQLQ.cjs.map
206
- //# sourceMappingURL=chunk-DHRLOQLQ.cjs.map
205
+ //# sourceMappingURL=chunk-7LQTDGV5.cjs.map
206
+ //# sourceMappingURL=chunk-7LQTDGV5.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/backend/capabilities/resolve.ts","../src/backend/capabilities/catalog.ts"],"names":["createDataKeyedBag","ConfigurationError","requireDefined","CLAIMS","UNIQUE_SIDECAR_BATCH","BATCH_POINT_READ","ENDPOINT_SET_READ","STATEMENT_EXECUTION","CONTRIBUTION_HEALTH","RECORDED_REVISION_ORIGINS"],"mappings":"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","file":"chunk-DHRLOQLQ.cjs","sourcesContent":["/**\n * The bundle verdict resolver — generalizing `claimSupport`\n * (`store/claims/backing.ts`).\n *\n * Resolution splits in two (ruling B1): the VERDICT — the support decision,\n * resolved once against `GraphBackend` and threaded — and the BINDING\n * (`bind.ts`) — the actual member functions, bound at the call site off\n * whichever port the site holds. A verdict carries names, never functions\n * (I19), so it crosses transaction boundaries safely.\n */\nimport { ConfigurationError } from \"../../errors\";\nimport { createDataKeyedBag } from \"../../utils/object\";\nimport { requireDefined } from \"../../utils/presence\";\nimport { type BackendCapabilities, type GraphBackend } from \"../types\";\nimport {\n BATCH_POINT_READ,\n type CapabilityBundleDefinition,\n type CapabilityBundleDisposition,\n type CapabilityBundleExtra,\n CLAIMS,\n CONTRIBUTION_HEALTH,\n ENDPOINT_SET_READ,\n type OptionalGraphBackendMember,\n RECORDED_REVISION_ORIGINS,\n STATEMENT_EXECUTION,\n UNIQUE_SIDECAR_BATCH,\n} from \"./bundle-registry\";\n\n/**\n * A bundle's extras, as a type-level map from extra id to the UNION of\n * member names that extra covers — derived from the definition's `extras`\n * array by `const` inference, never hand-written.\n */\nexport type CapabilityExtraSpec = Readonly<\n Record<string, OptionalGraphBackendMember>\n>;\n\n/**\n * One extra's verdict. `present: true` carries the member NAMES, not the\n * member functions (ruling B1) — the names are what the accessor binds\n * from, at the site, off the port.\n */\nexport type ExtraVerdict<M extends OptionalGraphBackendMember> =\n | Readonly<{ present: true; members: readonly M[] }>\n | Readonly<{\n present: false;\n missing: readonly M[];\n disposition: CapabilityBundleDisposition;\n }>;\n\n/** The verdict map: one entry per extra id, never a boolean. */\nexport type ExtraVerdicts<X extends CapabilityExtraSpec> = Readonly<{\n [K in keyof X]: ExtraVerdict<X[K]>;\n}>;\n\nexport type GatedBundleVerdict<\n MCore extends OptionalGraphBackendMember,\n X extends CapabilityExtraSpec,\n> =\n | Readonly<{\n supported: true;\n bundle: string;\n /** The core, guaranteed present. Names, not functions. */\n members: readonly MCore[];\n extras: ExtraVerdicts<X>;\n /** The `present: false` keys of `extras`. */\n missingExtras: readonly (keyof X)[];\n }>\n | Readonly<{\n supported: false;\n bundle: string;\n missing: readonly MCore[];\n /** Why it is unsupported: the bundle's own `disposition`, verbatim. */\n disposition: CapabilityBundleDisposition;\n }>;\n\n/** No `supported` field: a graduated bundle has no bundle-level verdict. */\nexport type GraduatedBundleVerdict<X extends CapabilityExtraSpec> = Readonly<{\n bundle: string;\n extras: ExtraVerdicts<X>;\n missingExtras: readonly (keyof X)[];\n}>;\n\n/**\n * Recovers the id→members map from a definition's `extras` TUPLE (not\n * `readonly CapabilityBundleExtra<XId, MExtra>[]` — over the array type the\n * id→members association is erased and `ExtraVerdicts<X>` degenerates to an\n * index signature).\n */\nexport type SpecOf<\n XS extends readonly CapabilityBundleExtra<\n string,\n OptionalGraphBackendMember\n >[],\n> = { [K in XS[number] as K[\"id\"]]: K[\"members\"][number] };\n\nexport type ExtrasOf<D extends CapabilityBundleDefinition> = SpecOf<\n NonNullable<D[\"extras\"]>\n>;\nexport type ExtraMember<\n D extends CapabilityBundleDefinition,\n X extends keyof ExtrasOf<D>,\n> = Extract<ExtrasOf<D>[X], OptionalGraphBackendMember>;\n\n/**\n * The definition union and the return-type mapping. Structural, matching\n * `bundle-registry.ts`'s `BundleMembers` helper's own lesson: reading `core`\n * off `D` directly (rather than re-matching `GatedBundleDefinition`) avoids\n * an unmatched `infer` silently widening to the member constraint.\n */\nexport type BundleVerdictOf<D extends CapabilityBundleDefinition> =\n D extends (\n {\n kind: \"graduated\";\n extras: infer XS extends readonly CapabilityBundleExtra<\n string,\n OptionalGraphBackendMember\n >[];\n }\n ) ?\n GraduatedBundleVerdict<SpecOf<XS>>\n : D extends (\n {\n kind: \"gated\";\n core: readonly (infer MCore extends OptionalGraphBackendMember)[];\n extras?: infer XS extends\n | readonly CapabilityBundleExtra<string, OptionalGraphBackendMember>[]\n | undefined;\n }\n ) ?\n GatedBundleVerdict<\n MCore,\n SpecOf<\n XS extends (\n readonly CapabilityBundleExtra<string, OptionalGraphBackendMember>[]\n ) ?\n XS\n : []\n >\n >\n : never;\n\nfunction resolveExtras<\n const XS extends readonly CapabilityBundleExtra<\n string,\n OptionalGraphBackendMember\n >[],\n>(\n backend: GraphBackend,\n extras: XS,\n): Readonly<{\n extras: ExtraVerdicts<SpecOf<XS>>;\n missingExtras: readonly (keyof SpecOf<XS>)[];\n}> {\n const verdicts =\n createDataKeyedBag<ExtraVerdict<OptionalGraphBackendMember>>();\n const missingExtras: string[] = [];\n for (const extra of extras) {\n const missing = extra.members.filter(\n (member) => backend[member] === undefined,\n );\n if (missing.length === 0) {\n verdicts[extra.id] = { present: true, members: extra.members };\n } else {\n verdicts[extra.id] = {\n present: false,\n missing,\n disposition: extra.disposition,\n };\n missingExtras.push(extra.id);\n }\n }\n return {\n extras: verdicts as ExtraVerdicts<SpecOf<XS>>,\n missingExtras: missingExtras,\n };\n}\n\n/**\n * The `claims` bidirectional cross-check (ruling F2), reproducing\n * `store/claims/backing.ts`'s pre-B7 message text, code and suggestion\n * BYTE-FOR-BYTE. B7 made `claimSupport` (`backing.ts`) delegate to\n * {@link resolveBundle}, so this is now the ONLY place the check runs — there\n * is no second copy left to keep in sync. `bidirectional` is `claims`-only by\n * design (§5.2.1): the two trailing sentences below name \"claim\"/\"fence\"\n * vocabulary that is specific to that one bundle, and a future bundle raising\n * `crossCheck` to `\"bidirectional\"` must carry its own justification row and,\n * with it, its own message pair here.\n *\n * @throws {ConfigurationError} when the declaration and the member surface\n * disagree in either direction.\n */\nfunction assertClaimsBidirectionalAgreement(\n backend: GraphBackend,\n definition: Readonly<{\n declaration?: keyof BackendCapabilities;\n core: readonly OptionalGraphBackendMember[];\n portSurfaceCode: string;\n }>,\n): void {\n if (definition.declaration === undefined) return;\n const declared = backend.capabilities[definition.declaration] === true;\n const present = definition.core.filter(\n (member) => backend[member] !== undefined,\n );\n if (declared && present.length === definition.core.length) return;\n if (!declared && present.length === 0) return;\n\n const missing = definition.core.filter(\n (member) => backend[member] === undefined,\n );\n const declarationName = definition.declaration;\n throw new ConfigurationError(\n declared ?\n `This backend declares \\`${declarationName}: true\\` but does not implement ${missing.join(\", \")}. ` +\n \"A declared constraint would then be written without the fence the declaration promises.\"\n : `This backend implements ${present.join(\", \")} but does not declare \\`${declarationName}: true\\`. ` +\n \"Claim support is read from the declaration, so these members would never be called.\",\n { code: definition.portSurfaceCode, missing, present },\n {\n suggestion:\n declared ?\n `Implement the missing members, or drop \\`${declarationName}\\` from the backend's capabilities.`\n : `Declare \\`${declarationName}: true\\` in the backend's capabilities, or drop the claim members.`,\n },\n );\n}\n\n/**\n * Resolved ONCE, at construction or entry, against the top-level backend —\n * never against a `TransactionBackend` (I15's `@ts-expect-error` row).\n *\n * Rules: the member surface is read always; the declaration is read only\n * when the definition names one AND `crossCheck !== \"none\"` (only `claims`\n * qualifies in the pilot registry); a gated bundle's core must be complete\n * or the bundle is unsupported with `missing`; a graduated bundle has no\n * bundle-level verdict, only per-extra verdicts. `missingExtras` is built by\n * the SAME fold that builds `extras` (one pass, one owner).\n */\nexport function resolveBundle<const D extends CapabilityBundleDefinition>(\n backend: GraphBackend,\n definition: D,\n): BundleVerdictOf<D> {\n const extras = (definition.extras ?? []) as readonly CapabilityBundleExtra<\n string,\n OptionalGraphBackendMember\n >[];\n const { extras: extraVerdicts, missingExtras } = resolveExtras(\n backend,\n extras,\n );\n\n // Rule 1: the declaration is read whenever `crossCheck !== \"none\"`,\n // regardless of kind — a graduated bundle's \"core\" for this purpose is the\n // union of every extra's members, since it has no core of its own. Only\n // `claims` (gated) exercises this in the pilot registry, but the check\n // itself must not silently no-op for a hypothetical graduated bidirectional\n // bundle (T11's mutation pins exactly this).\n if (definition.crossCheck === \"bidirectional\") {\n const memberSet =\n definition.kind === \"gated\" ?\n definition.core\n : extras.flatMap((extra) => extra.members);\n assertClaimsBidirectionalAgreement(backend, {\n ...(definition.declaration === undefined ?\n {}\n : { declaration: definition.declaration }),\n core: memberSet,\n portSurfaceCode: definition.portSurfaceCode,\n });\n }\n\n if (definition.kind === \"graduated\") {\n return {\n bundle: definition.id,\n extras: extraVerdicts,\n missingExtras,\n } as unknown as BundleVerdictOf<D>;\n }\n\n const missing = definition.core.filter(\n (member) => backend[member] === undefined,\n );\n if (missing.length > 0) {\n return {\n supported: false,\n bundle: definition.id,\n missing,\n disposition: definition.disposition,\n } as unknown as BundleVerdictOf<D>;\n }\n return {\n supported: true,\n bundle: definition.id,\n members: definition.core,\n extras: extraVerdicts,\n missingExtras,\n } as unknown as BundleVerdictOf<D>;\n}\n\n/** The literal operation names a bundle's `operations` table declares. */\nexport type OperationNames<D extends CapabilityBundleDefinition> =\n D[\"operations\"][number][\"operation\"];\n\n/** The extras a named operation `requires`, read from the ROW — never re-spelled at the call site. */\nexport type RequiredExtrasOf<\n D extends CapabilityBundleDefinition,\n Op extends OperationNames<D>,\n> =\n Extract<D[\"operations\"][number], { operation: Op }> extends (\n { requires: infer R extends readonly string[] }\n ) ?\n R[number]\n : never;\n\n/**\n * The registry's row lookup plus the presence fold, extracted verbatim from\n * {@link requireExtras}'s body (ruling B8 spec item 3): the ONE owner of\n * \"what this operation requires\" that both `requireExtras`'s default throw\n * and a call site's own `refuse` callback consult.\n *\n * `operation` is the literal key of the bundle's `operations` tuple, so the\n * required extras are looked up TYPE-LEVEL from the registry — no second\n * spelling of `requires` at the call site.\n *\n * @throws {ConfigurationError} naming the unknown operation when `operation`\n * is not a row of `definition.operations`.\n */\nexport function missingRequiredExtras<\n const D extends CapabilityBundleDefinition,\n Op extends OperationNames<D>,\n>(\n definition: D,\n verdict: BundleVerdictOf<D>,\n operation: Op,\n): readonly string[] {\n const row = definition.operations.find(\n (candidate) => candidate.operation === operation,\n );\n if (row === undefined) {\n throw new ConfigurationError(\n `Unknown operation \"${operation}\" for capability bundle \"${definition.id}\".`,\n { bundle: definition.id, operation },\n );\n }\n const required = row.requires ?? [];\n const extras:\n | Readonly<Record<string, ExtraVerdict<OptionalGraphBackendMember>>>\n | undefined = \"extras\" in verdict ? verdict.extras : undefined;\n return required.filter(\n (id) => extras === undefined || extras[id]?.present !== true,\n );\n}\n\n/**\n * The refusal for an operation whose `requires` extras are absent — how a\n * GRADUATED bundle refuses where the tree refuses today: the row names the\n * operation and the extras, this asserts they are present, and\n * {@link bindExtra} (`bind.ts`) binds them off the port.\n *\n * `refuse`, when supplied, is called instead of the registry-coded throw\n * below — this is how a call site keeps its OWN existing error text (message,\n * `details` shape, order relative to other refusals) while the registry\n * stays the one owner of \"what this operation requires\" (ruling B8 spec item\n * 3). Omitting it keeps the default behavior byte-identical to before this\n * parameter existed.\n *\n * @throws {ConfigurationError} naming the row's own `code` when one or more\n * required extras is absent from the verdict and no `refuse` callback is\n * supplied; otherwise calls `refuse(missing)`, which never returns.\n */\nexport function requireExtras<\n const D extends CapabilityBundleDefinition,\n Op extends OperationNames<D>,\n>(\n definition: D,\n verdict: BundleVerdictOf<D>,\n operation: Op,\n refuse?: (missing: readonly string[]) => never,\n): asserts verdict is BundleVerdictOf<D> & {\n extras: {\n [K in RequiredExtrasOf<D, Op> & keyof ExtrasOf<D>]: Extract<\n ExtraVerdict<ExtraMember<D, K>>,\n { present: true }\n >;\n };\n} {\n const missing = missingRequiredExtras(definition, verdict, operation);\n if (missing.length === 0) return;\n\n if (refuse !== undefined) refuse(missing);\n\n // `missingRequiredExtras` already threw the unknown-operation error above\n // when the row would be undefined, so `requireDefined` here is a redundant\n // (never-failing) narrowing, not a second lookup that could disagree.\n const { disposition } = requireDefined(\n definition.operations.find(\n (candidate) => candidate.operation === operation,\n ),\n );\n if (disposition.kind === \"refuse\") {\n throw new ConfigurationError(\n `Operation \"${operation}\" on capability bundle \"${definition.id}\" requires ${missing.join(\", \")}.`,\n { code: disposition.code, bundle: definition.id, operation, missing },\n );\n }\n // No pilot row reaches this: every row with a non-empty `requires` in the\n // registry disposes `refuse` (a graduated bundle's fallback rows never\n // name `requires` — the fallback IS the degrade path). Kept as a named,\n // typed refusal rather than a silent pass so a future `fallback` +\n // `requires` row cannot pass `requireExtras` unnoticed.\n throw new ConfigurationError(\n `Operation \"${operation}\" on capability bundle \"${definition.id}\" requires ${missing.join(\", \")}, and the registry names no refusal code for this fallback-dispositioned row.`,\n { bundle: definition.id, operation, missing },\n );\n}\n\n// ---------------------------------------------------------------------------\n// The seven named verdict accessors — GraphBackend-only, no exceptions (I15).\n// ---------------------------------------------------------------------------\n\nexport function claimsVerdict(\n backend: GraphBackend,\n): BundleVerdictOf<typeof CLAIMS> {\n return resolveBundle(backend, CLAIMS);\n}\n\nexport function uniqueSidecarBatchVerdict(\n backend: GraphBackend,\n): BundleVerdictOf<typeof UNIQUE_SIDECAR_BATCH> {\n return resolveBundle(backend, UNIQUE_SIDECAR_BATCH);\n}\n\nexport function batchPointReadVerdict(\n backend: GraphBackend,\n): BundleVerdictOf<typeof BATCH_POINT_READ> {\n return resolveBundle(backend, BATCH_POINT_READ);\n}\n\nexport function endpointSetReadVerdict(\n backend: GraphBackend,\n): BundleVerdictOf<typeof ENDPOINT_SET_READ> {\n return resolveBundle(backend, ENDPOINT_SET_READ);\n}\n\nexport function statementExecutionVerdict(\n backend: GraphBackend,\n): BundleVerdictOf<typeof STATEMENT_EXECUTION> {\n return resolveBundle(backend, STATEMENT_EXECUTION);\n}\n\nexport function contributionHealthVerdict(\n backend: GraphBackend,\n): BundleVerdictOf<typeof CONTRIBUTION_HEALTH> {\n return resolveBundle(backend, CONTRIBUTION_HEALTH);\n}\n\nexport function recordedRevisionOriginsVerdict(\n backend: GraphBackend,\n): BundleVerdictOf<typeof RECORDED_REVISION_ORIGINS> {\n return resolveBundle(backend, RECORDED_REVISION_ORIGINS);\n}\n\n// ---------------------------------------------------------------------------\n// The claims verdict THUNK — the reference implementation of §5.2.3's INTENT\n// (one owner, at-most-once resolution, no re-derivation) moved to WHEN it\n// resolves rather than IF (ruling B7 refinement 2).\n// ---------------------------------------------------------------------------\n\n/**\n * A memoized, at-most-once resolution of the `claims` bundle's verdict\n * against ONE backend.\n *\n * Eager resolution at store construction is forbidden: T14's\n * contradictory-declaration backends must still be able to construct a store\n * and create nodes — only a constrained edge write may legally reach the\n * bidirectional cross-check's throw, and it must do so lazily, at the first\n * write that needs the verdict.\n *\n * A cached verdict cannot go stale because `GraphBackend` is deep-frozen (B1):\n * nothing can flip `capabilities.constraintClaims` or add/remove a claim\n * member on a backend object after this thunk has already resolved it, so\n * \"resolve once and reuse forever\" is exactly as safe as \"resolve every\n * time\" — for one backend object, they observe the same immutable answer.\n */\nexport type ClaimsVerdictThunk = () => BundleVerdictOf<typeof CLAIMS>;\n\n/**\n * Interning: the same backend object always gets back the SAME thunk object.\n * This is what makes \"one shared thunk per backend\" structural rather than a\n * convention every population site has to honor — a second call to\n * {@link createClaimsVerdictThunk} for a backend already minted cannot produce\n * a second, independently-memoized verdict.\n */\nconst CLAIMS_VERDICT_THUNKS = new WeakMap<GraphBackend, ClaimsVerdictThunk>();\n\n/**\n * Mints — or returns the already-minted — {@link ClaimsVerdictThunk} for\n * `backend`.\n *\n * The thunk resolves {@link resolveBundle}`(backend, CLAIMS)` on its first\n * call and caches the outcome, INCLUDING a thrown `ConfigurationError`: a\n * refusal is cached and re-thrown on every subsequent call, never\n * re-resolved. Both layers — interning here, memoization inside the thunk —\n * are required: interning alone would still let two independently-memoized\n * thunks exist for one backend if a caller ignored the shared one; memoizing\n * alone would still let two different call sites mint two different thunks\n * that could disagree about whether they had already resolved.\n */\nexport function createClaimsVerdictThunk(\n backend: GraphBackend,\n): ClaimsVerdictThunk {\n const existing = CLAIMS_VERDICT_THUNKS.get(backend);\n if (existing !== undefined) return existing;\n\n type Memo =\n | Readonly<{ state: \"resolved\"; verdict: BundleVerdictOf<typeof CLAIMS> }>\n | Readonly<{ state: \"thrown\"; error: unknown }>;\n let memo: Memo | undefined;\n\n const thunk: ClaimsVerdictThunk = () => {\n if (memo === undefined) {\n try {\n memo = { state: \"resolved\", verdict: resolveBundle(backend, CLAIMS) };\n } catch (error) {\n memo = { state: \"thrown\", error };\n throw error;\n }\n }\n if (memo.state === \"thrown\") throw memo.error;\n return memo.verdict;\n };\n\n CLAIMS_VERDICT_THUNKS.set(backend, thunk);\n return thunk;\n}\n","/**\n * The backend's optional catalog-introspection surface: physical-schema\n * probes a store path consults directly, spelled once per dialect by the\n * two bundled profiles instead of a `dialect === \"postgres\"` branch at each\n * call site.\n *\n * Every member is a read-only probe except `dropInvalidIndex`, which issues\n * the one DDL statement that heals a crashed concurrent index build.\n * Nothing here writes a graph row, a sidecar row, or a status row.\n */\nimport { ConfigurationError } from \"../../errors\";\nimport { type GraphBackend } from \"../types\";\n\n/**\n * A physical index's presence and, on engines that can leave a build\n * half-finished, whether the leftover is usable.\n *\n * `invalid` is PostgreSQL's `pg_index.indisvalid = false` — an interrupted\n * `CREATE INDEX CONCURRENTLY` leaves a same-named index behind that a later\n * `IF NOT EXISTS` build would otherwise accept silently. SQLite has no such\n * state: `invalid` is always `false` there, and `exists` alone is the whole\n * answer.\n */\nexport type IndexState = Readonly<{\n /** The physical SQL index name that was probed. */\n name: string;\n /** Whether an index with this name exists in the engine catalog. */\n exists: boolean;\n /** PostgreSQL's invalid-build leftover flag; always `false` on SQLite. */\n invalid: boolean;\n}>;\n\n/**\n * A physical column's declared type, reduced to the family the two callers\n * that classify a recorded-time column actually distinguish: an integer\n * counter, text (SQLite's affinity for a wall-clock column stored as an\n * ISO-8601 string), PostgreSQL's exact `timestamp with time zone`, or\n * anything else. Kept this coarse on purpose — no caller needs a finer\n * classification, and each dialect's own probe decides which of these a\n * given declared type maps to, using that engine's own type rules (exact\n * match on PostgreSQL, affinity on SQLite).\n *\n * PostgreSQL's own normalizer never reports `\"text\"` — a declared `text`\n * column on that dialect falls through to `\"other\"`, since nothing\n * PostgreSQL-side stores a recorded-time column that way. That asymmetry is\n * why a revision or wall-time comparison must compare against\n * {@link REVISION_COLUMN_KINDS} / {@link WALL_TIME_COLUMN_KINDS} rather than\n * a single literal: the two dialects agree on the revision kind but not on\n * the wall-time one.\n */\nexport type NormalizedColumnKind =\n \"integer\" | \"text\" | \"timestamp-with-time-zone\" | \"other\";\n\n/**\n * The `columnTypes` kinds that count as a revision counter. Both dialects\n * normalize one to `\"integer\"`, so this is a single-member set today — named\n * and exported so a caller compares against ONE owned set instead of\n * re-spelling `=== \"integer\"` inline. Consumed by\n * `store/recorded-capture/schema-version.ts`'s `isCompatibleColumnKind`,\n * which replaced that file's dialect-branching `isCompatibleColumnType` and\n * its SQLite-affinity twin (`hasSqliteAffinity`) with this owned set.\n */\nexport const REVISION_COLUMN_KINDS: readonly NormalizedColumnKind[] = [\n \"integer\",\n];\n\n/**\n * The `columnTypes` kinds that count as a wall-clock timestamp. SQLite\n * stores one as an ISO-8601 string (`\"text\"`); PostgreSQL stores one as\n * `timestamp with time zone` (`\"timestamp-with-time-zone\"`) and never\n * normalizes a declared column to `\"text\"` at all — so this set stays exact\n * on both dialects without a caller ever branching on `dialect`. Consumed\n * by `store/recorded-capture/schema-version.ts`'s `isCompatibleColumnKind`,\n * alongside {@link REVISION_COLUMN_KINDS}.\n */\nexport const WALL_TIME_COLUMN_KINDS: readonly NormalizedColumnKind[] = [\n \"text\",\n \"timestamp-with-time-zone\",\n];\n\n/**\n * One physical column's name, normalized type family, and raw declared\n * type — trimmed and lower-cased, but otherwise exactly what the engine's\n * own catalog reports (`\"bigint\"`, `\"timestamp with time zone\"`, a SQLite\n * declared type such as `\"integer\"` or `\"text\"`, and so on). `kind` is what\n * a comparison should classify against; `declaredType` is what a\n * diagnostic should show a human, since `kind` discards the declared\n * spelling entirely.\n */\nexport type CatalogColumn = Readonly<{\n name: string;\n kind: NormalizedColumnKind;\n declaredType: string;\n}>;\n\n/** One physical table's catalog presence. See {@link BackendCatalogProbes.tablesExist}. */\nexport type TableState = Readonly<{\n /** The physical SQL table name that was probed. */\n name: string;\n /** Whether a table with this name exists in the engine catalog. */\n exists: boolean;\n}>;\n\n/**\n * The three facts index materialization used to keep in its own\n * dialect-keyed record: whether this engine can build an index\n * concurrently (without blocking readers/writers), whether a concurrent\n * build can be interrupted into a usable-but-invalid leftover, and whether\n * it offers the GIN index family fulltext/trigram indexing needs.\n */\nexport type CatalogIndexBehavior = Readonly<{\n concurrentBuilds: boolean;\n hasInvalidIndexState: boolean;\n supportsGinFamily: boolean;\n}>;\n\n/**\n * Physical-schema introspection a store path consults directly: table and\n * index presence, PostgreSQL's invalid-index leftover state and its\n * self-heal, normalized column types, and the per-dialect index-build\n * facts above.\n *\n * Optional: a custom backend that omits it loses the store paths that\n * consult it directly — index materialization (`store.materializeIndexes()`\n * refuses only once its empty-candidate short circuit and the status-table\n * ensure step have already run; `store.materializeSystemIndexes()`, which\n * has no candidate short circuit, refuses only once that same status-table\n * ensure step has run), the recorded-time schema check, and the\n * recorded-time migration's column read.\n */\nexport type BackendCatalogProbes = Readonly<{\n /**\n * Whether a table with this physical name exists in the engine catalog —\n * on PostgreSQL, anything an unqualified `DELETE`/`ANALYZE` against the\n * name could hit (ordinary and partitioned tables, views, materialized\n * views, foreign tables), matching the dialect operation strategy's own\n * DDL-target probe. A caller that means specifically \"is this a TABLE\",\n * as opposed to any relation an unqualified statement could resolve to,\n * wants {@link BackendCatalogProbes.tablesExist} instead — its narrower\n * predicate excludes views, materialized views, and foreign tables.\n */\n tableExists: (this: void, name: string) => Promise<boolean>;\n /**\n * The catalog state of each named physical TABLE, one entry per input\n * name (an absent name reports `exists: false`), resolved in one round\n * trip. On PostgreSQL this is ordinary and partitioned tables only\n * (`relkind IN ('r', 'p')`) — narrower than {@link tableExists}, which\n * also matches views, materialized views, and foreign tables. A caller\n * gating bulk, table-scoped work (a preload ahead of table DDL, say)\n * wants this member so it gets one round trip and the strict predicate,\n * rather than looping {@link tableExists} or accepting its wider match.\n */\n tablesExist: (\n this: void,\n names: readonly string[],\n ) => Promise<readonly TableState[]>;\n /**\n * The catalog state of each named physical index, one entry per input\n * name (an absent index reports `exists: false`), resolved in one\n * round trip.\n */\n indexStates: (\n this: void,\n names: readonly string[],\n ) => Promise<readonly IndexState[]>;\n /**\n * Drops the named index if — and only if — it is a PostgreSQL INVALID\n * leftover from an interrupted `CREATE INDEX CONCURRENTLY`. A no-op on\n * an engine whose `indexBehavior.hasInvalidIndexState` is `false`, and\n * a no-op for a valid or absent index on every engine.\n *\n * A ROOT-BACKEND operation on an engine with an invalid-index state:\n * PostgreSQL refuses `DROP INDEX CONCURRENTLY` inside a transaction\n * block, so there the `catalog` a `transaction()` handle exposes throws a\n * typed `ConfigurationError` from this member instead of attempting the\n * DDL. An engine whose `indexBehavior.hasInvalidIndexState` is `false`\n * (SQLite) has no invalid leftover to ever drop and stays a no-op in\n * both scopes — every other member here stays a plain read on that same\n * transaction-scoped bag regardless of engine.\n */\n dropInvalidIndex: (this: void, name: string) => Promise<void>;\n /** Every column's name and normalized type family for one physical table. */\n columnTypes: (this: void, table: string) => Promise<readonly CatalogColumn[]>;\n /** This engine's index-build facts. See {@link CatalogIndexBehavior}. */\n indexBehavior: CatalogIndexBehavior;\n}>;\n\n/**\n * THE refusal for a store path that needs the backend's catalog probes and\n * finds them absent, naming the missing port so a caller can add it — or\n * switch to a bundled backend — instead of chasing a `TypeError` two calls\n * deep into `materializeIndexes` or a recorded-time migration.\n */\nexport function requireCatalog(\n backend: Pick<GraphBackend, \"catalog\">,\n operation: string,\n): BackendCatalogProbes {\n const catalog = backend.catalog;\n if (catalog === undefined) {\n throw new ConfigurationError(\n `${operation} requires the backend's catalog probes, but this backend declares no \\`catalog\\`.`,\n { code: \"CATALOG_UNAVAILABLE\", operation },\n {\n suggestion:\n \"Implement `catalog` on this backend, or use a built-in SQLite or PostgreSQL backend.\",\n },\n );\n }\n return catalog;\n}\n"]}
1
+ {"version":3,"sources":["../src/backend/capabilities/resolve.ts","../src/backend/capabilities/catalog.ts"],"names":["createDataKeyedBag","ConfigurationError","requireDefined","CLAIMS","UNIQUE_SIDECAR_BATCH","BATCH_POINT_READ","ENDPOINT_SET_READ","STATEMENT_EXECUTION","CONTRIBUTION_HEALTH","RECORDED_REVISION_ORIGINS"],"mappings":"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","file":"chunk-7LQTDGV5.cjs","sourcesContent":["/**\n * The bundle verdict resolver — generalizing `claimSupport`\n * (`store/claims/backing.ts`).\n *\n * Resolution splits in two (ruling B1): the VERDICT — the support decision,\n * resolved once against `GraphBackend` and threaded — and the BINDING\n * (`bind.ts`) — the actual member functions, bound at the call site off\n * whichever port the site holds. A verdict carries names, never functions\n * (I19), so it crosses transaction boundaries safely.\n */\nimport { ConfigurationError } from \"../../errors\";\nimport { createDataKeyedBag } from \"../../utils/object\";\nimport { requireDefined } from \"../../utils/presence\";\nimport { type BackendCapabilities, type GraphBackend } from \"../types\";\nimport {\n BATCH_POINT_READ,\n type CapabilityBundleDefinition,\n type CapabilityBundleDisposition,\n type CapabilityBundleExtra,\n CLAIMS,\n CONTRIBUTION_HEALTH,\n ENDPOINT_SET_READ,\n type OptionalGraphBackendMember,\n RECORDED_REVISION_ORIGINS,\n STATEMENT_EXECUTION,\n UNIQUE_SIDECAR_BATCH,\n} from \"./bundle-registry\";\n\n/**\n * A bundle's extras, as a type-level map from extra id to the UNION of\n * member names that extra covers — derived from the definition's `extras`\n * array by `const` inference, never hand-written.\n */\nexport type CapabilityExtraSpec = Readonly<\n Record<string, OptionalGraphBackendMember>\n>;\n\n/**\n * One extra's verdict. `present: true` carries the member NAMES, not the\n * member functions (ruling B1) — the names are what the accessor binds\n * from, at the site, off the port.\n */\nexport type ExtraVerdict<M extends OptionalGraphBackendMember> =\n | Readonly<{ present: true; members: readonly M[] }>\n | Readonly<{\n present: false;\n missing: readonly M[];\n disposition: CapabilityBundleDisposition;\n }>;\n\n/** The verdict map: one entry per extra id, never a boolean. */\nexport type ExtraVerdicts<X extends CapabilityExtraSpec> = Readonly<{\n [K in keyof X]: ExtraVerdict<X[K]>;\n}>;\n\nexport type GatedBundleVerdict<\n MCore extends OptionalGraphBackendMember,\n X extends CapabilityExtraSpec,\n> =\n | Readonly<{\n supported: true;\n bundle: string;\n /** The core, guaranteed present. Names, not functions. */\n members: readonly MCore[];\n extras: ExtraVerdicts<X>;\n /** The `present: false` keys of `extras`. */\n missingExtras: readonly (keyof X)[];\n }>\n | Readonly<{\n supported: false;\n bundle: string;\n missing: readonly MCore[];\n /** Why it is unsupported: the bundle's own `disposition`, verbatim. */\n disposition: CapabilityBundleDisposition;\n }>;\n\n/** No `supported` field: a graduated bundle has no bundle-level verdict. */\nexport type GraduatedBundleVerdict<X extends CapabilityExtraSpec> = Readonly<{\n bundle: string;\n extras: ExtraVerdicts<X>;\n missingExtras: readonly (keyof X)[];\n}>;\n\n/**\n * Recovers the id→members map from a definition's `extras` TUPLE (not\n * `readonly CapabilityBundleExtra<XId, MExtra>[]` — over the array type the\n * id→members association is erased and `ExtraVerdicts<X>` degenerates to an\n * index signature).\n */\nexport type SpecOf<\n XS extends readonly CapabilityBundleExtra<\n string,\n OptionalGraphBackendMember\n >[],\n> = { [K in XS[number] as K[\"id\"]]: K[\"members\"][number] };\n\nexport type ExtrasOf<D extends CapabilityBundleDefinition> = SpecOf<\n NonNullable<D[\"extras\"]>\n>;\nexport type ExtraMember<\n D extends CapabilityBundleDefinition,\n X extends keyof ExtrasOf<D>,\n> = Extract<ExtrasOf<D>[X], OptionalGraphBackendMember>;\n\n/**\n * The definition union and the return-type mapping. Structural, matching\n * `bundle-registry.ts`'s `BundleMembers` helper's own lesson: reading `core`\n * off `D` directly (rather than re-matching `GatedBundleDefinition`) avoids\n * an unmatched `infer` silently widening to the member constraint.\n */\nexport type BundleVerdictOf<D extends CapabilityBundleDefinition> =\n D extends (\n {\n kind: \"graduated\";\n extras: infer XS extends readonly CapabilityBundleExtra<\n string,\n OptionalGraphBackendMember\n >[];\n }\n ) ?\n GraduatedBundleVerdict<SpecOf<XS>>\n : D extends (\n {\n kind: \"gated\";\n core: readonly (infer MCore extends OptionalGraphBackendMember)[];\n extras?: infer XS extends\n | readonly CapabilityBundleExtra<string, OptionalGraphBackendMember>[]\n | undefined;\n }\n ) ?\n GatedBundleVerdict<\n MCore,\n SpecOf<\n XS extends (\n readonly CapabilityBundleExtra<string, OptionalGraphBackendMember>[]\n ) ?\n XS\n : []\n >\n >\n : never;\n\nfunction resolveExtras<\n const XS extends readonly CapabilityBundleExtra<\n string,\n OptionalGraphBackendMember\n >[],\n>(\n backend: GraphBackend,\n extras: XS,\n): Readonly<{\n extras: ExtraVerdicts<SpecOf<XS>>;\n missingExtras: readonly (keyof SpecOf<XS>)[];\n}> {\n const verdicts =\n createDataKeyedBag<ExtraVerdict<OptionalGraphBackendMember>>();\n const missingExtras: string[] = [];\n for (const extra of extras) {\n const missing = extra.members.filter(\n (member) => backend[member] === undefined,\n );\n if (missing.length === 0) {\n verdicts[extra.id] = { present: true, members: extra.members };\n } else {\n verdicts[extra.id] = {\n present: false,\n missing,\n disposition: extra.disposition,\n };\n missingExtras.push(extra.id);\n }\n }\n return {\n extras: verdicts as ExtraVerdicts<SpecOf<XS>>,\n missingExtras: missingExtras,\n };\n}\n\n/**\n * The `claims` bidirectional cross-check (ruling F2), reproducing\n * `store/claims/backing.ts`'s pre-B7 message text, code and suggestion\n * BYTE-FOR-BYTE. B7 made `claimSupport` (`backing.ts`) delegate to\n * {@link resolveBundle}, so this is now the ONLY place the check runs — there\n * is no second copy left to keep in sync. `bidirectional` is `claims`-only by\n * design (§5.2.1): the two trailing sentences below name \"claim\"/\"fence\"\n * vocabulary that is specific to that one bundle, and a future bundle raising\n * `crossCheck` to `\"bidirectional\"` must carry its own justification row and,\n * with it, its own message pair here.\n *\n * @throws {ConfigurationError} when the declaration and the member surface\n * disagree in either direction.\n */\nfunction assertClaimsBidirectionalAgreement(\n backend: GraphBackend,\n definition: Readonly<{\n declaration?: keyof BackendCapabilities;\n core: readonly OptionalGraphBackendMember[];\n portSurfaceCode: string;\n }>,\n): void {\n if (definition.declaration === undefined) return;\n const declared = backend.capabilities[definition.declaration] === true;\n const present = definition.core.filter(\n (member) => backend[member] !== undefined,\n );\n if (declared && present.length === definition.core.length) return;\n if (!declared && present.length === 0) return;\n\n const missing = definition.core.filter(\n (member) => backend[member] === undefined,\n );\n const declarationName = definition.declaration;\n throw new ConfigurationError(\n declared ?\n `This backend declares \\`${declarationName}: true\\` but does not implement ${missing.join(\", \")}. ` +\n \"A declared constraint would then be written without the fence the declaration promises.\"\n : `This backend implements ${present.join(\", \")} but does not declare \\`${declarationName}: true\\`. ` +\n \"Claim support is read from the declaration, so these members would never be called.\",\n { code: definition.portSurfaceCode, missing, present },\n {\n suggestion:\n declared ?\n `Implement the missing members, or drop \\`${declarationName}\\` from the backend's capabilities.`\n : `Declare \\`${declarationName}: true\\` in the backend's capabilities, or drop the claim members.`,\n },\n );\n}\n\n/**\n * Resolved ONCE, at construction or entry, against the top-level backend —\n * never against a `TransactionBackend` (I15's `@ts-expect-error` row).\n *\n * Rules: the member surface is read always; the declaration is read only\n * when the definition names one AND `crossCheck !== \"none\"` (only `claims`\n * qualifies in the pilot registry); a gated bundle's core must be complete\n * or the bundle is unsupported with `missing`; a graduated bundle has no\n * bundle-level verdict, only per-extra verdicts. `missingExtras` is built by\n * the SAME fold that builds `extras` (one pass, one owner).\n */\nexport function resolveBundle<const D extends CapabilityBundleDefinition>(\n backend: GraphBackend,\n definition: D,\n): BundleVerdictOf<D> {\n const extras = (definition.extras ?? []) as readonly CapabilityBundleExtra<\n string,\n OptionalGraphBackendMember\n >[];\n const { extras: extraVerdicts, missingExtras } = resolveExtras(\n backend,\n extras,\n );\n\n // Rule 1: the declaration is read whenever `crossCheck !== \"none\"`,\n // regardless of kind — a graduated bundle's \"core\" for this purpose is the\n // union of every extra's members, since it has no core of its own. Only\n // `claims` (gated) exercises this in the pilot registry, but the check\n // itself must not silently no-op for a hypothetical graduated bidirectional\n // bundle (T11's mutation pins exactly this).\n if (definition.crossCheck === \"bidirectional\") {\n const memberSet =\n definition.kind === \"gated\" ?\n definition.core\n : extras.flatMap((extra) => extra.members);\n assertClaimsBidirectionalAgreement(backend, {\n ...(definition.declaration === undefined ?\n {}\n : { declaration: definition.declaration }),\n core: memberSet,\n portSurfaceCode: definition.portSurfaceCode,\n });\n }\n\n if (definition.kind === \"graduated\") {\n return {\n bundle: definition.id,\n extras: extraVerdicts,\n missingExtras,\n } as unknown as BundleVerdictOf<D>;\n }\n\n const missing = definition.core.filter(\n (member) => backend[member] === undefined,\n );\n if (missing.length > 0) {\n return {\n supported: false,\n bundle: definition.id,\n missing,\n disposition: definition.disposition,\n } as unknown as BundleVerdictOf<D>;\n }\n return {\n supported: true,\n bundle: definition.id,\n members: definition.core,\n extras: extraVerdicts,\n missingExtras,\n } as unknown as BundleVerdictOf<D>;\n}\n\n/** The literal operation names a bundle's `operations` table declares. */\nexport type OperationNames<D extends CapabilityBundleDefinition> =\n D[\"operations\"][number][\"operation\"];\n\n/** The extras a named operation `requires`, read from the ROW — never re-spelled at the call site. */\nexport type RequiredExtrasOf<\n D extends CapabilityBundleDefinition,\n Op extends OperationNames<D>,\n> =\n Extract<D[\"operations\"][number], { operation: Op }> extends (\n { requires: infer R extends readonly string[] }\n ) ?\n R[number]\n : never;\n\n/**\n * The registry's row lookup plus the presence fold, extracted verbatim from\n * {@link requireExtras}'s body (ruling B8 spec item 3): the ONE owner of\n * \"what this operation requires\" that both `requireExtras`'s default throw\n * and a call site's own `refuse` callback consult.\n *\n * `operation` is the literal key of the bundle's `operations` tuple, so the\n * required extras are looked up TYPE-LEVEL from the registry — no second\n * spelling of `requires` at the call site.\n *\n * @throws {ConfigurationError} naming the unknown operation when `operation`\n * is not a row of `definition.operations`.\n */\nexport function missingRequiredExtras<\n const D extends CapabilityBundleDefinition,\n Op extends OperationNames<D>,\n>(\n definition: D,\n verdict: BundleVerdictOf<D>,\n operation: Op,\n): readonly string[] {\n const row = definition.operations.find(\n (candidate) => candidate.operation === operation,\n );\n if (row === undefined) {\n throw new ConfigurationError(\n `Unknown operation \"${operation}\" for capability bundle \"${definition.id}\".`,\n { bundle: definition.id, operation },\n );\n }\n const required = row.requires ?? [];\n const extras:\n | Readonly<Record<string, ExtraVerdict<OptionalGraphBackendMember>>>\n | undefined = \"extras\" in verdict ? verdict.extras : undefined;\n return required.filter(\n (id) => extras === undefined || extras[id]?.present !== true,\n );\n}\n\n/**\n * The refusal for an operation whose `requires` extras are absent — how a\n * GRADUATED bundle refuses where the tree refuses today: the row names the\n * operation and the extras, this asserts they are present, and\n * {@link bindExtra} (`bind.ts`) binds them off the port.\n *\n * `refuse`, when supplied, is called instead of the registry-coded throw\n * below — this is how a call site keeps its OWN existing error text (message,\n * `details` shape, order relative to other refusals) while the registry\n * stays the one owner of \"what this operation requires\" (ruling B8 spec item\n * 3). Omitting it keeps the default behavior byte-identical to before this\n * parameter existed.\n *\n * @throws {ConfigurationError} naming the row's own `code` when one or more\n * required extras is absent from the verdict and no `refuse` callback is\n * supplied; otherwise calls `refuse(missing)`, which never returns.\n */\nexport function requireExtras<\n const D extends CapabilityBundleDefinition,\n Op extends OperationNames<D>,\n>(\n definition: D,\n verdict: BundleVerdictOf<D>,\n operation: Op,\n refuse?: (missing: readonly string[]) => never,\n): asserts verdict is BundleVerdictOf<D> & {\n extras: {\n [K in RequiredExtrasOf<D, Op> & keyof ExtrasOf<D>]: Extract<\n ExtraVerdict<ExtraMember<D, K>>,\n { present: true }\n >;\n };\n} {\n const missing = missingRequiredExtras(definition, verdict, operation);\n if (missing.length === 0) return;\n\n if (refuse !== undefined) refuse(missing);\n\n // `missingRequiredExtras` already threw the unknown-operation error above\n // when the row would be undefined, so `requireDefined` here is a redundant\n // (never-failing) narrowing, not a second lookup that could disagree.\n const { disposition } = requireDefined(\n definition.operations.find(\n (candidate) => candidate.operation === operation,\n ),\n );\n if (disposition.kind === \"refuse\") {\n throw new ConfigurationError(\n `Operation \"${operation}\" on capability bundle \"${definition.id}\" requires ${missing.join(\", \")}.`,\n { code: disposition.code, bundle: definition.id, operation, missing },\n );\n }\n // No pilot row reaches this: every row with a non-empty `requires` in the\n // registry disposes `refuse` (a graduated bundle's fallback rows never\n // name `requires` — the fallback IS the degrade path). Kept as a named,\n // typed refusal rather than a silent pass so a future `fallback` +\n // `requires` row cannot pass `requireExtras` unnoticed.\n throw new ConfigurationError(\n `Operation \"${operation}\" on capability bundle \"${definition.id}\" requires ${missing.join(\", \")}, and the registry names no refusal code for this fallback-dispositioned row.`,\n { bundle: definition.id, operation, missing },\n );\n}\n\n// ---------------------------------------------------------------------------\n// The seven named verdict accessors — GraphBackend-only, no exceptions (I15).\n// ---------------------------------------------------------------------------\n\nexport function claimsVerdict(\n backend: GraphBackend,\n): BundleVerdictOf<typeof CLAIMS> {\n return resolveBundle(backend, CLAIMS);\n}\n\nexport function uniqueSidecarBatchVerdict(\n backend: GraphBackend,\n): BundleVerdictOf<typeof UNIQUE_SIDECAR_BATCH> {\n return resolveBundle(backend, UNIQUE_SIDECAR_BATCH);\n}\n\nexport function batchPointReadVerdict(\n backend: GraphBackend,\n): BundleVerdictOf<typeof BATCH_POINT_READ> {\n return resolveBundle(backend, BATCH_POINT_READ);\n}\n\nexport function endpointSetReadVerdict(\n backend: GraphBackend,\n): BundleVerdictOf<typeof ENDPOINT_SET_READ> {\n return resolveBundle(backend, ENDPOINT_SET_READ);\n}\n\nexport function statementExecutionVerdict(\n backend: GraphBackend,\n): BundleVerdictOf<typeof STATEMENT_EXECUTION> {\n return resolveBundle(backend, STATEMENT_EXECUTION);\n}\n\nexport function contributionHealthVerdict(\n backend: GraphBackend,\n): BundleVerdictOf<typeof CONTRIBUTION_HEALTH> {\n return resolveBundle(backend, CONTRIBUTION_HEALTH);\n}\n\nexport function recordedRevisionOriginsVerdict(\n backend: GraphBackend,\n): BundleVerdictOf<typeof RECORDED_REVISION_ORIGINS> {\n return resolveBundle(backend, RECORDED_REVISION_ORIGINS);\n}\n\n// ---------------------------------------------------------------------------\n// The claims verdict THUNK — the reference implementation of §5.2.3's INTENT\n// (one owner, at-most-once resolution, no re-derivation) moved to WHEN it\n// resolves rather than IF (ruling B7 refinement 2).\n// ---------------------------------------------------------------------------\n\n/**\n * A memoized, at-most-once resolution of the `claims` bundle's verdict\n * against ONE backend.\n *\n * Eager resolution at store construction is forbidden: T14's\n * contradictory-declaration backends must still be able to construct a store\n * and create nodes — only a constrained edge write may legally reach the\n * bidirectional cross-check's throw, and it must do so lazily, at the first\n * write that needs the verdict.\n *\n * A cached verdict cannot go stale because `GraphBackend` is deep-frozen (B1):\n * nothing can flip `capabilities.constraintClaims` or add/remove a claim\n * member on a backend object after this thunk has already resolved it, so\n * \"resolve once and reuse forever\" is exactly as safe as \"resolve every\n * time\" — for one backend object, they observe the same immutable answer.\n */\nexport type ClaimsVerdictThunk = () => BundleVerdictOf<typeof CLAIMS>;\n\n/**\n * Interning: the same backend object always gets back the SAME thunk object.\n * This is what makes \"one shared thunk per backend\" structural rather than a\n * convention every population site has to honor — a second call to\n * {@link createClaimsVerdictThunk} for a backend already minted cannot produce\n * a second, independently-memoized verdict.\n */\nconst CLAIMS_VERDICT_THUNKS = new WeakMap<GraphBackend, ClaimsVerdictThunk>();\n\n/**\n * Mints — or returns the already-minted — {@link ClaimsVerdictThunk} for\n * `backend`.\n *\n * The thunk resolves {@link resolveBundle}`(backend, CLAIMS)` on its first\n * call and caches the outcome, INCLUDING a thrown `ConfigurationError`: a\n * refusal is cached and re-thrown on every subsequent call, never\n * re-resolved. Both layers — interning here, memoization inside the thunk —\n * are required: interning alone would still let two independently-memoized\n * thunks exist for one backend if a caller ignored the shared one; memoizing\n * alone would still let two different call sites mint two different thunks\n * that could disagree about whether they had already resolved.\n */\nexport function createClaimsVerdictThunk(\n backend: GraphBackend,\n): ClaimsVerdictThunk {\n const existing = CLAIMS_VERDICT_THUNKS.get(backend);\n if (existing !== undefined) return existing;\n\n type Memo =\n | Readonly<{ state: \"resolved\"; verdict: BundleVerdictOf<typeof CLAIMS> }>\n | Readonly<{ state: \"thrown\"; error: unknown }>;\n let memo: Memo | undefined;\n\n const thunk: ClaimsVerdictThunk = () => {\n if (memo === undefined) {\n try {\n memo = { state: \"resolved\", verdict: resolveBundle(backend, CLAIMS) };\n } catch (error) {\n memo = { state: \"thrown\", error };\n throw error;\n }\n }\n if (memo.state === \"thrown\") throw memo.error;\n return memo.verdict;\n };\n\n CLAIMS_VERDICT_THUNKS.set(backend, thunk);\n return thunk;\n}\n","/**\n * The backend's optional catalog-introspection surface: physical-schema\n * probes a store path consults directly, spelled once per dialect by the\n * two bundled profiles instead of a `dialect === \"postgres\"` branch at each\n * call site.\n *\n * Every member is a read-only probe except `dropInvalidIndex`, which issues\n * the one DDL statement that heals a crashed concurrent index build.\n * Nothing here writes a graph row, a sidecar row, or a status row.\n */\nimport { ConfigurationError } from \"../../errors\";\nimport { type GraphBackend } from \"../types\";\n\n/**\n * A physical index's presence and, on engines that can leave a build\n * half-finished, whether the leftover is usable.\n *\n * `invalid` is PostgreSQL's `pg_index.indisvalid = false` — an interrupted\n * `CREATE INDEX CONCURRENTLY` leaves a same-named index behind that a later\n * `IF NOT EXISTS` build would otherwise accept silently. SQLite has no such\n * state: `invalid` is always `false` there, and `exists` alone is the whole\n * answer.\n */\nexport type IndexState = Readonly<{\n /** The physical SQL index name that was probed. */\n name: string;\n /** Whether an index with this name exists in the engine catalog. */\n exists: boolean;\n /** PostgreSQL's invalid-build leftover flag; always `false` on SQLite. */\n invalid: boolean;\n}>;\n\n/**\n * A physical column's declared type, reduced to the family the two callers\n * that classify a recorded-time column actually distinguish: an integer\n * counter, text (SQLite's affinity for a wall-clock column stored as an\n * ISO-8601 string), PostgreSQL's exact `timestamp with time zone`, or\n * anything else. Kept this coarse on purpose — no caller needs a finer\n * classification, and each dialect's own probe decides which of these a\n * given declared type maps to, using that engine's own type rules (exact\n * match on PostgreSQL, affinity on SQLite).\n *\n * PostgreSQL's own normalizer never reports `\"text\"` — a declared `text`\n * column on that dialect falls through to `\"other\"`, since nothing\n * PostgreSQL-side stores a recorded-time column that way. That asymmetry is\n * why a revision or wall-time comparison must compare against\n * {@link REVISION_COLUMN_KINDS} / {@link WALL_TIME_COLUMN_KINDS} rather than\n * a single literal: the two dialects agree on the revision kind but not on\n * the wall-time one.\n */\nexport type NormalizedColumnKind =\n \"integer\" | \"text\" | \"timestamp-with-time-zone\" | \"other\";\n\n/**\n * The `columnTypes` kinds that count as a revision counter. Both dialects\n * normalize one to `\"integer\"`, so this is a single-member set today — named\n * and exported so a caller compares against ONE owned set instead of\n * re-spelling `=== \"integer\"` inline. Consumed by\n * `store/recorded-capture/schema-version.ts`'s `isCompatibleColumnKind`,\n * which replaced that file's dialect-branching `isCompatibleColumnType` and\n * its SQLite-affinity twin (`hasSqliteAffinity`) with this owned set.\n */\nexport const REVISION_COLUMN_KINDS: readonly NormalizedColumnKind[] = [\n \"integer\",\n];\n\n/**\n * The `columnTypes` kinds that count as a wall-clock timestamp. SQLite\n * stores one as an ISO-8601 string (`\"text\"`); PostgreSQL stores one as\n * `timestamp with time zone` (`\"timestamp-with-time-zone\"`) and never\n * normalizes a declared column to `\"text\"` at all — so this set stays exact\n * on both dialects without a caller ever branching on `dialect`. Consumed\n * by `store/recorded-capture/schema-version.ts`'s `isCompatibleColumnKind`,\n * alongside {@link REVISION_COLUMN_KINDS}.\n */\nexport const WALL_TIME_COLUMN_KINDS: readonly NormalizedColumnKind[] = [\n \"text\",\n \"timestamp-with-time-zone\",\n];\n\n/**\n * One physical column's name, normalized type family, and raw declared\n * type — trimmed and lower-cased, but otherwise exactly what the engine's\n * own catalog reports (`\"bigint\"`, `\"timestamp with time zone\"`, a SQLite\n * declared type such as `\"integer\"` or `\"text\"`, and so on). `kind` is what\n * a comparison should classify against; `declaredType` is what a\n * diagnostic should show a human, since `kind` discards the declared\n * spelling entirely.\n */\nexport type CatalogColumn = Readonly<{\n name: string;\n kind: NormalizedColumnKind;\n declaredType: string;\n}>;\n\n/** One physical table's catalog presence. See {@link BackendCatalogProbes.tablesExist}. */\nexport type TableState = Readonly<{\n /** The physical SQL table name that was probed. */\n name: string;\n /** Whether a table with this name exists in the engine catalog. */\n exists: boolean;\n}>;\n\n/**\n * The three facts index materialization used to keep in its own\n * dialect-keyed record: whether this engine can build an index\n * concurrently (without blocking readers/writers), whether a concurrent\n * build can be interrupted into a usable-but-invalid leftover, and whether\n * it offers the GIN index family fulltext/trigram indexing needs.\n */\nexport type CatalogIndexBehavior = Readonly<{\n concurrentBuilds: boolean;\n hasInvalidIndexState: boolean;\n supportsGinFamily: boolean;\n}>;\n\n/**\n * Physical-schema introspection a store path consults directly: table and\n * index presence, PostgreSQL's invalid-index leftover state and its\n * self-heal, normalized column types, and the per-dialect index-build\n * facts above.\n *\n * Optional: a custom backend that omits it loses the store paths that\n * consult it directly — index materialization (`store.materializeIndexes()`\n * refuses only once its empty-candidate short circuit and the status-table\n * ensure step have already run; `store.materializeSystemIndexes()`, which\n * has no candidate short circuit, refuses only once that same status-table\n * ensure step has run), the recorded-time schema check, and the\n * recorded-time migration's column read.\n */\nexport type BackendCatalogProbes = Readonly<{\n /**\n * Whether a table with this physical name exists in the engine catalog —\n * on PostgreSQL, anything an unqualified `DELETE`/`ANALYZE` against the\n * name could hit (ordinary and partitioned tables, views, materialized\n * views, foreign tables), matching the dialect operation strategy's own\n * DDL-target probe. A caller that means specifically \"is this a TABLE\",\n * as opposed to any relation an unqualified statement could resolve to,\n * wants {@link BackendCatalogProbes.tablesExist} instead — its narrower\n * predicate excludes views, materialized views, and foreign tables.\n */\n tableExists: (this: void, name: string) => Promise<boolean>;\n /**\n * The catalog state of each named physical TABLE, one entry per input\n * name (an absent name reports `exists: false`), resolved in one round\n * trip. On PostgreSQL this is ordinary and partitioned tables only\n * (`relkind IN ('r', 'p')`) — narrower than {@link tableExists}, which\n * also matches views, materialized views, and foreign tables. A caller\n * gating bulk, table-scoped work (a preload ahead of table DDL, say)\n * wants this member so it gets one round trip and the strict predicate,\n * rather than looping {@link tableExists} or accepting its wider match.\n */\n tablesExist: (\n this: void,\n names: readonly string[],\n ) => Promise<readonly TableState[]>;\n /**\n * The catalog state of each named physical index, one entry per input\n * name (an absent index reports `exists: false`), resolved in one\n * round trip.\n */\n indexStates: (\n this: void,\n names: readonly string[],\n ) => Promise<readonly IndexState[]>;\n /**\n * Drops the named index if — and only if — it is a PostgreSQL INVALID\n * leftover from an interrupted `CREATE INDEX CONCURRENTLY`. A no-op on\n * an engine whose `indexBehavior.hasInvalidIndexState` is `false`, and\n * a no-op for a valid or absent index on every engine.\n *\n * A ROOT-BACKEND operation on an engine with an invalid-index state:\n * PostgreSQL refuses `DROP INDEX CONCURRENTLY` inside a transaction\n * block, so there the `catalog` a `transaction()` handle exposes throws a\n * typed `ConfigurationError` from this member instead of attempting the\n * DDL. An engine whose `indexBehavior.hasInvalidIndexState` is `false`\n * (SQLite) has no invalid leftover to ever drop and stays a no-op in\n * both scopes — every other member here stays a plain read on that same\n * transaction-scoped bag regardless of engine.\n */\n dropInvalidIndex: (this: void, name: string) => Promise<void>;\n /** Every column's name and normalized type family for one physical table. */\n columnTypes: (this: void, table: string) => Promise<readonly CatalogColumn[]>;\n /** This engine's index-build facts. See {@link CatalogIndexBehavior}. */\n indexBehavior: CatalogIndexBehavior;\n}>;\n\n/**\n * THE refusal for a store path that needs the backend's catalog probes and\n * finds them absent, naming the missing port so a caller can add it — or\n * switch to a bundled backend — instead of chasing a `TypeError` two calls\n * deep into `materializeIndexes` or a recorded-time migration.\n */\nexport function requireCatalog(\n backend: Pick<GraphBackend, \"catalog\">,\n operation: string,\n): BackendCatalogProbes {\n const catalog = backend.catalog;\n if (catalog === undefined) {\n throw new ConfigurationError(\n `${operation} requires the backend's catalog probes, but this backend declares no \\`catalog\\`.`,\n { code: \"CATALOG_UNAVAILABLE\", operation },\n {\n suggestion:\n \"Implement `catalog` on this backend, or use a built-in SQLite or PostgreSQL backend.\",\n },\n );\n }\n return catalog;\n}\n"]}