@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
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/store/types.ts","../src/store/runtime-port.ts","../src/errors/validation.ts","../src/utils/id.ts","../src/store/recorded-capture/guards.ts","../src/store/recorded-capture/clock.ts","../src/store/insert-dispatch.ts","../src/identity/historical-sql.ts","../src/store/row-fetch.ts","../src/store/edge-fetch.ts","../src/store/node-fetch.ts","../src/store/recorded-capture/relations.ts","../src/store/recorded-capture/flush.ts","../src/store/recorded-capture/write-touch.ts","../src/store/recorded-capture/lineage.ts","../src/store/recorded-capture/schema-version.ts","../src/store/recorded-capture.ts","../src/store/operations/write-transaction.ts"],"names":["isolation","rows","executeStatement","sql"],"mappings":"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","file":"chunk-3SUZXB5X.js","sourcesContent":["/**\n * Store types for TypeGraph operations.\n */\nimport { type z } from \"zod\";\n\nimport {\n type BackendValidityEndMutation,\n type EdgeRow,\n type NodeRow,\n type TransactionBackend,\n type TransactionReadBackend,\n} from \"../backend/types\";\nimport {\n type AllNodeTypes,\n type EdgeKinds,\n type GraphDef,\n type GraphIdentityConfig,\n type NodeKinds,\n} from \"../core/define-graph\";\nimport type {\n RuntimeEdgeKind,\n RuntimeEdgeTypeFor,\n RuntimeNodeKind,\n RuntimeNodeTypeFor,\n} from \"../core/runtime-kind\";\nimport { type RecordedInstant } from \"../core/temporal\";\nimport {\n type AnyEdgeType,\n type EdgeId,\n type EdgeRegistration,\n type EdgeType,\n type JsonScalar,\n type KindEntity,\n type NodeId,\n type NodeRegistration,\n type NodeType,\n type TemporalMode,\n} from \"../core/types\";\nimport type { IdentityFacade, IdentityWriteSummary } from \"../identity/types\";\nimport type { TraversalExpansion } from \"../query/ast\";\nimport type {\n DynamicEdgeAccessor,\n DynamicNodeAccessor,\n DynamicNodeKind,\n DynamicNodeType,\n InitialQueryBuilder,\n} from \"../query/builder\";\nimport type { BatchOnceOptions } from \"../query/builder/one-statement-batch\";\nimport type {\n BatchableQuery,\n NodeAccessor,\n NodeCandidateQuery,\n OneStatementBatchReads,\n OneStatementBatchResults,\n} from \"../query/builder/types\";\nimport {\n type ExternalRecordedReadSource,\n type SqlSchema,\n} from \"../query/compiler/schema\";\nimport type { Predicate } from \"../query/predicates\";\nimport { typeGraphGlobalSymbol } from \"../utils/global-symbol\";\nimport type {\n CURRENT_ONLY_READ_NAMES,\n EDGE_BATCH_READ_NAMES,\n EDGE_TEMPORAL_READ_NAMES,\n EDGE_WRITE_NAMES,\n NODE_TEMPORAL_READ_NAMES,\n NODE_WRITE_NAMES,\n RECORDED_POINT_READ_NAMES,\n} from \"./collection-surface\";\nimport type { NeighborReadOptions, NeighborResult } from \"./neighbors\";\nimport type {\n BatchReadBuilder,\n EdgeCollectionLookup,\n RequiredEdgeCollectionLookup,\n} from \"./store\";\nimport type {\n StoreDescription,\n StoreValidationPage,\n ValidateStoreOptions,\n} from \"./store-analysis\";\nimport type {\n SubgraphOptions,\n SubgraphProject,\n SubgraphResult,\n} from \"./subgraph\";\n\n/**\n * An explicit validity-end mutation. Omission preserves the stored end,\n * `validTo` sets it, and `clearValidTo` reopens the window. The union keeps the\n * two write actions mutually exclusive without exposing public `null`.\n */\nexport type ValidityEndMutation = BackendValidityEndMutation;\n\n/**\n * Compare-and-set absence marker. `undefined` is deliberately not overloaded:\n * it can disappear while an object is assembled or serialized, whereas this\n * marker always states the caller's predicate explicitly.\n */\nexport const compareAndSetAbsent: unique symbol = typeGraphGlobalSymbol(\n \"compare-and-set-absent-v1\",\n);\n\n/** Explicitly requires that a compare-and-set property is not stored. */\nexport type CompareAndSetAbsent = typeof compareAndSetAbsent;\n\n/** Scalar-only exact predicates accepted by {@link NodeCollection.compareAndSet}. */\nexport type CompareAndSetExpected<Props> = Readonly<{\n [Property in keyof Props]?:\n | Extract<Exclude<Props[Property], undefined>, JsonScalar>\n | CompareAndSetAbsent;\n}>;\n\n// ============================================================\n// Row-to-Meta Field Mapping\n// ============================================================\n\n/**\n * Canonical mapping from snake_case row fields to camelCase meta fields.\n *\n * This is the single source of truth for which row columns become metadata.\n * Both the Meta types and the row-to-meta functions in row-mappers.ts must\n * stay in sync with this mapping. If you add a temporal/audit column to a\n * row type, add the mapping here — the compiler will then force you to\n * update the row mapper functions as well (since their return type is\n * NodeMeta/EdgeMeta, which is derived from this mapping).\n */\ntype TemporalMetaFieldMap = Readonly<{\n valid_from: \"validFrom\";\n valid_to: \"validTo\";\n created_at: \"createdAt\";\n updated_at: \"updatedAt\";\n deleted_at: \"deletedAt\";\n}>;\n\n/**\n * Maps row fields to their camelCase meta counterparts, preserving types.\n */\ntype MapRowToMeta<\n R extends Readonly<Record<string, unknown>>,\n M extends Readonly<Record<string, string>>,\n> = Readonly<{\n [SnakeKey in keyof M as M[SnakeKey] & string]: SnakeKey extends keyof R ?\n R[SnakeKey]\n : never;\n}>;\n\n// ============================================================\n// Node Instance Types\n// ============================================================\n\n/**\n * Metadata for a node instance.\n * Derived from NodeRow via TemporalMetaFieldMap + version.\n *\n * Adding a new metadata column requires:\n * 1. Add the column to NodeRow in backend/types.ts\n * 2. Add the mapping to TemporalMetaFieldMap above\n * 3. The compiler will error in rowToNodeMeta() until you add the field there\n */\nexport type NodeMeta = MapRowToMeta<NodeRow, TemporalMetaFieldMap> &\n Readonly<{ version: NodeRow[\"version\"] }>;\n\n/**\n * A node instance in the graph.\n *\n * Properties from the schema are spread at the top level for ergonomic access:\n * - `node.name` instead of `node.props.name`\n * - System metadata is under `node.meta.*`\n */\nexport type Node<N extends NodeType = NodeType> = Readonly<{\n kind: N[\"kind\"];\n id: NodeId<N>;\n meta: NodeMeta;\n}> &\n Readonly<z.infer<N[\"schema\"]>>;\n\n/**\n * Input for creating a node.\n */\nexport type CreateNodeInput<N extends NodeType = NodeType> = Readonly<{\n kind: N[\"kind\"];\n id?: string; // Optional - will generate ULID if not provided\n props: z.infer<N[\"schema\"]>;\n /** Omit to use the creation default; null explicitly requests no lower bound. */\n validFrom?: string | null;\n validTo?: string;\n}>;\n\n/** One caller-identified member of the closed heterogeneous node upsert batch. */\nexport type HeterogeneousNodeUpsertInput<\n G extends GraphDef,\n K extends NodeKinds<G> = NodeKinds<G>,\n> = {\n [P in K]: G[\"nodes\"][P] extends Readonly<{ type: infer N extends NodeType }> ?\n Readonly<{\n kind: P;\n id: NodeId<N>;\n props: z.input<N[\"schema\"]>;\n }>\n : never;\n}[K];\n\ntype HeterogeneousNodeForKind<G extends GraphDef, K extends NodeKinds<G>> =\n G[\"nodes\"][K] extends Readonly<{ type: infer N extends NodeType }> ? Node<N>\n : never;\n\n/** Ordered postimages returned by the recorded heterogeneous batch. */\nexport type HeterogeneousNodeUpsertResult<\n G extends GraphDef,\n Entries extends readonly HeterogeneousNodeUpsertInput<G>[],\n> = {\n readonly [I in keyof Entries]: Entries[I] extends (\n Readonly<{\n kind: infer K extends NodeKinds<G>;\n }>\n ) ?\n HeterogeneousNodeForKind<G, K>\n : never;\n};\n\n/**\n * Input for updating a node.\n */\nexport type UpdateNodeInput<N extends NodeType = NodeType> = Readonly<{\n kind: N[\"kind\"];\n id: NodeId<N>;\n props: Partial<z.infer<N[\"schema\"]>>;\n}> &\n ValidityEndMutation;\n\n// ============================================================\n// Edge Instance Types\n// ============================================================\n\n/**\n * Metadata for an edge instance.\n * Derived from EdgeRow via TemporalMetaFieldMap (edges have no version).\n */\nexport type EdgeMeta = MapRowToMeta<EdgeRow, TemporalMetaFieldMap>;\n\n/**\n * An edge instance in the graph.\n *\n * Properties from the schema are spread at the top level for ergonomic access:\n * - `edge.role` instead of `edge.props.role`\n * - System metadata is under `edge.meta.*`\n */\nexport type Edge<\n E extends AnyEdgeType = EdgeType,\n From extends NodeType = NodeType,\n To extends NodeType = NodeType,\n> = Readonly<{\n id: EdgeId<E>;\n kind: E[\"kind\"];\n fromKind: From[\"kind\"];\n fromId: NodeId<From>;\n toKind: To[\"kind\"];\n toId: NodeId<To>;\n meta: EdgeMeta;\n}> &\n Readonly<z.infer<E[\"schema\"]>>;\n\n/**\n * Input for creating an edge.\n */\nexport type CreateEdgeInput<E extends AnyEdgeType = EdgeType> = Readonly<{\n kind: E[\"kind\"];\n id?: string; // Optional - will generate ULID if not provided\n fromKind: string;\n fromId: string;\n toKind: string;\n toId: string;\n props: z.infer<E[\"schema\"]>;\n /** Omit to use the creation default; null explicitly requests no lower bound. */\n validFrom?: string | null;\n validTo?: string;\n}>;\n\n/**\n * Input for updating an edge.\n */\nexport type UpdateEdgeInput<E extends AnyEdgeType = EdgeType> = Readonly<{\n id: EdgeId<E>;\n props: Partial<z.infer<E[\"schema\"]>>;\n}> &\n ValidityEndMutation;\n\n// ============================================================\n// Query Options\n// ============================================================\n\n/**\n * Options for node and edge queries.\n */\nexport type NoRecordedCoordinate = Readonly<{\n /**\n * Recorded/system-time coordinates are internal-only and supplied by\n * RecordedStoreView. A public options object carrying this key is a type\n * error even when the object is pre-bound before the call site.\n */\n recordedAsOf?: never;\n}>;\n\nexport type QueryOptions = NoRecordedCoordinate &\n Readonly<{\n /** Temporal mode for the query */\n temporalMode?: TemporalMode;\n /** Specific timestamp for asOf queries */\n asOf?: string;\n }>;\n\n// ============================================================\n// Observability Hooks\n// ============================================================\n\n/**\n * Context passed to observability hooks.\n */\nexport type HookContext = Readonly<{\n /** Unique ID for this operation */\n operationId: string;\n /** Graph ID */\n graphId: string;\n /** Timestamp when operation started */\n startedAt: Date;\n /**\n * 1-based try number that produced this context. Always `1` outside a\n * `store.transaction(fn, { retry: { attempts } })` call; inside one, a\n * value above 1 marks a replay of the same logical operation after an\n * earlier attempt hit a transaction conflict, so a listener can tell a\n * retried attempt from a genuinely new operation. Absent means `1`: a\n * context built outside the store (a test fixture, a forwarded literal)\n * need not carry it.\n */\n attempt?: number;\n}>;\n\n/**\n * Context for one SQL statement a query builder submits to the backend.\n *\n * A single logical query can emit more than one context, for example when a\n * selective projection falls back to a full-row fetch. Backend-internal setup\n * statements are not exposed as separate query-hook events.\n */\nexport type QueryHookContext = HookContext &\n Readonly<{\n /** The SQL statement being executed */\n sql: string;\n /** Query parameters */\n params: readonly unknown[];\n }>;\n\n/**\n * Operation hook context for CRUD operations.\n */\nexport type OperationHookContext = HookContext &\n Readonly<{\n /** Operation type */\n operation: \"create\" | \"update\" | \"delete\";\n /** Entity type */\n entity: KindEntity;\n /** Kind of node or edge */\n kind: string;\n /** Entity ID */\n id: string;\n }>;\n\n/**\n * Context for one set-based collection mutation. The `operation` union is the\n * exhaustive list of what `onBulkOperationStart` / `onBulkOperationEnd`\n * observe, so a batch method absent from it (every `bulk*`, including\n * `bulkDelete`) emits no bulk event.\n */\nexport type BulkOperationHookContext = HookContext &\n Readonly<{\n operation: \"compareAndSet\" | \"updateWhere\";\n entity: \"node\";\n kind: string;\n }>;\n\n/**\n * Observability hooks for monitoring store operations.\n *\n * Note: Batch operations (`bulkCreate`, `bulkInsert`, `bulkUpsertById`,\n * `bulkDelete`) skip per-item operation hooks for throughput, and the bulk\n * hooks below do not stand in for them — those fire only for node\n * `compareAndSet` and `updateWhere`. A batch method emits no hook events at all,\n * neither per-item nor bulk. Query hooks still fire normally.\n *\n * @example\n * ```typescript\n * const hooks: StoreHooks = {\n * onQueryStart: (ctx) => {\n * console.log(`[${ctx.operationId}] Query: ${ctx.sql}`);\n * },\n * onQueryEnd: (ctx, result) => {\n * const duration = Date.now() - ctx.startedAt.getTime();\n * console.log(`[${ctx.operationId}] Completed in ${duration}ms`);\n * },\n * onError: (ctx, error) => {\n * console.error(`[${ctx.operationId}] Error:`, error);\n * },\n * };\n *\n * const store = createStore(graph, backend, { hooks });\n * ```\n */\nexport type StoreHooks = Readonly<{\n /** Called before each query-builder statement is submitted to the backend. */\n onQueryStart?: (ctx: QueryHookContext) => void;\n /** Called after each submitted query-builder statement succeeds. */\n onQueryEnd?: (\n ctx: QueryHookContext,\n result: Readonly<{ rowCount: number; durationMs: number }>,\n ) => void;\n /** Called before a CRUD operation starts */\n onOperationStart?: (ctx: OperationHookContext) => void;\n /** Called before a set-based collection mutation starts. */\n onBulkOperationStart?: (ctx: BulkOperationHookContext) => void;\n /**\n * Called after a CRUD operation completes AND is durably committed. For a\n * top-level operation that is when its own transaction commits; for an\n * operation inside `store.transaction`, emission is deferred until the\n * enclosing transaction commits — if that commit fails, the operation is\n * reported through `onError` instead. (Inside an adopted transaction —\n * `withTransaction` / `withRecordedTransaction` — the commit belongs to\n * the caller and cannot be observed, so this fires when the operation\n * completes within the still-open transaction.)\n */\n onOperationEnd?: (\n ctx: OperationHookContext,\n result: Readonly<{\n durationMs: number;\n /** The authoritative effect, or `unknown` when the command reports none. */\n outcome: \"written\" | \"unchanged\" | \"unknown\";\n }>,\n ) => void;\n /**\n * Called after a set-based mutation durably commits. Inside\n * `store.transaction`, emission is deferred until the enclosing commit.\n */\n onBulkOperationEnd?: (\n ctx: BulkOperationHookContext,\n result: Readonly<{ affectedCount: number; durationMs: number }>,\n ) => void;\n /**\n * Called when an operation fails — including an operation that completed\n * inside a `store.transaction` whose commit then failed and rolled it\n * back. Must not throw: an exception this hook raises while a\n * transaction's failure is being reported is discarded, so the failure\n * being reported — not the hook's exception — is what the caller and any\n * enclosing retry owner receive.\n */\n onError?: (ctx: HookContext, error: Error) => void;\n}>;\n\n// ============================================================\n// Store Configuration\n// ============================================================\n\n/**\n * Default row count at which an autocommit bulk write triggers an\n * automatic planner-statistics refresh. Below this, the refresh cost is\n * not worth paying per call and autovacuum/PRAGMA optimize cover it.\n */\nexport const AUTO_REFRESH_STATISTICS_ROW_THRESHOLD = 1000;\n\nexport type BaseStoreOptions = Readonly<{\n /** Observability hooks for monitoring */\n hooks?: StoreHooks;\n /**\n * Maintain a durable, graph-wide revision anchor for TypeGraph writes:\n * a random per-graph origin plus a monotonic revision clock. `branch()` uses\n * this anchor to validate that its base has not moved without\n * re-fingerprinting every live row, and cannot confuse a coincident clock in\n * a separately created store for its original base. `history: true` enables\n * the same tracking automatically through its recorded-time commit clock.\n *\n * This is intentionally opt-in for live stores: each successful graph write\n * advances the anchor inside its write transaction. On PostgreSQL, those\n * transactions take a graph-scoped advisory lock until commit; writes to the\n * same graph therefore serialize. Enable it for branchable graphs, but size\n * high-throughput multi-writer workloads for that trade-off.\n *\n * Writes performed directly through a backend — including raw graph-table\n * writes through `tx.sql` — bypass the anchor and are outside the\n * revision-tracking contract.\n */\n revisionTracking?: boolean;\n /**\n * Automatic planner-statistics refresh after large autocommit bulk\n * writes (bulkCreate and bulkInsert on nodes and edges). Stale statistics after a\n * bulk load are a whole class of planner cliffs: the planner keeps\n * pre-load row estimates until ANALYZE runs. When a single\n * autocommit bulk write reaches the threshold\n * ({@link AUTO_REFRESH_STATISTICS_ROW_THRESHOLD} rows by default),\n * the store runs `refreshStatistics()` after the write commits.\n * Pass a number to change the threshold, or `false` to disable.\n * Bulk writes inside a caller-provided transaction never\n * auto-refresh (statistics cannot see uncommitted rows); refresh\n * manually after commit. `importGraph` handles its own refresh.\n */\n autoRefreshStatistics?: false | number;\n /**\n * Skip the write for an `upsertById`, `bulkUpsertById` item, or endpoint\n * get-or-create update whose validated props are value-identical to the\n * existing live row. Default off.\n *\n * Enable this for at-least-once / replay materializers. An event log that\n * re-delivers a byte-identical change would otherwise rewrite the row anyway:\n * today an `upsertById` on an existing id calls `updateNode`\n * unconditionally, allocating a fresh recorded instant and a new history row\n * per re-delivery.\n *\n * The win is scoped to re-delivery of the **current** value. A full\n * replay-from-zero over the current state still writes wherever the stream\n * superseded a value in place: re-applying an older value over the live row\n * is a genuine change (and restoring the current value afterwards is\n * another), so only streams whose rows never supersede each other replay\n * without churn. A rebuild that should avoid that re-walk belongs in a fresh\n * store — replay into it and publish it, rather than re-applying the log\n * over current state.\n *\n * When enabled, an upsert that would not change the stored value performs\n * **no write at all**: no `updateNode`, no recorded-time capture, no history\n * row, no revision-anchor advance, and no `update` operation hooks (nothing\n * happened, so nothing is reported). It resolves with the **existing** node,\n * preserving its original `validFrom` / `updatedAt` / `version`. An endpoint\n * get-or-create reports action `\"found\"` when its requested update is\n * coalesced; `\"updated\"` always means an UPDATE actually ran.\n * Node `getOrCreateByConstraint` updates are outside this option's scope and\n * still write on every `ifExists: \"update\"` match; replay projectors that\n * need coalescing should use `upsertById` for nodes.\n *\n * Receipt shape is unchanged and needs no new signal: a coalesced upsert\n * still counts as one write intent (`writes.total` includes it), but\n * captures nothing (`receipt.recorded` stays `undefined` when it is the only\n * write) — the same shape a no-op delete already produces, so a consumer\n * that carries the prior anchor forward on `recorded === undefined` handles\n * it unchanged.\n *\n * A write is coalesced only when **all** of the following hold; otherwise the\n * normal write happens:\n * 1. A value to compare against is known for the id: an existing row, or —\n * for a repeated id in one bulk batch — the value an earlier item in that\n * batch already queued (a create or an update).\n * 2. That row is not soft-deleted (a deleted row resurrects — a real\n * change — and is never coalesced).\n * 3. Any requested `validFrom` / `validTo` names the window already stored;\n * a changed or inapplicable temporal request reaches the write path.\n * 4. The new props, merged over the stored props and run through the\n * kind's Zod schema (defaults applied, values normalized), are deeply\n * value-identical to the stored props (key order aside).\n *\n * Default-off because some consumers *want* an audit row per re-delivery as\n * proof the event was reprocessed; coalescing removes that signal.\n */\n coalesceUnchangedUpserts?: boolean;\n /** SQL schema configuration from createSqlSchema(...) for custom table names */\n schema?: SqlSchema;\n /** Query default behaviors. */\n queryDefaults?: Readonly<{\n /** Default traversal ontology expansion mode (default: \"inverse\"). */\n traversalExpansion?: TraversalExpansion;\n }>;\n}>;\n\n/**\n * Store options without built-in recorded-time capture. A recorded read relation\n * can still be bound explicitly for hosts that populate history externally.\n */\nexport type LiveStoreOptions = BaseStoreOptions &\n Readonly<{\n history?: false | undefined;\n recordedRead?: ExternalRecordedReadSource | undefined;\n }>;\n\n/** Live-store options that do not bind a recorded-read relation. */\nexport type UnboundLiveStoreOptions = LiveStoreOptions &\n Readonly<{ recordedRead?: undefined }>;\n\n/** Live-store options with an explicitly bound recorded-read relation. */\nexport type RecordedReadStoreOptions = LiveStoreOptions &\n Readonly<{\n recordedRead: NonNullable<LiveStoreOptions[\"recordedRead\"]>;\n }>;\n\n/**\n * Store options with TypeGraph-managed recorded-time capture. `history: true`\n * captures TypeGraph writes and binds TypeGraph's built-in recorded relation\n * internally. Externally populated recorded read sources are read-only bindings\n * and are intentionally accepted only by {@link LiveStoreOptions}.\n */\nexport type HistoryStoreOptions = BaseStoreOptions &\n Readonly<{\n history: true;\n recordedRead?: never;\n }>;\n\n/**\n * Options for creating a store.\n */\nexport type StoreOptions = LiveStoreOptions | HistoryStoreOptions;\n\n/**\n * The subset of a store's construction options that describe its own\n * observable behavior rather than its recorded-time configuration: hooks,\n * upsert coalescing, the SQL schema (custom table names), the auto-refresh-\n * statistics threshold, query defaults, and an externally-bound recorded-read\n * relation. `Store.workingCopyOptions` is the one place these are read off a\n * live store, so a working-copy strategy that needs them never re-derives\n * them from private construction state.\n *\n * `history` and `revisionTracking` are deliberately excluded: a working-copy\n * strategy decides those for itself (a fork mirrors the base's own\n * `historyEnabled`/`revisionTrackingEnabled`; a clone documents why it keeps\n * a narrower subset — see `cloneWorkingCopyStrategy`'s doc comment).\n */\nexport type WorkingCopyOptions = Omit<\n LiveStoreOptions,\n \"history\" | \"revisionTracking\"\n>;\n\n/**\n * A mutable handle to the current `Store`, used by `store.evolve(...)`\n * so long-lived consumers can dereference through the ref and pick up\n * the new Store after each evolve call. When the ref is passed via\n * `evolve(extension, { ref })`, `current` is overwritten with the replacement\n * before a successful call resolves.\n *\n * **Request semantics.** Dereference once at request entry only when that\n * request will not change the schema. A schema-changing call such as\n * `evolve()` returns the Store for the resulting schema and updates\n * `ref.current`; a Store captured before that call remains pinned to the old\n * schema. Use the returned Store (or dereference `ref.current` again) for every\n * subsequent operation in the same request:\n *\n * ```ts\n * async function handleRequest(): Promise<void> {\n * const store = ref.current;\n * const evolved = await store.evolve(extension, { ref });\n * await evolved.materializeIndexes();\n * // ref.current === evolved\n * }\n * ```\n *\n * A `StoreRef` tracks only schema changes made by calls that receive that ref.\n * When another process or isolate can commit a schema version, compare\n * `getCommittedSchemaVersion()` with the cached version before reuse and call\n * `createVerifiedStore()` or `createVerifiedAdapterStore()` when it changes.\n *\n * Pure dereferenceable handle — no event/subscription machinery. If\n * consumers need eventing, they wrap the ref themselves.\n *\n * Generic over the held value (typically `Store<G>`) so the store\n * module can refer to it without importing the `Store` class into\n * `types.ts`. The type parameter is deliberately invariant: evolution writes\n * a replacement into `current`, so a ref for an adapter-only or history-only\n * Store must never be accepted by a Store that cannot preserve that surface.\n */\nexport interface StoreRef<in out T> {\n current: T;\n}\n\n// ============================================================\n// Transaction Receipt Types\n// ============================================================\n\n/**\n * Result plus write summary. Returned by `store.transactionWithReceipt(fn)`,\n * `store.withRecordedTransaction(externalTx, fn)` (the adopted-commit path), and\n * `tx.measure(fn)` (a scoped sub-receipt). See {@link TransactionReceipt}.\n */\nexport type TransactionOutcome<T> = Readonly<{\n result: T;\n receipt: TransactionReceipt;\n}>;\n\n/**\n * Transaction write summary.\n *\n * Receipt counts are completed write intents at the collection surface, not\n * rows affected:\n *\n * 1. Every successful completion of a write method on `tx.nodes.*` /\n * `tx.edges.*` counts. The authoritative method list is\n * {@link NodeWrites} / {@link EdgeWrites}.\n * 2. Bulk methods count by input length; an empty bulk call (`bulkCreate([])`)\n * counts 0.\n * 3. Single-row methods count 1 on resolve — including `delete` of an absent\n * id and `getOrCreate*` that found an existing row. Consumers that need\n * \"did anything actually change\" semantics apply their own per-operation\n * policy.\n * 4. A method that rejects counts 0 — even when the backend applied part of a\n * bulk input before failing. On SQLite a failed statement does not abort\n * the surrounding transaction, so a caller that catches the rejection and\n * commits can persist rows the receipt never counted. Do not read the\n * receipt as rows-affected in that scenario.\n * 5. A node `delete` under `cascade` / `disconnect` removes connected edges\n * through the backend, not the edge-collection surface; those removals do\n * not appear in `edges`.\n * 6. Rows-affected fidelity is intentionally out of scope for this first\n * version; a future extension could ask backends to return row counts.\n */\nexport type TransactionReceipt = Readonly<{\n writes: Readonly<{\n /** Completed node write intents by node kind. */\n nodes: Readonly<Record<string, number>>;\n /** Completed edge write intents by edge kind. */\n edges: Readonly<Record<string, number>>;\n /** Completed identity assertion and retraction write intents. */\n identity: IdentityWriteSummary;\n /** Sum of all node, edge, and identity write intents. */\n total: number;\n }>;\n /**\n * The recorded commit instant allocated for this store's graph by this\n * transaction. Under TypeGraph-owned capture, an explicit\n * {@link RecordedRevisionRequest} allocates this instant without entity\n * writes. Otherwise it is undefined when history capture is off, the\n * transaction is read-only, or no captured writes were flushed. **Always undefined on a\n * scoped receipt from {@link ScopedMeasure}** (`tx.measure`) — the recorded\n * instant is a per-transaction flush concern allocated once when the whole\n * transaction's capture flushes, unknowable mid-transaction.\n *\n * Engine-native history does not support explicit revision requests. Under\n * an engine-native store (one whose backend tracks recorded time\n * itself; see {@link GraphBackend.recordedTime}), \"no captured writes were\n * flushed\" instead means no node, edge, or identity write inside the\n * transaction actually changed a row: a delete of a missing id, an\n * `insertNodeIfAbsent` that found the row, and a coalesced no-op upsert\n * all leave this undefined, matching a read-only transaction, even though\n * each reached the collection surface as a completed write intent. A\n * transaction whose only effect is a raw `tx.sql` statement also leaves\n * this undefined, since the engine's own revision advancing is not\n * something a graph-entity write observed.\n */\n recorded?: RecordedInstant;\n}>;\n\n// ============================================================\n// Get-Or-Create Types\n// ============================================================\n\n/**\n * Behavior when a get-or-create operation matches an existing record.\n */\nexport type IfExistsMode = \"return\" | \"update\";\n\n/**\n * Action taken by a get-or-create operation.\n */\nexport type GetOrCreateAction = \"created\" | \"found\" | \"updated\" | \"resurrected\";\n\n/**\n * Result of a node getOrCreateByConstraint operation.\n */\nexport type NodeGetOrCreateByConstraintResult<N extends NodeType> = Readonly<{\n node: Node<N>;\n action: GetOrCreateAction;\n}>;\n\n/**\n * Options for node getOrCreateByConstraint operations.\n */\nexport type NodeGetOrCreateByConstraintOptions = Readonly<{\n /** Existing record behavior. Default: \"return\" */\n ifExists?: IfExistsMode;\n}>;\n\n/**\n * Options for node bulkFindByIndex operations.\n */\nexport type NodeBulkFindByIndexOptions = Readonly<{\n /**\n * Maximum number of candidate nodes returned per input item. When omitted,\n * each input's candidate set is unbounded. Must be a positive integer.\n *\n * Candidates are ordered deterministically by node id, so the cap is stable\n * across calls. Use this to bound fan-out on low-selectivity index keys.\n */\n limitPerInput?: number;\n}>;\n\n/**\n * Per-endpoint fan-out cap shared by the live and view forms of the edge\n * bulk endpoint reads.\n */\nexport type EdgeBulkFindOptions = Readonly<{\n /**\n * Maximum number of edges returned for each input endpoint. When omitted,\n * every input's edge set is unbounded. Must be a positive integer.\n *\n * The cap keeps each input's leading edges under the same ordering\n * `findFrom` / `findTo` return, so it bounds fan-out without reordering\n * anything.\n */\n limitPerInput?: number;\n}>;\n\n/**\n * Options for the edge bulk endpoint reads: the temporal coordinate every\n * edge read accepts, plus the per-endpoint fan-out cap.\n */\nexport type EdgeBulkFindEndpointOptions = QueryOptions & EdgeBulkFindOptions;\n\n/** A kind-grouped source list for a heterogeneous bulk edge read. */\nexport type BulkEdgeSourceGroup<G extends GraphDef> = {\n [K in NodeKinds<G>]: Readonly<{\n kind: K;\n ids: readonly NodeId<G[\"nodes\"][K][\"type\"]>[];\n }>;\n}[NodeKinds<G>];\n\n/** A node reference whose kind and branded id remain correlated. */\nexport type GraphNodeReference<G extends GraphDef> = {\n [K in NodeKinds<G>]: Readonly<{\n kind: K;\n id: NodeId<G[\"nodes\"][K][\"type\"]>;\n }>;\n}[NodeKinds<G>];\n\n/** Runtime edge union narrowed to the selected graph edge kinds. */\nexport type GraphEdgeForKinds<G extends GraphDef, K extends EdgeKinds<G>> = {\n [P in K]: Edge<\n G[\"edges\"][P][\"type\"],\n G[\"edges\"][P][\"from\"][number],\n G[\"edges\"][P][\"to\"] extends readonly (infer N extends NodeType)[] ? N\n : G[\"edges\"][P][\"to\"] extends (\n Record<string, readonly (infer N extends NodeType)[]>\n ) ?\n N\n : NodeType\n >;\n}[K];\n\n/** Input for {@link Store.bulkFindEdgesFrom}. */\nexport type BulkFindEdgesFromParams<\n G extends GraphDef,\n K extends EdgeKinds<G>,\n> = Readonly<{\n sources: readonly BulkEdgeSourceGroup<G>[];\n edgeKinds: readonly K[];\n}>;\n\n/** One source bucket returned by {@link Store.bulkFindEdgesFrom}. */\nexport type BulkFindEdgesFromResult<\n G extends GraphDef,\n K extends EdgeKinds<G>,\n> = Readonly<{\n source: GraphNodeReference<G>;\n edges: readonly GraphEdgeForKinds<G, K>[];\n}>;\n\n/** Input for {@link Store.bulkFindEdgesTo}. */\nexport type BulkFindEdgesToParams<\n G extends GraphDef,\n K extends EdgeKinds<G>,\n> = Readonly<{\n targets: readonly BulkEdgeSourceGroup<G>[];\n edgeKinds: readonly K[];\n}>;\n\n/** One target bucket returned by {@link Store.bulkFindEdgesTo}. */\nexport type BulkFindEdgesToResult<\n G extends GraphDef,\n K extends EdgeKinds<G>,\n> = Readonly<{\n target: GraphNodeReference<G>;\n edges: readonly GraphEdgeForKinds<G, K>[];\n}>;\n\n/**\n * Result of an edge getOrCreateByEndpoints operation.\n */\nexport type EdgeGetOrCreateByEndpointsResult<\n E extends AnyEdgeType,\n From extends NodeType = NodeType,\n To extends NodeType = NodeType,\n> = Readonly<{\n edge: Edge<E, From, To>;\n action: GetOrCreateAction;\n}>;\n\n/**\n * Options for edge findByEndpoints operations.\n */\nexport type EdgeFindByEndpointsOptions<E extends AnyEdgeType> = Readonly<{\n /**\n * Edge property fields to include in the match alongside the (from, to) endpoints.\n * When omitted, matches on endpoints only (returns the first edge at the read coordinate).\n */\n matchOn?: readonly (keyof z.input<E[\"schema\"]>)[];\n /** Property values to match against when matchOn is specified. */\n props?: Partial<z.input<E[\"schema\"]>>;\n}>;\n\n/**\n * Options for edge getOrCreateByEndpoints operations.\n */\nexport type EdgeGetOrCreateByEndpointsOptions<E extends AnyEdgeType> =\n Readonly<{\n /**\n * Edge property fields to include in the match key alongside the (from, to) endpoints.\n * Default: `[]` — match on endpoints only.\n */\n matchOn?: readonly (keyof z.input<E[\"schema\"]>)[];\n /** Existing record behavior. Default: \"return\" */\n ifExists?: IfExistsMode;\n /**\n * Valid-time start for a created or RESURRECTED edge — on a resurrection it\n * asserts the complete window, so an omitted `validTo` reopens the revived\n * row.\n *\n * A live edge's stored lower bound is history, so an in-place update\n * (`ifExists: \"update\"`) cannot store this: one naming a different instant is\n * REFUSED with `IMMUTABLE_VALIDITY_LOWER_BOUND_CODE`, and one restating the\n * bound the edge holds is accepted. Ignored when an existing edge is returned\n * (`ifExists: \"return\"`), which writes nothing at all — there the window\n * describes the edge to create if none is found.\n */\n validFrom?: string | null;\n /**\n * How an `ifExists: \"update\"` write treats a stated `validFrom` that differs\n * from the live edge's stored lower bound. Default: `\"refuse\"`.\n *\n * `\"preserve\"` makes `validFrom` create/resurrection-only input: it is still\n * validated, but a live update keeps the stored lower bound while applying\n * properties and `validTo`.\n */\n onImmutableLowerBound?: \"preserve\" | \"refuse\";\n /**\n * Valid-time end for a created, updated, or resurrected edge. `validTo` is\n * ignored when the operation returns an existing edge without writing;\n * `clearValidTo` instead requires `ifExists: \"update\"` on a live match and\n * is refused with `CLEAR_VALID_TO_REQUIRES_UPDATE` under return mode. May\n * not precede the row's effective start; see\n * `INVERTED_VALIDITY_WINDOW_CODE`.\n */\n }> &\n ValidityEndMutation;\n\n// ============================================================\n// Collection Interfaces\n// ============================================================\n\n/**\n * A collection of nodes of a specific type.\n *\n * Provides ergonomic CRUD operations for a single node type.\n */\nexport type NodeCollection<\n N extends NodeType,\n CN extends string = string,\n> = Readonly<{\n /**\n * Create a new node.\n *\n * `validFrom` defaults to the operation's creation timestamp when omitted —\n * unless a stated `validTo` at or before that instant would leave the row\n * readable at no coordinate, in which case the row is stored with NO lower\n * bound (\"ended at T, start unknown\") and `meta.validFrom` reads back as\n * `undefined`. A future `validTo` is unaffected.\n */\n create: (\n props: z.input<N[\"schema\"]>,\n options?: Readonly<{\n id?: string;\n validFrom?: string | null;\n validTo?: string;\n }>,\n ) => Promise<Node<N>>;\n\n /** Get a node by ID */\n getById: (\n id: NodeId<N>,\n options?: QueryOptions,\n ) => Promise<Node<N> | undefined>;\n\n /** Get multiple nodes by ID, preserving input order (undefined for missing) */\n getByIds: (\n ids: readonly NodeId<N>[],\n options?: QueryOptions,\n ) => Promise<readonly (Node<N> | undefined)[]>;\n\n /**\n * Update a node's properties and optionally set or clear its validity end.\n * Omitting both end options preserves the stored window.\n */\n update: (\n id: NodeId<N>,\n props: Partial<z.input<N[\"schema\"]>>,\n options?: ValidityEndMutation,\n ) => Promise<Node<N>>;\n\n /**\n * Applies a property patch only while the current live row still has\n * caller-supplied exact property values. The identity and values participate in\n * the same set-based statement as the update, so a preceding read cannot\n * open a compare-and-set race. Returns `false` on a missing row or predicate\n * mismatch; neither case writes history or advances the row version.\n *\n * This is the narrow escape hatch for exceptional state recovery. It does\n * not widen schema-declared transition rules: callers state the exceptional\n * precondition at the call site and the complete after-image still passes\n * ordinary TypeGraph validation, uniqueness, history, and sidecar handling.\n */\n compareAndSet: (\n id: NodeId<N>,\n params: Readonly<{\n expected: CompareAndSetExpected<z.input<N[\"schema\"]>>;\n patch: Partial<z.input<N[\"schema\"]>>;\n }>,\n ) => Promise<boolean>;\n\n /**\n * Updates every current node selected by the supplied selectors in one\n * set-based write. A same-store candidate query can provide correlated\n * cross-kind selection; relationship clauses are independent EXISTS\n * predicates and are ANDed with each other and with `where`.\n */\n updateWhere: (\n params: Readonly<{\n patch: Partial<z.input<N[\"schema\"]>>;\n /**\n * A Store-created query selecting candidate nodes of this collection's\n * kind. The query is intersected with `where`/`exists` when supplied.\n */\n candidates?: NodeCandidateQuery;\n where?: (\n accessor: string extends N[\"kind\"] ? DynamicNodeAccessor\n : NodeAccessor<N>,\n ) => Predicate;\n exists?: readonly Readonly<{\n edgeKind: string;\n direction: \"out\" | \"in\";\n relatedKind: string;\n whereEdge?: (accessor: DynamicEdgeAccessor) => Predicate;\n whereRelated?: (accessor: DynamicNodeAccessor) => Predicate;\n }>[];\n all?: true;\n }>,\n ) => Promise<Readonly<{ affectedCount: number }>>;\n\n /** Delete a node (soft delete - sets deletedAt timestamp) */\n delete: (id: NodeId<N>) => Promise<void>;\n\n /**\n * Permanently delete a node from the database.\n *\n * Unlike `delete()` which performs a soft delete, this permanently\n * removes the node and its associated data (uniqueness entries, embeddings).\n *\n * **Warning:** This operation is irreversible and should be used carefully.\n * Consider using soft delete (`delete()`) for most use cases.\n *\n * @throws Error if edges are still connected to this node (delete edges first)\n */\n hardDelete: (id: NodeId<N>) => Promise<void>;\n\n /**\n * Find nodes matching criteria.\n *\n * Supports predicate filtering via the `where` option for SQL-level filtering.\n * For simple queries. Use store.query() for complex traversals.\n */\n find: (\n filter?: Readonly<{\n where?: (accessor: NodeAccessor<N>) => Predicate;\n limit?: number;\n offset?: number;\n }>,\n temporal?: QueryOptions,\n ) => Promise<Node<N>[]>;\n\n /** Count nodes matching criteria */\n count: (temporal?: QueryOptions) => Promise<number>;\n\n /**\n * Create a node from untyped data, relying on runtime Zod validation.\n *\n * Use this for dynamic dispatch (changesets, migrations, imports) where\n * the data shape is determined at runtime, not compile time.\n * The return type is fully typed — only the input gate is relaxed.\n *\n * `validFrom` defaults to the operation's creation timestamp when omitted —\n * unless a stated `validTo` at or before that instant would leave the row\n * readable at no coordinate, in which case the row is stored with NO lower\n * bound (\"ended at T, start unknown\") and `meta.validFrom` reads back as\n * `undefined`. A future `validTo` is unaffected.\n */\n createFromRecord: (\n data: Record<string, unknown>,\n options?: Readonly<{\n id?: string;\n validFrom?: string | null;\n validTo?: string;\n }>,\n ) => Promise<Node<N>>;\n\n /**\n * Create or update a node.\n *\n * If a node with the given ID exists, updates it with the provided props.\n * Otherwise, creates a new node with that ID.\n *\n * `validFrom` applies when the upsert CREATES the row and when it RESURRECTS\n * a tombstoned one — both write a fresh validity window — defaulting to the\n * operation's timestamp when omitted. That default is dropped when a stated\n * `validTo` at or before the write instant would leave the row readable at no\n * coordinate: NO lower bound is stored (\"ended at T, start unknown\") and\n * `meta.validFrom` reads back as `undefined`. A RESURRECTION takes the same\n * exception, decided against the instant it samples, so one stated window\n * reaches ONE stored shape whether the id is fresh or names a tombstone. An\n * update to a LIVE row stores no lower bound, because that row's is already\n * history, so one naming a different instant is REFUSED (`ValidationError`\n * carrying\n * `IMMUTABLE_VALIDITY_LOWER_BOUND_CODE`) rather than ignored. Restating the\n * bound the row already holds is accepted and changes nothing. Set\n * `onImmutableLowerBound: \"preserve\"` for event materializers whose\n * `validFrom` is create/resurrection input: a live update then preserves the\n * stored lower bound while still applying props and `validTo`.\n */\n upsertById: (\n id: string,\n props: z.input<N[\"schema\"]>,\n options?: Readonly<{\n validFrom?: string | null;\n onImmutableLowerBound?: \"preserve\" | \"refuse\";\n }> &\n ValidityEndMutation,\n ) => Promise<Node<N>>;\n\n /**\n * Upsert a node from untyped data, relying on runtime Zod validation.\n *\n * Use this for dynamic dispatch (changesets, migrations, imports) where\n * the data shape is determined at runtime, not compile time.\n * The return type is fully typed — only the input gate is relaxed.\n *\n * `validFrom` applies when the upsert CREATES the row and when it RESURRECTS\n * a tombstoned one — both write a fresh validity window — defaulting to the\n * operation's timestamp when omitted. That default is dropped when a stated\n * `validTo` at or before the write instant would leave the row readable at no\n * coordinate: NO lower bound is stored (\"ended at T, start unknown\") and\n * `meta.validFrom` reads back as `undefined`. A RESURRECTION takes the same\n * exception, decided against the instant it samples, so one stated window\n * reaches ONE stored shape whether the id is fresh or names a tombstone. An\n * update to a LIVE row stores no lower bound, because that row's is already\n * history, so one naming a different instant is REFUSED (`ValidationError`\n * carrying\n * `IMMUTABLE_VALIDITY_LOWER_BOUND_CODE`) rather than ignored. Restating the\n * bound the row already holds is accepted and changes nothing. Set\n * `onImmutableLowerBound: \"preserve\"` for create/resurrection-only input.\n */\n upsertByIdFromRecord: (\n id: string,\n data: Record<string, unknown>,\n options?: Readonly<{\n validFrom?: string | null;\n onImmutableLowerBound?: \"preserve\" | \"refuse\";\n }> &\n ValidityEndMutation,\n ) => Promise<Node<N>>;\n\n /**\n * Create multiple nodes in a batch.\n *\n * More efficient than calling create() multiple times.\n * Use `bulkInsert` for the dedicated fast path that skips returning results.\n *\n * `validFrom` defaults to the operation's creation timestamp when omitted —\n * unless a stated `validTo` at or before that instant would leave the row\n * readable at no coordinate, in which case the row is stored with NO lower\n * bound (\"ended at T, start unknown\") and `meta.validFrom` reads back as\n * `undefined`. A future `validTo` is unaffected.\n */\n bulkCreate: (\n items: readonly Readonly<{\n props: z.input<N[\"schema\"]>;\n id?: string;\n validFrom?: string | null;\n validTo?: string;\n }>[],\n ) => Promise<Node<N>[]>;\n\n /**\n * Create or update multiple nodes in a batch.\n *\n * For each item, if a node with the given ID exists, updates it.\n * Otherwise, creates a new node with that ID.\n *\n * Items are applied in order, so a **repeated id** within one batch is\n * last-write-wins: the first item creates or updates the row, and every later\n * copy is an update over the value the earlier item wrote — the same final row\n * the equivalent sequence of `upsertById` calls produces. This holds whether\n * or not the row existed before the batch.\n *\n * `validFrom` applies when the upsert CREATES the row and when it RESURRECTS\n * a tombstoned one — both write a fresh validity window — defaulting to the\n * operation's timestamp when omitted. That default is dropped when a stated\n * `validTo` at or before the write instant would leave the row readable at no\n * coordinate: NO lower bound is stored (\"ended at T, start unknown\") and\n * `meta.validFrom` reads back as `undefined`. A RESURRECTION takes the same\n * exception, decided against the instant it samples, so one stated window\n * reaches ONE stored shape whether the id is fresh or names a tombstone. An update to a LIVE row stores no lower\n * bound, because that row's is already history, so one naming a different\n * instant is REFUSED (`ValidationError` carrying\n * `IMMUTABLE_VALIDITY_LOWER_BOUND_CODE`) rather than ignored. Restating the\n * bound the row already holds is accepted and changes nothing. Per-item\n * `onImmutableLowerBound: \"preserve\"` makes the bound create/resurrection\n * input while a live update preserves the stored lower bound.\n *\n * **Limitation — a batch cannot hand a unique value from one row to\n * another.** Item order settles which value each id ends up with, but the\n * writes themselves are grouped: every create runs before every update. So a\n * batch where one item RELEASES a `unique` constraint value and a later item\n * CLAIMS it — `[{ id: \"a\", props: { email: \"moved@x\" } }, { id: \"b\", props:\n * { email: \"shared@x\" } }]` where `a` currently holds `\"shared@x\"` and `b` is\n * new — checks `b`'s create while `a` still reserves the value, and the whole\n * batch fails with a `UniquenessError`. The equivalent sequence of\n * single `upsertById` calls succeeds. A batch states the set of rows it wants,\n * not a script to reach them by; the failure is loud rather than silent, and\n * the workaround is to split the handoff across two batches (release, then\n * claim) or to apply those items as sequential `upsertById` calls.\n */\n bulkUpsertById: (\n items: readonly (Readonly<{\n id: string;\n props: z.input<N[\"schema\"]>;\n validFrom?: string | null;\n onImmutableLowerBound?: \"preserve\" | \"refuse\";\n }> &\n ValidityEndMutation)[],\n ) => Promise<Node<N>[]>;\n\n /**\n * Replaces complete node documents by id.\n *\n * Missing ids are created. Tombstones are resurrected with a freshly stamped\n * validity window. Live rows preserve their stored validity window. Unlike\n * `bulkUpsertById`, every `props` value is a complete replacement: omitted\n * optional fields are removed rather than merged from the stored document.\n * Duplicate ids are refused because replacement describes a set, not an\n * ordered script.\n */\n bulkReplaceById: (\n items: readonly Readonly<{\n id: string;\n props: z.input<N[\"schema\"]>;\n }>[],\n ) => Promise<Node<N>[]>;\n\n /**\n * Insert multiple nodes without returning results.\n *\n * This is the dedicated fast path for bulk inserts. Unlike `bulkCreate`\n * with `returnResults: false`, the intent is unambiguous: no results\n * are returned and the operation is wrapped in a transaction.\n *\n * `validFrom` defaults to the operation's creation timestamp when omitted —\n * unless a stated `validTo` at or before that instant would leave the row\n * readable at no coordinate, in which case the row is stored with NO lower\n * bound (\"ended at T, start unknown\") and `meta.validFrom` reads back as\n * `undefined`. A future `validTo` is unaffected.\n */\n bulkInsert: (\n items: readonly Readonly<{\n props: z.input<N[\"schema\"]>;\n id?: string;\n validFrom?: string | null;\n validTo?: string;\n }>[],\n ) => Promise<void>;\n\n /**\n * Delete multiple nodes by ID.\n *\n * Atomic when the backend supports transactions. Silently ignores IDs\n * that don't exist.\n */\n bulkDelete: (ids: readonly NodeId<N>[]) => Promise<void>;\n\n /**\n * Find a node by uniqueness constraint.\n *\n * Looks up a live node by the named constraint key computed from `props`.\n * Returns the node if found, or undefined. Soft-deleted nodes are excluded.\n *\n * @param constraintName - Name of the uniqueness constraint to match on\n * @param props - Properties to compute the constraint key from\n */\n findByConstraint: (\n constraintName: CN,\n props: z.input<N[\"schema\"]>,\n ) => Promise<Node<N> | undefined>;\n\n /**\n * Batch version of findByConstraint.\n *\n * Results are returned in the same order as the input items.\n * Returns undefined for entries that don't match.\n */\n bulkFindByConstraint: (\n constraintName: CN,\n items: readonly Readonly<{\n props: z.input<N[\"schema\"]>;\n }>[],\n ) => Promise<(Node<N> | undefined)[]>;\n\n /**\n * Batched candidate retrieval against a declared node index.\n *\n * For each input item, TypeGraph computes the index lookup key from\n * `index.fields` (JSON-pointer extraction, partial-`where` applied to\n * stored rows, null-safe matching) and returns the live, non-soft-deleted\n * nodes that share that key. Unlike {@link bulkFindByConstraint}, the index\n * may be non-unique, so each input yields a (possibly empty) array.\n *\n * Results preserve input order; each inner array is ordered by node id.\n * Empty input returns `[]`. An unknown index name throws\n * `NodeIndexNotFoundError`; a type-incompatible indexed field throws\n * `ValidationError`. This is candidate retrieval, not a uniqueness or\n * identity guarantee.\n *\n * @param indexName - Name of the declared node index to match on\n * @param items - Records whose `props` supply the indexed-field values\n * @param options - Optional `limitPerInput` to bound per-input fan-out\n */\n bulkFindByIndex: (\n indexName: string,\n items: readonly Readonly<{\n props: Partial<z.input<N[\"schema\"]>>;\n }>[],\n options?: NodeBulkFindByIndexOptions,\n ) => Promise<readonly Node<N>[][]>;\n\n /**\n * Get an existing node by uniqueness constraint, or create a new one.\n *\n * Looks up a node by the named constraint key computed from `props`.\n * If found, returns it (optionally updating with `ifExists: \"update\"`).\n * If not found, creates a new node. Soft-deleted matches are always resurrected.\n *\n * @param constraintName - Name of the uniqueness constraint to match on\n * @param props - Full properties for create, or merge source for update\n * @param options - Existing record behavior (default: \"return\")\n */\n getOrCreateByConstraint: (\n constraintName: CN,\n props: z.input<N[\"schema\"]>,\n options?: NodeGetOrCreateByConstraintOptions,\n ) => Promise<NodeGetOrCreateByConstraintResult<N>>;\n\n /**\n * Batch version of getOrCreateByConstraint.\n *\n * Results are returned in the same order as the input items.\n * Atomic when the backend supports transactions.\n */\n bulkGetOrCreateByConstraint: (\n constraintName: CN,\n items: readonly Readonly<{\n props: z.input<N[\"schema\"]>;\n }>[],\n options?: NodeGetOrCreateByConstraintOptions,\n ) => Promise<NodeGetOrCreateByConstraintResult<N>[]>;\n}>;\n\n/**\n * Reference to a node of a specific kind.\n *\n * Accepts either:\n * - A Node instance of the correct kind\n * - An explicit { kind, id } object with the correct kind name\n *\n * This provides compile-time checking that edge endpoints match the\n * allowed node kinds defined in the edge registration.\n */\nexport type NodeRef<N extends NodeType = NodeType> =\n Node<N> | Readonly<{ kind: N[\"kind\"]; id: string }>;\n\n/**\n * Options for creating an edge.\n */\ntype EdgeCreateOptions = Readonly<{\n id?: string;\n validFrom?: string | null;\n validTo?: string;\n}>;\n\n/**\n * Arguments for edge creation, with props optional when schema allows empty object.\n *\n * Uses `{}` to check if an empty object literal satisfies the schema input type.\n */\n/* eslint-disable @typescript-eslint/no-empty-object-type -- {} is intentional: checking if empty object satisfies schema */\ntype EdgeCreateArguments<E extends AnyEdgeType> =\n {} extends z.input<E[\"schema\"]> ?\n [props?: z.input<E[\"schema\"]>, options?: EdgeCreateOptions]\n : [props: z.input<E[\"schema\"]>, options?: EdgeCreateOptions];\n/* eslint-enable @typescript-eslint/no-empty-object-type */\n\n/**\n * A collection of edges of a specific type.\n *\n * Provides ergonomic CRUD operations for a single edge type.\n * The From and To type parameters enforce that edge endpoints\n * match the allowed node types at compile time.\n *\n * @example\n * ```typescript\n * // Create an edge - pass Node objects directly\n * const edge = await store.edges.worksAt.create(alice, acme, { role: \"Engineer\" });\n *\n * // TypeScript error: Company is not a valid 'from' type for worksAt\n * // store.edges.worksAt.create(acme, alice, { role: \"Engineer\" });\n *\n * // For edges with empty schemas, props is optional\n * await store.edges.wrote.create(author, book);\n *\n * // Find edges from a node\n * const edges = await store.edges.worksAt.findFrom(alice);\n * ```\n */\ntype EdgeEndpointPairTypes = Readonly<{\n from: NodeType;\n to: NodeType;\n}>;\n\ntype EdgeBulkCreateItem<\n Pairs extends EdgeEndpointPairTypes,\n Schema extends z.ZodObject<z.ZodRawShape>,\n> =\n Pairs extends EdgeEndpointPairTypes ?\n Readonly<{\n from: NodeRef<Pairs[\"from\"]>;\n to: NodeRef<Pairs[\"to\"]>;\n props?: z.input<Schema>;\n id?: string;\n validFrom?: string | null;\n validTo?: string;\n }>\n : never;\n\ntype EdgeBulkUpsertItem<\n E extends AnyEdgeType,\n Pairs extends EdgeEndpointPairTypes,\n Id extends string = EdgeId<E>,\n> =\n Pairs extends EdgeEndpointPairTypes ?\n Readonly<{\n id: Id;\n from: NodeRef<Pairs[\"from\"]>;\n to: NodeRef<Pairs[\"to\"]>;\n props?: z.input<E[\"schema\"]>;\n validFrom?: string | null;\n }> &\n ValidityEndMutation\n : never;\n\ntype EdgeBulkInsertItem<\n Pairs extends EdgeEndpointPairTypes,\n Schema extends z.ZodObject<z.ZodRawShape>,\n> =\n Pairs extends EdgeEndpointPairTypes ?\n Readonly<{\n from: NodeRef<Pairs[\"from\"]>;\n to: NodeRef<Pairs[\"to\"]>;\n props?: z.input<Schema>;\n id?: string;\n validFrom?: string | null;\n validTo?: string;\n }>\n : never;\n\ntype EdgeBulkGetOrCreateItem<\n E extends AnyEdgeType,\n Pairs extends EdgeEndpointPairTypes,\n> =\n Pairs extends EdgeEndpointPairTypes ?\n Readonly<{\n from: NodeRef<Pairs[\"from\"]>;\n to: NodeRef<Pairs[\"to\"]>;\n props: z.input<E[\"schema\"]>;\n validFrom?: string | null;\n onImmutableLowerBound?: \"preserve\" | \"refuse\";\n }> &\n ValidityEndMutation\n : never;\n\ntype EdgeCreateArgumentsTuple<\n E extends AnyEdgeType,\n Pairs extends EdgeEndpointPairTypes,\n> =\n Pairs extends EdgeEndpointPairTypes ?\n [\n from: NodeRef<Pairs[\"from\"]>,\n to: NodeRef<Pairs[\"to\"]>,\n ...args: EdgeCreateArguments<E>,\n ]\n : never;\n\ntype EdgeFindByEndpointsArguments<\n E extends AnyEdgeType,\n Pairs extends EdgeEndpointPairTypes,\n> =\n Pairs extends EdgeEndpointPairTypes ?\n [\n from: NodeRef<Pairs[\"from\"]>,\n to: NodeRef<Pairs[\"to\"]>,\n options?: EdgeFindByEndpointsOptions<E>,\n temporal?: QueryOptions,\n ]\n : never;\n\ntype EdgeGetOrCreateByEndpointsArguments<\n E extends AnyEdgeType,\n Pairs extends EdgeEndpointPairTypes,\n> =\n Pairs extends EdgeEndpointPairTypes ?\n [\n from: NodeRef<Pairs[\"from\"]>,\n to: NodeRef<Pairs[\"to\"]>,\n props: z.input<E[\"schema\"]>,\n options?: EdgeGetOrCreateByEndpointsOptions<E>,\n ]\n : never;\n\n/**\n * Typed edge operations. InputId controls accepted ID arguments only; returned\n * edges retain their schema-derived ID brand. Prefer DynamicEdgeCollection<E>\n * for runtime endpoint dispatch instead of spelling its parameters manually.\n */\nexport type EdgeCollection<\n E extends AnyEdgeType,\n From extends NodeType = NodeType,\n To extends NodeType = NodeType,\n Pairs extends EdgeEndpointPairTypes = { from: From; to: To },\n InputId extends string = EdgeId<E>,\n> = Readonly<{\n /**\n * Create a new edge.\n *\n * `validFrom` defaults to the operation's creation timestamp when omitted —\n * unless a stated `validTo` at or before that instant would leave the row\n * readable at no coordinate, in which case the row is stored with NO lower\n * bound (\"ended at T, start unknown\") and `meta.validFrom` reads back as\n * `undefined`. A future `validTo` is unaffected.\n *\n * @param from - Source node (must be one of the allowed 'from' types)\n * @param to - Target node (must be one of the allowed 'to' types)\n * @param args - Edge properties (optional if schema is empty) and creation options\n */\n create: (\n ...args: EdgeCreateArgumentsTuple<E, Pairs>\n ) => Promise<Edge<E, From, To>>;\n\n /** Get an edge by ID */\n getById: (\n id: InputId,\n options?: QueryOptions,\n ) => Promise<Edge<E, From, To> | undefined>;\n\n /** Get multiple edges by ID, preserving input order (undefined for missing) */\n getByIds: (\n ids: readonly InputId[],\n options?: QueryOptions,\n ) => Promise<readonly (Edge<E, From, To> | undefined)[]>;\n\n /**\n * Update an edge's properties and optionally set or clear its validity end.\n * Reopening a `oneActive` edge rechecks cardinality before the write.\n */\n update: (\n id: InputId,\n props: Partial<z.input<E[\"schema\"]>>,\n options?: ValidityEndMutation,\n ) => Promise<Edge<E, From, To>>;\n\n /**\n * Find edges from a specific node.\n *\n * Honors the same temporal model as `getById` / `find`: with no\n * `options`, the graph's default `temporalMode` applies (excluding\n * soft-deleted edges and, in `current` / `asOf` modes, edges outside\n * their validity window). Pass `temporalMode` / `asOf` to read the\n * endpoint's edges at another temporal coordinate.\n */\n findFrom: (\n from: NodeRef<From>,\n options?: QueryOptions,\n ) => Promise<Edge<E, From, To>[]>;\n\n /**\n * Find edges to a specific node.\n *\n * Temporal semantics mirror {@link EdgeCollection.findFrom}.\n */\n findTo: (\n to: NodeRef<To>,\n options?: QueryOptions,\n ) => Promise<Edge<E, From, To>[]>;\n\n /**\n * Find the edges from a SET of source nodes in one read.\n *\n * `findFrom` with a widened endpoint predicate and nothing else: the same\n * temporal model, the same soft-delete filtering, and the same per-source\n * ordering — but `from_id IN (...)` instead of `from_id = ?`, so a page of\n * N sources costs one statement per distinct source kind and bind-budget\n * chunk rather than N singleton statements.\n *\n * Results are grouped per input: the outer array is parallel to `froms`\n * (index `i` holds the edges of `froms[i]`), and repeated inputs each get\n * their own copy of the same edge set. Empty input returns `[]`; a source\n * with no edges gets an empty array. Large inputs are split across\n * statements to respect the backend's bound-parameter budget, which is\n * invisible in the result.\n *\n * Requires a backend implementing `findEdgesByEndpointSet` — both bundled\n * Drizzle backends do. On one that does not, this **refuses** with a\n * `ConfigurationError` rather than looping `findFrom` per input: asking for\n * a bulk read is asking for set-oriented statements, and silently issuing N\n * singleton statements is the cost surprise the method exists to remove.\n *\n * @param froms - Source nodes to read the edges of\n * @param options - Temporal coordinate plus optional `limitPerInput`\n * @throws {ConfigurationError} when the backend cannot read an endpoint set\n */\n bulkFindFrom: (\n froms: readonly NodeRef<From>[],\n options?: EdgeBulkFindEndpointOptions,\n ) => Promise<readonly Edge<E, From, To>[][]>;\n\n /**\n * Find the edges into a SET of target nodes in one read.\n *\n * Mirrors {@link EdgeCollection.bulkFindFrom} on the `to` endpoint.\n */\n bulkFindTo: (\n tos: readonly NodeRef<To>[],\n options?: EdgeBulkFindEndpointOptions,\n ) => Promise<readonly Edge<E, From, To>[][]>;\n\n /**\n * Deferred variant of `findFrom` for use with `store.batch()`.\n *\n * Returns a `BatchableQuery` instead of executing immediately. Accepts\n * the same temporal `options` as {@link EdgeCollection.findFrom}.\n *\n * Batching these still issues one statement per call — it does not merge\n * the reads, and whether they share a connection is up to the adapter. It\n * is not a snapshot: PostgreSQL's default read-committed isolation lets a\n * later read observe a commit the earlier ones did not. To read edges for\n * many sources in one statement, traverse from them in a single query.\n */\n batchFindFrom: (\n from: NodeRef<From>,\n options?: QueryOptions,\n ) => BatchableQuery<Edge<E, From, To>>;\n\n /**\n * Deferred variant of `findTo` for use with `store.batch()`.\n *\n * Returns a `BatchableQuery` instead of executing immediately. Accepts\n * the same temporal `options` as {@link EdgeCollection.findTo}. Costs one\n * statement per call, like {@link EdgeCollection.batchFindFrom}.\n */\n batchFindTo: (\n to: NodeRef<To>,\n options?: QueryOptions,\n ) => BatchableQuery<Edge<E, From, To>>;\n\n /**\n * Deferred variant of `findByEndpoints` for use with `store.batch()`.\n *\n * Returns a `BatchableQuery` that yields a 0-or-1 element array\n * (matching `findByEndpoints`' at-most-one semantics). Costs one statement\n * per call, like {@link EdgeCollection.batchFindFrom}.\n */\n batchFindByEndpoints: (\n ...args: EdgeFindByEndpointsArguments<E, Pairs>\n ) => BatchableQuery<Edge<E, From, To>>;\n\n /** Delete an edge (soft delete - sets deletedAt timestamp) */\n delete: (id: InputId) => Promise<void>;\n\n /**\n * Permanently delete an edge from the database.\n *\n * Unlike `delete()` which performs a soft delete, this permanently\n * removes the edge record.\n *\n * **Warning:** This operation is irreversible and should be used carefully.\n * Consider using soft delete (`delete()`) for most use cases.\n */\n hardDelete: (id: InputId) => Promise<void>;\n\n /** Find edges matching endpoint and pagination criteria */\n find: (\n filter?: Readonly<{\n from?: NodeRef<From>;\n to?: NodeRef<To>;\n limit?: number;\n offset?: number;\n }>,\n temporal?: QueryOptions,\n ) => Promise<Edge<E, From, To>[]>;\n\n /** Count edges matching criteria */\n count: (\n filter?: Readonly<{\n from?: NodeRef<From>;\n to?: NodeRef<To>;\n }>,\n temporal?: QueryOptions,\n ) => Promise<number>;\n\n /**\n * Create multiple edges in a batch.\n *\n * More efficient than calling create() multiple times.\n * Use `bulkInsert` for the dedicated fast path that skips returning results.\n *\n * `validFrom` defaults to the operation's creation timestamp when omitted —\n * unless a stated `validTo` at or before that instant would leave the row\n * readable at no coordinate, in which case the row is stored with NO lower\n * bound (\"ended at T, start unknown\") and `meta.validFrom` reads back as\n * `undefined`. A future `validTo` is unaffected.\n */\n bulkCreate: (\n items: readonly EdgeBulkCreateItem<Pairs, E[\"schema\"]>[],\n ) => Promise<Edge<E, From, To>[]>;\n\n /**\n * Create or update multiple edges in a batch.\n *\n * For each item, if an edge with the given ID exists, updates it.\n * Otherwise, creates a new edge with that ID.\n *\n * Items are applied in order, so a **repeated id** within one batch is\n * last-write-wins: the first item creates or updates the edge, and every later\n * copy is an update over the value the earlier item wrote. This holds whether\n * or not the edge existed before the batch. An update never repoints an edge,\n * so every item's `from` / `to` must exactly restate the endpoints already\n * owned by that id (including an earlier item in the same batch). A mismatch\n * is refused with `ValidationError` carrying\n * `EDGE_IDENTITY_MISMATCH_CODE`; it is never silently ignored.\n *\n * `validFrom` applies when the upsert CREATES the edge and when it RESURRECTS\n * a tombstoned one. A create writes a fresh validity window, defaulting to the\n * operation's timestamp when omitted — unless a stated `validTo` at or before\n * that instant would leave the row readable at no coordinate, in which case NO\n * lower bound is stored (\"ended at T, start unknown\") and `meta.validFrom`\n * reads back as `undefined`. A resurrection stamps nothing: an edge RETAINS\n * its stored lower bound unless the item names a new one, so a `validTo`\n * before the retained bound is REFUSED rather than stamped over. An update to\n * a LIVE row stores no lower bound, because that row's is already history, so\n * one naming a different instant is REFUSED (`ValidationError` carrying\n * `IMMUTABLE_VALIDITY_LOWER_BOUND_CODE`) rather than ignored. Restating the\n * bound the row already holds is accepted and changes nothing.\n *\n * **Limitation — a batch cannot hand a constrained slot from one edge to\n * another.** Item order settles the final props, but the writes are grouped:\n * every create runs before every update. So a batch where one item frees the\n * slot a `cardinality` constraint allows and a later item claims it — ending\n * the lone `oneActive` edge from a source while creating its replacement —\n * checks the create while the old edge is still active, and the whole batch\n * fails with a `CardinalityError`. Applying the update first, as\n * separate `update` / `create` calls, succeeds. A batch states the set of\n * edges it wants, not a script to reach them by; the failure is loud rather\n * than silent, and the workaround is to split the handoff across two batches\n * (free the slot, then claim it) or to apply those items individually.\n */\n bulkUpsertById: (\n items: readonly EdgeBulkUpsertItem<E, Pairs, InputId>[],\n ) => Promise<Edge<E, From, To>[]>;\n\n /**\n * Insert multiple edges without returning results.\n *\n * This is the dedicated fast path for bulk inserts. Unlike `bulkCreate`\n * with `returnResults: false`, the intent is unambiguous: no results\n * are returned and the operation is wrapped in a transaction.\n *\n * `validFrom` defaults to the operation's creation timestamp when omitted —\n * unless a stated `validTo` at or before that instant would leave the row\n * readable at no coordinate, in which case the row is stored with NO lower\n * bound (\"ended at T, start unknown\") and `meta.validFrom` reads back as\n * `undefined`. A future `validTo` is unaffected.\n */\n bulkInsert: (\n items: readonly EdgeBulkInsertItem<Pairs, E[\"schema\"]>[],\n ) => Promise<void>;\n\n /**\n * Delete multiple edges by ID.\n *\n * Atomic when the backend supports transactions. Silently ignores IDs\n * that don't exist.\n *\n * The batch runs as one transaction, checking each id's kind against the\n * authoritative row as it goes. An id owned by another edge kind is\n * refused with `ValidationError` carrying `EDGE_IDENTITY_MISMATCH_CODE`;\n * because the whole batch is one transaction, that refusal rolls back\n * every delete already applied for an earlier id in the same batch.\n */\n bulkDelete: (ids: readonly InputId[]) => Promise<void>;\n\n /**\n * Find an edge by endpoints and optional property fields.\n *\n * Returns the first matching edge at the read coordinate, or undefined.\n * Honors the temporal model like `findFrom` / `findTo`: by default\n * (`current` mode) soft-deleted and out-of-window edges are excluded; under\n * `includeTombstones` a soft-deleted edge can be returned.\n *\n * @param from - Source node\n * @param to - Target node\n * @param options - Match criteria (matchOn fields and property values)\n * @param temporal - Temporal coordinate. With no `temporal`, the graph's\n * default `temporalMode` applies (so under the default `\"current\"` mode,\n * edges outside their validity window are excluded). Pass\n * `temporalMode` / `asOf` to read the edge as of another coordinate.\n */\n findByEndpoints: (\n ...args: EdgeFindByEndpointsArguments<E, Pairs>\n ) => Promise<Edge<E, From, To> | undefined>;\n\n /**\n * Get an existing edge by endpoints and optional property fields, or create a new one.\n *\n * Matches edges of this kind between `(from, to)`. When `matchOn` specifies\n * property fields, only edges whose properties match on those fields are considered.\n * Soft-deleted matches are resurrected when cardinality allows.\n *\n * `validFrom` applies on the create and RESURRECT branches. A create defaults\n * it to the operation's creation timestamp when omitted — unless a stated\n * `validTo` at or before that instant would leave the row readable at no\n * coordinate, in which case no lower bound is stored (\"ended at T, start\n * unknown\"). A resurrection stamps nothing: an edge RETAINS its stored lower\n * bound unless the call names a new one, so a `validTo` before the retained\n * bound is REFUSED rather than stamped over. On the `ifExists: \"update\"`\n * branch a live edge's lower bound is history and cannot be stored, so a\n * `validFrom` naming a different instant is REFUSED (`ValidationError`\n * carrying `IMMUTABLE_VALIDITY_LOWER_BOUND_CODE`); restating the bound the\n * edge holds is accepted. A returned existing edge (`ifExists: \"return\"`)\n * writes nothing and judges nothing — the window options describe the row to\n * create if none is found. `validTo` applies on create, update, and\n * resurrection, but not when an existing edge is returned without a write.\n *\n * @param from - Source node\n * @param to - Target node\n * @param props - Full properties for create, or merge source for update\n * @param options - Match criteria and conflict resolution\n */\n getOrCreateByEndpoints: (\n ...args: EdgeGetOrCreateByEndpointsArguments<E, Pairs>\n ) => Promise<EdgeGetOrCreateByEndpointsResult<E, From, To>>;\n\n /**\n * Batch version of getOrCreateByEndpoints.\n *\n * Results are returned in the same order as the input items.\n * Atomic when the backend supports transactions.\n */\n bulkGetOrCreateByEndpoints: (\n items: readonly EdgeBulkGetOrCreateItem<E, Pairs>[],\n options?: Pick<\n EdgeGetOrCreateByEndpointsOptions<E>,\n \"matchOn\" | \"ifExists\"\n >,\n ) => Promise<EdgeGetOrCreateByEndpointsResult<E, From, To>[]>;\n}>;\n\n// ============================================================\n// Type Helpers\n// ============================================================\n\n/**\n * Extract uniqueness constraint names from a NodeRegistration.\n *\n * - Returns `never` when no uniqueness constraints are configured.\n * - Returns a literal union when names are inferred via `defineGraph` const params.\n * - Falls back to `string` when names are widened/dynamic.\n */\nexport type ConstraintNames<R extends NodeRegistration> =\n \"unique\" extends keyof R ?\n R[\"unique\"] extends readonly { readonly name: infer N }[] ?\n N & string\n : string\n : never;\n\n/**\n * Extract the union of 'from' node types from an EdgeRegistration.\n */\ntype EdgeFromTypes<R extends EdgeRegistration> =\n R[\"from\"] extends readonly (infer N)[] ? N : never;\n\ntype ExtractTargets<T> =\n T extends readonly (infer N extends NodeType)[] ? N\n : T extends Record<string, readonly (infer N extends NodeType)[]> ? N\n : never;\n\n/**\n * Extract the union of 'to' node types from an EdgeRegistration.\n */\ntype EdgeToTypes<R extends EdgeRegistration> = ExtractTargets<R[\"to\"]>;\n\ntype ExtractAllowedPairs<From, To> =\n To extends readonly (infer ToNode extends NodeType)[] ?\n {\n from: From extends readonly (infer FromNode extends NodeType)[] ? FromNode\n : NodeType;\n to: ToNode;\n }\n : To extends Record<string, readonly NodeType[]> ?\n {\n [K in keyof To & string]: {\n from: Extract<\n From extends readonly (infer FromNode extends NodeType)[] ? FromNode\n : NodeType,\n { kind: K }\n >;\n to: To[K] extends readonly (infer ToNode extends NodeType)[] ? ToNode\n : NodeType;\n };\n }[keyof To & string]\n : { from: NodeType; to: NodeType };\n\n/**\n * Extract the allowed endpoint pairs from an EdgeRegistration.\n */\ntype EdgeAllowedPairs<R extends EdgeRegistration> = ExtractAllowedPairs<\n R[\"from\"],\n R[\"to\"]\n>;\n\n/**\n * Create a type-safe EdgeCollection from an EdgeRegistration.\n * Extracts the edge type and from/to node types automatically.\n */\nexport type TypedEdgeCollection<R extends EdgeRegistration> = EdgeCollection<\n R[\"type\"],\n EdgeFromTypes<R> extends NodeType ? EdgeFromTypes<R> : NodeType,\n EdgeToTypes<R> extends NodeType ? EdgeToTypes<R> : NodeType,\n EdgeAllowedPairs<R>\n>;\n\n// ============================================================\n// Transaction Types\n// ============================================================\n\n// ============================================================\n// Graph Collection Maps\n// ============================================================\n\n/** Mapped type of all node collections for a graph. */\nexport type GraphNodeCollections<G extends GraphDef> = {\n [K in keyof G[\"nodes\"] & string]-?: NodeCollection<\n G[\"nodes\"][K][\"type\"],\n ConstraintNames<G[\"nodes\"][K]>\n >;\n};\n\n/** Mapped type of all edge collections for a graph. */\nexport type GraphEdgeCollections<G extends GraphDef> = {\n [K in keyof G[\"edges\"] & string]-?: TypedEdgeCollection<G[\"edges\"][K]>;\n};\n\n// ============================================================\n// StoreView read-only collection surfaces\n// ============================================================\n\n/** Temporal-aware node reads — a {@link StoreView} pins these. */\nexport type NodeTemporalReads<\n N extends NodeType,\n CN extends string = string,\n> = Pick<NodeCollection<N, CN>, (typeof NODE_TEMPORAL_READ_NAMES)[number]>;\n\n/**\n * Current-state-only node reads (constraint / index lookups). No temporal\n * axis, so a {@link StoreView} delegates them on a `current` pin and refuses\n * them on a temporal pin.\n */\nexport type NodeCurrentReads<\n N extends NodeType,\n CN extends string = string,\n> = Pick<NodeCollection<N, CN>, (typeof CURRENT_ONLY_READ_NAMES)[number]>;\n\n/** Node writes — never available on a read-only {@link StoreView}. */\nexport type NodeWrites<N extends NodeType, CN extends string = string> = Pick<\n NodeCollection<N, CN>,\n (typeof NODE_WRITE_NAMES)[number]\n>;\n\n/** Temporal-aware edge reads — a {@link StoreView} pins these. */\nexport type EdgeTemporalReads<\n E extends AnyEdgeType,\n From extends NodeType = NodeType,\n To extends NodeType = NodeType,\n> = Pick<\n EdgeCollection<E, From, To>,\n (typeof EDGE_TEMPORAL_READ_NAMES)[number]\n>;\n\n/**\n * Deferred edge reads for `store.batch()` — absent from a {@link StoreView},\n * which has no batch context.\n */\nexport type EdgeBatchReads<\n E extends AnyEdgeType,\n From extends NodeType = NodeType,\n To extends NodeType = NodeType,\n> = Pick<EdgeCollection<E, From, To>, (typeof EDGE_BATCH_READ_NAMES)[number]>;\n\n/** Edge writes — never available on a read-only {@link StoreView}. */\nexport type EdgeWrites<\n E extends AnyEdgeType,\n From extends NodeType = NodeType,\n To extends NodeType = NodeType,\n> = Pick<EdgeCollection<E, From, To>, (typeof EDGE_WRITE_NAMES)[number]>;\n\n/**\n * The read-only node surface a {@link StoreView} exposes for one node kind.\n * The temporal reads drop the per-call temporal argument — the pin owns the\n * axis; the current reads ({@link NodeCurrentReads}) are exposed as-is\n * (delegated on a `current` view, refused on a temporal pin). Writes live on\n * the live `Store`. The conformance test asserts the temporal part equals the\n * pinned form of {@link NodeTemporalReads}.\n */\nexport type StoreViewNodeCollection<\n N extends NodeType,\n CN extends string = string,\n> = Readonly<{\n /** Get a node by ID at the view's pinned coordinate. */\n getById: (id: NodeId<N>) => Promise<Node<N> | undefined>;\n\n /** Get multiple nodes by ID, preserving input order (undefined for missing). */\n getByIds: (\n ids: readonly NodeId<N>[],\n ) => Promise<readonly (Node<N> | undefined)[]>;\n\n /** Find nodes matching criteria at the view's pinned coordinate. */\n find: (\n filter?: Readonly<{\n where?: (accessor: NodeAccessor<N>) => Predicate;\n limit?: number;\n offset?: number;\n }>,\n ) => Promise<Node<N>[]>;\n\n /** Count nodes at the view's pinned coordinate. */\n count: () => Promise<number>;\n}> &\n NodeCurrentReads<N, CN>;\n\n/**\n * The read-only edge surface a {@link StoreView} exposes for one edge\n * kind, mirroring {@link StoreViewNodeCollection}. Every edge read —\n * including `findByEndpoints` — honors the pin via the same temporal model,\n * so (unlike nodes) there are no current-state-only edge reads.\n */\nexport type StoreViewEdgeCollection<\n E extends AnyEdgeType,\n From extends NodeType = NodeType,\n To extends NodeType = NodeType,\n Pairs extends EdgeEndpointPairTypes = {\n from: From;\n to: To;\n },\n> = Readonly<{\n /** Get an edge by ID at the view's pinned coordinate. */\n getById: (id: EdgeId<E>) => Promise<Edge<E, From, To> | undefined>;\n\n /** Get multiple edges by ID, preserving input order (undefined for missing). */\n getByIds: (\n ids: readonly EdgeId<E>[],\n ) => Promise<readonly (Edge<E, From, To> | undefined)[]>;\n\n /** Find edges matching endpoint and pagination criteria. */\n find: (\n filter?: Readonly<{\n from?: NodeRef<From>;\n to?: NodeRef<To>;\n limit?: number;\n offset?: number;\n }>,\n ) => Promise<Edge<E, From, To>[]>;\n\n /** Count edges matching criteria at the view's pinned coordinate. */\n count: (\n filter?: Readonly<{ from?: NodeRef<From>; to?: NodeRef<To> }>,\n ) => Promise<number>;\n\n /** Find edges from a specific node at the view's pinned coordinate. */\n findFrom: (from: NodeRef<From>) => Promise<Edge<E, From, To>[]>;\n\n /** Find edges to a specific node at the view's pinned coordinate. */\n findTo: (to: NodeRef<To>) => Promise<Edge<E, From, To>[]>;\n\n /** Find the edges from a set of source nodes at the view's pinned coordinate. */\n bulkFindFrom: (\n froms: readonly NodeRef<From>[],\n options?: EdgeBulkFindOptions,\n ) => Promise<readonly Edge<E, From, To>[][]>;\n\n /** Find the edges into a set of target nodes at the view's pinned coordinate. */\n bulkFindTo: (\n tos: readonly NodeRef<To>[],\n options?: EdgeBulkFindOptions,\n ) => Promise<readonly Edge<E, From, To>[][]>;\n\n /** Find the edge between two endpoints at the view's pinned coordinate. */\n findByEndpoints: (\n ...args: Pairs extends EdgeEndpointPairTypes ?\n [\n from: NodeRef<Pairs[\"from\"]>,\n to: NodeRef<Pairs[\"to\"]>,\n options?: EdgeFindByEndpointsOptions<E>,\n ]\n : never\n ) => Promise<Edge<E, From, To> | undefined>;\n}>;\n\n/**\n * Read-only view edge collection derived from an `EdgeRegistration`,\n * extracting the edge type and from/to node types — the read-only\n * counterpart of {@link TypedEdgeCollection}.\n */\nexport type TypedStoreViewEdgeCollection<R extends EdgeRegistration> =\n StoreViewEdgeCollection<\n R[\"type\"],\n EdgeFromTypes<R> extends NodeType ? EdgeFromTypes<R> : NodeType,\n EdgeToTypes<R> extends NodeType ? EdgeToTypes<R> : NodeType,\n EdgeAllowedPairs<R>\n >;\n\n/** Mapped type of all read-only view node collections for a graph. */\nexport type StoreViewNodeCollections<G extends GraphDef> = {\n [K in keyof G[\"nodes\"] & string]-?: StoreViewNodeCollection<\n G[\"nodes\"][K][\"type\"]\n >;\n};\n\n/** Mapped type of all read-only view edge collections for a graph. */\nexport type StoreViewEdgeCollections<G extends GraphDef> = {\n [K in keyof G[\"edges\"] & string]-?: TypedStoreViewEdgeCollection<\n G[\"edges\"][K]\n >;\n};\n\n/** Options for one bounded, forward-only recorded-time collection scan. */\nexport type RecordedScanOptions = Readonly<{\n /** Maximum entities to return. Defaults to 1,000 and cannot exceed 1,000. */\n limit?: number;\n /** Opaque cursor returned by the preceding page. */\n after?: string;\n}>;\n\n/** One page from a deterministic recorded-time collection scan. */\nexport type RecordedScanPage<T> = Readonly<{\n /** Entities ordered by canonical id ascending. */\n data: readonly T[];\n /** Cursor for the next page, or `undefined` when the scan is complete. */\n nextCursor: string | undefined;\n /** Whether another page exists after this one. */\n hasNextPage: boolean;\n}>;\n\n/** Recorded-time reconstructing reads for one node kind. */\nexport type RecordedStoreViewNodeCollection<N extends NodeType> = Pick<\n StoreViewNodeCollection<N>,\n (typeof RECORDED_POINT_READ_NAMES)[number]\n> &\n Readonly<{\n /** Scan one bounded page at the view's pinned coordinate. */\n scan: (options?: RecordedScanOptions) => Promise<RecordedScanPage<Node<N>>>;\n }>;\n\n/** Recorded-time reconstructing reads for one edge kind. */\nexport type RecordedStoreViewEdgeCollection<\n E extends AnyEdgeType,\n From extends NodeType = NodeType,\n To extends NodeType = NodeType,\n Pairs extends EdgeEndpointPairTypes = {\n from: From;\n to: To;\n },\n> = Pick<\n StoreViewEdgeCollection<E, From, To, Pairs>,\n (typeof RECORDED_POINT_READ_NAMES)[number]\n> &\n Readonly<{\n /** Scan one bounded page at the view's pinned coordinate. */\n scan: (\n options?: RecordedScanOptions,\n ) => Promise<RecordedScanPage<Edge<E, From, To>>>;\n }>;\n\n/** Recorded-time edge collection derived from an `EdgeRegistration`. */\nexport type TypedRecordedStoreViewEdgeCollection<R extends EdgeRegistration> =\n RecordedStoreViewEdgeCollection<\n R[\"type\"],\n EdgeFromTypes<R> extends NodeType ? EdgeFromTypes<R> : NodeType,\n EdgeToTypes<R> extends NodeType ? EdgeToTypes<R> : NodeType,\n EdgeAllowedPairs<R>\n >;\n\n/** Mapped type of all recorded-time node reconstructing-read collections. */\nexport type RecordedStoreViewNodeCollections<G extends GraphDef> = {\n [K in keyof G[\"nodes\"] & string]-?: RecordedStoreViewNodeCollection<\n G[\"nodes\"][K][\"type\"]\n >;\n};\n\n/** Mapped type of all recorded-time edge reconstructing-read collections. */\nexport type RecordedStoreViewEdgeCollections<G extends GraphDef> = {\n [K in keyof G[\"edges\"] & string]-?: TypedRecordedStoreViewEdgeCollection<\n G[\"edges\"][K]\n >;\n};\n\n// ============================================================\n// Transaction Context\n// ============================================================\n\n/**\n * Whether — and why — `tx.sql` can be used on a transaction context. A single\n * required discriminant covering exactly the four states raw-SQL access can be\n * in, so an adapter caller branches on capability instead of truthiness-testing\n * `tx.sql`. The non-available variants omit `sql` entirely, so even reading the\n * handle requires first narrowing `sqlAvailability` to `\"available\"`. The\n * runtime object keeps a fail-loud getter under history / revision tracking for\n * JavaScript and type-suppressed callers. See\n * {@link AdapterTransactionContext} for the per-value semantics.\n */\nexport type SqlAvailability =\n \"available\" | \"history\" | \"revisionTracking\" | \"unavailable\";\n\ntype AdapterTransactionSqlAccess<TNativeTransaction> =\n | Readonly<{\n sql: TNativeTransaction;\n sqlAvailability: \"available\";\n }>\n | Readonly<{\n sqlAvailability: \"history\" | \"revisionTracking\";\n }>\n | Readonly<{\n sqlAvailability: \"unavailable\";\n }>;\n\nexport const TRANSACTION_RUNTIME: unique symbol = typeGraphGlobalSymbol(\n \"transaction-runtime-v1\",\n);\n\ntype TransactionRuntime = Readonly<{\n backend: TransactionBackend;\n runNodeOperationHooks: <T>(\n operation: \"create\" | \"update\" | \"delete\",\n kind: string,\n id: string,\n fn: () => Promise<T>,\n ) => Promise<T>;\n}>;\n\n/**\n * The portable transaction context mirrors the Store's typed graph operations\n * while exposing only a read-only backend projection bound to the transaction.\n * Adapter-native handles are available only through\n * {@link AdapterTransactionContext}; arbitrary backend writes are absent from\n * every public transaction context. TypeGraph's non-enumerable symbol port is\n * an unsupported implementation detail, not a JavaScript security boundary:\n * reflective code can still discover symbol properties.\n *\n * @example\n * ```typescript\n * await store.transaction(async (tx) => {\n * const person = await tx.nodes.Person.create({ name: \"Alice\" });\n * const company = await tx.nodes.Company.create({ name: \"Acme\" });\n * await tx.edges.worksAt.create(person, company, { role: \"Engineer\" });\n * });\n * ```\n */\ntype TransactionCollections<G extends GraphDef> = Readonly<{\n [TRANSACTION_RUNTIME]: TransactionRuntime;\n nodes: GraphNodeCollections<G>;\n edges: GraphEdgeCollections<G>;\n /** Runtime endpoint validation with the selected edge's property schema retained. */\n getEdgeCollection: EdgeCollectionLookup<G>;\n /** Like getEdgeCollection, throwing KindNotFoundError when absent. */\n getEdgeCollectionOrThrow: RequiredEdgeCollectionLookup<G>;\n /** Read-only backend projection bound to the same graph transaction. */\n backend: TransactionReadBackend;\n /**\n * Runtime string-keyed node collection access, mirroring\n * `Store.getNodeCollection`. Returns `undefined` when `kind` is not\n * registered in this graph.\n */\n getNodeCollection: <const K extends string>(\n kind: K,\n ) => DynamicNodeCollection<K> | undefined;\n}> &\n (G[\"identity\"] extends GraphIdentityConfig ?\n Readonly<{ identity: IdentityFacade<G> }>\n : Readonly<Record<never, never>>);\n\n/**\n * A portable transaction context containing TypeGraph-owned collections and\n * transaction-bound graph reads. Managed Stores use this surface so\n * adapter-native handles never enter their public contract.\n */\nexport type TransactionContext<G extends GraphDef> = TransactionCollections<G> &\n Readonly<{\n query: () => InitialQueryBuilder<G, \"open\">;\n /** Describes current population through this transaction's pinned session. */\n describe: () => Promise<StoreDescription>;\n /** Validates current records through this transaction's pinned session. */\n validateStore: (\n options: ValidateStoreOptions,\n ) => Promise<StoreValidationPage>;\n batchOnce: <const Queries extends OneStatementBatchReads>(\n build: (read: BatchReadBuilder<G>) => Queries,\n options?: BatchOnceOptions,\n ) => Promise<OneStatementBatchResults<Queries>>;\n neighbors: <const K extends EdgeKinds<G>>(\n source: GraphNodeReference<G>,\n options: NeighborReadOptions<G, K>,\n ) => Promise<readonly NeighborResult<G, K>[]>;\n countNeighbors: <const K extends EdgeKinds<G>>(\n source: GraphNodeReference<G>,\n options: Omit<NeighborReadOptions<G, K>, \"limit\" | \"orderBy\">,\n ) => Promise<number>;\n subgraph: <\n const EK extends EdgeKinds<G>,\n const NK extends NodeKinds<G> = NodeKinds<G>,\n const P extends SubgraphProject<G, NK, EK> | undefined = undefined,\n >(\n rootId: NodeId<AllNodeTypes<G>>,\n options: SubgraphOptions<G, EK, NK, P>,\n ) => Promise<SubgraphResult<G, NK, EK, P>>;\n }>;\n\n/**\n * Requests a recorded revision even when a history transaction makes no entity\n * changes. Repeated requests are idempotent. Receipt-enabled transactions\n * expose the allocated instant on their terminal {@link TransactionReceipt},\n * after capture flushes.\n */\nexport type RecordedRevisionRequest = Readonly<{\n requestRecordedRevision: () => void;\n}>;\n\n/** The narrow, one-statement write envelope available only to recorded transactions. */\nexport type RecordedHeterogeneousNodeWriteBatch<G extends GraphDef> = Readonly<{\n writeNodeUpsertBatch: <\n const Entries extends readonly HeterogeneousNodeUpsertInput<G>[],\n >(\n entries: Entries,\n ) => Promise<HeterogeneousNodeUpsertResult<G, Entries>>;\n}>;\n\n/** A portable transaction context bound to a history-enabled Store. */\nexport type HistoryTransactionContext<G extends GraphDef> =\n TransactionContext<G> &\n RecordedRevisionRequest &\n RecordedHeterogeneousNodeWriteBatch<G>;\n\n/**\n * A transaction context exposed by an {@link AdapterStore}. In addition to the\n * portable graph collections, it carries the adapter-native handle when that\n * capability is available. The TypeGraph backend remains the same runtime\n * read projection as the portable context; adapter-native writes intentionally\n * go through `sql`, making that escape hatch explicit.\n */\nexport type AdapterTransactionContext<\n G extends GraphDef,\n TNativeTransaction,\n> = TransactionContext<G> & AdapterTransactionSqlAccess<TNativeTransaction>;\n\n/**\n * Scoped write measurement, available only on the receipt-enabled transaction\n * contexts (`transactionWithReceipt`, `withRecordedTransaction`). Runs `fn`,\n * passing it a **scoped context** — a second view over the same transaction — and\n * returns a {@link TransactionOutcome} whose receipt counts exactly the writes\n * made *through that scoped context* (`scoped.nodes` / `scoped.edges`).\n *\n * Attribution is by **which context you write through**, not by timing. A write\n * through the scoped context counts in both the scope and the outer receipt (it\n * happened in the transaction); a write through the outer `tx` during the scope\n * counts only in the outer receipt. This makes overlapping and concurrent\n * measures safe by construction — two scopes running under `Promise.all`, each\n * writing through its own scoped context, never cross-count. Nesting composes:\n * `scoped.measure(...)` opens a child scope that counts in itself, every\n * ancestor scope, and the outer receipt.\n *\n * Counts otherwise inherit {@link TransactionReceipt} (bulk by input length, a\n * rejected write counts 0). The returned receipt's `recorded` is **always\n * `undefined`**: the recorded commit instant is a per-transaction flush concern,\n * unknowable mid-transaction.\n */\nexport type ScopedMeasure<Context> = <T>(\n fn: (scoped: Context) => Promise<T>,\n) => Promise<TransactionOutcome<T>>;\n\n/**\n * A {@link TransactionContext} that also exposes {@link ScopedMeasure}. Only the\n * receipt-enabled entry points (`transactionWithReceipt`,\n * `withRecordedTransaction`) hand a callback this type; plain `transaction()`\n * contexts have no recorder and therefore no `measure`, keeping that path\n * zero-overhead. Assignable to {@link TransactionContext}, so a projector helper\n * typed `(tx: TransactionContext<G>) => ...` accepts a measurable context. The\n * scoped context handed to `measure` is itself measurable, so scopes nest.\n */\nexport type MeasurableTransactionContext<G extends GraphDef> =\n TransactionContext<G> &\n Readonly<{\n measure: ScopedMeasure<MeasurableTransactionContext<G>>;\n }>;\n\n/** Receipt-enabled transaction context for a history-enabled Store. */\nexport type MeasurableHistoryTransactionContext<G extends GraphDef> =\n HistoryTransactionContext<G> &\n Readonly<{\n measure: ScopedMeasure<MeasurableHistoryTransactionContext<G>>;\n }>;\n\n/** Receipt-enabled transaction context for an {@link AdapterStore}. */\nexport type MeasurableAdapterTransactionContext<\n G extends GraphDef,\n TNativeTransaction,\n> = AdapterTransactionContext<G, TNativeTransaction> &\n Readonly<{\n measure: ScopedMeasure<\n MeasurableAdapterTransactionContext<G, TNativeTransaction>\n >;\n }>;\n\n// ============================================================\n// Dynamic Collection Types (widened for runtime dispatch)\n// ============================================================\n\n/**\n * A node returned by a runtime string-keyed collection.\n *\n * Its nominal node-type brand proves the value passed through the dynamic\n * collection API while its properties remain runtime-schema-shaped.\n */\nexport type DynamicNode<K extends string = string> = Node<DynamicNodeType<K>>;\n\ndeclare const DYNAMIC_NODE_REFERENCE_BRAND: unique symbol;\n\n/** A nominal lightweight reference returned by runtime-aware identity reads. */\nexport type DynamicNodeReference<K extends string = string> = Readonly<{\n kind: DynamicNodeKind<K>;\n id: NodeId<DynamicNodeType<K>>;\n [DYNAMIC_NODE_REFERENCE_BRAND]: true;\n}>;\n\n/**\n * Replace branded `NodeId` / `EdgeId` with plain `string` in each\n * method's parameter list. Return types are preserved unchanged.\n *\n * Handles three shapes:\n * 1. Direct branded ID parameter → `string`\n * 2. `readonly NodeId[]` / `readonly EdgeId[]` → `readonly string[]`\n * 3. Branded IDs nested one level inside bulk-item object arrays\n */\ntype WidenBrandedIds<T> = {\n readonly [K in keyof T]: T[K] extends (...args: infer A) => infer R ?\n (...args: { [P in keyof A]: UnbrandParam<A[P]> }) => R\n : T[K];\n};\n\n/** Replace a branded ID with `string`, recursing one level into arrays. */\ntype UnbrandParam<T> =\n T extends NodeId<NodeType> ? string\n : T extends EdgeId<AnyEdgeType> ? string\n : T extends readonly NodeId<NodeType>[] ? readonly string[]\n : T extends readonly EdgeId<AnyEdgeType>[] ? readonly string[]\n : T extends readonly (infer Item extends Record<string, unknown>)[] ?\n readonly UnbrandRecord<Item>[]\n : T;\n\n/** Replace branded ID values in object properties (does not recurse into nested structures). */\ntype UnbrandRecord<T extends Record<string, unknown>> = {\n readonly [K in keyof T]: T[K] extends NodeId<NodeType> ? string\n : T[K] extends EdgeId<AnyEdgeType> ? string\n : T[K];\n};\n\n/**\n * A node collection with widened generics for runtime string-keyed access.\n *\n * This is the return type of `store.getNodeCollection(kind)`. It exposes\n * the full `NodeCollection` API but with a nominal `DynamicNodeType` and\n * `string` constraint names instead of the specific generic parameters, since\n * the concrete type is not known at compile time.\n *\n * ID parameters accept plain `string` instead of branded `NodeId<N>`, since\n * the dynamic path typically receives IDs from edge metadata, snapshots,\n * or external input where the brand is not available.\n */\nexport type DynamicNodeCollection<K extends string = string> = WidenBrandedIds<\n NodeCollection<DynamicNodeType<K>, string>\n>;\n\n/**\n * An edge collection with widened generics for runtime string-keyed access.\n *\n * This is the return type of `store.getEdgeCollection(kind)`. It exposes\n * the full `EdgeCollection` API but with `NodeType` endpoint types, since\n * the concrete from/to types are not known at compile time.\n *\n * ID parameters accept plain `string` instead of branded `EdgeId<E>`, since\n * the dynamic path typically receives IDs from edge metadata, snapshots,\n * or external input where the brand is not available.\n */\nexport type DynamicEdgeCollection<E extends AnyEdgeType = AnyEdgeType> = Omit<\n EdgeCollection<\n E,\n NodeType,\n NodeType,\n { from: NodeType; to: NodeType },\n string\n >,\n \"create\"\n> &\n Readonly<{\n /** Create with runtime-validated endpoints and schema-typed properties. */\n create: (\n from: NodeRef,\n to: NodeRef,\n ...args: EdgeCreateArguments<E>\n ) => Promise<Edge<E>>;\n }>;\n\n/** Runtime endpoint reads at a view's pinned coordinate; no writes or temporal overrides. */\nexport type DynamicStoreViewEdgeCollection<\n E extends AnyEdgeType = AnyEdgeType,\n> = Omit<StoreViewEdgeCollection<E>, \"getById\" | \"getByIds\"> &\n Readonly<{\n getById: (id: string) => Promise<Edge<E> | undefined>;\n getByIds: (\n ids: readonly string[],\n ) => Promise<readonly (Edge<E> | undefined)[]>;\n }>;\n\n/** A node collection narrowed by Store-issued runtime-kind evidence. */\nexport type RuntimeNodeCollection<T extends RuntimeNodeKind> = WidenBrandedIds<\n NodeCollection<RuntimeNodeTypeFor<T>, string>\n>;\n\n/** An edge collection narrowed by Store-issued runtime-kind evidence. */\nexport type RuntimeEdgeCollection<T extends RuntimeEdgeKind> =\n DynamicEdgeCollection<RuntimeEdgeTypeFor<T>>;\n\n/** One kind-grouped source input for a token-validated heterogeneous read. */\nexport type RuntimeBulkEdgeSourceGroup<T extends RuntimeNodeKind> =\n T extends RuntimeNodeKind ? Readonly<{ kind: T; ids: readonly string[] }>\n : never;\n\n/** A source reference narrowed to the node token that licensed it. */\nexport type RuntimeNodeReferenceFor<T extends RuntimeNodeKind> =\n T extends RuntimeNodeKind ?\n Readonly<{\n kind: T[\"kind\"];\n id: NodeId<RuntimeNodeTypeFor<T>>;\n }>\n : never;\n\n/** An edge value narrowed to the edge token that licensed its read. */\nexport type RuntimeEdgeFor<T extends RuntimeEdgeKind> =\n T extends RuntimeEdgeKind ? Edge<RuntimeEdgeTypeFor<T>, NodeType, NodeType>\n : never;\n\n/** Input for {@link Store.bulkFindRuntimeEdgesFrom}. */\nexport type BulkFindRuntimeEdgesFromParams<\n NT extends RuntimeNodeKind,\n ET extends RuntimeEdgeKind,\n> = Readonly<{\n sources: readonly RuntimeBulkEdgeSourceGroup<NT>[];\n edgeKinds: readonly ET[];\n}>;\n\n/** One source bucket returned by {@link Store.bulkFindRuntimeEdgesFrom}. */\nexport type BulkFindRuntimeEdgesFromResult<\n NT extends RuntimeNodeKind,\n ET extends RuntimeEdgeKind,\n> = Readonly<{\n source: RuntimeNodeReferenceFor<NT>;\n edges: readonly RuntimeEdgeFor<ET>[];\n}>;\n\n// ============================================================\n// Store Projection\n// ============================================================\n\n/**\n * A type-level projection of a store's surface onto a subset of its\n * node and edge collections.\n *\n * Node collections are projected with constraint names erased (`never`),\n * so constraint-based methods like `findByConstraint` become uncallable.\n * This is intentional: unique constraints are graph-registration-level\n * details that differ between graphs sharing the same node types.\n *\n * @example\n * ```typescript\n * type CoreStore = StoreProjection<\n * typeof myGraph,\n * \"Document\" | \"Chunk\",\n * \"hasChunk\"\n * >;\n *\n * async function ingestChunk(\n * store: CoreStore,\n * document: Node<typeof Document>,\n * text: string,\n * ) {\n * const chunk = await store.nodes.Chunk.create({ text });\n * await store.edges.hasChunk.create(document, chunk);\n * return chunk;\n * }\n * ```\n *\n * Both `Store<G>` and `TransactionContext<G>` are structurally assignable\n * to a `StoreProjection` whose keys are a subset of `G`.\n */\nexport type StoreProjection<\n G extends GraphDef,\n N extends keyof G[\"nodes\"] & string = never,\n E extends keyof G[\"edges\"] & string = never,\n> = Readonly<{\n nodes: { [K in N]-?: NodeCollection<G[\"nodes\"][K][\"type\"], never> };\n edges: Pick<GraphEdgeCollections<G>, E>;\n}>;\n","import { type UNIQUE_SIDECAR_BATCH } from \"../backend/capabilities/bundle-registry\";\nimport { type BundleVerdictOf } from \"../backend/capabilities/resolve\";\nimport {\n type BackendIdentity,\n type GraphBackend,\n type GraphEntityReadBackend,\n type QueryExecutionBackend,\n type RawQueryExecutionBackend,\n type SchemaReadBackend,\n type SqlCompilationBackend,\n type TransactionBackend,\n} from \"../backend/types\";\nimport {\n type AllNodeTypes,\n type EdgeKinds,\n type GraphDef,\n type NodeKinds,\n} from \"../core/define-graph\";\nimport { type ReadCoordinate } from \"../core/temporal\";\nimport {\n type AnyEdgeType,\n type EdgeId,\n type NodeId,\n type NodeType,\n} from \"../core/types\";\nimport { ConfigurationError } from \"../errors\";\nimport { type IdentityReadFacade } from \"../identity/types\";\nimport { type InitialQueryBuilder } from \"../query/builder\";\nimport type { EvolutionPlan } from \"../schema/evolution-plan\";\nimport { typeGraphGlobalSymbol } from \"../utils/global-symbol\";\nimport { requireDefined } from \"../utils/presence\";\nimport { type InternalGraphAlgorithms } from \"./algorithms\";\nimport type { Store } from \"./store\";\nimport {\n type InternalSubgraphOptions,\n type SubgraphProject,\n type SubgraphResult,\n} from \"./subgraph\";\nimport {\n type Edge,\n type Node,\n type RecordedScanOptions,\n type RecordedScanPage,\n TRANSACTION_RUNTIME,\n} from \"./types\";\n\nexport const STORE_RUNTIME: unique symbol =\n typeGraphGlobalSymbol(\"store-runtime-v1\");\n\n/**\n * @internal Operations used by Store-owned views. The port is absent from the\n * public Store contract and non-enumerable at runtime. JavaScript reflection\n * can still discover symbol properties, so this is an unsupported internal\n * surface rather than a security boundary.\n */\nexport type StoreRuntime<G extends GraphDef> = Readonly<{\n backend: GraphBackend;\n /** Constructs a plan-owned resulting-schema view for outside-transaction merge planning. */\n evolutionPlanningTarget?: (plan: EvolutionPlan) => Store<G>;\n /**\n * @internal Whether TypeGraph itself performs recorded-time capture for\n * this store — recorded relations, a TypeGraph clock, the write-fence/\n * schema-lock machinery capture needs. This is `Store`'s private\n * `#captureEnabled`, distinct from the public `historyEnabled` getter\n * (which answers \"was `history: true` requested,\" true under\n * engine-native ownership too, where the engine tracks history on its\n * own and none of the TypeGraph-relations machinery below runs). A reader\n * of a recorded relation's own columns — `recordedRelationsLineage`, the\n * trusted-import bypass refusal, a revision-anchor lineage delta, the\n * capture-only merge-transaction isolation choice — consults this member,\n * never the public getter, so it cannot be fooled by an engine-native\n * store into reading a recorded relation the engine never populates.\n *\n * Optional at this boundary for the same contravariant-reach reason as\n * `uniqueSidecarBatch` below: the one real producer (`store.ts`'s\n * constructor) always populates it, and a consumer asserts it with\n * {@link storeCaptureEnabled}.\n */\n captureEnabled?: boolean;\n /**\n * @internal The `uniqueSidecarBatch` bundle's verdict, resolved once at\n * store construction against `backend` (ruling B8 spec item 2) and exposed\n * here so a Store-owned view (provenance's fact close/reopen) can build a\n * {@link file://./claims/node-claims.ts NodeClaimContext} without re-minting\n * a second verdict for the same backend — the same reason `backend` itself\n * is exposed here rather than reconstructed.\n *\n * Optional at this boundary — a `StoreRuntime`-shaped value is a\n * contravariant (externally-authorable) position, so a new REQUIRED member\n * here would be a breaking change (`scripts/api-surface-compat.ts`).\n * Required after resolution instead, the same pattern\n * `CompileQueryOptions.recursiveTraversal` uses: the one real producer\n * (`store.ts`'s constructor) always populates it, and the one real\n * consumer (`provenance/index.ts`) asserts it with `requireDefined`.\n */\n uniqueSidecarBatch?: BundleVerdictOf<typeof UNIQUE_SIDECAR_BATCH> | undefined;\n /**\n * @internal The backend this Store's queries actually execute through for\n * `target` — the Store's own backend when `target` is omitted.\n *\n * It is the SAME private construction the query path uses rather than a\n * reconstruction of it, because the object it returns is the one a lost\n * derivation corrupts: the hooked query backend is a transient local inside\n * query construction that is stored nowhere, so no other handle on it exists\n * and a regression there is invisible to every assertion about\n * {@link StoreRuntime.backend}.\n *\n * NOTE for anything asserting on it: with no query hook configured this\n * returns its argument unchanged, so a hookless Store answers with the very\n * object it was handed and a comparison against that object is a tautology.\n */\n queryBackend: (target?: GraphBackend | TransactionBackend) => GraphBackend;\n sealedQuery: (coordinate: ReadCoordinate) => InitialQueryBuilder<G, \"sealed\">;\n recordedNodeGetById: <N extends NodeType>(\n kind: string,\n id: NodeId<N>,\n coordinate: ReadCoordinate,\n ) => Promise<Node<N> | undefined>;\n recordedNodeGetByIds: <N extends NodeType>(\n kind: string,\n ids: readonly NodeId<N>[],\n coordinate: ReadCoordinate,\n ) => Promise<readonly (Node<N> | undefined)[]>;\n recordedNodeScan: <N extends NodeType>(\n kind: string,\n coordinate: ReadCoordinate,\n options?: RecordedScanOptions,\n ) => Promise<RecordedScanPage<Node<N>>>;\n recordedEdgeGetById: <E extends AnyEdgeType>(\n kind: string,\n id: EdgeId<E>,\n coordinate: ReadCoordinate,\n ) => Promise<Edge<E> | undefined>;\n recordedEdgeGetByIds: <E extends AnyEdgeType>(\n kind: string,\n ids: readonly EdgeId<E>[],\n coordinate: ReadCoordinate,\n ) => Promise<readonly (Edge<E> | undefined)[]>;\n recordedEdgeScan: <E extends AnyEdgeType>(\n kind: string,\n coordinate: ReadCoordinate,\n options?: RecordedScanOptions,\n ) => Promise<RecordedScanPage<Edge<E>>>;\n subgraphAtCoordinate: <\n const EK extends EdgeKinds<G>,\n const NK extends NodeKinds<G> = NodeKinds<G>,\n const P extends SubgraphProject<G, NK, EK> | undefined = undefined,\n >(\n rootId: NodeId<AllNodeTypes<G>>,\n options: InternalSubgraphOptions<G, EK, NK, P>,\n ) => Promise<SubgraphResult<G, NK, EK, P>>;\n algorithmsAtCoordinate: (\n coordinate: ReadCoordinate,\n ) => InternalGraphAlgorithms<G>;\n identityAtCoordinate: (coordinate: ReadCoordinate) => IdentityReadFacade<G>;\n rebuildIdentityClosure: () => Promise<void>;\n validateIdentity: () => Promise<void>;\n /**\n * Validates one final resolved node write set, then clears the affected\n * nodes' claim rows so its upserts may take their approved keys in any order,\n * and re-takes the complete claim set once the writes have landed. The caller\n * must supply a transaction-bound backend.\n *\n * The clear is by OWNER, so it takes every claim the affected nodes hold —\n * uniqueness and `disjointWith` alike — and the rebuild therefore goes through\n * the same claim writer an ordinary create uses rather than a uniqueness-only\n * insert. See `store/claims/resolved-node-claims.ts`.\n */\n applyResolvedNodeUniqueness: <Output>(\n target: TransactionBackend,\n writes: Readonly<{\n upserts: readonly Readonly<{\n kind: string;\n id: string;\n props: Readonly<Record<string, unknown>>;\n }>[];\n releases: readonly Readonly<{ kind: string; id: string }>[];\n }>,\n apply: () => Promise<Output>,\n ) => Promise<Output>;\n /**\n * @internal Reads the graph's identity assertions in transfer shape, honoring\n * this store's SQL binding. Used by interchange export, base-version\n * fingerprinting, and merge staging/diff.\n */\n readCurrentIdentityAssertions: (\n mode: \"state\" | \"archival\",\n options?: Readonly<{\n nodeKinds?: readonly string[];\n includeDeleted?: boolean;\n }>,\n ) => Promise<\n readonly Readonly<{\n id: string;\n relation: \"same\" | \"different\";\n a: Readonly<{ kind: string; id: string }>;\n b: Readonly<{ kind: string; id: string }>;\n validFrom: string;\n validTo?: string | undefined;\n endedBy?: Readonly<{ kind: string; id: string }> | undefined;\n }>[]\n >;\n /**\n * Live nodes (registry kinds only) sharing any of the given bare ids —\n * the cross-kind peer set same-id folding would join. Used by graph-merge's\n * plan-time contradiction simulation to seed its node universe.\n */\n liveNodesSharingIds: (\n ids: readonly string[],\n target?: GraphBackend | TransactionBackend,\n ) => Promise<readonly Readonly<{ kind: string; id: string }>[]>;\n /**\n * Every stored assertion row (ended rows included) for the given assertion\n * ids — the rows the import coordinator's id-conflict check compares\n * against. Used by graph-merge to validate the one-id-one-truth invariant\n * at plan time and inside the commit transaction.\n */\n identityAssertionRowsByIds: (\n ids: readonly string[],\n target?: GraphBackend | TransactionBackend,\n ) => Promise<\n ReadonlyMap<\n string,\n Readonly<{\n id: string;\n relation: \"same\" | \"different\";\n a: Readonly<{ kind: string; id: string }>;\n b: Readonly<{ kind: string; id: string }>;\n validFrom: string;\n validTo?: string | undefined;\n endedBy?: Readonly<{ kind: string; id: string }> | undefined;\n }>\n >\n >;\n /**\n * The CURRENT structural identity class (materialized closure: folds plus\n * asserted links) of each reference, keyed by `refKey` — the\n * `JSON.stringify([kind, id])` serialization exported from\n * `identity/service`, which callers must use to probe the returned map. A\n * missing node coalesces to its singleton. Used by graph-merge's fold-peer\n * window guard to detect class-transitive drift in the plan→commit window.\n */\n structuralIdentityClasses: (\n references: readonly Readonly<{ kind: string; id: string }>[],\n target?: GraphBackend | TransactionBackend,\n ) => Promise<\n ReadonlyMap<string, readonly Readonly<{ kind: string; id: string }>[]>\n >;\n identityAssertionsAtTarget: (\n target: GraphBackend | TransactionBackend,\n mode?: \"state\" | \"archival\",\n ) => Promise<\n readonly Readonly<{\n id: string;\n relation: \"same\" | \"different\";\n a: Readonly<{ kind: string; id: string }>;\n b: Readonly<{ kind: string; id: string }>;\n validFrom: string;\n validTo?: string | undefined;\n endedBy?: Readonly<{ kind: string; id: string }> | undefined;\n }>[]\n >;\n readIdentityAssertionPageAtTarget: (\n target: GraphBackend | TransactionBackend,\n mode: \"state\" | \"archival\",\n options: Readonly<{\n nodeKinds?: readonly string[];\n includeDeleted?: boolean;\n after?: string;\n limit: number;\n }>,\n ) => Promise<\n Readonly<{\n assertions: readonly Readonly<{\n id: string;\n relation: \"same\" | \"different\";\n a: Readonly<{ kind: string; id: string }>;\n b: Readonly<{ kind: string; id: string }>;\n validFrom: string;\n validTo?: string | undefined;\n endedBy?: Readonly<{ kind: string; id: string }> | undefined;\n }>[];\n nextAfter?: string;\n done: boolean;\n }>\n >;\n lockIdentityImportTarget: (\n target: Readonly<\n BackendIdentity &\n GraphEntityReadBackend &\n SchemaReadBackend &\n QueryExecutionBackend &\n SqlCompilationBackend &\n RawQueryExecutionBackend &\n Pick<GraphBackend, \"executeStatement\">\n >,\n ) => Promise<void>;\n foldImportedIdentityNodes: (\n target: Readonly<\n BackendIdentity &\n GraphEntityReadBackend &\n SchemaReadBackend &\n QueryExecutionBackend &\n SqlCompilationBackend &\n RawQueryExecutionBackend &\n Pick<GraphBackend, \"executeStatement\">\n >,\n references: readonly Readonly<{ kind: string; id: string }>[],\n ) => Promise<void>;\n importIdentityAssertionsAtTarget: (\n target: Readonly<\n BackendIdentity &\n GraphEntityReadBackend &\n SchemaReadBackend &\n QueryExecutionBackend &\n SqlCompilationBackend &\n RawQueryExecutionBackend &\n Pick<GraphBackend, \"executeStatement\">\n >,\n assertions: readonly Readonly<{\n id: string;\n relation: \"same\" | \"different\";\n a: Readonly<{ kind: string; id: string }>;\n b: Readonly<{ kind: string; id: string }>;\n validFrom: string;\n validTo?: string | undefined;\n endedBy?: Readonly<{ kind: string; id: string }> | undefined;\n }>[],\n mode: \"state\" | \"archival\",\n ) => Promise<Readonly<{ created: number; skipped: number }>>;\n applyIdentityMergeAtTarget: (\n target: GraphBackend | TransactionBackend,\n retractions: readonly Readonly<{\n id: string;\n relation: \"same\" | \"different\";\n a: Readonly<{ kind: string; id: string }>;\n b: Readonly<{ kind: string; id: string }>;\n validFrom: string;\n validTo?: string | undefined;\n endedBy?: Readonly<{ kind: string; id: string }> | undefined;\n }>[],\n assertions: readonly Readonly<{\n id: string;\n relation: \"same\" | \"different\";\n a: Readonly<{ kind: string; id: string }>;\n b: Readonly<{ kind: string; id: string }>;\n validFrom: string;\n validTo?: string | undefined;\n endedBy?: Readonly<{ kind: string; id: string }> | undefined;\n }>[],\n ) => Promise<Readonly<{ created: number; retracted: number }>>;\n /**\n * Proves the identity classes of `seeds` carry no contradiction in the state\n * the caller's transaction has just written — the post-write half of\n * graph-merge's identity correctness, scoped to the classes the merge\n * touched. A refusal aborts the caller's transaction; identity-disabled\n * graphs resolve immediately.\n */\n assertIdentityClassesConsistentAtTarget: (\n target: GraphBackend | TransactionBackend,\n seeds: readonly Readonly<{ kind: string; id: string }>[],\n ) => Promise<void>;\n}>;\n\nexport function storeRuntime<G extends GraphDef>(\n store: Readonly<{ [STORE_RUNTIME]?: StoreRuntime<G> }>,\n): StoreRuntime<G> {\n const runtime = store[STORE_RUNTIME];\n if (runtime === undefined) {\n throw new TypeError(\n \"Cannot access this Store's runtime port. The Store may come from an incompatible TypeGraph version.\",\n );\n }\n return runtime;\n}\n\nexport function storeBackend<G extends GraphDef>(\n store: Readonly<{ [STORE_RUNTIME]?: StoreRuntime<G> }>,\n): GraphBackend {\n return storeRuntime(store).backend;\n}\n\n/**\n * Whether TypeGraph itself performs recorded-time capture for `store` — see\n * {@link StoreRuntime.captureEnabled}. Consult this, never the public\n * `historyEnabled` getter, when the decision at hand is specifically about\n * TypeGraph's own recorded relations (a reader of their columns, the\n * capture-only merge-transaction isolation choice, the trusted-import\n * bypass refusal): `historyEnabled` answers \"was `history: true`\n * requested,\" true for an engine-native store too, which never populates\n * those relations.\n */\nexport function storeCaptureEnabled<G extends GraphDef>(\n store: Readonly<{ [STORE_RUNTIME]?: StoreRuntime<G> }>,\n): boolean {\n return requireDefined(\n storeRuntime(store).captureEnabled,\n \"Cannot read this Store's capture flag. The Store may come from an incompatible TypeGraph version.\",\n );\n}\n\n/**\n * The backend a Store's queries execute through — see\n * {@link StoreRuntime.queryBackend}, including its note about hookless Stores.\n */\nexport function storeQueryBackend<G extends GraphDef>(\n store: Readonly<{ [STORE_RUNTIME]?: StoreRuntime<G> }>,\n target?: GraphBackend | TransactionBackend,\n): GraphBackend {\n return storeRuntime(store).queryBackend(target);\n}\n\ntype TransactionRuntimePort = Readonly<{\n [TRANSACTION_RUNTIME]?: Readonly<{\n backend: TransactionBackend;\n runNodeOperationHooks: TransactionNodeOperationHookRunner;\n }>;\n}>;\n\ntype TransactionNodeOperationHookRunner = <T>(\n operation: \"create\" | \"update\" | \"delete\",\n kind: string,\n id: string,\n fn: () => Promise<T>,\n) => Promise<T>;\n\nconst transactionStoreOwners = new WeakMap<object, object>();\nconst evolvedTransactionOriginalOwners = new WeakMap<object, object>();\nconst evolvedTransactionStores = new WeakMap<object, object>();\nconst activeTransactionContexts = new WeakSet<object>();\n\n/** Binds the hidden context port to the Store that created its collections. */\nexport function bindTransactionStore<G extends GraphDef>(\n transaction: TransactionRuntimePort,\n store: Readonly<{ [STORE_RUNTIME]?: StoreRuntime<G> }>,\n): void {\n const runtime = requireDefined(transaction[TRANSACTION_RUNTIME]);\n transactionStoreOwners.set(runtime, storeRuntime(store));\n}\n\n/** Binds an evolved callback to its original Store and temporary evolved view. */\nexport function bindEvolvedTransactionStore<TStore extends object>(\n transaction: TransactionRuntimePort,\n originalStore: TStore,\n evolvedStore: TStore,\n): void {\n const runtime = requireDefined(transaction[TRANSACTION_RUNTIME]);\n transactionStoreOwners.set(runtime, storeRuntime(evolvedStore));\n evolvedTransactionOriginalOwners.set(runtime, storeRuntime(originalStore));\n evolvedTransactionStores.set(runtime, evolvedStore);\n}\n\n/** Resolves the Store whose graph actually owns an active callback context. */\nexport function resolveEvolvedTransactionStore<TStore extends object>(\n transaction: TransactionRuntimePort,\n originalStore: TStore,\n): TStore {\n const runtime = transaction[TRANSACTION_RUNTIME];\n if (runtime === undefined || !activeTransactionContexts.has(runtime)) {\n throw new ConfigurationError(\n \"The merge transaction must belong to an active callback of the target Store.\",\n { capability: \"mergeTransactionStore\" },\n );\n }\n const originalRuntime = storeRuntime(originalStore);\n if (transactionStoreOwners.get(runtime) === originalRuntime) {\n return originalStore;\n }\n if (evolvedTransactionOriginalOwners.get(runtime) === originalRuntime) {\n const evolvedStore = evolvedTransactionStores.get(runtime);\n if (evolvedStore !== undefined) return evolvedStore as TStore;\n }\n throw new ConfigurationError(\n \"The merge transaction must belong to an active callback of the target Store.\",\n { capability: \"mergeTransactionStore\" },\n );\n}\n\n/** The callback boundary owns the lifetime of every measurable context overlay. */\nexport async function runInTransactionContext<\n T,\n Context extends TransactionRuntimePort,\n>(context: Context, fn: (context: Context) => Promise<T>): Promise<T> {\n const runtime = requireDefined(context[TRANSACTION_RUNTIME]);\n activeTransactionContexts.add(runtime);\n try {\n return await fn(context);\n } finally {\n activeTransactionContexts.delete(runtime);\n }\n}\n\n/** Returns the full backend for privileged transaction-bound internals. */\nexport function transactionBackend(\n transaction: TransactionRuntimePort,\n): TransactionBackend {\n const runtime = transaction[TRANSACTION_RUNTIME];\n if (runtime === undefined) {\n throw new TypeError(\n \"Cannot access this transaction's runtime port. The transaction may come from an incompatible TypeGraph version.\",\n );\n }\n return runtime.backend;\n}\n\n/** Returns the hook runner paired with a transaction's internal backend. */\nexport function transactionNodeOperationHookRunner(\n transaction: TransactionRuntimePort,\n): TransactionNodeOperationHookRunner {\n const runtime = transaction[TRANSACTION_RUNTIME];\n if (runtime === undefined) {\n throw new TypeError(\n \"Cannot access this transaction's runtime port. The transaction may come from an incompatible TypeGraph version.\",\n );\n }\n return runtime.runNodeOperationHooks;\n}\n","/**\n * Contextual Validation Utilities\n *\n * Provides Zod validation wrappers that include full context about\n * which entity (node/edge) and operation (create/update) failed.\n *\n * @example\n * ```typescript\n * const props = validateNodeProps(schema, input, {\n * kind: \"Person\",\n * operation: \"create\",\n * });\n * ```\n */\n\nimport { type ZodError, type ZodType } from \"zod\";\n\nimport type { KindEntity } from \"../core/types\";\nimport { ValidationError, type ValidationIssue } from \"./index\";\n\n// ============================================================\n// Types\n// ============================================================\n\n/**\n * Context for validation operations.\n */\nexport type ValidationContext = Readonly<{\n /** Type of entity being validated */\n entityType: KindEntity;\n /** Kind/type name of the entity */\n kind: string;\n /** Operation being performed */\n operation: \"create\" | \"update\";\n /** Entity ID (for updates) */\n id?: string;\n}>;\n\n// ============================================================\n// Validation Functions\n// ============================================================\n\n/**\n * Converts Zod issues to ValidationIssue format.\n */\nfunction zodIssuesToValidationIssues(error: ZodError): ValidationIssue[] {\n return error.issues.map((issue) => ({\n path: issue.path.join(\".\"),\n message: issue.message,\n code: issue.code,\n }));\n}\n\n/**\n * Builds a descriptive location string for error messages.\n */\nfunction buildLocationString(context: ValidationContext): string {\n if (context.id) {\n return `${context.kind}/${context.id}`;\n }\n return `new ${context.kind}`;\n}\n\n/**\n * Validates props with full context for error messages.\n *\n * @param schema - Zod schema to validate against\n * @param props - Properties to validate\n * @param context - Context about the entity and operation\n * @returns Validated and transformed props\n * @throws ValidationError with full context if validation fails\n *\n * @example\n * ```typescript\n * const validatedProps = validateProps(personSchema, input, {\n * entityType: \"node\",\n * kind: \"Person\",\n * operation: \"create\",\n * });\n * ```\n */\nexport function validateProps<T>(\n schema: ZodType<T>,\n props: unknown,\n context: ValidationContext,\n): T {\n const result = schema.safeParse(props);\n\n if (result.success) {\n return result.data;\n }\n\n const issues = zodIssuesToValidationIssues(result.error);\n const location = buildLocationString(context);\n\n throw new ValidationError(\n `Invalid ${context.entityType} props for ${location}: ${result.error.message}`,\n {\n entityType: context.entityType,\n kind: context.kind,\n operation: context.operation,\n ...(context.id !== undefined && { id: context.id }),\n issues,\n },\n { cause: result.error },\n );\n}\n\n/**\n * Validates node props with full context.\n *\n * Convenience wrapper around validateProps for node operations.\n *\n * @example\n * ```typescript\n * const props = validateNodeProps(schema, input, {\n * kind: \"Person\",\n * operation: \"create\",\n * });\n * ```\n */\nexport function validateNodeProps<T>(\n schema: ZodType<T>,\n props: unknown,\n context: Readonly<{\n kind: string;\n operation: \"create\" | \"update\";\n id?: string;\n }>,\n): T {\n return validateProps(schema, props, {\n entityType: \"node\",\n ...context,\n });\n}\n\n/**\n * Validates edge props with full context.\n *\n * Convenience wrapper around validateProps for edge operations.\n *\n * @example\n * ```typescript\n * const props = validateEdgeProps(schema, input, {\n * kind: \"worksAt\",\n * operation: \"create\",\n * });\n * ```\n */\nexport function validateEdgeProps<T>(\n schema: ZodType<T>,\n props: unknown,\n context: Readonly<{\n kind: string;\n operation: \"create\" | \"update\";\n id?: string;\n }>,\n): T {\n return validateProps(schema, props, {\n entityType: \"edge\",\n ...context,\n });\n}\n\n/**\n * Wraps a Zod error with TypeGraph context.\n *\n * Use this when you've already caught a ZodError and want to\n * convert it to a ValidationError with context.\n *\n * @example\n * ```typescript\n * try {\n * schema.parse(input);\n * } catch (error) {\n * if (error instanceof ZodError) {\n * throw wrapZodError(error, {\n * entityType: \"node\",\n * kind: \"Person\",\n * operation: \"create\",\n * });\n * }\n * throw error;\n * }\n * ```\n */\nexport function wrapZodError(\n error: ZodError,\n context: ValidationContext,\n): ValidationError {\n const issues = zodIssuesToValidationIssues(error);\n const location = buildLocationString(context);\n\n return new ValidationError(\n `Validation failed for ${context.entityType} ${location}: ${error.message}`,\n {\n entityType: context.entityType,\n kind: context.kind,\n operation: context.operation,\n ...(context.id !== undefined && { id: context.id }),\n issues,\n },\n { cause: error },\n );\n}\n\n/**\n * Creates a simple ValidationError without Zod context.\n *\n * Use this for custom validation rules that aren't part of a Zod schema.\n *\n * @example\n * ```typescript\n * if (startDate > endDate) {\n * throw createValidationError(\n * \"Start date must be before end date\",\n * [{ path: \"startDate\", message: \"Must be before endDate\" }],\n * { entityType: \"edge\", kind: \"employment\", operation: \"create\" }\n * );\n * }\n * ```\n */\nexport function createValidationError(\n message: string,\n issues: ValidationIssue[],\n context?: Partial<ValidationContext>,\n): ValidationError {\n return new ValidationError(message, {\n ...(context?.entityType !== undefined && {\n entityType: context.entityType,\n }),\n ...(context?.kind !== undefined && { kind: context.kind }),\n ...(context?.operation !== undefined && { operation: context.operation }),\n ...(context?.id !== undefined && { id: context.id }),\n issues,\n });\n}\n","import { nanoid } from \"nanoid\";\n\n/**\n * ID generation utilities.\n *\n * Default implementation uses nanoid.\n * Benefits:\n * - URL-safe\n * - Compact (21 characters by default)\n * - Secure random generation\n */\n\n/**\n * Generates a new unique ID.\n */\nexport function generateId(): string {\n return nanoid();\n}\n\n/**\n * ID generator function type.\n */\nexport type IdGenerator = () => string;\n\n/**\n * Default ID generator configuration.\n */\nexport type IdConfig = Readonly<{\n /** Generator for node IDs */\n nodeIdGenerator: IdGenerator;\n /** Generator for edge IDs */\n edgeIdGenerator: IdGenerator;\n}>;\n","import {\n batchRefusalDetails,\n batchRefusalSuffix,\n resolveBatchWriteVerdict,\n} from \"../../backend/capabilities/batch-write-verdict\";\nimport {\n recordedRevisionOriginsVerdict,\n statementExecutionVerdict,\n} from \"../../backend/capabilities/resolve\";\nimport {\n refuseFenceSqlSessionFactUnavailable,\n resolveFenceStatements,\n} from \"../../backend/capabilities/write-fence\";\nimport { normalizeGraphCommandIsolation } from \"../../backend/command-contract\";\nimport {\n type GraphBackend,\n type TransactionBackend,\n type TransactionOptions,\n} from \"../../backend/types\";\nimport {\n ConfigurationError,\n type RecordedCaptureGuardCode,\n} from \"../../errors\";\nimport { createSqlSchema, type SqlSchema } from \"../../query/compiler/schema\";\nimport type { SqlDialect } from \"../../query/dialect/types\";\nimport { type SqlFragment } from \"../../query/sql-fragment\";\nimport {\n asCompiledRowsSql,\n asCompiledStatementSql,\n type CompiledStatementSql,\n} from \"../../query/sql-intent\";\nexport { withRecordedRelationsPrecondition } from \"../../utils/sql-errors\";\n\ntype IsolationRow = Readonly<{ transaction_isolation: unknown }>;\n\nconst RECORDED_ISOLATION_REQUIRES_POSTGRES_CHECK = {\n postgres: true,\n sqlite: false,\n} as const satisfies Record<SqlDialect, boolean>;\n\n/**\n * Resolves the recorded-relation schema for a capture target, failing loud when\n * the backend does not expose `tableNames`. Without this guard a custom backend\n * that omits `tableNames` would silently fall back to {@link createSqlSchema}'s\n * defaults and write/close recorded rows against the wrong tables.\n */\nexport function requireRecordedSchema(\n target: Pick<GraphBackend, \"tableNames\" | \"dialect\">,\n): SqlSchema {\n if (target.tableNames === undefined) {\n throw new ConfigurationError(\n \"Recorded-time capture requires the backend to expose tableNames.\",\n { dialect: target.dialect },\n {\n suggestion:\n \"Use a built-in SQLite/PostgreSQL backend, or set tableNames on the custom backend so recorded-time capture targets the configured relations.\",\n },\n );\n }\n return createSqlSchema(target.tableNames);\n}\n\n/**\n * Asserts the transaction target can run capture's non-row-returning\n * statements. Checked once when a capture scope opens so the failure surfaces\n * before any write, not mid-flush after the live row is already written —\n * `assertCapturableBackend` only validates the outer backend, and a custom\n * backend's transaction target can differ from it.\n */\nexport function requireCaptureStatements(\n target: Pick<GraphBackend, \"dialect\" | \"executeStatement\">,\n): asserts target is Pick<GraphBackend, \"dialect\" | \"executeStatement\"> &\n Readonly<{\n executeStatement: NonNullable<GraphBackend[\"executeStatement\"]>;\n }> {\n if (target.executeStatement === undefined) {\n throw new ConfigurationError(\n \"Recorded-time capture requires backend.executeStatement support on the transaction backend.\",\n { dialect: target.dialect },\n {\n suggestion:\n \"Use the built-in SQLite/PostgreSQL backends or provide executeStatement on the custom backend's transaction target.\",\n },\n );\n }\n}\n\nexport async function executeStatement(\n target: Pick<GraphBackend, \"dialect\" | \"executeStatement\">,\n query: SqlFragment,\n): Promise<void> {\n requireCaptureStatements(target);\n await target.executeStatement(asCompiledStatementSql(query));\n}\n\nfunction unsupportedPostgresIsolationError(\n isolationLevel: string | undefined,\n): ConfigurationError {\n return new ConfigurationError(\n \"Recorded-time capture on PostgreSQL requires read_committed isolation.\",\n { isolationLevel: isolationLevel ?? \"unknown\" },\n {\n suggestion:\n \"Omit the transaction isolation option or use read_committed. PostgreSQL repeatable_read/serializable snapshots cannot safely allocate the per-graph recorded clock inside the captured transaction.\",\n },\n );\n}\n\nfunction isSupportedRecordedIsolationLevel(\n isolationLevel: string | undefined,\n): boolean {\n return (\n isolationLevel === undefined ||\n isolationLevel === \"read_committed\" ||\n isolationLevel === \"read_uncommitted\"\n );\n}\n\nexport function assertRequestedRecordedIsolation(\n backend: Pick<GraphBackend, \"dialect\">,\n options: TransactionOptions | undefined,\n): void {\n if (!RECORDED_ISOLATION_REQUIRES_POSTGRES_CHECK[backend.dialect]) return;\n if (options?.accessMode === \"read_only\") return;\n const isolationLevel = options?.isolationLevel;\n if (isSupportedRecordedIsolationLevel(isolationLevel)) return;\n\n throw unsupportedPostgresIsolationError(isolationLevel);\n}\n\nexport async function assertRecordedCaptureTransactionIsolation(\n target: Pick<TransactionBackend, \"dialect\" | \"execute\" | \"fenceSql\">,\n options?: TransactionOptions,\n): Promise<void> {\n if (!RECORDED_ISOLATION_REQUIRES_POSTGRES_CHECK[target.dialect]) return;\n if (options?.accessMode === \"read_only\") return;\n\n // This check is gated purely on `dialect`, not on a resolved write-fence\n // plan (it runs whether or not history capture takes a lock at all), so it\n // cannot resolve a `WriteFencePlan` to read the isolation fact through —\n // it derives the standalone `isolationFact` statement from the target's\n // OWN `fenceSql` directly instead, via `resolveFenceStatements`. A\n // PostgreSQL target that declares no `fenceSql` gets a typed refusal\n // naming the session-fact read it cannot spell, rather than having the\n // bundled spelling substituted under it or being told to fix a lock\n // declaration this path never consults.\n if (target.fenceSql === undefined) {\n refuseFenceSqlSessionFactUnavailable(target.dialect);\n }\n const rows = await target.execute<IsolationRow>(\n asCompiledRowsSql(resolveFenceStatements(target.fenceSql).isolationFact()),\n );\n const isolationLevel = normalizeGraphCommandIsolation(\n rows[0]?.transaction_isolation,\n );\n if (isolationLevel === \"read_committed\") return;\n\n throw unsupportedPostgresIsolationError(isolationLevel);\n}\n\n/**\n * The single error raised when a caller tries to adopt a context-returning\n * external transaction while history capture is on — there is no flush point\n * before the caller commits. The branchable `details.code` is set here so no\n * call site can omit it; any extra `details` merge underneath it.\n */\nexport function recordedCaptureRequiresCallbackTransactionError(\n details: Record<string, unknown> = {},\n): ConfigurationError {\n return new ConfigurationError(\n \"withTransaction() has no recorded-time capture flush point when history is enabled.\",\n {\n ...details,\n code: \"RECORDED_CAPTURE_REQUIRES_CALLBACK_TRANSACTION\" satisfies RecordedCaptureGuardCode,\n },\n {\n suggestion:\n \"Use store.withRecordedTransaction(externalTx, async (tx) => ...) so TypeGraph can flush capture before the caller commits.\",\n },\n );\n}\n\n/**\n * Raw SQL surfaces (`tx.sql`, `backend.executeStatement`) write relational rows\n * without advancing recorded-time capture, so they are disabled on a\n * history-enabled store. `surface` names the escape the caller reached for.\n */\nfunction historyUnsafeRawWriteError(surface: string): ConfigurationError {\n return new ConfigurationError(\n `${surface} is not available when history capture is enabled because raw SQL writes bypass recorded-time capture.`,\n {\n code: \"RECORDED_CAPTURE_RAW_SQL_DISABLED\" satisfies RecordedCaptureGuardCode,\n },\n {\n suggestion:\n \"Run graph writes through store.nodes/store.edges (or tx.nodes/tx.edges inside a transaction), or perform raw relational writes outside a history-enabled TypeGraph store.\",\n },\n );\n}\n\nfunction revisionTrackingUnsafeRawWriteError(\n surface: string,\n): ConfigurationError {\n return new ConfigurationError(\n `${surface} is not available when revision tracking is enabled because raw SQL writes bypass the revision anchor.`,\n {\n code: \"REVISION_TRACKING_RAW_SQL_DISABLED\" satisfies RecordedCaptureGuardCode,\n },\n {\n suggestion:\n \"Run graph writes through store.nodes/store.edges (or tx.nodes/tx.edges inside a transaction), so TypeGraph can advance the revision anchor.\",\n },\n );\n}\n\nexport function throwHistoryUnsafeSqlAccess(): never {\n throw historyUnsafeRawWriteError(\"tx.sql\");\n}\n\nexport function throwRevisionTrackingUnsafeSqlAccess(): never {\n throw revisionTrackingUnsafeRawWriteError(\"tx.sql\");\n}\n\n/**\n * Disables the raw, non-row-returning write escapes on a history-enabled\n * backend: `executeStatement` and `executeDdl` both return `Promise<void>` and\n * exist solely to run relational writes/DDL that would bypass recorded-time\n * capture. The row-returning raw read path (`executeRaw`, the prepared-query\n * fast path) and `execute` are left intact — they are read contracts, treated\n * identically, and must not be used to route writes (e.g. `DELETE ...\n * RETURNING`); that invariant is documented, not policed by inspecting SQL text.\n */\nexport function rawWriteGuards(\n target: Pick<GraphBackend, \"executeStatement\" | \"executeDdl\">,\n prefix: string,\n): Pick<Partial<GraphBackend>, \"executeStatement\" | \"executeDdl\"> {\n return {\n ...(target.executeStatement === undefined ?\n {}\n : {\n executeStatement(_query: CompiledStatementSql): Promise<void> {\n return Promise.reject(\n historyUnsafeRawWriteError(`${prefix}.executeStatement`),\n );\n },\n }),\n ...(target.executeDdl === undefined ?\n {}\n : {\n executeDdl(_ddl: string): Promise<void> {\n return Promise.reject(\n historyUnsafeRawWriteError(`${prefix}.executeDdl`),\n );\n },\n }),\n };\n}\n\n/**\n * Defense-in-depth on the non-interactive branch: `Store`'s constructor\n * already routes `history: true` through `#revisionTrackingEnabled` and\n * calls {@link assertRevisionTrackableBackend} — which refuses a batch-tier\n * backend first — before it ever reaches {@link createRecordedBackend} (and\n * so this gate). It stays here, re-checked with the same verdict, for any\n * caller of `createRecordedBackend` that does not go through that\n * constructor path.\n */\nexport function assertCapturableBackend(backend: GraphBackend): void {\n if (!backend.capabilities.execution.interactiveTransactions) {\n const verdict = resolveBatchWriteVerdict(backend, { needs: \"history\" });\n throw new ConfigurationError(\n \"history: true requires a backend with transaction support.\" +\n batchRefusalSuffix(verdict),\n {\n dialect: backend.dialect,\n ...batchRefusalDetails(verdict),\n },\n {\n suggestion:\n \"Use a transactional SQLite/PostgreSQL backend or disable recorded-time capture for this store.\",\n },\n );\n }\n if (!statementExecutionVerdict(backend).supported) {\n throw new ConfigurationError(\n \"history: true requires a backend that supports executeStatement.\",\n { dialect: backend.dialect },\n {\n suggestion:\n \"Use a built-in SQLite/PostgreSQL backend, or implement executeStatement on the custom backend so recorded-time capture can write history rows.\",\n },\n );\n }\n if (backend.capabilities.returning === false) {\n throw new ConfigurationError(\n \"history: true requires a backend that supports UPDATE … RETURNING.\",\n { dialect: backend.dialect },\n {\n suggestion:\n \"Use a built-in SQLite/PostgreSQL backend, or run recorded-time capture on a backend whose engine supports UPDATE … RETURNING — capture closes recorded intervals with a RETURNING statement on its hot path.\",\n },\n );\n }\n if (backend.tableNames === undefined) {\n throw new ConfigurationError(\n \"history: true requires a backend that exposes tableNames.\",\n { dialect: backend.dialect },\n {\n suggestion:\n \"Use a built-in SQLite/PostgreSQL backend, or set tableNames on the custom backend so recorded-time capture can resolve the recorded relations instead of silently falling back to defaults.\",\n },\n );\n }\n}\n\n/**\n * Verifies the narrower backend contract for live-store revision tracking.\n * Unlike recorded-time history, a revision anchor does not capture after-images\n * and therefore does not require `UPDATE … RETURNING`.\n */\nexport function assertRevisionTrackableBackend(backend: GraphBackend): void {\n if (!backend.capabilities.execution.interactiveTransactions) {\n const verdict = resolveBatchWriteVerdict(backend, { needs: \"history\" });\n throw new ConfigurationError(\n \"revisionTracking: true requires a backend with transaction support.\" +\n batchRefusalSuffix(verdict),\n {\n dialect: backend.dialect,\n ...batchRefusalDetails(verdict),\n },\n {\n suggestion:\n \"Use a transactional SQLite/PostgreSQL backend or leave revision tracking disabled.\",\n },\n );\n }\n if (!statementExecutionVerdict(backend).supported) {\n throw new ConfigurationError(\n \"revisionTracking: true requires a backend that supports executeStatement.\",\n { dialect: backend.dialect },\n {\n suggestion:\n \"Use a built-in SQLite/PostgreSQL backend, or implement executeStatement so TypeGraph can advance the revision clock.\",\n },\n );\n }\n if (backend.tableNames === undefined) {\n throw new ConfigurationError(\n \"revisionTracking: true requires a backend that exposes tableNames.\",\n { dialect: backend.dialect },\n {\n suggestion:\n \"Use a built-in SQLite/PostgreSQL backend, or set tableNames so TypeGraph can address the revision clock relation.\",\n },\n );\n }\n if (!recordedRevisionOriginsVerdict(backend).supported) {\n throw new ConfigurationError(\n \"revisionTracking: true requires a backend that can bootstrap revision origins.\",\n { dialect: backend.dialect },\n {\n suggestion:\n \"Use a built-in SQLite/PostgreSQL backend, or implement ensureRevisionOriginsTable so TypeGraph can durably namespace revision anchors.\",\n },\n );\n }\n}\n","import { RECORDED_GRAPH_WRITE_ADVISORY_LOCK_NAMESPACE } from \"../../backend/advisory-lock-namespaces\";\nimport { recordedRevisionOriginsMembers } from \"../../backend/capabilities/bind\";\nimport { type RECORDED_REVISION_ORIGINS } from \"../../backend/capabilities/bundle-registry\";\nimport { type BundleVerdictOf } from \"../../backend/capabilities/resolve\";\nimport {\n type FenceStatements,\n requireWriteFence,\n resolveFenceStatements,\n resolveWriteFencePlan,\n} from \"../../backend/capabilities/write-fence\";\nimport {\n mintGraphCommandCoordination,\n normalizeGraphCommandIsolation,\n} from \"../../backend/command-contract\";\nimport { postgresFenceSql } from \"../../backend/drizzle/postgres-fence-sql\";\nimport type {\n GraphBackend,\n GraphCommandCoordination,\n GraphCommandIsolation,\n} from \"../../backend/types\";\nimport {\n createRecordedInstant,\n parseRecordedInstant,\n RECORDED_MAX_REVISION,\n type RecordedInstant,\n} from \"../../core/temporal\";\nimport { ConfigurationError } from \"../../errors\";\nimport { type SqlSchema } from \"../../query/compiler/schema\";\nimport { sql, type SqlFragment } from \"../../query/sql-fragment\";\nimport { asCompiledRowsSql } from \"../../query/sql-intent\";\nimport { canonicalizeDatabaseTimestamp, nowIso } from \"../../utils/date\";\nimport { generateId } from \"../../utils/id\";\nimport { executeStatement } from \"./guards\";\n\ntype ClockRow = Readonly<{ recorded_at: unknown; revision: unknown }>;\ntype RecordedClockParts = Readonly<{ recordedAt: string; revision: number }>;\nexport type AllocatedRecordedCommit = RecordedClockParts &\n Readonly<{ instant: string }>;\ntype RevisionOriginRow = Readonly<{ origin: unknown }>;\n\ntype RecordedClockBackend = Pick<\n GraphBackend,\n \"capabilities\" | \"dialect\" | \"execute\" | \"executeStatement\"\n>;\n\ntype RevisionOriginBackend = Pick<\n GraphBackend,\n \"dialect\" | \"ensureRevisionOriginsTable\" | \"execute\" | \"executeStatement\"\n>;\n\n/**\n * Floor sentinel used only to seed-and-lock a graph's clock row before the\n * read/advance/write sequence on SQLite-family backends. Always overwritten by\n * the real commit within the same transaction. Revision zero is reserved for\n * this internal row and is never exposed as a valid recorded instant.\n */\nconst RECORDED_MIN_REVISION = 0;\nconst RECORDED_MIN_TIME = \"1970-01-01T00:00:00.000Z\";\nconst RECORDED_CLOCK_ADVISORY_LOCK_NAMESPACE = \"typegraph:recorded-clock\";\n\n/**\n * `resolveFenceStatements(postgresFenceSql)`, hoisted once: the bundled\n * PostgreSQL spelling's derived standalone-statement forms, for the two\n * functions below that render this module's advisory locks' actual SQL text\n * for a caller that needs it directly rather than through a resolved plan —\n * a test driving a raw connection, or a competing manual lock.\n */\nconst postgresFenceStatements = resolveFenceStatements(postgresFenceSql);\n\n/**\n * Renders the bundled PostgreSQL spelling of this module's two advisory\n * locks, for a caller that needs the actual SQL text rather than a resolved\n * plan — a test driving a raw connection, or a competing manual lock. The\n * lock SITES themselves (`lockRecordedClock`, `acquireRecordedGraphWriteLock`)\n * never call these: they consume `fence.sql.*` from their own resolved\n * {@link resolveWriteFencePlan}, so a backend with a different lock spelling\n * is honored instead of overridden by this module's PostgreSQL default.\n *\n * Keep lock namespaces tied to acquire order, not to feature names:\n *\n * - recorded graph writes take `typegraph:recorded-graph-write` before any row\n * reads/writes that can affect graph state;\n * - recorded-clock allocation takes `typegraph:recorded-clock` late, at flush,\n * after the live writes have already happened.\n *\n * Sharing one key across those two acquire-order positions creates a circular\n * wait under ordinary concurrent load.\n */\nexport function recordedClockAdvisoryLockSql(graphId: string): SqlFragment {\n return postgresFenceStatements.acquireKeyed(\n RECORDED_CLOCK_ADVISORY_LOCK_NAMESPACE,\n graphId,\n );\n}\n\nexport function recordedGraphWriteAdvisoryLockSql(\n graphId: string,\n): SqlFragment {\n return postgresFenceStatements.acquireKeyedWithIsolation(\n RECORDED_GRAPH_WRITE_ADVISORY_LOCK_NAMESPACE,\n graphId,\n );\n}\n\n/**\n * Compile-time evidence that the per-graph write-lock discipline was\n * satisfied BEFORE any row work in the current transaction — either the\n * advisory lock was actually acquired ({@link lockRecordedGraphWrite}, on a\n * capture-enabled Postgres store) or the store provably needs no lock\n * ({@link uncapturedGraphWriteLock}). Functions that perform captured row\n * writes (the node write pipeline) require this token as a parameter, so\n * \"sidecar write before lock\" is a compile error rather than a lock-order\n * inversion found in review.\n */\ndeclare const GRAPH_WRITE_LOCK_BRAND: unique symbol;\n\nexport type GraphWriteLock = Readonly<{\n [GRAPH_WRITE_LOCK_BRAND]: true;\n coordination: GraphCommandCoordination | undefined;\n}>;\n\nconst UNCOORDINATED_GRAPH_WRITE_LOCK = Object.freeze({\n coordination: undefined,\n}) as GraphWriteLock;\n\nfunction acquiredGraphWriteLock(\n target: Pick<GraphBackend, \"commands\">,\n graphId: string,\n isolation: GraphCommandIsolation,\n): GraphWriteLock {\n return Object.freeze({\n coordination: mintGraphCommandCoordination(\n target.commands,\n graphId,\n isolation,\n ),\n }) as GraphWriteLock;\n}\n\n/** Record an advisory lock acquired by a combined backend primitive. */\nexport function acquiredGraphWriteLockFromCombinedFence(\n target: Pick<GraphBackend, \"commands\">,\n graphId: string,\n isolation: GraphCommandIsolation,\n): GraphWriteLock {\n return acquiredGraphWriteLock(target, graphId, isolation);\n}\n\n/**\n * Evidence constructor for stores WITHOUT history capture, where no\n * advisory lock exists to acquire. Calling this is an explicit claim that\n * the target store is not capture-enabled — do not use it to skip the lock\n * on a history store.\n */\nexport function uncapturedGraphWriteLock(): GraphWriteLock {\n return UNCOORDINATED_GRAPH_WRITE_LOCK;\n}\n\n/**\n * Per-transaction memo of graphs whose advisory lock is already held.\n *\n * `pg_advisory_xact_lock` is reentrant and held until the top-level\n * transaction ends, so re-acquiring it on every captured write inside one\n * transaction is pure round-trip churn — a multi-write transaction paid one\n * lock round trip per write. The capture layer registers its per-transaction\n * backend here; every lock path that receives that backend (the capture\n * delegate's own writes, `runInWriteTransaction`, provenance) then skips the\n * `SqlFragment` once the graph's lock is held.\n *\n * Keyed weakly by the backend object: the delegate is created per transaction,\n * so memo lifetime equals lock lifetime. The recorded savepoint coordinator\n * checkpoints and restores this memo with captured touches; manual savepoints\n * remain outside the capture contract.\n *\n * Single-flight per graph: the memo stores the IN-FLIGHT acquisition\n * promise, not just completed acquisitions, so concurrent same-transaction\n * writers (`Promise.all` over captured writes) coalesce onto one advisory\n * round trip instead of racing past an empty resolved-set. A rejected\n * acquisition evicts its entry so a retry is not poisoned (in practice a\n * failed statement has aborted the Postgres transaction anyway).\n */\nexport type RecordedGraphLockMemo = Map<string, Promise<GraphCommandIsolation>>;\n\nexport function createRecordedGraphLockMemo(): RecordedGraphLockMemo {\n return new Map();\n}\n\nconst recordedGraphLockMemos = new WeakMap<object, RecordedGraphLockMemo>();\n/**\n * Seeds the registered single-flight memo after another statement acquired the\n * same transaction-scoped graph lock.\n *\n * The combined schema/graph fence is the only caller: it invokes this only\n * after its statement succeeds. An existing entry is never replaced — it may\n * be an in-flight acquisition whose rejection must retain the ordinary\n * eviction/error semantics.\n */\nexport function memoizeAcquiredRecordedGraphWriteLock(\n backend: object,\n graphId: string,\n isolation: GraphCommandIsolation,\n): void {\n const memo = recordedGraphLockMemos.get(backend);\n if (memo === undefined || memo.has(graphId)) return;\n memo.set(graphId, Promise.resolve(isolation));\n}\n\nexport function registerRecordedGraphLockMemo(\n backend: object,\n memo: RecordedGraphLockMemo,\n): void {\n recordedGraphLockMemos.set(backend, memo);\n}\n\nasync function acquireRecordedGraphWriteLock(\n target: Pick<GraphBackend, \"execute\">,\n fenceSql: FenceStatements,\n graphId: string,\n): Promise<GraphCommandIsolation> {\n const rows = await target.execute<\n Readonly<{ transaction_isolation: unknown }>\n >(\n asCompiledRowsSql(\n fenceSql.acquireKeyedWithIsolation(\n RECORDED_GRAPH_WRITE_ADVISORY_LOCK_NAMESPACE,\n graphId,\n ),\n ),\n );\n return normalizeGraphCommandIsolation(rows[0]?.transaction_isolation);\n}\n\nexport async function lockRecordedGraphWrite(\n target: Pick<\n GraphBackend,\n \"capabilities\" | \"commands\" | \"dialect\" | \"execute\"\n >,\n graphId: string,\n memo?: RecordedGraphLockMemo,\n): Promise<GraphWriteLock> {\n const plan = resolveWriteFencePlan(target);\n const fence = requireWriteFence(plan, \"recorded graph write\", \"keyed\");\n switch (fence.kind) {\n case \"engine-serialized\":\n case \"caller-serialized\": {\n // A writer slot — or, under `caller-serialized`, the deployment's own\n // serialization promise — can serialize ordinary row work, but\n // neither is an advisory acquisition bound to this graph/port. It\n // cannot authorize the PostgreSQL convergence command.\n return uncapturedGraphWriteLock();\n }\n case \"lock\":\n case \"row\": {\n break;\n }\n default: {\n fence satisfies never;\n }\n }\n const effectiveMemo = memo ?? recordedGraphLockMemos.get(target);\n if (effectiveMemo === undefined) {\n const isolation = await acquireRecordedGraphWriteLock(\n target,\n fence.sql,\n graphId,\n );\n return acquiredGraphWriteLock(target, graphId, isolation);\n }\n let pending = effectiveMemo.get(graphId);\n if (pending === undefined) {\n pending = acquireRecordedGraphWriteLock(target, fence.sql, graphId).catch(\n (error: unknown) => {\n effectiveMemo.delete(graphId);\n throw error;\n },\n );\n effectiveMemo.set(graphId, pending);\n }\n const isolation = await pending;\n return acquiredGraphWriteLock(target, graphId, isolation);\n}\n\nfunction failInvalidClock(value: unknown, cause?: unknown): never {\n throw new ConfigurationError(\n \"Recorded clock row contained an invalid revision or wall time\",\n { value },\n {\n cause,\n suggestion:\n \"Run migrateLegacyRecordedTime() before using recorded-time tables created by the timestamp-only preview schema.\",\n },\n );\n}\n\nfunction recordedClockRevision(value: unknown): number {\n const revision =\n typeof value === \"bigint\" ? Number(value)\n : typeof value === \"string\" && /^\\d+$/.test(value) ? Number(value)\n : value;\n if (\n typeof revision !== \"number\" ||\n !Number.isSafeInteger(revision) ||\n revision < RECORDED_MIN_REVISION ||\n revision >= RECORDED_MAX_REVISION\n ) {\n return failInvalidClock(value);\n }\n return revision;\n}\n\nfunction recordedClockWallTime(value: unknown): string {\n return canonicalizeDatabaseTimestamp(value) ?? failInvalidClock(value);\n}\n\nfunction recordedClockParts(row: ClockRow): RecordedClockParts | undefined {\n const revision = recordedClockRevision(row.revision);\n if (revision === RECORDED_MIN_REVISION) return undefined;\n return { revision, recordedAt: recordedClockWallTime(row.recorded_at) };\n}\n\nfunction nextRecordedCommitParts(\n previous: RecordedClockParts | undefined,\n): RecordedClockParts {\n const wallTime = nowIso();\n if (previous === undefined) {\n return { revision: 1, recordedAt: wallTime };\n }\n\n return {\n revision: previous.revision + 1,\n // Keep diagonal replay cumulative across backward clock corrections without\n // manufacturing a new millisecond for same-ms commits. Throughput can make\n // this component repeat, never run ahead of the greatest observed wall time.\n recordedAt: nonDecreasingWallTime(wallTime, previous.recordedAt),\n };\n}\n\nfunction nonDecreasingWallTime(current: string, previous: string): string {\n if (current < previous) return previous;\n return current;\n}\n\n/**\n * Reads the recorded-time high-water mark for a graph — the latest committed\n * recorded instant. Exported so {@link Store.recordedNow} can hand callers a\n * deterministic `asOfRecorded` anchor. Accepts any read-capable backend or\n * transaction.\n */\nexport async function readRecordedClock(\n target: Pick<GraphBackend, \"execute\">,\n schema: SqlSchema,\n graphId: string,\n): Promise<RecordedInstant | undefined> {\n const parts = await readRecordedClockParts(target, schema, graphId);\n return parts === undefined ? undefined : (\n createRecordedInstant(parts.revision, parts.recordedAt)\n );\n}\n\nasync function readRecordedClockParts(\n target: Pick<GraphBackend, \"execute\">,\n schema: SqlSchema,\n graphId: string,\n): Promise<RecordedClockParts | undefined> {\n const rows = await target.execute<ClockRow>(\n asCompiledRowsSql(sql`\n SELECT revision, recorded_at\n FROM ${schema.recordedClockTable}\n WHERE graph_id = ${graphId}\n `),\n );\n const row = rows[0];\n return row === undefined ? undefined : recordedClockParts(row);\n}\n\n/**\n * Reads the durable, random origin assigned to one graph's revision clock.\n * The origin namespaces an otherwise graph-local revision anchor, so a\n * branch cannot mistake another store's coincident clock value for its base.\n */\nexport async function readRevisionOrigin(\n target: Pick<GraphBackend, \"execute\">,\n schema: SqlSchema,\n graphId: string,\n): Promise<string | undefined> {\n const rows = await target.execute<RevisionOriginRow>(\n asCompiledRowsSql(sql`\n SELECT origin\n FROM ${schema.revisionOriginsTable}\n WHERE graph_id = ${graphId}\n `),\n );\n const first = rows[0];\n if (first === undefined) return undefined;\n if (typeof first.origin !== \"string\" || first.origin.length === 0) {\n throw new ConfigurationError(\n \"Revision origin row contained an invalid origin\",\n { graphId, origin: first.origin },\n );\n }\n return first.origin;\n}\n\n/**\n * Ensures the origins relation exists and refuses a backend that cannot\n * bootstrap it. Runs the same `ensureRevisionOriginsTable` DDL member\n * {@link ensureRevisionOrigin} bootstraps from — exported separately (rather\n * than folded into a single ensure-and-write call) because that member is a\n * schema-DDL operation, never projected onto an open `transaction()` handle:\n * a caller that needs a row change inside a transaction (`Store.clear()`\n * pairing this with {@link resetRevisionOrigin}) must ensure the table on\n * the ROOT backend, BEFORE opening that transaction, then touch the row\n * inside it.\n */\nexport async function ensureRevisionOriginsRelation(\n target: RevisionOriginBackend,\n verdict: BundleVerdictOf<typeof RECORDED_REVISION_ORIGINS>,\n): Promise<void> {\n if (!verdict.supported) {\n throw new ConfigurationError(\n \"Revision tracking requires a backend that can bootstrap revision origins.\",\n { dialect: target.dialect },\n {\n suggestion:\n \"Use a built-in SQLite/PostgreSQL backend, or implement ensureRevisionOriginsTable on the custom backend.\",\n },\n );\n }\n if (ENSURED_ORIGINS_RELATIONS.has(target)) return;\n const { ensureRevisionOriginsTable: ensureTable } =\n recordedRevisionOriginsMembers(target, verdict);\n await ensureTable();\n ENSURED_ORIGINS_RELATIONS.add(target);\n}\n\n/**\n * Backends whose origins relation this process has already ensured. The\n * relation is DDL (`CREATE TABLE IF NOT EXISTS`) and a table never goes\n * away once created, so ensuring it once per backend object is enough; the\n * origin ROW is read fresh on every call because `Store.clear()` rotates\n * it, and that freshness is what callers of {@link ensureRevisionOrigin}\n * pay for — not a DDL round trip per mint.\n */\nconst ENSURED_ORIGINS_RELATIONS = new WeakSet<object>();\n\n/**\n * Returns a graph's durable revision-origin nonce, creating it exactly once.\n * The unique graph-id row makes concurrent first readers converge on the\n * winner's origin rather than manufacturing incompatible anchors.\n */\nexport async function ensureRevisionOrigin(\n target: RevisionOriginBackend,\n verdict: BundleVerdictOf<typeof RECORDED_REVISION_ORIGINS>,\n schema: SqlSchema,\n graphId: string,\n): Promise<string> {\n await ensureRevisionOriginsRelation(target, verdict);\n const existing = await readRevisionOrigin(target, schema, graphId);\n if (existing !== undefined) return existing;\n\n await executeStatement(\n target,\n sql`\n INSERT INTO ${schema.revisionOriginsTable} (graph_id, origin)\n VALUES (${graphId}, ${generateId()})\n ON CONFLICT (graph_id) DO NOTHING\n `,\n );\n const origin = await readRevisionOrigin(target, schema, graphId);\n if (origin !== undefined) return origin;\n throw new ConfigurationError(\n \"Revision origin was not persisted after initialization.\",\n { graphId, dialect: target.dialect },\n );\n}\n\n/**\n * Deletes a graph's durable revision-origin row so the next\n * {@link ensureRevisionOrigin} call mints a fresh nonce. Row-write only\n * (`execute`/`executeStatement`, the same narrow surface\n * {@link readRecordedClock} needs) — deliberately NOT the DDL-capable\n * {@link RevisionOriginBackend} `ensureRevisionOrigin` takes, so this is\n * safe to call on an open `transaction()` handle. A caller whose origins\n * table might not exist yet must call {@link ensureRevisionOriginsRelation}\n * on the root backend first (`Store.clear()` does, before opening its\n * transaction).\n *\n * `Store.clear()` calls this inside the same transaction as `clearGraph`:\n * the recorded clock (and, for a non-capturing revision-tracked store, its\n * immediate reseed) restarts numbering from the same low values every\n * clear, so leaving the origin row untouched would let a graph repopulated\n * to the same revision COUNT after a clear silently reconstruct the exact\n * `base@V` anchor a pre-clear branch forked from — schema half unchanged,\n * origin unchanged, revision numbering coincidentally realigned. Rotating\n * the origin here is what makes that recurrence impossible: every mint\n * after this point draws a new random nonce, so no later anchor can equal\n * one minted before the clear.\n */\nexport async function resetRevisionOrigin(\n target: RecordedClockBackend,\n schema: SqlSchema,\n graphId: string,\n): Promise<void> {\n await executeStatement(\n target,\n sql`\n DELETE FROM ${schema.revisionOriginsTable}\n WHERE graph_id = ${graphId}\n `,\n );\n}\n\n/**\n * Persists a graph's clock row, SELF-FENCED against a backward move.\n *\n * The per-graph revision is the total order every recorded instant is read\n * back in, so lowering it re-issues instants that were already handed out —\n * silent corruption of recorded-time ordering, not a loud failure. The row\n * therefore refuses the write itself instead of trusting whoever computed the\n * value: the conflict update applies only when the proposed revision strictly\n * advances the stored one. A caller that read the clock outside the lock and\n * lost the race becomes a no-op here (and is refused by\n * {@link assertRecordedClockAdvanced}) rather than a rollback of the clock.\n *\n * One predicate for both dialects: SQLite and PostgreSQL share the\n * `ON CONFLICT ... DO UPDATE ... WHERE` form and the `excluded.` alias for the\n * proposed row. The stored row is qualified by table name so neither engine has\n * to resolve a bare `revision` against two candidate rows.\n */\nasync function writeRecordedClock(\n target: RecordedClockBackend,\n schema: SqlSchema,\n graphId: string,\n parts: RecordedClockParts,\n): Promise<void> {\n await executeStatement(\n target,\n sql`\n INSERT INTO ${schema.recordedClockTable} (graph_id, revision, recorded_at)\n VALUES (${graphId}, ${parts.revision}, ${parts.recordedAt})\n ON CONFLICT (graph_id) DO UPDATE\n SET revision = excluded.revision, recorded_at = excluded.recorded_at\n WHERE ${schema.recordedClockTable}.revision < excluded.revision\n `,\n );\n}\n\n/**\n * Confirms the fenced UPSERT actually took the allocated revision.\n *\n * Runs only on the `previousRevision` path — the one where the caller, not this\n * module, supplied the clock's previous value. There the fence alone is not\n * enough: it protects the ROW, but the allocated instant has already been\n * computed from the caller's claim and would be returned as if committed,\n * stamping rows with an instant the clock never reached. An allocation that the\n * row declined is refused here instead of reported.\n *\n * WHY THE OTHER ARM NEEDS NO RE-READ, and why that is a property rather than an\n * assumption: when `previousRevision` is absent the value is read by\n * {@link readRecordedClockParts} AFTER {@link lockRecordedClock}, inside the\n * same transaction that then writes — a real fence on both dialects\n * (`pg_advisory_xact_lock`; SQLite's seed-UPSERT or the enclosing\n * `BEGIN IMMEDIATE`). Those constructs are transaction-scoped, so the fence\n * would be vacuous on a backend with no transactions — but such a backend can\n * never reach here: `assertRevisionTrackableBackend` refuses\n * `revisionTracking` (and therefore `history`, which implies it) at Store\n * construction unless `capabilities.execution.interactiveTransactions` is set. Adding the re-read to\n * that arm would put an unfalsifiable extra SELECT on every captured write.\n */\nasync function assertRecordedClockAdvanced(\n target: RecordedClockBackend,\n schema: SqlSchema,\n graphId: string,\n revision: number,\n): Promise<void> {\n const stored = await readRecordedClockParts(target, schema, graphId);\n if (stored?.revision === revision) return;\n throw new ConfigurationError(\n \"Recorded commit allocation was refused: the supplied previous revision was stale, so the write would have moved the graph's revision clock backward.\",\n { graphId, allocatedRevision: revision, storedRevision: stored?.revision },\n {\n suggestion:\n \"Read the previous revision inside the same transaction that allocates the commit (omit previousRevision), or hold the per-graph write lock across the read and the allocation.\",\n },\n );\n}\n\nasync function lockRecordedClock(\n target: RecordedClockBackend,\n schema: SqlSchema,\n graphId: string,\n ownsWriteLock: boolean,\n): Promise<void> {\n // Serialize the read/advance/write sequence per graph. Without this,\n // concurrent transactions can read the same previous clock value and\n // allocate the same recorded instant.\n const plan = resolveWriteFencePlan(target);\n const fence = requireWriteFence(plan, \"recorded clock allocation\", \"keyed\");\n switch (fence.kind) {\n case \"lock\":\n case \"row\": {\n await target.execute(\n asCompiledRowsSql(\n fence.sql.acquireKeyed(\n RECORDED_CLOCK_ADVISORY_LOCK_NAMESPACE,\n graphId,\n ),\n ),\n );\n return;\n }\n case \"engine-serialized\": {\n // SQLite: the seed-UPSERT exists only to take the clock row's write lock\n // before reading when the enclosing transaction did NOT already hold one.\n // Bundled transactions open BEGIN IMMEDIATE, so the lock is already held.\n if (ownsWriteLock) return;\n await executeStatement(\n target,\n sql`\n INSERT INTO ${schema.recordedClockTable} (graph_id, revision, recorded_at)\n VALUES (${graphId}, ${RECORDED_MIN_REVISION}, ${RECORDED_MIN_TIME})\n ON CONFLICT (graph_id) DO UPDATE SET revision = revision\n `,\n );\n return;\n }\n case \"caller-serialized\": {\n // Unlike `engine-serialized`, this is never conditional on\n // `ownsWriteLock`: the seed-UPSERT above exists to take a row-level\n // write lock SQLite's `BEGIN IMMEDIATE` might not already hold, which\n // is a proof about that one engine's transaction, not about this\n // declaration. `caller-serialized` is the deployment's own promise\n // that no other client writes to this database at all, so there is no\n // concurrent writer for a seed row to exclude regardless of which\n // transaction opened this one.\n return;\n }\n default: {\n fence satisfies never;\n }\n }\n}\n\n/**\n * Narrows a parsed `previousRevision` to TypeGraph's own numeric clock shape.\n * This module allocates ONLY TypeGraph-owned commits — an engine-native\n * backend never touches a TypeGraph clock at all, so it never reaches\n * `allocateRecordedCommit` — so a caller-supplied `previousRevision` that\n * parses as an engine-native (`e1`) anchor can only be a caller mistake.\n */\nfunction requireTypeGraphClockParts(\n parts: ReturnType<typeof parseRecordedInstant>,\n): RecordedClockParts {\n if (parts.kind !== \"typegraph\") {\n throw new ConfigurationError(\n \"allocateRecordedCommit's previousRevision must be a TypeGraph-owned (r1) recorded instant.\",\n { revisionKind: parts.kind },\n );\n }\n return parts;\n}\n\nexport async function allocateRecordedCommit(\n target: RecordedClockBackend,\n schema: SqlSchema,\n graphId: string,\n ownsWriteLock: boolean,\n previousRevision?: string,\n): Promise<AllocatedRecordedCommit> {\n await lockRecordedClock(target, schema, graphId, ownsWriteLock);\n const previous =\n previousRevision === undefined ?\n await readRecordedClockParts(target, schema, graphId)\n : requireTypeGraphClockParts(\n parseRecordedInstant(previousRevision, \"previous recorded revision\"),\n );\n const { revision, recordedAt } = nextRecordedCommitParts(previous);\n if (revision >= RECORDED_MAX_REVISION) {\n throw new ConfigurationError(\n `Recorded commit clock reached the open revision sentinel ${RECORDED_MAX_REVISION}`,\n { graphId, revision },\n {\n suggestion:\n \"Start a new graph before exhausting the per-graph recorded revision space.\",\n },\n );\n }\n const instant = createRecordedInstant(revision, recordedAt);\n await writeRecordedClock(target, schema, graphId, { revision, recordedAt });\n if (previousRevision !== undefined) {\n await assertRecordedClockAdvanced(target, schema, graphId, revision);\n }\n return { instant, revision, recordedAt };\n}\n\n/**\n * Advances the durable graph revision after a successful live-store write.\n *\n * Revision tracking deliberately reuses the monotonic per-graph revision already\n * owned by recorded-time capture. The write path holds the graph write lock\n * before this runs. Callers additionally state whether their SQLite\n * transaction owns the write lock so `allocateRecordedCommit` can skip its\n * redundant seed-UPSERT only on bundled `BEGIN IMMEDIATE` paths. It preserves\n * monotonicity independently of wall-clock behavior. History capture calls\n * `allocateRecordedCommit` during its own flush instead, so a captured write\n * remains one revision rather than being advanced twice.\n */\nexport async function advanceRevisionClock(\n target: RecordedClockBackend,\n schema: SqlSchema,\n graphId: string,\n ownsWriteLock: boolean,\n previousRevision?: string,\n): Promise<string> {\n const commit = await allocateRecordedCommit(\n target,\n schema,\n graphId,\n ownsWriteLock,\n previousRevision,\n );\n return commit.instant;\n}\n","import {\n type EdgeRow,\n type GraphBackend,\n type InsertEdgeParams,\n type InsertNodeParams,\n type NodeRow,\n type TransactionBackend,\n} from \"../backend/types\";\nimport { requireDefined } from \"../utils/presence\";\n\nexport type InsertDispatch<Params, Row> = Readonly<{\n one: (params: Params) => Promise<Row>;\n ifAbsent?: ((params: Params) => Promise<Row | undefined>) | undefined;\n oneNoReturn?: ((params: Params) => Promise<void>) | undefined;\n batch?: ((params: readonly Params[]) => Promise<void>) | undefined;\n batchReturning?:\n ((params: readonly Params[]) => Promise<readonly Row[]>) | undefined;\n}>;\n\ntype InsertBackend = GraphBackend | TransactionBackend;\n\nexport function nodeInsertDispatch(\n backend: InsertBackend,\n): InsertDispatch<InsertNodeParams, NodeRow> {\n return {\n one: (params) => backend.insertNode(params),\n ifAbsent:\n backend.insertNodeIfAbsent === undefined ?\n undefined\n : (params) => requireDefined(backend.insertNodeIfAbsent)(params),\n oneNoReturn:\n backend.insertNodeNoReturn === undefined ?\n undefined\n : (params) => requireDefined(backend.insertNodeNoReturn)(params),\n batch:\n backend.insertNodesBatch === undefined ?\n undefined\n : (params) => requireDefined(backend.insertNodesBatch)(params),\n batchReturning:\n backend.insertNodesBatchReturning === undefined ?\n undefined\n : (params) => requireDefined(backend.insertNodesBatchReturning)(params),\n };\n}\n\nexport async function runInsertIfAbsent<Params, Row>(\n dispatch: InsertDispatch<Params, Row>,\n params: Params,\n): Promise<Row | undefined> {\n if (dispatch.ifAbsent === undefined) return undefined;\n return dispatch.ifAbsent(params);\n}\n\nexport function edgeInsertDispatch(\n backend: InsertBackend,\n): InsertDispatch<InsertEdgeParams, EdgeRow> {\n return {\n one: (params) => backend.insertEdge(params),\n oneNoReturn:\n backend.insertEdgeNoReturn === undefined ?\n undefined\n : (params) => requireDefined(backend.insertEdgeNoReturn)(params),\n batch:\n backend.insertEdgesBatch === undefined ?\n undefined\n : (params) => requireDefined(backend.insertEdgesBatch)(params),\n batchReturning:\n backend.insertEdgesBatchReturning === undefined ?\n undefined\n : (params) => requireDefined(backend.insertEdgesBatchReturning)(params),\n };\n}\n\nexport async function runInsertNoReturn<Params, Row>(\n dispatch: InsertDispatch<Params, Row>,\n params: Params,\n): Promise<void> {\n if (dispatch.oneNoReturn !== undefined) {\n await dispatch.oneNoReturn(params);\n return;\n }\n await dispatch.one(params);\n}\n\nexport async function runInsertBatch<Params, Row>(\n dispatch: InsertDispatch<Params, Row>,\n params: readonly Params[],\n): Promise<void> {\n if (params.length === 0) return;\n if (dispatch.batch !== undefined) {\n await dispatch.batch(params);\n return;\n }\n for (const insertParams of params) {\n await runInsertNoReturn(dispatch, insertParams);\n }\n}\n\nexport async function runInsertBatchReturning<Params, Row>(\n dispatch: InsertDispatch<Params, Row>,\n params: readonly Params[],\n): Promise<readonly Row[]> {\n if (params.length === 0) return [];\n if (dispatch.batchReturning !== undefined) {\n return dispatch.batchReturning(params);\n }\n const rows: Row[] = [];\n for (const insertParams of params) {\n rows.push(await dispatch.one(insertParams));\n }\n return rows;\n}\n","import {\n assertRecursiveTraversal,\n type RecursiveTraversalVerdict,\n} from \"../backend/capabilities/recursive-traversal\";\nimport {\n optionalRecordedInstantParts,\n type ReadCoordinate,\n type RecordedInstantParts,\n} from \"../core/temporal\";\nimport { type TemporalMode } from \"../core/types\";\nimport { ConfigurationError } from \"../errors\";\nimport { type SqlSchema } from \"../query/compiler/schema\";\nimport { sql, type SqlFragment } from \"../query/sql-fragment\";\nimport { type IdentityRelation } from \"./types\";\n\n/**\n * THE refusal shared by every historical identity read entry point —\n * {@link Store.identityAtCoordinate}'s facade and the query compiler's\n * identity-traversal path alike — for a recorded coordinate under\n * engine-native recorded time.\n *\n * `identityNodeSnapshotSource`/`identityAssertionSnapshotSource` below read a\n * recorded relation's own columns (`schema.recordedNodesTable`/\n * `recordedIdentityAssertionsTable`, `recorded_from`/`recorded_to`) directly\n * rather than through the `RecordedReadSource` seam an engine-native binding\n * satisfies — an engine-native backend has no such relation to read, so this\n * refuses before either function ever runs, rather than emitting SQL against\n * a relation that does not exist.\n */\nexport function refuseEngineNativeRecordedIdentityRead(surface: string): never {\n throw new ConfigurationError(\n `${surface} cannot reconstruct identity at a recorded coordinate under engine-native recorded time: identity history reads TypeGraph's own recorded relations directly, which an engine-native backend does not populate.`,\n { code: \"ENGINE_NATIVE_RECORDED_IDENTITY_UNSUPPORTED\", surface },\n {\n suggestion:\n \"Read identity at the current coordinate, or use a store whose recorded time is TypeGraph-owned (history/revisionTracking without an engine-native recordedTime member) for historical identity reconstruction.\",\n },\n );\n}\n\n/**\n * Column list of the identity assertion relation, in storage order. Every\n * assertion SELECT projection and the INSERT column clause share this fragment,\n * so a column added to the relation cannot be picked up by one read path and\n * silently missed by another.\n */\nexport const IDENTITY_ASSERTION_COLUMNS: SqlFragment = sql.raw(\n [\n \"graph_id\",\n \"id\",\n \"rel\",\n \"a_kind\",\n \"a_id\",\n \"b_kind\",\n \"b_id\",\n \"valid_from\",\n \"valid_to\",\n \"created_at\",\n \"updated_at\",\n \"deleted_at\",\n \"ended_by_kind\",\n \"ended_by_id\",\n ].join(\", \"),\n);\n\nexport type HistoricalIdentitySqlCoordinate = Readonly<{\n validMode: TemporalMode;\n validAsOf?: string | undefined;\n recorded?: RecordedInstantParts | undefined;\n currentInstant: SqlFragment;\n}>;\n\nexport function identitySqlCoordinate(\n coordinate: ReadCoordinate | undefined,\n currentInstant: string | SqlFragment,\n): HistoricalIdentitySqlCoordinate {\n return {\n validMode: coordinate?.valid.mode ?? \"current\",\n validAsOf: coordinate?.valid.asOf,\n recorded: optionalRecordedInstantParts(\n coordinate?.recorded?.asOf,\n \"recorded.asOf\",\n ),\n currentInstant:\n typeof currentInstant === \"string\" ?\n sql`${currentInstant}`\n : currentInstant,\n };\n}\n\nfunction validityInstant(\n coordinate: HistoricalIdentitySqlCoordinate,\n): SqlFragment {\n if (coordinate.validMode === \"asOf\" && coordinate.validAsOf !== undefined) {\n return sql`${coordinate.validAsOf}`;\n }\n if (coordinate.recorded !== undefined) {\n return sql`${coordinate.recorded.recordedAt}`;\n }\n return coordinate.currentInstant;\n}\n\nfunction qualifiedColumn(alias: string, column: string): SqlFragment {\n return sql`${sql.identifier(alias)}.${sql.identifier(column)}`;\n}\n\n/** Point-in-time node visibility shared by identity reads and traversal SQL. */\nexport function identityNodeVisibilitySql(\n coordinate: HistoricalIdentitySqlCoordinate,\n alias: string,\n): SqlFragment {\n const deletedAt = qualifiedColumn(alias, \"deleted_at\");\n if (coordinate.validMode === \"includeTombstones\") return sql`1 = 1`;\n if (coordinate.validMode === \"includeEnded\") {\n return sql`${deletedAt} IS NULL`;\n }\n const validFrom = qualifiedColumn(alias, \"valid_from\");\n const validTo = qualifiedColumn(alias, \"valid_to\");\n const instant = validityInstant(coordinate);\n return sql`\n ${deletedAt} IS NULL\n AND (${validFrom} IS NULL OR ${validFrom} <= ${instant})\n AND (${validTo} IS NULL OR ${validTo} > ${instant})\n `;\n}\n\n/**\n * Lifecycle predicate for implicit same-id folds.\n *\n * A valid-time read before a later soft deletion must still see the fold that\n * existed then. Recorded reads already source a historical row image, while a\n * valid-time-only read has the live row and therefore reconstructs existence\n * from created_at/deleted_at.\n */\nfunction structuralFoldVisibilitySql(\n coordinate: HistoricalIdentitySqlCoordinate,\n alias: string,\n): SqlFragment {\n const deletedAt = qualifiedColumn(alias, \"deleted_at\");\n if (coordinate.recorded !== undefined) return sql`${deletedAt} IS NULL`;\n if (coordinate.validMode !== \"asOf\") return sql`${deletedAt} IS NULL`;\n const createdAt = qualifiedColumn(alias, \"created_at\");\n const instant = validityInstant(coordinate);\n return sql`${createdAt} <= ${instant} AND (${deletedAt} IS NULL OR ${deletedAt} > ${instant})`;\n}\n\nexport function identityNodeSnapshotSource(\n schema: SqlSchema,\n graphId: string,\n coordinate: HistoricalIdentitySqlCoordinate,\n): SqlFragment {\n const table =\n coordinate.recorded === undefined ?\n schema.nodesTable\n : schema.recordedNodesTable;\n const recordedFilter =\n coordinate.recorded === undefined ?\n sql``\n : sql`\n AND recorded_from <= ${coordinate.recorded.revision}\n AND recorded_to > ${coordinate.recorded.revision}\n `;\n return sql`\n SELECT kind, id, valid_from, valid_to, created_at, deleted_at\n FROM ${table}\n WHERE graph_id = ${graphId}\n ${recordedFilter}\n `;\n}\n\nexport function identityAssertionSnapshotSource(\n schema: SqlSchema,\n graphId: string,\n coordinate: HistoricalIdentitySqlCoordinate,\n relation: IdentityRelation | undefined,\n): SqlFragment {\n const table =\n coordinate.recorded === undefined ?\n schema.identityAssertionsTable\n : schema.recordedIdentityAssertionsTable;\n const recordedFilter =\n coordinate.recorded === undefined ?\n sql``\n : sql`\n AND recorded_from <= ${coordinate.recorded.revision}\n AND recorded_to > ${coordinate.recorded.revision}\n `;\n const relationFilter =\n relation === undefined ? sql`` : sql`AND rel = ${relation}`;\n const instant = validityInstant(coordinate);\n return sql`\n SELECT ${IDENTITY_ASSERTION_COLUMNS}\n FROM ${table}\n WHERE graph_id = ${graphId}\n ${recordedFilter}\n AND deleted_at IS NULL\n ${relationFilter}\n AND valid_from <= ${instant}\n AND (valid_to IS NULL OR valid_to > ${instant})\n `;\n}\n\n/**\n * Builds the shared recursive CTE body used to reconstruct an identity class.\n * `seedSource` must select `(seed_kind, seed_id)` columns.\n *\n * The assert below names this call site \"historical identity class read\"\n * (site C). {@link historicalIdentityPeerClassQuery} (site D) asserts with its\n * own label *before* calling this builder, so on the D path this assert is\n * unreachable — the D-labeled refusal always fires first.\n */\nexport function historicalIdentityReconstructionCtes(\n input: Readonly<{\n schema: SqlSchema;\n graphId: string;\n coordinate: HistoricalIdentitySqlCoordinate;\n seedSource: SqlFragment;\n sameIdAcrossKinds: \"fold\" | \"ignore\";\n recursiveTraversal: RecursiveTraversalVerdict;\n }>,\n): SqlFragment {\n assertRecursiveTraversal(\n input.recursiveTraversal,\n \"historical identity class read\",\n );\n const nodes = identityNodeSnapshotSource(\n input.schema,\n input.graphId,\n input.coordinate,\n );\n const assertions = identityAssertionSnapshotSource(\n input.schema,\n input.graphId,\n input.coordinate,\n \"same\",\n );\n const sameIdEdges =\n input.sameIdAcrossKinds === \"fold\" ?\n sql`\n UNION ALL\n SELECT left_node.kind, left_node.id, right_node.kind, right_node.id\n FROM node_snapshot left_node\n JOIN node_snapshot right_node\n ON right_node.id = left_node.id\n AND right_node.kind <> left_node.kind\n WHERE ${structuralFoldVisibilitySql(input.coordinate, \"left_node\")}\n AND ${structuralFoldVisibilitySql(input.coordinate, \"right_node\")}\n `\n : sql``;\n // `seeds` is declared after `identity_edges` so a seed source may itself read\n // the edge relation (see {@link historicalIdentityPeerClassQuery}); every\n // entry still references only entries declared before it.\n return sql`\n node_snapshot(kind, id, valid_from, valid_to, created_at, deleted_at) AS (\n ${nodes}\n ),\n same_assertions(a_kind, a_id, b_kind, b_id) AS (\n SELECT a_kind, a_id, b_kind, b_id FROM (${assertions}) identity_assertions\n ),\n identity_edges(a_kind, a_id, b_kind, b_id) AS (\n SELECT a_kind, a_id, b_kind, b_id FROM same_assertions\n UNION ALL\n SELECT b_kind, b_id, a_kind, a_id FROM same_assertions\n ${sameIdEdges}\n ),\n seeds(seed_kind, seed_id) AS (\n ${input.seedSource}\n ),\n identity_members(seed_kind, seed_id, kind, id) AS (\n SELECT seeds.seed_kind, seeds.seed_id, seeds.seed_kind, seeds.seed_id\n FROM seeds\n JOIN node_snapshot n\n ON n.kind = seeds.seed_kind AND n.id = seeds.seed_id\n WHERE ${identityNodeVisibilitySql(input.coordinate, \"n\")}\n UNION\n SELECT member.seed_kind, member.seed_id, edge.b_kind, edge.b_id\n FROM identity_members member\n JOIN identity_edges edge\n ON edge.a_kind = member.kind\n AND edge.a_id = member.id\n )\n `;\n}\n\n/**\n * Column contract of the peer-class relation built by\n * {@link historicalIdentityPeerClassQuery}, in projection order. A consumer names\n * the relation itself, so it declares these columns on the name it chooses.\n */\nexport const IDENTITY_PEER_CLASS_COLUMNS: SqlFragment = sql.raw(\n [\"seed_kind\", \"seed_id\", \"kind\", \"id\"].join(\", \"),\n);\n\n/**\n * A self-contained query for the *visible* identity classes of every node that\n * has at least one identity peer at `coordinate`, as\n * `(seed_kind, seed_id, kind, id)` rows.\n *\n * Unlike {@link historicalIdentityReconstructionCtes}, nothing here depends on\n * which nodes a caller is asking about: the seeds are the endpoints of the\n * identity-edge relation itself. That is what makes the result hoistable to a\n * query-level CTE evaluated once, rather than a correlated subquery a planner\n * may re-evaluate per candidate row (typegraph#310). Nodes with no peer are\n * absent by construction, leaving the \"member is the seed itself\" case to the\n * consumer; that is what keeps this relation proportional to the identity ledger\n * and the folded-id population rather than to the whole graph.\n *\n * Members are filtered to those visible at `coordinate`, matching the\n * point-in-time node check a membership consumer would otherwise apply itself.\n * The filter sits in the projection, not in the recursion, so a class may still\n * be held together through a member that is not visible.\n *\n * The returned fragment is a complete `SELECT` carrying its own\n * `WITH RECURSIVE`, so the inner relation names stay scoped to it and multiple\n * consumers in one statement cannot collide.\n */\nexport function historicalIdentityPeerClassQuery(\n input: Readonly<{\n schema: SqlSchema;\n graphId: string;\n coordinate: HistoricalIdentitySqlCoordinate;\n sameIdAcrossKinds: \"fold\" | \"ignore\";\n recursiveTraversal: RecursiveTraversalVerdict;\n }>,\n): SqlFragment {\n assertRecursiveTraversal(\n input.recursiveTraversal,\n \"historical identity expansion\",\n );\n const reconstruction = historicalIdentityReconstructionCtes({\n ...input,\n seedSource: sql`SELECT DISTINCT a_kind, a_id FROM identity_edges`,\n });\n return sql`\n WITH RECURSIVE\n ${reconstruction}\n SELECT member.seed_kind, member.seed_id, member.kind, member.id\n FROM identity_members member\n JOIN node_snapshot n ON n.kind = member.kind AND n.id = member.id\n WHERE ${identityNodeVisibilitySql(input.coordinate, \"n\")}\n `;\n}\n","type RowWithId = Readonly<{ id: string }>;\n\nexport type RowFetchPolicy<Row extends RowWithId> = Readonly<{\n batch?: ((ids: readonly string[]) => Promise<readonly Row[]>) | undefined;\n one: (id: string) => Promise<Row | undefined>;\n}>;\n\n/**\n * Shared \"batch if available, otherwise deduped single reads\" policy for\n * store row hydration. Node and edge callers supply only the backend-specific\n * read functions, so future bind-limit/chunking changes land in one place.\n */\nexport async function getRowsByIds<Row extends RowWithId>(\n ids: readonly string[],\n policy: RowFetchPolicy<Row>,\n): Promise<Map<string, Row>> {\n const rowsById = new Map<string, Row>();\n if (ids.length === 0) return rowsById;\n\n if (policy.batch !== undefined) {\n const rows = await policy.batch(ids);\n for (const row of rows) {\n rowsById.set(row.id, row);\n }\n return rowsById;\n }\n\n const uniqueIds = [...new Set(ids)];\n const rows = await Promise.all(uniqueIds.map((id) => policy.one(id)));\n for (const row of rows) {\n if (row !== undefined) rowsById.set(row.id, row);\n }\n return rowsById;\n}\n","/**\n * Shared edge-row fetching.\n *\n * The edge twin of {@link ./node-fetch}: collection reads (`getByIds`), bulk\n * upsert existence probes, and recorded-time after-image capture all need to\n * fetch many edge rows by id, preferring the backend's batch `getEdges` and\n * falling back to parallel `getEdge` calls. Centralizing the fetch mechanics\n * keeps the copies from drifting; each caller layers its own filtering\n * (temporal mode, kind narrowing) on top.\n */\nimport { bindExtraIfReachable } from \"../backend/capabilities/bind\";\nimport { BATCH_POINT_READ } from \"../backend/capabilities/bundle-registry\";\nimport { type BundleVerdictOf } from \"../backend/capabilities/resolve\";\nimport { type EdgeRow, type GraphBackend } from \"../backend/types\";\nimport { getRowsByIds } from \"./row-fetch\";\n\n/**\n * Fetches edge rows by id into a Map keyed by id. Uses `backend.getEdges`\n * when available, otherwise issues parallel `getEdge` calls for the distinct\n * ids. Missing ids are simply absent from the returned Map. `verdict` is the\n * threaded `batchPointRead` verdict (`\"edge batch fetch\"` operation) — bound\n * off `backend`, the port the call executes on, never re-resolved here.\n */\nexport async function getEdgeRowsByIds(\n backend: Readonly<Pick<GraphBackend, \"getEdge\" | \"getEdges\">>,\n verdict: BundleVerdictOf<typeof BATCH_POINT_READ>,\n graphId: string,\n ids: readonly string[],\n): Promise<Map<string, EdgeRow>> {\n const bound = bindExtraIfReachable(\n backend,\n verdict.extras.getEdges,\n BATCH_POINT_READ.id,\n );\n return getRowsByIds(ids, {\n batch:\n bound === undefined ? undefined : (\n (batchIds) => bound.getEdges(graphId, batchIds)\n ),\n one: (id) => backend.getEdge(graphId, id),\n });\n}\n","/**\n * Shared node-row fetching.\n *\n * Both collection reads (`getByIds`) and declared-index lookup hydration need\n * to fetch many node rows by id, preferring the backend's batch `getNodes`\n * and falling back to parallel `getNode` calls. Centralizing the fetch\n * mechanics keeps the two paths from drifting; each caller layers its own\n * filtering (temporal mode vs. live-only) on top.\n */\nimport { bindExtraIfReachable } from \"../backend/capabilities/bind\";\nimport { BATCH_POINT_READ } from \"../backend/capabilities/bundle-registry\";\nimport { type BundleVerdictOf } from \"../backend/capabilities/resolve\";\nimport {\n type GraphBackend,\n type NodeRow as BackendNodeRow,\n} from \"../backend/types\";\nimport { getRowsByIds } from \"./row-fetch\";\n\n/**\n * Fetches node rows by id into a Map keyed by id. Uses `backend.getNodes`\n * when available, otherwise issues parallel `getNode` calls for the distinct\n * ids. Missing ids are simply absent from the returned Map. `verdict` is the\n * threaded `batchPointRead` verdict (`\"node batch fetch\"` operation) — bound\n * off `backend`, the port the call executes on, never re-resolved here.\n */\nexport async function getNodeRowsByIds(\n backend: Readonly<Pick<GraphBackend, \"getNode\" | \"getNodes\">>,\n verdict: BundleVerdictOf<typeof BATCH_POINT_READ>,\n graphId: string,\n kind: string,\n ids: readonly string[],\n): Promise<Map<string, BackendNodeRow>> {\n const bound = bindExtraIfReachable(\n backend,\n verdict.extras.getNodes,\n BATCH_POINT_READ.id,\n );\n return getRowsByIds(ids, {\n batch:\n bound === undefined ? undefined : (\n (batchIds) => bound.getNodes(graphId, kind, batchIds)\n ),\n one: (id) => backend.getNode(graphId, kind, id),\n });\n}\n","import {\n type EdgeRow,\n type NodeRow,\n rowPropsToJsonText,\n type TransactionBackend,\n} from \"../../backend/types\";\nimport { RECORDED_MAX_REVISION } from \"../../core/temporal\";\nimport { ConfigurationError } from \"../../errors\";\nimport { type IdentityAssertionStorageRow } from \"../../identity/storage-types\";\nimport { sql, type SqlFragment } from \"../../query/sql-fragment\";\nimport { generateId } from \"../../utils/id\";\nimport { executeStatement } from \"./guards\";\n\nexport type RecordedOperation = \"create\" | \"update\" | \"delete\";\n\nexport type RecordedInsert<Row> = Readonly<{\n row: Row;\n operation: RecordedOperation;\n}>;\n\n/**\n * `meta`, `schema_version`, and `tx_id` are reserved SQL:2011 audit columns of\n * the recorded relations. They are not yet populated by a writer, so every\n * captured row stamps `meta` with this empty object and leaves `schema_version`\n * / `tx_id` NULL; they are carried now so the relation shape is stable when a\n * populator lands.\n */\nconst RECORDED_HISTORY_META = \"{}\";\n\n/**\n * Recorded-relation column order. The same list builds each INSERT's column\n * clause, projects its VALUES tuple through the relation's cell builders, and\n * derives the per-statement chunk size, so adding a column updates all three in\n * lockstep instead of relying on a hand-counted bind-parameter count.\n */\nexport const RECORDED_NODE_COLUMNS = [\n \"history_id\",\n \"graph_id\",\n \"kind\",\n \"id\",\n \"props\",\n \"version\",\n \"valid_from\",\n \"valid_to\",\n \"created_at\",\n \"updated_at\",\n \"deleted_at\",\n \"recorded_from\",\n \"recorded_to\",\n \"op\",\n \"schema_version\",\n \"tx_id\",\n \"meta\",\n] as const;\n\nexport const RECORDED_EDGE_COLUMNS = [\n \"history_id\",\n \"graph_id\",\n \"id\",\n \"kind\",\n \"from_kind\",\n \"from_id\",\n \"to_kind\",\n \"to_id\",\n \"props\",\n \"valid_from\",\n \"valid_to\",\n \"created_at\",\n \"updated_at\",\n \"deleted_at\",\n \"recorded_from\",\n \"recorded_to\",\n \"op\",\n \"schema_version\",\n \"tx_id\",\n \"meta\",\n] as const;\n\n/** The recorded identity-assertion relation's columns, same contract. */\nconst RECORDED_IDENTITY_ASSERTION_COLUMNS = [\n \"history_id\",\n \"graph_id\",\n \"id\",\n \"rel\",\n \"a_kind\",\n \"a_id\",\n \"b_kind\",\n \"b_id\",\n \"valid_from\",\n \"valid_to\",\n \"created_at\",\n \"updated_at\",\n \"deleted_at\",\n \"ended_by_kind\",\n \"ended_by_id\",\n \"recorded_from\",\n \"recorded_to\",\n \"op\",\n] as const;\n\nconst RECORDED_NODE_COLUMN_LIST = sql.raw(RECORDED_NODE_COLUMNS.join(\", \"));\nconst RECORDED_EDGE_COLUMN_LIST = sql.raw(RECORDED_EDGE_COLUMNS.join(\", \"));\nconst RECORDED_IDENTITY_ASSERTION_COLUMN_LIST = sql.raw(\n RECORDED_IDENTITY_ASSERTION_COLUMNS.join(\", \"),\n);\n\n/**\n * Conservative per-statement bound-parameter budget, used only as the fallback\n * when a backend does not advertise `capabilities.maxBindParameters`.\n */\nconst RECORDED_BIND_PARAM_BUDGET = 900;\n\nexport function recordedBindParamBudget(\n target: Pick<TransactionBackend, \"capabilities\">,\n): number {\n const budget =\n target.capabilities.maxBindParameters ?? RECORDED_BIND_PARAM_BUDGET;\n if (!Number.isSafeInteger(budget) || budget < 1) {\n throw new ConfigurationError(\n `backend capabilities.maxBindParameters must be a positive integer, got: ${String(budget)}`,\n {\n code: \"INVALID_BACKEND_CAPABILITY\",\n capability: \"maxBindParameters\",\n value: budget,\n },\n );\n }\n return budget;\n}\n\n/**\n * Rows per recorded INSERT statement: the backend's real bound-parameter ceiling\n * divided by the per-row column count.\n */\nfunction recordedChunkSize(\n target: Pick<TransactionBackend, \"capabilities\">,\n columnCount: number,\n): number {\n const budget = recordedBindParamBudget(target);\n return Math.max(1, Math.floor(budget / columnCount));\n}\n\n/**\n * Builds one recorded column's value from an after-image row, the commit\n * instant, and the operation. Each recorded relation maps every column name to\n * one of these, so VALUES tuples are derived from the column list.\n */\ntype RecordedCellBuilder<Row> = (\n row: Row,\n recordedRevision: number,\n operation: RecordedOperation,\n) => SqlFragment;\n\ntype RecordedCommonColumn =\n | \"history_id\"\n | \"graph_id\"\n | \"id\"\n | \"kind\"\n | \"props\"\n | \"valid_from\"\n | \"valid_to\"\n | \"created_at\"\n | \"updated_at\"\n | \"deleted_at\"\n | \"recorded_from\"\n | \"recorded_to\"\n | \"op\"\n | \"schema_version\"\n | \"tx_id\"\n | \"meta\";\n\nfunction sqlNull(value: string | undefined): SqlFragment {\n return value === undefined ? sql.raw(\"NULL\") : sql`${value}`;\n}\n\nfunction recordedCommonCells<Row extends NodeRow | EdgeRow>(): Record<\n RecordedCommonColumn,\n RecordedCellBuilder<Row>\n> {\n return {\n history_id: () => sql`${generateId()}`,\n graph_id: (row) => sql`${row.graph_id}`,\n id: (row) => sql`${row.id}`,\n kind: (row) => sql`${row.kind}`,\n props: (row) => sql`${rowPropsToJsonText(row.props)}`,\n valid_from: (row) => sql`${sqlNull(row.valid_from)}`,\n valid_to: (row) => sql`${sqlNull(row.valid_to)}`,\n created_at: (row) => sql`${row.created_at}`,\n updated_at: (row) => sql`${row.updated_at}`,\n deleted_at: (row) => sql`${sqlNull(row.deleted_at)}`,\n recorded_from: (_row, recordedRevision) => sql`${recordedRevision}`,\n recorded_to: () => sql`${RECORDED_MAX_REVISION}`,\n op: (_row, _recordedCommit, operation) => sql`${operation}`,\n schema_version: () => sql`NULL`,\n tx_id: () => sql`NULL`,\n meta: () => sql`${RECORDED_HISTORY_META}`,\n };\n}\n\nconst recordedNodeCells: Record<\n (typeof RECORDED_NODE_COLUMNS)[number],\n RecordedCellBuilder<NodeRow>\n> = {\n ...recordedCommonCells<NodeRow>(),\n version: (row) => sql`${row.version}`,\n};\n\nconst recordedEdgeCells: Record<\n (typeof RECORDED_EDGE_COLUMNS)[number],\n RecordedCellBuilder<EdgeRow>\n> = {\n ...recordedCommonCells<EdgeRow>(),\n from_kind: (row) => sql`${row.from_kind}`,\n from_id: (row) => sql`${row.from_id}`,\n to_kind: (row) => sql`${row.to_kind}`,\n to_id: (row) => sql`${row.to_id}`,\n};\n\n/**\n * The identity assertion after-image is a storage row rather than a `NodeRow` /\n * `EdgeRow`, so it shares no cells with {@link recordedCommonCells} — but it\n * projects through the same column list, which is what keeps its VALUES tuple\n * and its INSERT column clause in the order the relation actually declares.\n *\n * The fallback after-image read is an un-normalized row, so a nullable column\n * can arrive as SQL `null` rather than `undefined`; `??` covers both.\n */\nconst recordedIdentityAssertionCells: Record<\n (typeof RECORDED_IDENTITY_ASSERTION_COLUMNS)[number],\n RecordedCellBuilder<IdentityAssertionStorageRow>\n> = {\n history_id: () => sql`${generateId()}`,\n graph_id: (row) => sql`${row.graph_id}`,\n id: (row) => sql`${row.id}`,\n rel: (row) => sql`${row.rel}`,\n a_kind: (row) => sql`${row.a_kind}`,\n a_id: (row) => sql`${row.a_id}`,\n b_kind: (row) => sql`${row.b_kind}`,\n b_id: (row) => sql`${row.b_id}`,\n valid_from: (row) => sql`${row.valid_from}`,\n valid_to: (row) => sql`${row.valid_to ?? sql.raw(\"NULL\")}`,\n created_at: (row) => sql`${row.created_at}`,\n updated_at: (row) => sql`${row.updated_at}`,\n deleted_at: (row) => sql`${row.deleted_at ?? sql.raw(\"NULL\")}`,\n ended_by_kind: (row) => sql`${row.ended_by_kind ?? sql.raw(\"NULL\")}`,\n ended_by_id: (row) => sql`${row.ended_by_id ?? sql.raw(\"NULL\")}`,\n recorded_from: (_row, recordedRevision) => sql`${recordedRevision}`,\n recorded_to: () => sql`${RECORDED_MAX_REVISION}`,\n op: (_row, _recordedRevision, operation) => sql`${operation}`,\n};\n\nfunction recordedValuesTuple<Row, Column extends string>(\n columns: readonly Column[],\n cells: Record<Column, RecordedCellBuilder<Row>>,\n row: Row,\n recordedRevision: number,\n operation: RecordedOperation,\n): SqlFragment {\n const tuple = columns.map((column) =>\n cells[column](row, recordedRevision, operation),\n );\n return sql`(${sql.join(tuple, sql`, `)})`;\n}\n\nasync function insertRecordedRows<Row, Column extends string>(\n target: TransactionBackend,\n table: SqlFragment,\n columnList: SqlFragment,\n columns: readonly Column[],\n cells: Record<Column, RecordedCellBuilder<Row>>,\n inserts: readonly RecordedInsert<Row>[],\n recordedRevision: number,\n): Promise<void> {\n if (inserts.length === 0) return;\n const values = inserts.map((insert) =>\n recordedValuesTuple(\n columns,\n cells,\n insert.row,\n recordedRevision,\n insert.operation,\n ),\n );\n await executeStatement(\n target,\n sql`\n INSERT INTO ${table} (${columnList})\n VALUES ${sql.join(values, sql`, `)}\n `,\n );\n}\n\nexport function recordedNodeChunkSize(target: TransactionBackend): number {\n return recordedChunkSize(target, RECORDED_NODE_COLUMNS.length);\n}\n\nexport function recordedEdgeChunkSize(target: TransactionBackend): number {\n return recordedChunkSize(target, RECORDED_EDGE_COLUMNS.length);\n}\n\nexport function recordedIdentityAssertionChunkSize(\n target: TransactionBackend,\n): number {\n return recordedChunkSize(target, RECORDED_IDENTITY_ASSERTION_COLUMNS.length);\n}\n\nexport function insertRecordedNodeRows(\n target: TransactionBackend,\n table: SqlFragment,\n inserts: readonly RecordedInsert<NodeRow>[],\n recordedRevision: number,\n): Promise<void> {\n return insertRecordedRows(\n target,\n table,\n RECORDED_NODE_COLUMN_LIST,\n RECORDED_NODE_COLUMNS,\n recordedNodeCells,\n inserts,\n recordedRevision,\n );\n}\n\nexport function insertRecordedEdgeRows(\n target: TransactionBackend,\n table: SqlFragment,\n inserts: readonly RecordedInsert<EdgeRow>[],\n recordedRevision: number,\n): Promise<void> {\n return insertRecordedRows(\n target,\n table,\n RECORDED_EDGE_COLUMN_LIST,\n RECORDED_EDGE_COLUMNS,\n recordedEdgeCells,\n inserts,\n recordedRevision,\n );\n}\n\nexport function insertRecordedIdentityAssertionRows(\n target: TransactionBackend,\n table: SqlFragment,\n inserts: readonly RecordedInsert<IdentityAssertionStorageRow>[],\n recordedRevision: number,\n): Promise<void> {\n return insertRecordedRows(\n target,\n table,\n RECORDED_IDENTITY_ASSERTION_COLUMN_LIST,\n RECORDED_IDENTITY_ASSERTION_COLUMNS,\n recordedIdentityAssertionCells,\n inserts,\n recordedRevision,\n );\n}\n","import { type BATCH_POINT_READ } from \"../../backend/capabilities/bundle-registry\";\nimport { type BundleVerdictOf } from \"../../backend/capabilities/resolve\";\nimport {\n type EdgeRow,\n type HardDeleteNodeParams,\n type NodeRow,\n type TransactionBackend,\n} from \"../../backend/types\";\nimport { RECORDED_MAX_REVISION } from \"../../core/temporal\";\nimport { IDENTITY_ASSERTION_COLUMNS } from \"../../identity/historical-sql\";\nimport { type IdentityAssertionStorageRow } from \"../../identity/storage-types\";\nimport { sqlValueList } from \"../../query/compiler/predicate-utils\";\nimport { type SqlSchema } from \"../../query/compiler/schema\";\nimport { sql, type SqlFragment } from \"../../query/sql-fragment\";\nimport { asCompiledRowsSql } from \"../../query/sql-intent\";\nimport { chunk } from \"../../utils/array\";\nimport { isPresent } from \"../../utils/presence\";\nimport { getEdgeRowsByIds } from \"../edge-fetch\";\nimport { getNodeRowsByIds } from \"../node-fetch\";\nimport { allocateRecordedCommit } from \"./clock\";\nimport { executeStatement } from \"./guards\";\nimport {\n insertRecordedEdgeRows,\n insertRecordedIdentityAssertionRows,\n insertRecordedNodeRows,\n recordedEdgeChunkSize,\n recordedIdentityAssertionChunkSize,\n type RecordedInsert,\n recordedNodeChunkSize,\n type RecordedOperation,\n} from \"./relations\";\n\nexport type TouchedNode = Readonly<{\n entity: \"node\";\n graphId: string;\n kind: string;\n id: string;\n // The after-image returned by the live write, when it returned one. Carried so\n // flush can build the recorded row without re-reading a row the write already\n // handed back. Absent for writes that return no row.\n afterImage?: NodeRow | undefined;\n}>;\n\nexport type TouchedEdge = Readonly<{\n entity: \"edge\";\n graphId: string;\n id: string;\n afterImage?: EdgeRow | undefined;\n}>;\n\nexport type TouchedIdentityAssertion = Readonly<{\n entity: \"identity\";\n graphId: string;\n id: string;\n afterImage?: IdentityAssertionStorageRow | undefined;\n}>;\n\nexport type TouchedEntity =\n TouchedNode | TouchedEdge | TouchedIdentityAssertion;\n\ntype IdRow = Readonly<{ id: string }>;\ntype ClosedRow = Readonly<{ id: string; deleted_at: unknown }>;\n\nexport function entityKey(entity: TouchedEntity): string {\n switch (entity.entity) {\n case \"node\": {\n return `node\\u0000${entity.graphId}\\u0000${entity.kind}\\u0000${entity.id}`;\n }\n case \"edge\": {\n return `edge\\u0000${entity.graphId}\\u0000${entity.id}`;\n }\n case \"identity\": {\n return `identity\\u0000${entity.graphId}\\u0000${entity.id}`;\n }\n }\n}\n\n/**\n * Closes every open recorded interval for the given ids in one statement and\n * returns, per id, whether the row it just closed was a soft-delete tombstone.\n */\nasync function closeOpenReturning(\n target: TransactionBackend,\n table: SqlFragment,\n graphId: string,\n ids: readonly string[],\n recordedRevision: number,\n kind?: string,\n): Promise<ReadonlyMap<string, boolean>> {\n const kindFilter = kind === undefined ? sql`` : sql`AND kind = ${kind}`;\n const rows = await target.execute<ClosedRow>(\n asCompiledRowsSql(sql`\n UPDATE ${table}\n SET recorded_to = ${recordedRevision}\n WHERE graph_id = ${graphId}\n ${kindFilter}\n AND recorded_to = ${RECORDED_MAX_REVISION}\n AND id IN (${sqlValueList(ids)})\n RETURNING id, deleted_at\n `),\n );\n return new Map(rows.map((row) => [row.id, isPresent(row.deleted_at)]));\n}\n\nfunction recordedOp(\n hadOpenRow: boolean,\n priorRowWasTombstone: boolean,\n after: Readonly<{ deleted_at: string | undefined }>,\n): RecordedOperation {\n if (isPresent(after.deleted_at)) return \"delete\";\n if (!hadOpenRow || priorRowWasTombstone) return \"create\";\n return \"update\";\n}\n\nfunction groupNodesByKind(\n entities: readonly TouchedNode[],\n): ReadonlyMap<string, TouchedNode[]> {\n const byKind = new Map<string, TouchedNode[]>();\n for (const entity of entities) {\n const group = byKind.get(entity.kind) ?? [];\n group.push(entity);\n byKind.set(entity.kind, group);\n }\n return byKind;\n}\n\nasync function resolveAfterImages<Row>(\n entities: readonly Readonly<{ id: string; afterImage?: Row | undefined }>[],\n readMissing: (ids: readonly string[]) => Promise<ReadonlyMap<string, Row>>,\n): Promise<ReadonlyMap<string, Row>> {\n const afterById = new Map<string, Row>();\n const needRead: string[] = [];\n for (const entity of entities) {\n if (entity.afterImage === undefined) {\n needRead.push(entity.id);\n } else {\n afterById.set(entity.id, entity.afterImage);\n }\n }\n if (needRead.length > 0) {\n for (const [id, row] of await readMissing(needRead)) afterById.set(id, row);\n }\n return afterById;\n}\n\nfunction recordedInsertsFor<\n Row extends Readonly<{ id: string; deleted_at: string | undefined }>,\n>(\n afterById: ReadonlyMap<string, Row>,\n closed: ReadonlyMap<string, boolean>,\n): readonly RecordedInsert<Row>[] {\n return [...afterById.values()].map((row) => ({\n row,\n operation: recordedOp(closed.has(row.id), closed.get(row.id) ?? false, row),\n }));\n}\n\nexport async function flushNodes(\n target: TransactionBackend,\n batchPointRead: BundleVerdictOf<typeof BATCH_POINT_READ>,\n schema: SqlSchema,\n graphId: string,\n entities: readonly TouchedNode[],\n recordedRevision: number,\n): Promise<void> {\n const chunkSize = recordedNodeChunkSize(target);\n for (const [kind, group] of groupNodesByKind(entities)) {\n for (const entityChunk of chunk(group, chunkSize)) {\n const ids = entityChunk.map((entity) => entity.id);\n const closed = await closeOpenReturning(\n target,\n schema.recordedNodesTable,\n graphId,\n ids,\n recordedRevision,\n kind,\n );\n const afterById = await resolveAfterImages(entityChunk, (missing) =>\n getNodeRowsByIds(target, batchPointRead, graphId, kind, missing),\n );\n await insertRecordedNodeRows(\n target,\n schema.recordedNodesTable,\n recordedInsertsFor(afterById, closed),\n recordedRevision,\n );\n }\n }\n}\n\nexport async function flushEdges(\n target: TransactionBackend,\n batchPointRead: BundleVerdictOf<typeof BATCH_POINT_READ>,\n schema: SqlSchema,\n graphId: string,\n entities: readonly TouchedEdge[],\n recordedRevision: number,\n): Promise<void> {\n const chunkSize = recordedEdgeChunkSize(target);\n for (const entityChunk of chunk(entities, chunkSize)) {\n const ids = entityChunk.map((entity) => entity.id);\n const closed = await closeOpenReturning(\n target,\n schema.recordedEdgesTable,\n graphId,\n ids,\n recordedRevision,\n );\n const afterById = await resolveAfterImages(entityChunk, (missing) =>\n getEdgeRowsByIds(target, batchPointRead, graphId, missing),\n );\n await insertRecordedEdgeRows(\n target,\n schema.recordedEdgesTable,\n recordedInsertsFor(afterById, closed),\n recordedRevision,\n );\n }\n}\n\nasync function getIdentityAssertionRowsByIds(\n target: TransactionBackend,\n schema: SqlSchema,\n graphId: string,\n ids: readonly string[],\n): Promise<ReadonlyMap<string, IdentityAssertionStorageRow>> {\n if (ids.length === 0) return new Map();\n const rows = await target.execute<IdentityAssertionStorageRow>(\n asCompiledRowsSql(sql`\n SELECT ${IDENTITY_ASSERTION_COLUMNS}\n FROM ${schema.identityAssertionsTable}\n WHERE graph_id = ${graphId}\n AND id IN (${sqlValueList(ids)})\n `),\n );\n return new Map(rows.map((row) => [row.id, row] as const));\n}\n\nexport async function flushIdentityAssertions(\n target: TransactionBackend,\n schema: SqlSchema,\n graphId: string,\n entities: readonly TouchedIdentityAssertion[],\n recordedRevision: number,\n): Promise<void> {\n if (entities.length === 0) return;\n const chunkSize = recordedIdentityAssertionChunkSize(target);\n for (const entityChunk of chunk(entities, chunkSize)) {\n const ids = entityChunk.map((entity) => entity.id);\n const closed = await closeOpenReturning(\n target,\n schema.recordedIdentityAssertionsTable,\n graphId,\n ids,\n recordedRevision,\n );\n const afterById = await resolveAfterImages(entityChunk, (missing) =>\n getIdentityAssertionRowsByIds(target, schema, graphId, missing),\n );\n // A hard deletion closes the prior recorded row without leaving a current\n // after-image; the insert below is then empty and the UPDATE above is the\n // complete capture.\n await insertRecordedIdentityAssertionRows(\n target,\n schema.recordedIdentityAssertionsTable,\n recordedInsertsFor(afterById, closed),\n recordedRevision,\n );\n }\n}\n\nasync function closeOpenByKind(\n target: TransactionBackend,\n table: SqlFragment,\n graphId: string,\n kind: string,\n recordedRevision: number,\n): Promise<void> {\n await executeStatement(\n target,\n sql`\n UPDATE ${table}\n SET recorded_to = ${recordedRevision}\n WHERE graph_id = ${graphId}\n AND kind = ${kind}\n AND recorded_to = ${RECORDED_MAX_REVISION}\n `,\n );\n}\n\nasync function closeOpenEdgesByNodeKind(\n target: TransactionBackend,\n schema: SqlSchema,\n graphId: string,\n nodeKind: string,\n recordedRevision: number,\n): Promise<void> {\n await executeStatement(\n target,\n sql`\n UPDATE ${schema.recordedEdgesTable}\n SET recorded_to = ${recordedRevision}\n WHERE graph_id = ${graphId}\n AND (from_kind = ${nodeKind} OR to_kind = ${nodeKind})\n AND recorded_to = ${RECORDED_MAX_REVISION}\n `,\n );\n}\n\nexport async function closeRecordedHardDeletedKind(\n target: TransactionBackend,\n schema: SqlSchema,\n graphId: string,\n removal: Readonly<{ entity: \"node\" | \"edge\"; kind: string }>,\n ownsWriteLock: boolean,\n): Promise<void> {\n const recordedCommit = await allocateRecordedCommit(\n target,\n schema,\n graphId,\n ownsWriteLock,\n );\n if (removal.entity === \"node\") {\n await closeOpenByKind(\n target,\n schema.recordedNodesTable,\n graphId,\n removal.kind,\n recordedCommit.revision,\n );\n await closeOpenEdgesByNodeKind(\n target,\n schema,\n graphId,\n removal.kind,\n recordedCommit.revision,\n );\n return;\n }\n await closeOpenByKind(\n target,\n schema.recordedEdgesTable,\n graphId,\n removal.kind,\n recordedCommit.revision,\n );\n}\n\nexport async function queryConnectedEdgeIds(\n target: TransactionBackend,\n schema: SqlSchema,\n params: HardDeleteNodeParams,\n): Promise<readonly string[]> {\n const rows = await target.execute<IdRow>(\n asCompiledRowsSql(sql`\n SELECT id\n FROM ${schema.edgesTable}\n WHERE graph_id = ${params.graphId}\n AND (\n (from_kind = ${params.kind} AND from_id = ${params.id})\n OR (to_kind = ${params.kind} AND to_id = ${params.id})\n )\n `),\n );\n return rows.map((row) => row.id);\n}\n","/**\n * The one place that decides, per graph-entity write member, whether a\n * wrapped backend call actually changed a row — rather than merely having\n * been called. TypeGraph-owned recorded-time capture and the engine-native\n * mutation witness both need this exact decision (insertNodeIfAbsent's\n * `undefined` result is not a write, a `compareAndSetNode`/`updateNodeSet`\n * whose `rows` come back empty coalesced to nothing, and so on), so both\n * read it through this shared wrapper instead of re-deriving it — a second,\n * independent spelling of \"did this member write\" is exactly the kind of\n * drift `AGENTS.md`'s \"one predicate, one owner\" rule exists to prevent.\n *\n * `buildRecordedWriteMembers` covers every member in\n * `RECORDED_REQUIRED_WRITE_METHODS` ∪ `RECORDED_OPTIONAL_WRITE_METHODS`\n * (`./write-surface.ts`) except `commands`, which\n * {@link buildRecordedCommandsPort} covers separately because it is a\n * nested port rather than a plain method. `_writeTouchOverlayMatchesChecklist`\n * below pins the returned member set to that same checklist at compile\n * time, so a write surface changed in one place cannot silently narrow the\n * set both consumers wrap.\n *\n * Locking, session-liveness assertion, and image collection are consumer\n * concerns, not this module's: `hooks` lets a caller run something before\n * each write (recorded-time capture supplies `assertOpen` + the per-graph\n * advisory lock; the engine-native mutation witness supplies nothing, since\n * it neither writes a recorded relation nor needs the lock capture takes to\n * protect one), and `sink` is where the write's outcome is reported\n * (capture's sink builds history after-images; the witness's sink is a\n * single boolean flip).\n */\nimport { assertCommandResultMatchesCommand } from \"../../backend/command-contract\";\nimport { deriveBackend } from \"../../backend/derive-backend\";\nimport {\n type DeleteEdgesBatchParams,\n type EdgeRow,\n type GraphCommand,\n type GraphCommandExecutionContext,\n type GraphCommandPort,\n type GraphCommandResult,\n type HardDeleteNodeParams,\n type HeterogeneousNodeUpsertParams,\n type InsertEdgeParams,\n type InsertNodeParams,\n type NodeRow,\n type SchemaWriteFenceParams,\n type TransactionBackend,\n} from \"../../backend/types\";\nimport { type IdentityAssertionStorageRow } from \"../../identity/storage-types\";\nimport { requireDefined } from \"../../utils/presence\";\nimport { type Assert, type Equal } from \"../../utils/type-assert\";\nimport {\n edgeInsertDispatch,\n nodeInsertDispatch,\n runInsertBatch,\n runInsertBatchReturning,\n runInsertNoReturn,\n} from \"../insert-dispatch\";\nimport type {\n RECORDED_OPTIONAL_WRITE_METHODS,\n RECORDED_REQUIRED_WRITE_METHODS,\n} from \"./write-surface\";\n\n/**\n * Where a write member's outcome is reported. See the module doc comment.\n * `touchIdentity` is not called by anything in this module — identity\n * assertions run through `withRecordedIdentityMutationTarget`\n * (`../recorded-capture.ts`), a wholly separate seam from\n * `buildRecordedWriteMembers`'s overlay — but both consumers of this sink\n * (capture and the engine-native mutation witness) report identity touches\n * through the same object, so a caller reading \"did this transaction write\"\n * off one sink sees node, edge, AND identity writes rather than only two of\n * the three.\n */\nexport type WriteTouchSink = Readonly<{\n touchNode: (\n graphId: string,\n kind: string,\n id: string,\n afterImage?: NodeRow,\n ) => void;\n touchEdge: (graphId: string, id: string, afterImage?: EdgeRow) => void;\n touchIdentity: (\n graphId: string,\n id: string,\n afterImage?: IdentityAssertionStorageRow,\n ) => void;\n}>;\n\n/**\n * What a consumer needs to run before a write reaches the wrapped backend\n * (recorded-time capture's session-open assertion and per-graph advisory\n * lock), and how to resolve `hardDeleteNode`'s connected-edge cascade (capture\n * queries it to touch the edges a hard delete implicitly removes; the\n * mutation witness has no need of the ids themselves, only that a mutation\n * happened, so it omits this hook). Every field is optional and a no-op when\n * omitted.\n */\nexport type WriteMemberHooks = Readonly<{\n beforeOne?: (graphId: string) => Promise<void>;\n beforeMany?: (\n params: readonly Readonly<{ graphId: string }>[],\n ) => Promise<void>;\n connectedEdgeIdsForHardDelete?: (\n params: HardDeleteNodeParams,\n ) => Promise<readonly string[]>;\n}>;\n\ndeclare const NODE_IDENTITY_KEY_BRAND: unique symbol;\ndeclare const EDGE_IDENTITY_KEY_BRAND: unique symbol;\n\ntype NodeIdentityKey = string &\n Readonly<{ [NODE_IDENTITY_KEY_BRAND]: \"node-identity-key\" }>;\ntype EdgeIdentityKey = string &\n Readonly<{ [EDGE_IDENTITY_KEY_BRAND]: \"edge-identity-key\" }>;\n\ntype NodeIdentityParams = Pick<InsertNodeParams, \"graphId\" | \"kind\" | \"id\">;\ntype NodeIdentityRow = Pick<NodeRow, \"graph_id\" | \"kind\" | \"id\">;\ntype EdgeIdentityParams = Pick<InsertEdgeParams, \"graphId\" | \"id\">;\ntype EdgeIdentityRow = Pick<EdgeRow, \"graph_id\" | \"id\">;\n\nfunction nodeIdentityKey(\n graphId: string,\n kind: string,\n id: string,\n): NodeIdentityKey {\n return `${graphId}\\u0000${kind}\\u0000${id}` as NodeIdentityKey;\n}\n\nfunction nodeParamsIdentityKey(params: NodeIdentityParams): NodeIdentityKey {\n return nodeIdentityKey(params.graphId, params.kind, params.id);\n}\n\nfunction nodeRowIdentityKey(row: NodeIdentityRow): NodeIdentityKey {\n return nodeIdentityKey(row.graph_id, row.kind, row.id);\n}\n\nfunction edgeIdentityKey(graphId: string, id: string): EdgeIdentityKey {\n return `${graphId}\\u0000${id}` as EdgeIdentityKey;\n}\n\nfunction edgeParamsIdentityKey(params: EdgeIdentityParams): EdgeIdentityKey {\n return edgeIdentityKey(params.graphId, params.id);\n}\n\nfunction edgeRowIdentityKey(row: EdgeIdentityRow): EdgeIdentityKey {\n return edgeIdentityKey(row.graph_id, row.id);\n}\n\n/** The member set {@link buildRecordedWriteMembers} returns. */\nexport type RecordedWriteMembersOverlay = Pick<\n TransactionBackend,\n | \"insertNode\"\n | \"updateNode\"\n | \"deleteNode\"\n | \"hardDeleteNode\"\n | \"insertEdge\"\n | \"updateEdge\"\n | \"deleteEdge\"\n | \"hardDeleteEdge\"\n> &\n Partial<\n Pick<\n TransactionBackend,\n | \"insertNodeIfAbsent\"\n | \"insertNodeIfAbsentWithSchemaFence\"\n | \"insertNodeWithSchemaFence\"\n | \"insertNodeNoReturn\"\n | \"insertNodesBatch\"\n | \"insertNodesBatchReturning\"\n | \"updateResolvedNodesBatch\"\n | \"updateNodeSet\"\n | \"upsertHeterogeneousNodes\"\n | \"compareAndSetNode\"\n | \"insertEdgeNoReturn\"\n | \"insertEdgesBatch\"\n | \"insertEdgesBatchReturning\"\n | \"insertEdgesDurableBatchReturning\"\n | \"deleteEdgesBatch\"\n | \"hardDeleteEdgesBatch\"\n >\n >;\n\n// Pins `RecordedWriteMembersOverlay` to the write-surface checklist minus\n// `commands` (covered by `buildRecordedCommandsPort`): if either side gains\n// or loses a member without the other, this fails to compile rather than\n// silently leaving one consumer of this wrapper short a member.\n// eslint-disable-next-line @typescript-eslint/no-unused-vars -- compile-time assertion\ntype _writeTouchOverlayMatchesChecklist = Assert<\n Equal<\n keyof RecordedWriteMembersOverlay,\n Exclude<\n | (typeof RECORDED_REQUIRED_WRITE_METHODS)[number]\n | (typeof RECORDED_OPTIONAL_WRITE_METHODS)[number],\n \"commands\"\n >\n >\n>;\n\n/**\n * Builds the graph-entity write member overlay both recorded-time capture and\n * the engine-native mutation witness install on a transaction backend. See\n * the module doc comment for the division of responsibility between this\n * function, `sink`, and `hooks`.\n */\nexport function buildRecordedWriteMembers(\n target: TransactionBackend,\n sink: WriteTouchSink,\n hooks: WriteMemberHooks = {},\n): RecordedWriteMembersOverlay {\n const nodeDispatch = nodeInsertDispatch(target);\n const edgeDispatch = edgeInsertDispatch(target);\n\n return {\n async insertNode(params) {\n await hooks.beforeOne?.(params.graphId);\n const row = await target.insertNode(params);\n sink.touchNode(params.graphId, params.kind, params.id, row);\n return row;\n },\n\n ...(target.insertNodeIfAbsent === undefined ?\n {}\n : {\n async insertNodeIfAbsent(\n params: InsertNodeParams,\n ): Promise<NodeRow | undefined> {\n await hooks.beforeOne?.(params.graphId);\n const row = await requireDefined(target.insertNodeIfAbsent)(params);\n if (row !== undefined) {\n sink.touchNode(params.graphId, params.kind, params.id, row);\n }\n return row;\n },\n }),\n\n ...(target.insertNodeIfAbsentWithSchemaFence === undefined ?\n {}\n : {\n async insertNodeIfAbsentWithSchemaFence(\n params: InsertNodeParams,\n schemaFence: SchemaWriteFenceParams,\n ): Promise<NodeRow | undefined> {\n await hooks.beforeOne?.(params.graphId);\n const row = await requireDefined(\n target.insertNodeIfAbsentWithSchemaFence,\n )(params, schemaFence);\n if (row !== undefined) {\n sink.touchNode(params.graphId, params.kind, params.id, row);\n }\n return row;\n },\n }),\n\n ...(target.insertNodeWithSchemaFence === undefined ?\n {}\n : {\n async insertNodeWithSchemaFence(\n params: InsertNodeParams,\n schemaFence: SchemaWriteFenceParams,\n ): Promise<NodeRow | undefined> {\n await hooks.beforeOne?.(params.graphId);\n const row = await requireDefined(target.insertNodeWithSchemaFence)(\n params,\n schemaFence,\n );\n if (row !== undefined) {\n sink.touchNode(params.graphId, params.kind, params.id, row);\n }\n return row;\n },\n }),\n\n ...(target.insertNodeNoReturn === undefined ?\n {}\n : {\n async insertNodeNoReturn(params: InsertNodeParams): Promise<void> {\n await hooks.beforeOne?.(params.graphId);\n await runInsertNoReturn(nodeDispatch, params);\n sink.touchNode(params.graphId, params.kind, params.id);\n },\n }),\n\n ...(target.insertNodesBatch === undefined ?\n {}\n : {\n async insertNodesBatch(\n params: readonly InsertNodeParams[],\n ): Promise<void> {\n await hooks.beforeMany?.(params);\n await runInsertBatch(nodeDispatch, params);\n for (const node of params) {\n sink.touchNode(node.graphId, node.kind, node.id);\n }\n },\n }),\n\n ...(target.insertNodesBatchReturning === undefined ?\n {}\n : {\n async insertNodesBatchReturning(\n params: readonly InsertNodeParams[],\n ): Promise<readonly NodeRow[]> {\n await hooks.beforeMany?.(params);\n const rows = await runInsertBatchReturning(nodeDispatch, params);\n const rowsByIdentity = new Map(\n rows.map((row) => [nodeRowIdentityKey(row), row] as const),\n );\n for (const node of params) {\n sink.touchNode(\n node.graphId,\n node.kind,\n node.id,\n rowsByIdentity.get(nodeParamsIdentityKey(node)),\n );\n }\n return rows;\n },\n }),\n\n async updateNode(params) {\n await hooks.beforeOne?.(params.graphId);\n const row = await target.updateNode(params);\n sink.touchNode(params.graphId, params.kind, params.id, row);\n return row;\n },\n\n ...(target.upsertHeterogeneousNodes === undefined ?\n {}\n : {\n async upsertHeterogeneousNodes(\n params: HeterogeneousNodeUpsertParams,\n ): Promise<readonly NodeRow[]> {\n await hooks.beforeOne?.(params.schemaFence.graphId);\n const rows = await requireDefined(target.upsertHeterogeneousNodes)(\n params,\n );\n for (const row of rows) {\n sink.touchNode(row.graph_id, row.kind, row.id, row);\n }\n return rows;\n },\n }),\n\n ...(target.updateResolvedNodesBatch === undefined ?\n {}\n : {\n async updateResolvedNodesBatch(params) {\n if (params.entries.length === 0) return [];\n const first = requireDefined(params.entries[0]);\n await hooks.beforeOne?.(first.graphId);\n const rows = await requireDefined(target.updateResolvedNodesBatch)(\n params,\n );\n for (const row of rows) {\n sink.touchNode(row.graph_id, row.kind, row.id, row);\n }\n return rows;\n },\n }),\n\n ...(target.updateNodeSet === undefined ?\n {}\n : {\n async updateNodeSet(params) {\n await hooks.beforeOne?.(params.graphId);\n const result = await requireDefined(target.updateNodeSet)(params);\n for (const row of result.rows) {\n sink.touchNode(row.graph_id, row.kind, row.id, row);\n }\n return result;\n },\n }),\n\n ...(target.compareAndSetNode === undefined ?\n {}\n : {\n async compareAndSetNode(params) {\n await hooks.beforeOne?.(params.graphId);\n const result = await requireDefined(target.compareAndSetNode)(params);\n for (const row of result.rows) {\n sink.touchNode(row.graph_id, row.kind, row.id, row);\n }\n return result;\n },\n }),\n\n async deleteNode(params) {\n await hooks.beforeOne?.(params.graphId);\n await target.deleteNode(params);\n sink.touchNode(params.graphId, params.kind, params.id);\n },\n\n async hardDeleteNode(params) {\n await hooks.beforeOne?.(params.graphId);\n const connectedEdgeIds =\n (await hooks.connectedEdgeIdsForHardDelete?.(params)) ?? [];\n await target.hardDeleteNode(params);\n sink.touchNode(params.graphId, params.kind, params.id);\n for (const edgeId of connectedEdgeIds) {\n sink.touchEdge(params.graphId, edgeId);\n }\n },\n\n async insertEdge(params) {\n await hooks.beforeOne?.(params.graphId);\n const row = await target.insertEdge(params);\n sink.touchEdge(params.graphId, params.id, row);\n return row;\n },\n\n ...(target.insertEdgeNoReturn === undefined ?\n {}\n : {\n async insertEdgeNoReturn(params: InsertEdgeParams): Promise<void> {\n await hooks.beforeOne?.(params.graphId);\n await runInsertNoReturn(edgeDispatch, params);\n sink.touchEdge(params.graphId, params.id);\n },\n }),\n\n ...(target.insertEdgesBatch === undefined ?\n {}\n : {\n async insertEdgesBatch(\n params: readonly InsertEdgeParams[],\n ): Promise<void> {\n await hooks.beforeMany?.(params);\n await runInsertBatch(edgeDispatch, params);\n for (const edge of params) {\n sink.touchEdge(edge.graphId, edge.id);\n }\n },\n }),\n\n ...(target.insertEdgesBatchReturning === undefined ?\n {}\n : {\n async insertEdgesBatchReturning(\n params: readonly InsertEdgeParams[],\n ): Promise<readonly EdgeRow[]> {\n await hooks.beforeMany?.(params);\n const rows = await runInsertBatchReturning(edgeDispatch, params);\n const rowsByIdentity = new Map(\n rows.map((row) => [edgeRowIdentityKey(row), row] as const),\n );\n for (const edge of params) {\n sink.touchEdge(\n edge.graphId,\n edge.id,\n rowsByIdentity.get(edgeParamsIdentityKey(edge)),\n );\n }\n return rows;\n },\n }),\n\n ...(target.insertEdgesDurableBatchReturning === undefined ?\n {}\n : {\n async insertEdgesDurableBatchReturning(\n params: readonly InsertEdgeParams[],\n ): Promise<readonly EdgeRow[]> {\n await hooks.beforeMany?.(params);\n const rows = await requireDefined(\n target.insertEdgesDurableBatchReturning,\n )(params);\n for (const row of rows) {\n sink.touchEdge(row.graph_id, row.id, row);\n }\n return rows;\n },\n }),\n\n async updateEdge(params) {\n await hooks.beforeOne?.(params.graphId);\n const row = await target.updateEdge(params);\n sink.touchEdge(params.graphId, params.id, row);\n return row;\n },\n\n async deleteEdge(params) {\n await hooks.beforeOne?.(params.graphId);\n await target.deleteEdge(params);\n sink.touchEdge(params.graphId, params.id);\n },\n\n async hardDeleteEdge(params) {\n await hooks.beforeOne?.(params.graphId);\n await target.hardDeleteEdge(params);\n sink.touchEdge(params.graphId, params.id);\n },\n\n ...(target.deleteEdgesBatch === undefined ?\n {}\n : {\n async deleteEdgesBatch(params: DeleteEdgesBatchParams): Promise<void> {\n await hooks.beforeOne?.(params.graphId);\n await requireDefined(target.deleteEdgesBatch)(params);\n for (const id of params.ids) {\n sink.touchEdge(params.graphId, id);\n }\n },\n }),\n\n ...(target.hardDeleteEdgesBatch === undefined ?\n {}\n : {\n async hardDeleteEdgesBatch(\n params: DeleteEdgesBatchParams,\n ): Promise<void> {\n await hooks.beforeOne?.(params.graphId);\n await requireDefined(target.hardDeleteEdgesBatch)(params);\n for (const id of params.ids) {\n sink.touchEdge(params.graphId, id);\n }\n },\n }),\n };\n}\n\n/**\n * Builds the `commands` port override both consumers install alongside\n * {@link buildRecordedWriteMembers} — a nested port rather than a plain\n * method, so it cannot join that function's returned object literal.\n */\nexport function buildRecordedCommandsPort(\n target: TransactionBackend,\n sink: WriteTouchSink,\n hooks: WriteMemberHooks = {},\n): GraphCommandPort {\n return {\n session: target.commands.session,\n execute: async (\n command: GraphCommand,\n context: GraphCommandExecutionContext,\n ): Promise<GraphCommandResult> => {\n await hooks.beforeOne?.(command.plan.params.graphId);\n const result = await target.commands.execute(command, context);\n assertCommandResultMatchesCommand(command, result);\n if (result.outcome === \"created\") {\n if (result.entity === \"node\") {\n sink.touchNode(\n command.plan.params.graphId,\n command.plan.params.kind,\n command.plan.params.id,\n result.row,\n );\n } else {\n sink.touchEdge(\n command.plan.params.graphId,\n command.plan.params.id,\n result.row,\n );\n }\n }\n return result;\n },\n };\n}\n\n/**\n * An engine-native transaction's counterpart to a TypeGraph-owned capture\n * session: `wrap` installs the same write-member overlay\n * {@link buildRecordedWriteMembers} builds for capture, but its sink flips\n * one boolean instead of collecting after-images, and it takes no\n * `WriteMemberHooks` — engine-native writes no recorded relation, so there\n * is neither a session to keep open nor an advisory lock to take. `mutated`\n * answers `true` once any wrapped member has genuinely changed a row; it is\n * the source of truth an engine-native store reads before minting\n * `TransactionReceipt.recorded`, rather than a collection-level write-INTENT\n * count reaching the collection surface — a delete of a missing row, an\n * `insertNodeIfAbsent` that found the row, or a coalesced unchanged upsert\n * all reach the collection surface without a single row having changed.\n *\n * `wrap`'s overlay alone only observes the graph-entity write surface\n * {@link buildRecordedWriteMembers} covers — a real identity assertion needs\n * the returned `sink` separately registered against the SAME wrapped target\n * through `registerRecordedIdentityMutationWitness`\n * (`../recorded-capture.ts`), the identical binding seam TypeGraph-owned\n * capture registers its own session-backed sink through for\n * `withRecordedIdentityMutationTarget`. A transaction whose only effect is a\n * raw `tx.sql` statement still leaves `mutated` `false` even though the\n * engine's own revision advanced underneath it — neither this sink nor\n * identity's binding observes raw SQL, the same gap\n * `TransactionReceiptRecorder`'s old write-intent counters always had. See\n * `apps/docs/src/content/docs/queries/temporal.md`'s engine-native paragraph\n * for the same boundary stated for readers.\n *\n * `wrap` uses {@link deriveBackend}, not `deriveTransactionSessionBackend`,\n * so a source session that declared session-scoped atomic-batch authority\n * (`capabilities.execution.atomicBatch === \"session\"`) loses it on the\n * wrapped object. This is deliberate, not an oversight: an atomic batch\n * program executes as one opaque unit the backend runs without calling back\n * into any of the overlay's individual write members, so a write issued\n * through it would commit unobserved — silently invalidating `mutated`\n * rather than merely losing a performance optimization. Withdrawing the\n * capability keeps every write inside a receipted engine-native transaction\n * routed through a member this witness can see.\n */\nexport function createMutationWitness(): Readonly<{\n wrap: (target: TransactionBackend) => TransactionBackend;\n readonly mutated: boolean;\n /** The sink `wrap` installs, for `registerRecordedIdentityMutationWitness`\n * to register against the same wrapped target so an identity assertion\n * also flips `mutated`. */\n readonly sink: WriteTouchSink;\n}> {\n let mutated = false;\n const sink: WriteTouchSink = {\n touchNode: () => {\n mutated = true;\n },\n touchEdge: () => {\n mutated = true;\n },\n touchIdentity: () => {\n mutated = true;\n },\n };\n return {\n wrap(target: TransactionBackend): TransactionBackend {\n return deriveBackend(target, {\n ...buildRecordedWriteMembers(target, sink),\n commands: buildRecordedCommandsPort(target, sink),\n });\n },\n get mutated(): boolean {\n return mutated;\n },\n sink,\n };\n}\n","/**\n * Derives the backend's optional `lineage` capability\n * (`backend/capabilities/lineage.ts`) from TypeGraph's own recorded\n * relations, for a store that captures history — and the one place that\n * picks between an engine's own `lineage` and this derived one.\n *\n * ## Revision encoding\n *\n * `revision()` reports `<origin>:<clock>` as an `EngineRevision`: the\n * graph's durable, random revision-origin nonce ({@link readRevisionOrigin},\n * minted on demand through `store.revisionOriginNow()` — the SAME\n * `typegraph_revision_origins` row `base-version.ts`'s revision and engine\n * anchors bind to), joined to the graph's recorded-time clock (the same\n * value `store.revisionNow()` exposes, or the fixed genesis token before\n * this graph has ever advanced its clock). The clock half is per GRAPH, not\n * per engine — stricter than the general `LineageMembers` contract, which\n * describes a whole-database revision — and is exactly the anchor the\n * base-version token already uses, so it costs nothing new to read.\n *\n * The origin half is what makes the token safe to compare across a\n * `Store.clear()` boundary or a numerically coincidental clock from a\n * different physical store sharing this `graphId` (see \"Token identity\"\n * below): `changesSince` parses it back out of `since` and treats a\n * mismatch against the graph's LIVE origin exactly like an unparseable\n * revision — `unbounded`, never a guess. `revision()` resolves the origin\n * entirely through `store.revisionOriginNow()` rather than reading\n * {@link readRevisionOrigin} on `session` itself first: minting a\n * never-before-seen origin is a WRITE (schema DDL plus an insert), and for a\n * capture-enabled store `session` is often the recorded-capture wrapper,\n * which refuses raw `executeStatement` regardless of which table it\n * targets — but even a plain READ of the origins relation cannot safely run\n * on `session` ahead of that DDL: a backend whose `ensureRevisionOriginsTable`\n * provisions the relation lazily (see `Store.clear()`'s own comment on this)\n * has no such table at all until something ensures it, and `session` (a\n * `LineageSession`) carries no `ensureRevisionOriginsTable` member of its\n * own to do that with. `Store.revisionOriginNow()` already knows both how to\n * ensure the relation and how to route the read/mint around the\n * recorded-capture wrapper onto the store's raw backend (see its own doc\n * comment), so this module defers to it completely rather than re-deriving\n * either half.\n *\n * ## The changed-since predicate\n *\n * `changesSince` reads both recorded relations for rows with\n * `recorded_from > rev` OR (`recorded_to > rev` AND `recorded_to` is not\n * the open-interval sentinel, {@link RECORDED_MAX_REVISION} — the ONE owner\n * of that value, also used by every write to these relations). Every write\n * shape a recorded relation can express is covered by one side or the\n * other:\n *\n * - a plain insert or update: the flush pipeline always inserts the new\n * row with `recorded_from` set to the commit revision, so it matches\n * `recorded_from > rev` directly;\n * - an update also closes the row it replaces, moving that PRIOR row's\n * `recorded_to` to the same commit revision — matched by the second\n * arm, and deduplicated against the first (same `(kind, id)`) by the\n * `DISTINCT` this module's queries always apply;\n * - a soft delete inserts a tombstone row exactly like an update, so it is\n * covered the same way;\n * - a hard delete (a single node/edge, or an entire kind) closes the open\n * recorded row WITHOUT inserting a replacement — covered only by the\n * second arm, which is why the sentinel exclusion cannot be dropped: a\n * still-open row's `recorded_to` sentinel must never itself register as\n * \"changed\";\n * - a resurrection (`upsertById` reviving a soft-deleted row) closes the\n * tombstone and inserts a fresh row, so it is covered by both arms and\n * reported exactly once via the same deduplication.\n *\n * ## What `changesSince` cannot answer\n *\n * A revision strictly newer than the graph's own clock is not something\n * this graph could have produced (a caller confusing graphs, or a\n * revision from a store this backend never wrote through) — a caller of\n * `resolveLineage` already knows to fall back to a full comparison when a\n * delta cannot be trusted, so this reports `unbounded` rather than\n * guessing. The same is true of a token this module never minted at all\n * (a garbage string, or one from a different `lineage` source): it fails\n * {@link parseLineageRevision}'s grammar and is treated identically.\n *\n * ## Completeness evidence\n *\n * The delta is trustworthy only when EVERY commit that touched this graph\n * between `since` and the current clock left recorded-relation evidence —\n * TypeGraph's revision clock is shared between `revisionTracking` and\n * `history` (see `clock.ts`'s `advanceRevisionClock`), so a second `Store`\n * over the same backend/graph constructed with `revisionTracking: true` but\n * no `history` advances the SAME clock without ever inserting a recorded\n * row, and a graph that ran that way before `history: true` was ever\n * enabled has an identical gap at its start. Both are the same shape: a\n * revision this graph's clock reached with no row in any recorded relation\n * to show for it.\n *\n * `changesSince` proves completeness directly rather than inferring it from\n * a ceiling: {@link evidencedRevisionCount} counts the DISTINCT revisions in\n * `(since, current]` that have direct evidence — a `recorded_from` or a\n * non-sentinel `recorded_to` — in ANY of the three recorded relations\n * (nodes, edges, identity assertions; folding identity assertions in keeps a\n * graph whose earliest commits only asserted identities from looking like a\n * gap). Every capturing commit allocates exactly one revision and touches\n * EITHER `recorded_from` (an insert, update, soft delete, or resurrection)\n * OR `recorded_to` (a hard delete, which closes the open row without\n * inserting a replacement) AT that revision — never neither — so a\n * genuinely complete span has EXACTLY `current - since` evidenced revisions,\n * one per commit. Fewer than that means some revision in the span has no\n * evidence at all: a hole, wherever in the span it falls. Unlike a\n * ceiling-only check, this catches a non-capturing write REGARDLESS of\n * whether a later capturing commit follows it — there is no way for a\n * subsequent commit to \"close\" a hole that already happened, because the\n * missing revision itself never gets evidence no matter what comes after.\n *\n * Two commit shapes can legitimately allocate a revision and leave ZERO\n * evidence behind. A kind-level hard delete (`closeRecordedHardDeletedKind`\n * in `flush.ts`, run when a schema migration removes a node or edge kind)\n * over a kind that currently has no live rows: the\n * `UPDATE ... WHERE recorded_to = sentinel` it issues matches nothing, so\n * neither column moves at that revision. And a forced revision\n * (`forceRecordedGraphRevision`, which every `applyMergePlan` requests so an\n * applied plan always advances the target's anchor, honored by `flush()`'s\n * forced-revision branch with an empty entity list) when the plan carried no\n * writes at all. When such a commit is the ONLY thing that happened at that\n * revision, the evidence count comes up one short of a span that in truth\n * changed nothing for this graph, and `changesSince` reports `unbounded`\n * even though the honest answer would have been an empty `\"keys\"` delta. This is the capability's fail-open contract working\n * as designed: a false `unbounded` costs a caller an avoidable full\n * comparison, never a missed change, so it is accepted rather than special-cased.\n *\n * A raw `GraphBackend` write bypassing every `Store` entirely, or an\n * engine-side mutation outside TypeGraph, is a DIFFERENT shape than the gap\n * above and this evidence count cannot catch it: such a write never\n * allocates a revision on this graph's clock at all, so `currentRevision`\n * does not move to account for it, the evidence count still comes out\n * exactly equal to `currentRevision - since`, and the row it touched is\n * simply absent from the `\"keys\"` delta with no signal anywhere that\n * anything was missed. Routing every writer through a capturing `Store` is\n * the only way to keep this source's delta exhaustive; nothing in\n * `changesSince` can detect a writer that never touched the clock it reads.\n * The only writer this module RULES OUT rather than merely fails to catch is\n * one that advances a DIFFERENT graph's clock or touches a different\n * database — `refuseForeignGraph` and the origin check below reject those\n * before this check ever runs.\n *\n * ## Token identity is scoped to one graph, not one physical store\n *\n * Two independently created stores that happen to share a `graphId` mint\n * numerically comparable clock values (a fresh database starts counting\n * from the same low integers as any other), and the SAME store's clock\n * after `clear()` restarts numbering too (`Store.clear()` drops the\n * recorded relations and the clock row, and rotates the origin — see\n * `resetRevisionOrigin`). The origin half of the token is what makes\n * this safe: `changesSince` reads the graph's LIVE origin and refuses\n * (`unbounded`) whenever it differs from the one embedded in `since`, so a\n * revision minted before a `clear()`, or by a different physical store that\n * happens to share this `graphId`, can never satisfy a post-clear or\n * cross-store comparison even when the numeric clock values coincide. Every\n * caller that anchors ACROSS stores or across time —\n * `base-version.ts`'s revision-anchor branch, `branch()`'s `forkRevision`\n * capture, and `staging.ts`'s pruning are the ones today — gets this check\n * for free by going through `revision()`/`changesSince()` rather than\n * comparing a bare clock value itself. `base-version.ts`'s OWN `base@V`\n * token grammar carries a separate, independently-checked origin pairing\n * for its own revision and engine anchors (see that module's doc and\n * `revisionOriginMatch`) — the two origin checks protect different tokens\n * and neither substitutes for the other, though both draw on the same\n * durable `typegraph_revision_origins` row.\n */\nimport {\n type EngineRevision,\n type EntityKey,\n type LineageDelta,\n type LineageMembers,\n type LineageSession,\n} from \"../../backend/types\";\nimport { type GraphDef } from \"../../core/define-graph\";\nimport {\n asRecordedInstant,\n RECORDED_MAX_REVISION,\n recordedInstantRevision,\n} from \"../../core/temporal\";\nimport { ConfigurationError } from \"../../errors\";\nimport { type SqlSchema } from \"../../query/compiler/schema\";\nimport { sql, type SqlFragment } from \"../../query/sql-fragment\";\nimport { asCompiledRowsSql } from \"../../query/sql-intent\";\nimport {\n type STORE_RUNTIME,\n storeBackend,\n storeCaptureEnabled,\n type StoreRuntime,\n} from \"../runtime-port\";\nimport { readRecordedClock, readRevisionOrigin } from \"./clock\";\n\n/**\n * The minimal store surface {@link recordedRelationsLineage} and\n * {@link resolveLineage} need: the graph this lineage answers for, the\n * schema naming the physical recorded relations, and the runtime port\n * reaching the store's own backend and its `storeCaptureEnabled` flag —\n * whether this store captures history through TypeGraph's own recorded\n * relations, not merely whether `history: true` was requested (an\n * engine-native store answers that too, without ever populating them; see\n * `storeCaptureEnabled`'s own doc comment).\n *\n * A structural type rather than the `Store` class itself: `store/store.ts`\n * constructs the store's runtime port using exports from this same\n * `recorded-capture` family, so importing `Store` back here would cycle.\n * Every real `Store<G>` already carries these members, so a live store is\n * assignable to this type without adaptation.\n */\nexport type RecordedLineageStore<G extends GraphDef = GraphDef> = Readonly<{\n graphId: string;\n revisionTrackingEnabled: boolean;\n revisionSchema: SqlSchema;\n /**\n * Mints (or returns) this graph's durable revision-origin nonce, always\n * through the store's OWN raw backend regardless of which session called\n * it — see `Store.revisionOriginNow()`'s own doc for why it deliberately\n * bypasses the recorded-capture wrapper. `revision()` defers to this\n * rather than re-deriving the mint here: a capture-enabled store's\n * wrapped backend refuses raw `executeStatement` outright (it exists to\n * catch a graph write bypassing capture), so minting through anything\n * `resolveLineage`'s callers might pass as a `LineageSession` — which,\n * for a history-enabled store, is that very wrapper — would refuse for a\n * reason that has nothing to do with this row.\n */\n revisionOriginNow: () => Promise<string>;\n [STORE_RUNTIME]?: StoreRuntime<G>;\n}>;\n\n/**\n * Brands a plain string as an `EngineRevision`. The one cast site this\n * module uses to mint the branded type — from the genesis sentinel below,\n * and from a real `RecordedInstant` string (a distinct brand, so crossing\n * from one to the other goes through this shared `string` step rather than\n * each call site inventing its own cross-brand assertion).\n */\nfunction brandEngineRevision(value: string): EngineRevision {\n return value as EngineRevision;\n}\n\n/**\n * The `since`-half of {@link recordedRelationsLineage}'s revision grammar\n * when this graph has never advanced its recorded clock: `revision()`\n * reports `<origin>${LINEAGE_REVISION_SEPARATOR}${GENESIS_REVISION_TOKEN}`\n * rather than a real `RecordedInstant`. Deliberately NOT a valid\n * `RecordedInstant` (it fails that grammar), so it can never collide with a\n * real committed revision; recognized only by this module's own\n * `parseLineageRevision`, per the opaque-token contract every `lineage`\n * source shares.\n *\n * This is a distinct constant from `base-version.ts`'s `INITIAL_REVISION`,\n * not a re-spelling of one predicate: that string lives in the `EngineRevision`\n * grammar. `store/recorded-capture` sits below `graph-merge` in the\n * dependency graph, so this module cannot import the base-token constant\n * without inverting that layering.\n */\nconst GENESIS_REVISION_TOKEN = \"recorded-relations-lineage:genesis\";\nconst GENESIS_REVISION_NUMBER = 0;\n\n/**\n * Separates the durable per-graph origin from the clock half of a bundled\n * `EngineRevision` (see the module doc's \"Revision encoding\" and \"Token\n * identity\" sections). `generateId()` origins never contain this character\n * (URL-safe nanoid alphabet), so splitting at the FIRST occurrence\n * unambiguously recovers the origin even though the clock half — a\n * `RecordedInstant`, itself colon-delimited — contains more of them.\n */\nconst LINEAGE_REVISION_SEPARATOR = \":\";\n\nconst UNBOUNDED_DELTA: LineageDelta = Object.freeze({ kind: \"unbounded\" });\n\n/**\n * THE one owner of the bundled `EngineRevision` grammar: `<origin>` then\n * {@link LINEAGE_REVISION_SEPARATOR} then either a real `RecordedInstant` or\n * {@link GENESIS_REVISION_TOKEN} (`instant` omitted). Used by `revision()`\n * to mint the token, and by `base-version.ts`'s `lineageDeltaSinceAnchor` to\n * rebuild the equivalent token from a `base@V` revision anchor's own\n * (already-verified) origin and revision components — so neither producer\n * hand-spells the separator.\n */\nexport function encodeRecordedLineageRevision(\n origin: string,\n instant: string | undefined,\n): EngineRevision {\n return brandEngineRevision(\n `${origin}${LINEAGE_REVISION_SEPARATOR}${instant ?? GENESIS_REVISION_TOKEN}`,\n );\n}\n\n/**\n * Decodes a `COUNT`/`MIN`/`MAX`-shaped aggregate value into a JS number.\n * BIGINT columns come back as a `bigint` on some drivers and a numeric\n * string on others (PostgreSQL's default driver never parses BIGINT), so\n * both are normalized alongside the plain-number case a small SQLite value\n * already arrives as.\n */\nfunction decodeAggregateRevision(value: bigint | number | string): number {\n return typeof value === \"number\" ? value : Number(value);\n}\n\n/**\n * Parses an `EngineRevision` this module minted back into the durable\n * origin and the numeric per-graph revision `changesSince` compares columns\n * against, or `undefined` for anything that does not fit the grammar — a\n * token from an unrelated `lineage` source, or a corrupted value.\n * `changesSince` treats an unparseable revision the same as a live-origin\n * mismatch or one newer than the clock: unknown, so `unbounded`.\n */\nfunction parseLineageRevision(\n revision: EngineRevision,\n): Readonly<{ origin: string; revision: number }> | undefined {\n const separatorIndex = revision.indexOf(LINEAGE_REVISION_SEPARATOR);\n if (separatorIndex <= 0) return undefined;\n const origin = revision.slice(0, separatorIndex);\n const remainder = revision.slice(separatorIndex + 1);\n if (remainder === GENESIS_REVISION_TOKEN) {\n return { origin, revision: GENESIS_REVISION_NUMBER };\n }\n try {\n return {\n origin,\n revision: recordedInstantRevision(asRecordedInstant(remainder)),\n };\n } catch {\n return undefined;\n }\n}\n\n/**\n * The number of DISTINCT revisions in `(sinceRevision, currentRevision]`\n * with direct completeness evidence — a `recorded_from` or a non-sentinel\n * `recorded_to` — in ANY of the three recorded relations for this graph\n * (nodes, edges, identity assertions). This is the whole completeness\n * check `changesSince` runs (see the module doc's \"Completeness evidence\"):\n * a genuinely complete span has exactly `currentRevision - sinceRevision`\n * evidenced revisions, one per capturing commit; fewer means a hole\n * somewhere in the span, regardless of where.\n *\n * Evidence means EITHER column, not `recorded_from` alone: an insert,\n * update, soft delete, or resurrection writes a row whose `recorded_from`\n * is the allocated revision, but a HARD delete closes the existing open row\n * — moving ONLY its `recorded_to` to the allocated revision — without\n * inserting any row at that revision (see the module doc's per-write-shape\n * breakdown). Excluding the open-interval sentinel from the `recorded_to`\n * arm is required for the same reason `changedEntityKeys` excludes it: a\n * still-open row's sentinel must never itself register as activity at the\n * sentinel revision.\n */\nasync function evidencedRevisionCount(\n session: LineageSession,\n schema: SqlSchema,\n graphId: string,\n sinceRevision: number,\n currentRevision: number,\n): Promise<number> {\n const rows = await session.execute<\n Readonly<{ evidenced: bigint | number | string | null }>\n >(\n asCompiledRowsSql(sql`\n SELECT COUNT(DISTINCT rev) AS evidenced FROM (\n SELECT recorded_from AS rev FROM ${schema.recordedNodesTable}\n WHERE graph_id = ${graphId} AND recorded_from > ${sinceRevision} AND recorded_from <= ${currentRevision}\n UNION ALL\n SELECT recorded_to AS rev FROM ${schema.recordedNodesTable}\n WHERE graph_id = ${graphId} AND recorded_to <> ${RECORDED_MAX_REVISION} AND recorded_to > ${sinceRevision} AND recorded_to <= ${currentRevision}\n UNION ALL\n SELECT recorded_from AS rev FROM ${schema.recordedEdgesTable}\n WHERE graph_id = ${graphId} AND recorded_from > ${sinceRevision} AND recorded_from <= ${currentRevision}\n UNION ALL\n SELECT recorded_to AS rev FROM ${schema.recordedEdgesTable}\n WHERE graph_id = ${graphId} AND recorded_to <> ${RECORDED_MAX_REVISION} AND recorded_to > ${sinceRevision} AND recorded_to <= ${currentRevision}\n UNION ALL\n SELECT recorded_from AS rev FROM ${schema.recordedIdentityAssertionsTable}\n WHERE graph_id = ${graphId} AND recorded_from > ${sinceRevision} AND recorded_from <= ${currentRevision}\n UNION ALL\n SELECT recorded_to AS rev FROM ${schema.recordedIdentityAssertionsTable}\n WHERE graph_id = ${graphId} AND recorded_to <> ${RECORDED_MAX_REVISION} AND recorded_to > ${sinceRevision} AND recorded_to <= ${currentRevision}\n ) AS lineage_evidenced_revisions\n `),\n );\n const evidenced = rows[0]?.evidenced;\n return evidenced === null || evidenced === undefined ?\n 0\n : decodeAggregateRevision(evidenced);\n}\n\n/**\n * Every `(kind, id)` in one recorded relation with a change strictly after\n * `sinceRevision` — the shared query behind both the node and edge halves\n * of a `\"keys\"` delta. See the module doc for why the two-armed predicate\n * covers every write shape and why `DISTINCT` is what keeps a row that\n * matches both arms (a resurrection) from being reported twice.\n */\nasync function changedEntityKeys(\n session: LineageSession,\n table: SqlFragment,\n graphId: string,\n sinceRevision: number,\n): Promise<readonly EntityKey[]> {\n const rows = await session.execute<Readonly<{ kind: string; id: string }>>(\n asCompiledRowsSql(sql`\n SELECT DISTINCT kind, id\n FROM ${table}\n WHERE graph_id = ${graphId}\n AND (\n recorded_from > ${sinceRevision}\n OR (recorded_to > ${sinceRevision} AND recorded_to <> ${RECORDED_MAX_REVISION})\n )\n ORDER BY kind, id\n `),\n );\n return rows.map((row) => ({ kind: row.kind, id: row.id }));\n}\n\n/**\n * Builds a `lineage` capability sourced from `store`'s own recorded\n * relations. Callers get this indirectly through {@link resolveLineage};\n * call it directly only to consult the recorded-relations source even when\n * the backend also declares its own `lineage` (e.g. the conformance suite).\n *\n * `revision`/`changesSince` run every READ on the {@link LineageSession}\n * they are given, never on a backend this function closed over — the same\n * \"session facts come from the session that enforces them\" contract every\n * `LineageMembers` implementation honors (see that type's own doc). Every\n * call graph-merge makes into this source (`branch()`'s fork-revision\n * capture, `staging.ts`'s pruning, `base-version.ts`'s\n * `lineageDeltaSinceAnchor`) runs at PLANNING time, strictly outside any\n * commit transaction, and passes the root backend it already holds as the\n * session — the recorded-relations source never actually reaches a\n * `transaction()` handle today, but nothing in `changesSince`'s\n * implementation depends on that: it reads correctly on whatever session a\n * future caller hands it, transaction handle included. `revision()`'s\n * ORIGIN resolution (`resolveOrigin`, see its own doc) is the one\n * exception: it always goes through `store.revisionOriginNow()`, never\n * `session`, for BOTH the mint and the ordinary read — minting is a WRITE,\n * and `session` for a capture-enabled store's `lineage` is the\n * recorded-capture wrapper, which refuses raw `executeStatement` outright,\n * but even a plain read cannot safely run on `session` ahead of the DDL\n * that guarantees the origins relation exists. `changesSince`'s own\n * live-origin comparison (below) DOES read on `session`, unlike\n * `resolveOrigin`: by the time a real `since` token reaches it, some prior\n * `revision()` call already minted this graph's origin through\n * `store.revisionOriginNow()`, so the relation is already physically\n * present for any session sharing that database.\n */\nexport function recordedRelationsLineage<G extends GraphDef>(\n store: RecordedLineageStore<G>,\n): LineageMembers {\n if (!storeCaptureEnabled(store)) {\n throw new ConfigurationError(\n \"recordedRelationsLineage requires a store constructed with `history: true` — a non-capturing store never populates the recorded relations this lineage reads, so every changesSince would silently report an empty delta instead of the truth.\",\n { code: \"LINEAGE_REQUIRES_HISTORY\" },\n {\n suggestion:\n \"Construct the store with `history: true`, or call resolveLineage(store) instead — it already checks this and returns undefined for a non-capturing store rather than deriving a lineage that cannot see any writes.\",\n },\n );\n }\n\n const schema = store.revisionSchema;\n const graphId = store.graphId;\n\n function refuseForeignGraph(requestedGraphId: string): void {\n if (requestedGraphId === graphId) return;\n throw new ConfigurationError(\n \"recordedRelationsLineage's changesSince was called for a different graph than the one this lineage was derived from.\",\n {\n code: \"LINEAGE_GRAPH_MISMATCH\",\n derivedForGraphId: graphId,\n requestedGraphId,\n },\n {\n suggestion:\n \"Derive a separate lineage per graph with resolveLineage(store) — this lineage's revision() is a per-graph anchor, not comparable against another graph's rows.\",\n },\n );\n }\n\n /**\n * Resolves this graph's durable revision-origin nonce entirely through\n * `store.revisionOriginNow()` — never by reading {@link readRevisionOrigin}\n * on `session` first. A direct read on `session` would throw rather than\n * return `undefined` on a backend whose `ensureRevisionOriginsTable`\n * provisions the origins relation lazily (see the module doc's \"Revision\n * encoding\" section): the relation would not exist yet, and `session` (a\n * `LineageSession`) has no `ensureRevisionOriginsTable` member with which\n * to create it. `store.revisionOriginNow()` already ensures the relation\n * and mints a fresh origin only when none exists, so this function has no\n * ensure-or-mint logic of its own to get out of step with it. Takes no\n * `session`: there is nothing left for one to read.\n */\n function resolveOrigin(): Promise<string> {\n return store.revisionOriginNow();\n }\n\n async function revision(session: LineageSession): Promise<EngineRevision> {\n const [origin, instant] = await Promise.all([\n resolveOrigin(),\n readRecordedClock(session, schema, graphId),\n ]);\n return encodeRecordedLineageRevision(origin, instant);\n }\n\n async function changesSince(\n session: LineageSession,\n since: EngineRevision,\n requestedGraphId: string,\n ): Promise<LineageDelta> {\n refuseForeignGraph(requestedGraphId);\n const parsed = parseLineageRevision(since);\n if (parsed === undefined) return UNBOUNDED_DELTA;\n\n // Token identity (see the module doc): a revision minted before this\n // graph's origin last rotated (a `clear()`), or by a different physical\n // store that happens to share this `graphId`, can never satisfy this\n // check even when the numeric clock values below coincide. Reading\n // directly on `session` (rather than through `resolveOrigin`) is safe\n // here, unlike in `revision()`: a real `since` already came from some\n // earlier `revision()` call, which only ever returns after\n // `store.revisionOriginNow()` has ensured the origins relation exists.\n const liveOrigin = await readRevisionOrigin(session, schema, graphId);\n if (liveOrigin === undefined || liveOrigin !== parsed.origin) {\n return UNBOUNDED_DELTA;\n }\n\n const requested = parsed.revision;\n const currentInstant = await readRecordedClock(session, schema, graphId);\n const currentRevision =\n currentInstant === undefined ?\n GENESIS_REVISION_NUMBER\n : recordedInstantRevision(currentInstant);\n if (requested > currentRevision) return UNBOUNDED_DELTA;\n\n if (requested < currentRevision) {\n // Completeness evidence (see the module doc): the span is trustworthy\n // only when EVERY revision in it left a recorded row behind.\n const evidenced = await evidencedRevisionCount(\n session,\n schema,\n graphId,\n requested,\n currentRevision,\n );\n if (evidenced < currentRevision - requested) return UNBOUNDED_DELTA;\n }\n\n const [nodes, edges] = await Promise.all([\n changedEntityKeys(session, schema.recordedNodesTable, graphId, requested),\n changedEntityKeys(session, schema.recordedEdgesTable, graphId, requested),\n ]);\n return { kind: \"keys\", nodes, edges };\n }\n\n return Object.freeze({ revision, changesSince });\n}\n\n/**\n * Whether this store's base token is namespaced by the graph's durable\n * revision origin — true for the revision anchor (tracking on) and for the\n * engine anchor (tracking off, a backend `lineage` present), false only for\n * the content-fingerprint fallback. The one spelling `Store.clear()` uses\n * to decide whether there is an origin to rotate, so it cannot drift from\n * the anchor precedence `computeBaseVersion` applies: a store that mints an\n * origin-namespaced anchor is exactly a store whose `clear()` must rotate\n * that origin. A backend whose `lineage` is present but which cannot\n * bootstrap the origins relation mints no anchor at all (`computeBaseVersion`\n * refuses), so it has nothing to rotate either.\n */\nexport function mintsOriginNamespacedAnchor<G extends GraphDef>(\n store: RecordedLineageStore<G>,\n originsSupported: boolean,\n): boolean {\n if (store.revisionTrackingEnabled) return true;\n return resolveLineage(store) !== undefined && originsSupported;\n}\n\n/**\n * THE one owner of lineage source selection: the backend's own `lineage`\n * when it declares one, else the store's recorded-relations lineage when\n * this store captures history, else `undefined`. Every caller that wants a\n * `lineage` — graph-merge's base-token anchor and pruned diff among\n * them — consults this function instead of re-deriving the choice.\n */\nexport function resolveLineage<G extends GraphDef>(\n store: RecordedLineageStore<G>,\n): LineageMembers | undefined {\n const backend = storeBackend(store);\n if (backend.lineage !== undefined) return backend.lineage;\n if (storeCaptureEnabled(store)) return recordedRelationsLineage(store);\n return undefined;\n}\n","import {\n type CatalogColumn,\n type NormalizedColumnKind,\n requireCatalog,\n REVISION_COLUMN_KINDS,\n WALL_TIME_COLUMN_KINDS,\n} from \"../../backend/capabilities/catalog\";\nimport { type GraphBackend } from \"../../backend/types\";\nimport { ConfigurationError } from \"../../errors\";\nimport { type SqlSchema } from \"../../query/compiler/schema\";\n\ntype RecordedColumnKind = \"revision\" | \"wall-time\";\n\ntype RequiredRecordedColumn = Readonly<{\n column: string;\n kind: RecordedColumnKind;\n table: string;\n}>;\n\nasync function readColumnTypes(\n backend: Pick<GraphBackend, \"catalog\">,\n table: string,\n): Promise<ReadonlyMap<string, CatalogColumn>> {\n const catalog = requireCatalog(backend, \"assertCurrentRecordedSchema\");\n const columns = await catalog.columnTypes(table);\n return new Map(columns.map((column) => [column.name, column]));\n}\n\n/**\n * Whether a column normalized to `actual` is compatible with the recorded\n * time role `kind` expects, checked against the owned kind set for that\n * role ({@link REVISION_COLUMN_KINDS} / {@link WALL_TIME_COLUMN_KINDS})\n * rather than a dialect branch — the two dialects agree on the revision\n * kind but not on the wall-time one, which is exactly what those two sets\n * already encode.\n */\nfunction isCompatibleColumnKind(\n kind: RecordedColumnKind,\n actual: NormalizedColumnKind,\n): boolean {\n const allowed =\n kind === \"revision\" ? REVISION_COLUMN_KINDS : WALL_TIME_COLUMN_KINDS;\n return allowed.includes(actual);\n}\n\nfunction requiredRecordedColumns(\n schema: SqlSchema,\n includeIdentity: boolean,\n): readonly RequiredRecordedColumn[] {\n const identityColumns: readonly RequiredRecordedColumn[] =\n includeIdentity ?\n [\n {\n table: schema.tables.recordedIdentityAssertions,\n column: \"recorded_from\",\n kind: \"revision\",\n },\n {\n table: schema.tables.recordedIdentityAssertions,\n column: \"recorded_to\",\n kind: \"revision\",\n },\n ]\n : [];\n return [\n {\n table: schema.tables.recordedNodes,\n column: \"recorded_from\",\n kind: \"revision\",\n },\n {\n table: schema.tables.recordedNodes,\n column: \"recorded_to\",\n kind: \"revision\",\n },\n {\n table: schema.tables.recordedEdges,\n column: \"recorded_from\",\n kind: \"revision\",\n },\n {\n table: schema.tables.recordedEdges,\n column: \"recorded_to\",\n kind: \"revision\",\n },\n {\n table: schema.tables.recordedClock,\n column: \"revision\",\n kind: \"revision\",\n },\n {\n table: schema.tables.recordedClock,\n column: \"recorded_at\",\n kind: \"wall-time\",\n },\n ...identityColumns,\n ];\n}\n\n/**\n * Verifies that a history-enabled async store open targets the current\n * physical recorded schema. The synchronous `createStore` attach path cannot\n * perform this I/O and retains its fail-loud first-operation behavior.\n *\n * `includeIdentity` extends the check to the recorded identity relation, which\n * only exists for graphs that enable the TypeGraph Identity Profile.\n */\nexport async function assertCurrentRecordedSchema(\n backend: Pick<GraphBackend, \"catalog\" | \"dialect\">,\n schema: SqlSchema,\n includeIdentity = false,\n): Promise<void> {\n const requirements = requiredRecordedColumns(schema, includeIdentity);\n const tables = [...new Set(requirements.map((entry) => entry.table))];\n const columnTypes = new Map(\n await Promise.all(\n tables.map(\n async (table) =>\n [table, await readColumnTypes(backend, table)] as const,\n ),\n ),\n );\n const recordedIdentityTable = schema.tables.recordedIdentityAssertions;\n if (\n includeIdentity &&\n (columnTypes.get(recordedIdentityTable)?.size ?? 0) === 0\n ) {\n throw new ConfigurationError(\n \"Recorded identity history is not provisioned for this database.\",\n {\n code: \"RECORDED_IDENTITY_SCHEMA_MISSING\",\n dialect: backend.dialect,\n table: recordedIdentityTable,\n },\n {\n suggestion:\n \"Restore the missing recorded identity ledger from backup. If this is confirmed first-time identity enablement with no identity history to preserve, provision the relation through the backend's privileged setup path before reopening with history: true.\",\n },\n );\n }\n const incompatible = requirements.flatMap((requirement) => {\n const column = columnTypes.get(requirement.table)?.get(requirement.column);\n if (\n column !== undefined &&\n isCompatibleColumnKind(requirement.kind, column.kind)\n ) {\n return [];\n }\n // An empty declared type (SQLite accepts a column with none at all,\n // e.g. `CREATE TABLE t (a, ...)`) reports the same \"missing\" diagnostic\n // as an absent column — the catalog probe reports it as declaredType\n // \"\", not as an absent CatalogColumn, so an absent column alone is not\n // enough to catch it here.\n const actual =\n column === undefined || column.declaredType === \"\" ?\n \"missing\"\n : column.declaredType;\n return [{ ...requirement, actual }];\n });\n if (incompatible.length === 0) return;\n\n throw new ConfigurationError(\n \"Recorded-time schema is incompatible with history capture.\",\n {\n code: \"RECORDED_SCHEMA_INCOMPATIBLE\",\n dialect: backend.dialect,\n incompatible,\n },\n {\n suggestion:\n \"Run migrateLegacyRecordedTime({ backend }) before opening a store with history: true. If these are not preview-schema tables, provision the current recorded relations first.\",\n },\n );\n}\n","import { statementExecutionMembers } from \"../backend/capabilities/bind\";\nimport {\n type BATCH_POINT_READ,\n type STATEMENT_EXECUTION,\n} from \"../backend/capabilities/bundle-registry\";\nimport {\n batchPointReadVerdict,\n type BundleVerdictOf,\n} from \"../backend/capabilities/resolve\";\nimport {\n assertGraphCommandExecutionContext,\n executeAuthoritativeGraphCommand,\n type GraphCommandExecutionContext,\n} from \"../backend/command-contract\";\nimport {\n deriveBackend,\n isBackendDerivedFrom,\n projectGraphBackend,\n} from \"../backend/derive-backend\";\nimport {\n type DeleteEdgesBatchParams,\n type EdgeRow,\n type GraphBackend,\n type GraphCommand,\n type GraphCommandResult,\n type HeterogeneousNodeUpsertParams,\n type InsertEdgeParams,\n type InsertNodeParams,\n type InternalTransactionOptions,\n type NodeRow,\n type SchemaWriteFenceParams,\n type TransactionBackend,\n} from \"../backend/types\";\nimport { CompilerInvariantError, ConfigurationError } from \"../errors\";\nimport { type IdentityTarget } from \"../identity/sql-target\";\nimport { type IdentityAssertionStorageRow } from \"../identity/storage-types\";\nimport { type SqlSchema } from \"../query/compiler/schema\";\nimport { sql as portableSql } from \"../query/sql-fragment\";\nimport { asCompiledStatementSql } from \"../query/sql-intent\";\nimport { groupBy } from \"../utils/array\";\nimport { requireDefined } from \"../utils/presence\";\nimport {\n edgeInsertDispatch,\n nodeInsertDispatch,\n runInsertBatch,\n runInsertBatchReturning,\n runInsertNoReturn,\n} from \"./insert-dispatch\";\nimport {\n allocateRecordedCommit,\n createRecordedGraphLockMemo,\n lockRecordedGraphWrite,\n registerRecordedGraphLockMemo,\n} from \"./recorded-capture/clock\";\nimport {\n entityKey,\n flushEdges,\n flushIdentityAssertions,\n flushNodes,\n queryConnectedEdgeIds,\n type TouchedEdge,\n type TouchedEntity,\n type TouchedIdentityAssertion,\n type TouchedNode,\n} from \"./recorded-capture/flush\";\nimport {\n assertCapturableBackend,\n assertRecordedCaptureTransactionIsolation,\n assertRequestedRecordedIsolation,\n rawWriteGuards,\n requireCaptureStatements,\n requireRecordedSchema,\n withRecordedRelationsPrecondition,\n} from \"./recorded-capture/guards\";\nimport {\n buildRecordedCommandsPort,\n buildRecordedWriteMembers,\n type WriteMemberHooks,\n type WriteTouchSink,\n} from \"./recorded-capture/write-touch\";\n\nexport {\n advanceRevisionClock,\n ensureRevisionOrigin,\n ensureRevisionOriginsRelation,\n lockRecordedGraphWrite,\n readRecordedClock,\n readRevisionOrigin,\n recordedClockAdvisoryLockSql,\n recordedGraphWriteAdvisoryLockSql,\n resetRevisionOrigin,\n} from \"./recorded-capture/clock\";\nexport { closeRecordedHardDeletedKind } from \"./recorded-capture/flush\";\nexport {\n assertRecordedCaptureTransactionIsolation,\n assertRevisionTrackableBackend,\n recordedCaptureRequiresCallbackTransactionError,\n throwHistoryUnsafeSqlAccess,\n throwRevisionTrackingUnsafeSqlAccess,\n withRecordedRelationsPrecondition,\n} from \"./recorded-capture/guards\";\nexport {\n encodeRecordedLineageRevision,\n mintsOriginNamespacedAnchor,\n recordedRelationsLineage,\n resolveLineage,\n} from \"./recorded-capture/lineage\";\nexport {\n RECORDED_EDGE_COLUMNS,\n RECORDED_NODE_COLUMNS,\n} from \"./recorded-capture/relations\";\nexport { assertCurrentRecordedSchema } from \"./recorded-capture/schema-version\";\nexport {\n RECORDED_OPTIONAL_WRITE_METHODS,\n RECORDED_REQUIRED_WRITE_METHODS,\n} from \"./recorded-capture/write-surface\";\nexport { createMutationWitness } from \"./recorded-capture/write-touch\";\n\ntype RecordedCaptureSession = Readonly<{\n /**\n * Throws if the session is sealed. Called at the TOP of every overlay write\n * method, *before* the live write runs, so a write through a context retained\n * past its `withRecordedTransaction` callback fails loud instead of committing\n * an uncaptured live row. (`touch*` also re-checks after the write; this is\n * the pre-write guard that actually prevents the live mutation.)\n */\n assertOpen: () => void;\n touchNode: (\n graphId: string,\n kind: string,\n id: string,\n afterImage?: NodeRow,\n ) => void;\n touchEdge: (graphId: string, id: string, afterImage?: EdgeRow) => void;\n touchIdentityAssertion: (\n graphId: string,\n id: string,\n afterImage?: IdentityAssertionStorageRow,\n ) => void;\n forceGraphRevision: (graphId: string) => void;\n checkpoint: () => RecordedCaptureCheckpoint;\n restore: (checkpoint: RecordedCaptureCheckpoint) => void;\n flush: (\n target: TransactionBackend,\n batchPointRead: BundleVerdictOf<typeof BATCH_POINT_READ>,\n schema: SqlSchema,\n ownsWriteLock: boolean,\n ) => Promise<RecordedFlushInstants>;\n}>;\n\ntype RecordedCaptureCheckpoint = Readonly<{\n touched: ReadonlyMap<string, TouchedEntity>;\n forcedGraphRevisions: ReadonlySet<string>;\n}>;\n\nexport type RecordedFlushInstants = ReadonlyMap<string, string>;\n\ntype RecordedFlushObserver = (instants: RecordedFlushInstants) => void;\n\nconst RECORDED_FLUSH_OBSERVER = Symbol(\"typegraph.recordedFlushObserver\");\n\ntype RecordedFlushObserverOptions = InternalTransactionOptions &\n Readonly<{\n [RECORDED_FLUSH_OBSERVER]?: RecordedFlushObserver;\n }>;\n\nfunction readRecordedFlushObserver(\n options: InternalTransactionOptions | undefined,\n): RecordedFlushObserver | undefined {\n return (options as RecordedFlushObserverOptions | undefined)?.[\n RECORDED_FLUSH_OBSERVER\n ];\n}\n\nfunction stripRecordedFlushObserver(\n options: InternalTransactionOptions | undefined,\n): InternalTransactionOptions | undefined {\n if (options === undefined) return undefined;\n // Omit only the observer symbol; every other (current or future)\n // TransactionOptions field passes through to the wrapped backend untouched.\n const { [RECORDED_FLUSH_OBSERVER]: _observer, ...backendOptions } =\n options as RecordedFlushObserverOptions;\n return backendOptions;\n}\n\nexport function withRecordedFlushObserver(\n options: InternalTransactionOptions | undefined,\n observer: RecordedFlushObserver,\n): InternalTransactionOptions {\n return {\n ...stripRecordedFlushObserver(options),\n [RECORDED_FLUSH_OBSERVER]: observer,\n } as RecordedFlushObserverOptions;\n}\n\ntype RecordedTransactionScope = Readonly<{\n backend: TransactionBackend;\n flush: () => Promise<RecordedFlushInstants>;\n}>;\n\nfunction recordedCaptureSealedError(\n details: Record<string, unknown>,\n): ConfigurationError {\n return new ConfigurationError(\n \"Recorded-time capture session is sealed: a graph write happened after the transaction's capture was flushed.\",\n details,\n {\n suggestion:\n \"Perform all writes inside the withRecordedTransaction callback; do not reuse the transaction context after it returns.\",\n },\n );\n}\n\nfunction createRecordedCaptureSession(): RecordedCaptureSession {\n const touched = new Map<string, TouchedEntity>();\n const forcedGraphRevisions = new Set<string>();\n // Sealed by flush(): a scope flushes exactly once, at its terminal point, so\n // any touch afterward means a graph write happened after capture lost its\n // flush window (e.g. a caller reused the withRecordedTransaction context after\n // it returned). Fail loud rather than let that write commit uncaptured and\n // silently diverge history from live state.\n let sealed = false;\n\n function touch(entity: TouchedEntity): void {\n if (sealed) {\n throw recordedCaptureSealedError({\n entity: entity.entity,\n graphId: entity.graphId,\n id: entity.id,\n });\n }\n touched.set(entityKey(entity), entity);\n }\n\n return {\n assertOpen(): void {\n if (sealed) throw recordedCaptureSealedError({});\n },\n\n touchNode(\n graphId: string,\n kind: string,\n id: string,\n afterImage?: NodeRow,\n ): void {\n touch({ entity: \"node\", graphId, kind, id, afterImage });\n },\n\n touchEdge(graphId: string, id: string, afterImage?: EdgeRow): void {\n touch({ entity: \"edge\", graphId, id, afterImage });\n },\n\n touchIdentityAssertion(\n graphId: string,\n id: string,\n afterImage?: IdentityAssertionStorageRow,\n ): void {\n touch({ entity: \"identity\", graphId, id, afterImage });\n },\n\n forceGraphRevision(graphId: string): void {\n if (sealed) throw recordedCaptureSealedError({ graphId });\n forcedGraphRevisions.add(graphId);\n },\n\n checkpoint(): RecordedCaptureCheckpoint {\n if (sealed) throw recordedCaptureSealedError({});\n return {\n touched: new Map(touched),\n forcedGraphRevisions: new Set(forcedGraphRevisions),\n };\n },\n\n restore(checkpoint: RecordedCaptureCheckpoint): void {\n if (sealed) throw recordedCaptureSealedError({});\n touched.clear();\n for (const [key, entity] of checkpoint.touched) touched.set(key, entity);\n forcedGraphRevisions.clear();\n for (const graphId of checkpoint.forcedGraphRevisions) {\n forcedGraphRevisions.add(graphId);\n }\n },\n\n async flush(\n target: TransactionBackend,\n batchPointRead: BundleVerdictOf<typeof BATCH_POINT_READ>,\n schema: SqlSchema,\n ownsWriteLock: boolean,\n ): Promise<RecordedFlushInstants> {\n if (sealed) {\n throw new ConfigurationError(\n \"Recorded-time capture session was already flushed.\",\n {},\n {\n suggestion:\n \"A capture scope flushes once at its terminal point; do not flush it twice.\",\n },\n );\n }\n // Seal before the early-return so a no-write scope is sealed too, and\n // before any awaits so a re-entrant touch during flush also fails loud.\n // flush() writes recorded rows directly (never via touch), so sealing here\n // does not block its own work.\n sealed = true;\n if (touched.size === 0 && forcedGraphRevisions.size === 0)\n return new Map();\n const recordedByGraph = new Map<string, string>();\n const byGraph = groupBy(touched.values(), (entity) => entity.graphId);\n for (const graphId of forcedGraphRevisions) {\n if (!byGraph.has(graphId)) byGraph.set(graphId, []);\n }\n for (const [graphId, entities] of byGraph) {\n const recordedCommit = await allocateRecordedCommit(\n target,\n schema,\n graphId,\n ownsWriteLock,\n );\n recordedByGraph.set(graphId, recordedCommit.instant);\n const nodes = entities.filter(\n (entity): entity is TouchedNode => entity.entity === \"node\",\n );\n const edges = entities.filter(\n (entity): entity is TouchedEdge => entity.entity === \"edge\",\n );\n const identityAssertions = entities.filter(\n (entity): entity is TouchedIdentityAssertion =>\n entity.entity === \"identity\",\n );\n await flushNodes(\n target,\n batchPointRead,\n schema,\n graphId,\n nodes,\n recordedCommit.revision,\n );\n await flushEdges(\n target,\n batchPointRead,\n schema,\n graphId,\n edges,\n recordedCommit.revision,\n );\n await flushIdentityAssertions(\n target,\n schema,\n graphId,\n identityAssertions,\n recordedCommit.revision,\n );\n }\n touched.clear();\n forcedGraphRevisions.clear();\n return recordedByGraph;\n },\n };\n}\n\n/**\n * What `recordedTransactionBindings` maps a transaction object to. Every\n * binding can answer `withRecordedIdentityMutationTarget`'s question (\"is\n * this identity write touched, and what is the underlying raw target?\");\n * `capture` carries the additional session state only a TypeGraph-owned\n * transaction has — the engine-native mutation witness registers a binding\n * with `capture` absent, since it keeps no checkpoint to restore across a\n * savepoint and takes no advisory lock to release one.\n */\ntype RecordedTransactionBinding = Readonly<{\n target: TransactionBackend;\n assertOpen: () => void;\n sink: WriteTouchSink;\n capture?: Readonly<{\n session: RecordedCaptureSession;\n graphLocks: ReturnType<typeof createRecordedGraphLockMemo>;\n }>;\n}>;\n\ntype TransactionControlTarget = Readonly<\n Pick<TransactionBackend, \"executeStatement\">\n>;\n\ntype RecordedSavepointDecision<T> =\n | Readonly<{ action: \"release\"; value: T }>\n | Readonly<{ action: \"rollback\"; value: T; cause: unknown }>;\n\nconst recordedTransactionBindings = new WeakMap<\n object,\n RecordedTransactionBinding\n>();\n\nconst recordedRevisionBindings = new WeakMap<object, RecordedCaptureSession>();\n\n/** Carries capture/control state through a lifetime-guarded backend decoration. */\nexport function inheritRecordedTransactionBindings(\n source: TransactionBackend,\n derived: TransactionBackend,\n assertScopeOpen: () => void,\n): void {\n if (!isBackendDerivedFrom(derived, source)) {\n throw new TypeError(\"Capture bindings require a derived backend.\");\n }\n const binding = recordedTransactionBindings.get(source);\n if (binding !== undefined) {\n recordedTransactionBindings.set(derived, {\n ...binding,\n assertOpen: () => {\n assertScopeOpen();\n binding.assertOpen();\n },\n });\n if (binding.capture !== undefined) {\n registerRecordedGraphLockMemo(derived, binding.capture.graphLocks);\n }\n }\n const session = recordedRevisionBindings.get(source);\n if (session !== undefined) recordedRevisionBindings.set(derived, session);\n}\n\n/**\n * Runs one TypeGraph-owned savepoint without letting recorded state drift from\n * live state. A rollback restores both pending capture and the transaction's\n * graph-lock memo to their pre-savepoint snapshots. Callers never receive the\n * raw transaction target, so they cannot roll back SQL while forgetting the\n * TypeGraph sidecars that mirror it.\n *\n * This is deliberately the only supported savepoint seam for recorded writes.\n * Savepoints issued directly through an adopted backend remain outside the\n * capture contract because TypeGraph cannot observe their rollback boundary.\n */\nexport async function runRecordedTransactionSavepoint<T>(\n target: TransactionControlTarget,\n statementExecution: Extract<\n BundleVerdictOf<typeof STATEMENT_EXECUTION>,\n { supported: true }\n >,\n savepoint: string,\n fn: () => Promise<RecordedSavepointDecision<T>>,\n): Promise<T> {\n const binding = recordedTransactionBindings.get(target);\n binding?.assertOpen();\n const rawTarget = binding?.target ?? target;\n const { executeStatement } = statementExecutionMembers(\n rawTarget,\n statementExecution,\n );\n // Only a TypeGraph-owned capture binding carries session state to\n // checkpoint/restore across this savepoint — an engine-native mutation\n // witness's binding has no `capture`, so it degrades to the same no-op\n // `restoreCapture` an entirely unbound target already gets below.\n const captureCheckpoint = binding?.capture?.session.checkpoint();\n const graphLockCheckpoint =\n binding?.capture === undefined ?\n undefined\n : new Map(binding.capture.graphLocks);\n const restoreCapture = (): void => {\n if (\n binding?.capture === undefined ||\n captureCheckpoint === undefined ||\n graphLockCheckpoint === undefined\n )\n return;\n binding.capture.session.restore(captureCheckpoint);\n binding.capture.graphLocks.clear();\n for (const [graphId, lock] of graphLockCheckpoint) {\n binding.capture.graphLocks.set(graphId, lock);\n }\n };\n const executeControl = (sql: string): Promise<unknown> =>\n executeStatement(asCompiledStatementSql(portableSql.raw(sql)));\n const rollback = async (cause: unknown): Promise<void> => {\n try {\n await executeControl(`ROLLBACK TO SAVEPOINT ${savepoint}`);\n restoreCapture();\n await executeControl(`RELEASE SAVEPOINT ${savepoint}`);\n } catch (recoveryError) {\n throw new AggregateError(\n [cause],\n \"Failed to recover a TypeGraph recorded transaction savepoint.\",\n { cause: recoveryError },\n );\n }\n };\n\n await executeControl(`SAVEPOINT ${savepoint}`);\n let result: RecordedSavepointDecision<T>;\n try {\n result = await fn();\n } catch (error) {\n await rollback(error);\n throw error;\n }\n if (result.action === \"rollback\") {\n await rollback(result.cause);\n } else {\n await executeControl(`RELEASE SAVEPOINT ${savepoint}`);\n }\n return result.value;\n}\n\n/** Internal fence/control statements bypass row capture but retain its lifetime guard. */\nexport function recordedTransactionControlTarget(\n backend: TransactionBackend,\n): TransactionBackend {\n const binding = recordedTransactionBindings.get(backend);\n binding?.assertOpen();\n return binding?.target ?? backend;\n}\n\n/** Pending capture is not yet visible in the durable revision clock. */\nexport function hasPendingRecordedGraphWrites(\n backend: TransactionBackend,\n graphId: string,\n): boolean {\n recordedTransactionBindings.get(backend)?.assertOpen();\n const session = recordedRevisionBindings.get(backend);\n if (session === undefined) return false;\n const checkpoint = session.checkpoint();\n return (\n checkpoint.forcedGraphRevisions.has(graphId) ||\n [...checkpoint.touched.values()].some(\n (entity) => entity.graphId === graphId,\n )\n );\n}\n\n/** Forces one revision allocation when this capture transaction flushes. */\nexport function forceRecordedGraphRevision(\n backend: TransactionBackend,\n graphId: string,\n): boolean {\n recordedTransactionBindings.get(backend)?.assertOpen();\n const session = recordedRevisionBindings.get(backend);\n if (session === undefined) return false;\n session.forceGraphRevision(graphId);\n return true;\n}\n\nfunction ignoreIdentityTouch(): void {\n return;\n}\n\n/**\n * Both sides are {@link IdentityTarget}, not the backend union: what this hands\n * `fn` is the handle identity STATEMENTS run against, and the recorded binding\n * it may swap in is a `TransactionBackend`, which satisfies that projection.\n * Typing it this way is what lets a write frame's row work — whose handle is\n * the read-only `WriteTarget` — reach the identity fold at all.\n */\nexport async function withRecordedIdentityMutationTarget<T>(\n target: IdentityTarget,\n fn: (\n rawTarget: IdentityTarget,\n touch: (\n graphId: string,\n id: string,\n afterImage?: IdentityAssertionStorageRow,\n ) => void,\n ) => Promise<T>,\n): Promise<T> {\n const binding = recordedTransactionBindings.get(target);\n if (binding === undefined) {\n return fn(target, ignoreIdentityTouch);\n }\n binding.assertOpen();\n return fn(binding.target, (graphId, id, afterImage) => {\n binding.sink.touchIdentity(graphId, id, afterImage);\n });\n}\n\n/**\n * Registers an engine-native mutation witness's sink against `overlay` (the\n * wrapped committing transaction {@link createMutationWitness}'s `wrap`\n * returned) and `target` (the raw session it wrapped) through the same\n * binding seam {@link createRecordedTransactionBackend} registers a\n * TypeGraph-owned capture session's sink through — so an identity assertion\n * issued via either object flips the witness's `mutated` flag the same way a\n * real node or edge write does. There is no session to assert open (the\n * witness never seals) and no capture-only session/lock state to carry, so\n * this binding's `capture` stays absent.\n */\nexport function registerRecordedIdentityMutationWitness(\n overlay: TransactionBackend,\n target: TransactionBackend,\n sink: WriteTouchSink,\n): void {\n const binding: RecordedTransactionBinding = {\n target,\n assertOpen: () => {\n /* An engine-native mutation witness never seals. */\n },\n sink,\n };\n recordedTransactionBindings.set(overlay, binding);\n recordedTransactionBindings.set(target, binding);\n}\n\n/**\n * Runs one opaque node program against the session that owns recorded capture\n * and publishes its returned after-images to that same session. The closed\n * heterogeneous CTE cannot pass through per-method write overlays.\n */\nexport async function withRecordedNodeMutationTarget(\n target: TransactionBackend,\n graphId: string,\n run: (target: TransactionBackend) => Promise<readonly NodeRow[]>,\n): Promise<readonly NodeRow[]> {\n const binding = recordedTransactionBindings.get(target);\n if (binding === undefined) return run(target);\n binding.assertOpen();\n if (binding.capture !== undefined) {\n await lockRecordedGraphWrite(\n binding.target,\n graphId,\n binding.capture.graphLocks,\n );\n }\n const rows = await run(binding.target);\n for (const row of rows) {\n binding.sink.touchNode(row.graph_id, row.kind, row.id, row);\n }\n return rows;\n}\n\nfunction createRecordedTransactionBackend(\n target: TransactionBackend,\n session: RecordedCaptureSession,\n schema: SqlSchema,\n): TransactionBackend {\n // One advisory-lock round trip per graph per transaction: the memo is\n // shared with the returned overlay (see registerRecordedGraphLockMemo),\n // so external lock paths handed this backend dedupe against the same\n // single-flight promises — including concurrent same-transaction writers.\n const graphLocks = createRecordedGraphLockMemo();\n\n async function lockGraph(graphId: string): Promise<void> {\n await lockRecordedGraphWrite(target, graphId, graphLocks);\n }\n\n async function lockGraphs(\n params: readonly Readonly<{ graphId: string }>[],\n ): Promise<void> {\n // Codepoint sort, NOT localeCompare: every process must acquire\n // multi-graph locks in the same order, and locale-sensitive collation\n // varies with the host's ICU configuration — two processes sorting the\n // same ids differently would take the same lock pair in opposite\n // orders and deadlock.\n const graphIds = [\n ...new Set(params.map((parameter) => parameter.graphId)),\n ].toSorted();\n for (const graphId of graphIds) {\n await lockRecordedGraphWrite(target, graphId, graphLocks);\n }\n }\n\n // The per-member \"did this write actually change a row\" decision, and the\n // member enumeration it covers, live in `write-touch.ts` — shared with the\n // engine-native mutation witness rather than re-implemented here. Capture's\n // sink collects the after-image every touched entity needs for its history\n // row; its hooks are the session-liveness assertion and the advisory lock\n // this factory always took inline.\n const sink: WriteTouchSink = {\n touchNode: session.touchNode,\n touchEdge: session.touchEdge,\n touchIdentity: session.touchIdentityAssertion,\n };\n const hooks: WriteMemberHooks = {\n beforeOne: async (graphId) => {\n session.assertOpen();\n await lockGraph(graphId);\n },\n beforeMany: async (params) => {\n session.assertOpen();\n await lockGraphs(params);\n },\n connectedEdgeIdsForHardDelete: (params) =>\n queryConnectedEdgeIds(target, schema, params),\n };\n\n const overlay = deriveBackend(target, {\n ...rawWriteGuards(target, \"tx.backend\"),\n ...buildRecordedWriteMembers(target, sink, hooks),\n commands: buildRecordedCommandsPort(target, sink, hooks),\n });\n registerRecordedGraphLockMemo(overlay, graphLocks);\n // Bind BOTH the overlay and the raw target to this capture session. Identity\n // mutations first resolve the overlay to its raw target (runIdentityMutation),\n // then a nested coordinator (importIdentityAssertionsIntoTarget) re-wraps that\n // RAW target — without a raw-target binding the second lookup would miss and\n // silently drop every touch, losing the merge-created assertions from history.\n const binding: RecordedTransactionBinding = {\n target,\n assertOpen: session.assertOpen,\n sink,\n capture: { session, graphLocks },\n };\n recordedTransactionBindings.set(overlay, binding);\n recordedTransactionBindings.set(target, binding);\n recordedRevisionBindings.set(overlay, session);\n return overlay;\n}\n\nexport function createRecordedTransactionScope(\n target: TransactionBackend,\n batchPointRead: BundleVerdictOf<typeof BATCH_POINT_READ>,\n schema?: SqlSchema,\n // True only when the enclosing transaction already holds a SQLite write lock\n // (the bundled BEGIN IMMEDIATE paths), letting clock allocation skip the\n // redundant seed-UPSERT. Defaults to false so an adopted (possibly deferred)\n // external transaction still seeds the lock — the safe choice.\n ownsWriteLock = false,\n): RecordedTransactionScope {\n // Fail fast — before any write runs in the adopted/opened transaction — if\n // the transaction target cannot execute the statements capture flush needs,\n // rather than throwing mid-flush after the live write has already happened.\n requireCaptureStatements(target);\n const session = createRecordedCaptureSession();\n // Table names are fixed for the transaction's lifetime, so resolve the schema\n // once and thread it through capture instead of rebuilding it per flush. The\n // store passes its resolved schema so capture targets the same recorded\n // relations recorded reads do; the fallback covers standalone capture.\n const resolvedSchema = schema ?? requireRecordedSchema(target);\n return {\n backend: createRecordedTransactionBackend(target, session, resolvedSchema),\n async flush(): Promise<RecordedFlushInstants> {\n // By flush time the live write has committed within this transaction, so a\n // missing-table error can only be a recorded relation — surface it as the\n // typed precondition the constructor gate could not check.\n return withRecordedRelationsPrecondition(\n session.flush(target, batchPointRead, resolvedSchema, ownsWriteLock),\n { dialect: target.dialect, surface: \"capture-flush\" },\n );\n },\n };\n}\n\nasync function runCapturedAutocommit<T>(\n backend: GraphBackend,\n schema: SqlSchema | undefined,\n batchPointRead: BundleVerdictOf<typeof BATCH_POINT_READ>,\n fn: (target: TransactionBackend) => Promise<T>,\n options?: InternalTransactionOptions,\n): Promise<T> {\n assertRequestedRecordedIsolation(backend, options);\n return backend.transaction(async (target) => {\n await assertRecordedCaptureTransactionIsolation(target);\n // The bundled transaction opened BEGIN IMMEDIATE, so the write lock is held.\n const scope = createRecordedTransactionScope(\n target,\n batchPointRead,\n schema,\n true,\n );\n const result = await fn(scope.backend);\n await scope.flush();\n return result;\n }, options);\n}\n\nexport function createRecordedBackend(\n backend: GraphBackend,\n schema?: SqlSchema,\n): GraphBackend {\n assertCapturableBackend(backend);\n // Resolved ONCE, here, into a closure local threaded to every capture path\n // this overlay opens (ruling B8 spec item 2): the autocommit-wrapped single\n // write below and the multi-statement `transaction` override further down.\n const batchPointRead = batchPointReadVerdict(backend);\n const capture = <T>(\n fn: (target: TransactionBackend) => Promise<T>,\n ): Promise<T> => runCapturedAutocommit(backend, schema, batchPointRead, fn);\n\n const projectedBackend = projectGraphBackend(backend);\n return deriveBackend(projectedBackend, {\n ...rawWriteGuards(backend, \"backend\"),\n\n async insertNode(params) {\n return capture((target) => target.insertNode(params));\n },\n\n ...(backend.insertNodeIfAbsent === undefined ?\n {}\n : {\n async insertNodeIfAbsent(\n params: InsertNodeParams,\n ): Promise<NodeRow | undefined> {\n return capture((target) =>\n requireDefined(target.insertNodeIfAbsent)(params),\n );\n },\n }),\n\n ...(backend.insertNodeIfAbsentWithSchemaFence === undefined ?\n {}\n : {\n async insertNodeIfAbsentWithSchemaFence(\n params: InsertNodeParams,\n schemaFence: SchemaWriteFenceParams,\n ): Promise<NodeRow | undefined> {\n return capture((target) =>\n requireDefined(target.insertNodeIfAbsentWithSchemaFence)(\n params,\n schemaFence,\n ),\n );\n },\n }),\n\n ...(backend.insertNodeWithSchemaFence === undefined ?\n {}\n : {\n async insertNodeWithSchemaFence(\n params: InsertNodeParams,\n schemaFence: SchemaWriteFenceParams,\n ): Promise<NodeRow | undefined> {\n return capture((target) =>\n requireDefined(target.insertNodeWithSchemaFence)(\n params,\n schemaFence,\n ),\n );\n },\n }),\n\n commands: {\n session: \"root\",\n execute: async (\n command: GraphCommand,\n context: GraphCommandExecutionContext,\n ): Promise<GraphCommandResult> => {\n assertGraphCommandExecutionContext(context);\n if (context.session !== \"root\") {\n throw new CompilerInvariantError(\n \"A recorded root command received a transaction execution context.\",\n { contextSession: context.session },\n );\n }\n const result = await capture((target) =>\n executeAuthoritativeGraphCommand(target.commands, command),\n );\n return result;\n },\n },\n\n ...(backend.insertNodeNoReturn === undefined ?\n {}\n : {\n async insertNodeNoReturn(params: InsertNodeParams): Promise<void> {\n await capture((target) =>\n runInsertNoReturn(nodeInsertDispatch(target), params),\n );\n },\n }),\n\n ...(backend.insertNodesBatch === undefined ?\n {}\n : {\n async insertNodesBatch(\n params: readonly InsertNodeParams[],\n ): Promise<void> {\n await capture((target) =>\n runInsertBatch(nodeInsertDispatch(target), params),\n );\n },\n }),\n\n ...(backend.insertNodesBatchReturning === undefined ?\n {}\n : {\n async insertNodesBatchReturning(\n params: readonly InsertNodeParams[],\n ): Promise<readonly NodeRow[]> {\n return capture((target) =>\n runInsertBatchReturning(nodeInsertDispatch(target), params),\n );\n },\n }),\n\n async updateNode(params) {\n return capture((target) => target.updateNode(params));\n },\n\n ...(backend.upsertHeterogeneousNodes === undefined ?\n {}\n : {\n async upsertHeterogeneousNodes(\n params: HeterogeneousNodeUpsertParams,\n ): Promise<readonly NodeRow[]> {\n return capture((target) => {\n const upsert = target.upsertHeterogeneousNodes;\n if (upsert === undefined) {\n throw new ConfigurationError(\n \"Recorded heterogeneous node upsert capability disappeared inside a transaction.\",\n { operation: \"upsertHeterogeneousNodes\" },\n );\n }\n return upsert(params);\n });\n },\n }),\n\n ...(backend.updateResolvedNodesBatch === undefined ?\n {}\n : {\n async updateResolvedNodesBatch(params) {\n return capture((target) => {\n const updateResolvedNodesBatch = target.updateResolvedNodesBatch;\n if (updateResolvedNodesBatch === undefined) {\n throw new ConfigurationError(\n \"Recorded resolved node update batch capability disappeared inside a transaction\",\n { operation: \"updateResolvedNodesBatch\" },\n );\n }\n return updateResolvedNodesBatch(params);\n });\n },\n }),\n\n ...(backend.updateNodeSet === undefined ?\n {}\n : {\n async updateNodeSet(params) {\n return capture((target) => {\n const updateNodeSet = target.updateNodeSet;\n if (updateNodeSet === undefined) {\n throw new ConfigurationError(\n \"Recorded updateNodeSet capability disappeared inside a transaction\",\n { operation: \"updateNodeSet\" },\n );\n }\n return updateNodeSet(params);\n });\n },\n }),\n\n ...(backend.compareAndSetNode === undefined ?\n {}\n : {\n async compareAndSetNode(params) {\n return capture((target) => {\n const compareAndSetNode = target.compareAndSetNode;\n if (compareAndSetNode === undefined) {\n throw new ConfigurationError(\n \"Recorded compareAndSetNode capability disappeared inside a transaction\",\n { operation: \"compareAndSetNode\" },\n );\n }\n return compareAndSetNode(params);\n });\n },\n }),\n\n async deleteNode(params) {\n await capture((target) => target.deleteNode(params));\n },\n\n async hardDeleteNode(params) {\n await capture((target) => target.hardDeleteNode(params));\n },\n\n async insertEdge(params) {\n return capture((target) => target.insertEdge(params));\n },\n\n ...(backend.insertEdgeNoReturn === undefined ?\n {}\n : {\n async insertEdgeNoReturn(params: InsertEdgeParams): Promise<void> {\n await capture((target) =>\n runInsertNoReturn(edgeInsertDispatch(target), params),\n );\n },\n }),\n\n ...(backend.insertEdgesBatch === undefined ?\n {}\n : {\n async insertEdgesBatch(\n params: readonly InsertEdgeParams[],\n ): Promise<void> {\n await capture((target) =>\n runInsertBatch(edgeInsertDispatch(target), params),\n );\n },\n }),\n\n ...(backend.insertEdgesBatchReturning === undefined ?\n {}\n : {\n async insertEdgesBatchReturning(\n params: readonly InsertEdgeParams[],\n ): Promise<readonly EdgeRow[]> {\n return capture((target) =>\n runInsertBatchReturning(edgeInsertDispatch(target), params),\n );\n },\n }),\n\n ...(backend.insertEdgesDurableBatchReturning === undefined ?\n {}\n : {\n async insertEdgesDurableBatchReturning(\n params: readonly InsertEdgeParams[],\n ): Promise<readonly EdgeRow[]> {\n return capture((target) =>\n requireDefined(target.insertEdgesDurableBatchReturning)(params),\n );\n },\n }),\n\n async updateEdge(params) {\n return capture((target) => target.updateEdge(params));\n },\n\n async deleteEdge(params) {\n await capture((target) => target.deleteEdge(params));\n },\n\n async hardDeleteEdge(params) {\n await capture((target) => target.hardDeleteEdge(params));\n },\n\n ...(backend.deleteEdgesBatch === undefined ?\n {}\n : {\n async deleteEdgesBatch(params: DeleteEdgesBatchParams): Promise<void> {\n await capture((target) =>\n requireDefined(target.deleteEdgesBatch)(params),\n );\n },\n }),\n\n ...(backend.hardDeleteEdgesBatch === undefined ?\n {}\n : {\n async hardDeleteEdgesBatch(\n params: DeleteEdgesBatchParams,\n ): Promise<void> {\n await capture((target) =>\n requireDefined(target.hardDeleteEdgesBatch)(params),\n );\n },\n }),\n\n async transaction(fn, options) {\n const observer = readRecordedFlushObserver(options);\n const backendOptions = stripRecordedFlushObserver(options);\n assertRequestedRecordedIsolation(backend, backendOptions);\n return backend.transaction(async (target) => {\n await assertRecordedCaptureTransactionIsolation(target, backendOptions);\n const readOnly = backendOptions?.accessMode === \"read_only\";\n const scope = createRecordedTransactionScope(\n target,\n batchPointRead,\n schema,\n !readOnly,\n );\n const result = await fn(scope.backend);\n const instants = await scope.flush();\n observer?.(instants);\n return result;\n }, backendOptions);\n },\n });\n}\n","/**\n * Shared transaction boundary for graph-entity mutations.\n *\n * A node/edge mutation is a cascade of steps — the core row write plus its\n * integrity side effects (uniqueness, embeddings, fulltext) or its delete\n * behavior (restrict / cascade / disconnect). Those steps are individually\n * atomic but not collectively atomic, so the cascade runs inside one top-level\n * transaction whether or not recorded-time capture is enabled: a mid-cascade\n * failure then rolls back the whole operation instead of leaving a half-applied\n * write (e.g. an inserted node whose uniqueness/embedding/fulltext rows were\n * never written, or a uniqueness conflict that leaves an orphaned node row).\n * Under history capture the per-graph write lock is additionally taken inside\n * that transaction so recorded capture serializes.\n *\n * Both {@link NodeOperationContext} and {@link EdgeOperationContext} route their\n * mutations through this one helper, replacing the byte-identical per-file\n * copies that previously drifted independently.\n *\n * ## Lock order\n *\n * Every managed Store write acquires, in this order and no other:\n *\n * 1. the schema-version fence ({@link lockSchemaVersionForStoreWrite}), which\n * pins the schema the write compiles against;\n * 2. the per-graph write lock — `typegraph:recorded-graph-write`, taken here\n * BEFORE any row read or write, so nothing a later step decides can be\n * invalidated by a concurrent graph write;\n * 3. the per-graph identity lock (`typegraph:identity`), taken by the identity\n * service inside `fn`;\n * 4. row work;\n * 5. `typegraph:recorded-clock`, taken LAST, at capture flush.\n *\n * The comment on `graphAdvisoryLockSql` in\n * {@link file://../recorded-capture/clock.ts} states the rule this order\n * exists to satisfy: a lock namespace belongs to ONE acquire-order position,\n * and sharing a key across two positions creates a circular wait.\n * Bundled PostgreSQL transaction targets may acquire positions 1 and 2 with\n * one optional strong member; its SQL preserves this same order inside the\n * statement. Every other target retains the two portable acquisitions.\n *\n * Constrained writes (see `fencesConstraintProbe` below) therefore reuse the\n * EXISTING `typegraph:recorded-graph-write` key rather than introducing a\n * sibling namespace. A sibling would be strictly wrong here: it would sit at\n * the same acquire-order position but form a disjoint exclusion set, so a\n * capture-enabled writer holding the recorded key and a constrained writer\n * holding the sibling would not exclude each other — which is precisely the\n * mutual exclusion the constrained write needs.\n *\n * ## Fenced or refused\n *\n * A declared constraint's probe and the write it guards commit under one\n * per-graph mutual exclusion ON EVERY BACKEND. Both halves of the fence are\n * transaction-scoped constructs — SQLite's `BEGIN IMMEDIATE`, PostgreSQL's\n * `pg_advisory_xact_lock` — so a backend with no transactions can supply\n * neither. Such a write is REFUSED\n * ({@link constraintFenceRefusal}, `CONSTRAINT_WRITE_FENCE_UNSUPPORTED`)\n * rather than run unfenced: a constraint enforced only when nothing races is\n * the exact failure the fence exists to close, and reporting it as enforced\n * would make the claim above false wherever it matters most. Unconstrained\n * writes assert nothing and keep working on those backends.\n */\nimport {\n batchRefusalDetails,\n batchRefusalSuffix,\n resolveBatchWriteVerdict,\n} from \"../../backend/capabilities/batch-write-verdict\";\nimport { statementExecutionMembers } from \"../../backend/capabilities/bind\";\nimport { type STATEMENT_EXECUTION } from \"../../backend/capabilities/bundle-registry\";\nimport { type BundleVerdictOf } from \"../../backend/capabilities/resolve\";\nimport {\n isOptimisticRetryTier,\n OPTIMISTIC_RETRY_ATTEMPTS,\n runRetriedUnit,\n} from \"../../backend/capabilities/retried-unit\";\nimport {\n isFirstPartyFactory,\n resolveWriteFencePlan,\n} from \"../../backend/capabilities/write-fence\";\nimport { engineSerializedWriterSlotStatement } from \"../../backend/sqlite-writer-slot\";\nimport {\n type GraphBackend,\n runOptionallyInTransaction,\n type TransactionBackend,\n} from \"../../backend/types\";\nimport { ConfigurationError, StaleVersionError } from \"../../errors\";\nimport { type SqlSchema } from \"../../query/compiler/schema\";\nimport { isSqliteStaleSnapshotError } from \"../../utils/sql-errors\";\nimport { type ConstraintFenceReason } from \"../constraints\";\nimport {\n advanceRevisionClock,\n lockRecordedGraphWrite,\n recordedTransactionControlTarget,\n} from \"../recorded-capture\";\nimport {\n acquiredGraphWriteLockFromCombinedFence,\n type GraphWriteLock,\n memoizeAcquiredRecordedGraphWriteLock,\n uncapturedGraphWriteLock,\n} from \"../recorded-capture/clock\";\nimport { type OperationHookContext } from \"../types\";\n\n/**\n * The slice of an operation context {@link runInWriteTransaction} needs: the\n * graph id (for the capture lock) and whether recorded-time capture is on.\n * Both {@link NodeOperationContext} and {@link EdgeOperationContext} satisfy it.\n */\nexport type WriteTransactionContext = Readonly<{\n graphId: string;\n schemaVersion: number | undefined;\n historyEnabled: boolean;\n revisionTrackingEnabled: boolean;\n revisionSchema: SqlSchema;\n /** Resolved once from the root backend; exact targets are bound separately. */\n statementExecution?: BundleVerdictOf<typeof STATEMENT_EXECUTION>;\n}>;\n\ninterface WriteTransactionSession {\n lock: GraphWriteLock | undefined;\n wrote: boolean;\n}\n\nconst writeTransactionSessions = new WeakMap<object, WriteTransactionSession>();\n\n/**\n * Schema fences deliberately do not normally memoize: PostgreSQL releases a\n * lock acquired after a savepoint when a caller rolls back to that savepoint.\n * The one safe exception is a TypeGraph-owned Store transaction whose public\n * surface has no native SQL handle. Its first managed write therefore cannot\n * follow a caller-controlled savepoint; once that write acquires the fence,\n * subsequent managed writes can reuse it until the outer transaction ends.\n *\n * The key includes the expected version rather than only the graph id. A\n * transaction target is also the cache owner, never the root backend, so a\n * pooled connection cannot inherit a prior transaction's success.\n */\nconst leasedSchemaFences = new WeakMap<object, Map<string, Promise<void>>>();\n\nfunction schemaFenceLeaseKey(graphId: string, expectedVersion: number): string {\n return `${graphId}\\u0000${expectedVersion}`;\n}\n\n/** Whether this transaction has already acquired the exact schema fence. */\nexport function hasLeasedSchemaFence(\n ctx: Pick<WriteTransactionContext, \"graphId\" | \"schemaVersion\">,\n target: object,\n): boolean {\n const expectedVersion = ctx.schemaVersion;\n return (\n expectedVersion !== undefined &&\n leasedSchemaFences\n .get(target)\n ?.has(schemaFenceLeaseKey(ctx.graphId, expectedVersion)) === true\n );\n}\n\n/** Records a schema fence acquired inside a successful fused write statement. */\nexport function memoizeLeasedSchemaFence(\n ctx: Pick<WriteTransactionContext, \"graphId\" | \"schemaVersion\">,\n target: object,\n): void {\n const expectedVersion = ctx.schemaVersion;\n const leases = leasedSchemaFences.get(target);\n if (expectedVersion === undefined || leases === undefined) return;\n leases.set(\n schemaFenceLeaseKey(ctx.graphId, expectedVersion),\n Promise.resolve(),\n );\n}\n\n/**\n * Marks a TypeGraph-owned transaction as eligible for lazy schema-fence\n * leasing. The first managed write acquires the fence; read-only transactions\n * pay nothing and retain their existing visibility/locking behavior.\n *\n * Custom transaction backends deliberately take the callback unchanged: their\n * savepoint/connection lifetime has not been audited by TypeGraph, so their\n * managed writes retain the conservative per-call fence behavior.\n */\nexport async function withTransactionSchemaFenceLease<T>(\n ctx: Pick<WriteTransactionContext, \"graphId\" | \"schemaVersion\">,\n target: TransactionBackend,\n fn: () => Promise<T>,\n): Promise<T> {\n const expectedVersion = ctx.schemaVersion;\n if (expectedVersion === undefined || !isFirstPartyFactory(target)) {\n return fn();\n }\n\n leasedSchemaFences.set(target, new Map());\n try {\n return await fn();\n } finally {\n leasedSchemaFences.delete(target);\n }\n}\n\n/**\n * Leases a schema fence acquired before a caller-owned history callback.\n *\n * The adopted history path acquires its fence before invoking user code, so a\n * savepoint created by that callback cannot predate the lock. That is the one\n * adopted-transaction shape where reusing the lock is savepoint-safe. The\n * lease is bound to the exact targets the callback can resolve, including\n * derived capture and execution-lifetime targets plus the raw target used by\n * identity mutations, and is removed when the callback and its capture flush\n * finish.\n *\n * This deliberately does not require the first-party factory mark: adopted\n * transaction backends are marked caller-owned even when their root backend\n * came from a bundled factory. The safety proof here is the pre-callback\n * acquisition and the bounded history scope, not backend provenance.\n */\nexport async function withPreAcquiredTransactionSchemaFenceLease<T>(\n ctx: Pick<WriteTransactionContext, \"graphId\" | \"schemaVersion\">,\n targets: readonly TransactionBackend[],\n fn: () => Promise<T>,\n): Promise<T> {\n const expectedVersion = ctx.schemaVersion;\n if (expectedVersion === undefined) return fn();\n\n const leases = new Map<string, Promise<void>>([\n [schemaFenceLeaseKey(ctx.graphId, expectedVersion), Promise.resolve()],\n ]);\n const uniqueTargets = [...new Set(targets)];\n const previousLeases = new Map<\n TransactionBackend,\n Map<string, Promise<void>> | undefined\n >();\n for (const target of uniqueTargets) {\n previousLeases.set(target, leasedSchemaFences.get(target));\n leasedSchemaFences.set(target, leases);\n }\n try {\n return await fn();\n } finally {\n for (const target of uniqueTargets) {\n if (leasedSchemaFences.get(target) !== leases) continue;\n const previous = previousLeases.get(target);\n if (previous === undefined) leasedSchemaFences.delete(target);\n else leasedSchemaFences.set(target, previous);\n }\n }\n}\n\n/** A managed revision is allocated only when its outer callback completes. */\nexport function hasPendingWriteTransactionRevision(\n target: TransactionBackend,\n): boolean {\n return writeTransactionSessions.get(target)?.wrote === true;\n}\n\n/** Takes the engine writer slot without changing graph data. */\nexport async function ensureEngineSerializedWriterSlot(\n target: GraphBackend | TransactionBackend,\n schema: SqlSchema,\n statementExecution: Extract<\n BundleVerdictOf<typeof STATEMENT_EXECUTION>,\n { supported: true }\n >,\n): Promise<void> {\n const { executeStatement } = statementExecutionMembers(\n recordedTransactionControlTarget(target),\n statementExecution,\n );\n await executeStatement(\n engineSerializedWriterSlotStatement(schema.nodesTable),\n );\n}\n\n/** Forces the enclosing managed Store transaction to consume one revision. */\nexport function forceWriteTransactionRevision(\n target: TransactionBackend,\n): boolean {\n const session = writeTransactionSessions.get(target);\n if (session === undefined) return false;\n session.wrote = true;\n return true;\n}\n\n/**\n * Graphs whose per-graph write lock a still-running {@link runInWriteTransaction}\n * frame already holds on a given target.\n *\n * `pg_advisory_xact_lock` is reentrant and held to the end of the top-level\n * transaction, so re-acquiring it is pure round-trip churn. Operations compose\n * — a bulk `getOrCreateByEndpoints` calls the create batch and the upsert\n * update against ITS transaction target — and each nested call would otherwise\n * pay a lock round trip the enclosing frame already paid.\n *\n * `store.transaction(...)` is covered by {@link WriteTransactionSession}\n * instead; this covers the operation-calls-operation nesting inside a single\n * managed write. Same caveat as the capture layer's memo in\n * `recorded-capture/clock.ts`: NOT savepoint-aware. A manual `SAVEPOINT` rolled\n * back across the outer acquisition releases the lock but not this entry;\n * manual savepoints inside a managed write are outside the contract.\n */\nconst heldGraphWriteLocks = new WeakMap<object, Set<string>>();\n\nfunction adoptedConstraintWriterSlotError(\n ctx: Pick<WriteTransactionContext, \"graphId\">,\n cause: unknown,\n): ConfigurationError {\n return new ConfigurationError(\n \"This constrained write could not take the SQLite writer slot: the adopted transaction was begun DEFERRED and another connection committed after its read snapshot was established.\",\n {\n code: \"CONSTRAINT_TRANSACTION_NOT_WRITE_FENCED\",\n graphId: ctx.graphId,\n },\n {\n cause,\n suggestion:\n \"Roll back and re-run the transaction with BEGIN IMMEDIATE, or run the writes through store.transaction(), which acquires the writer slot before any decision-driving read.\",\n },\n );\n}\n\n/**\n * Makes SQLite's engine-serialized fence true for a transaction TypeGraph did\n * not open. A zero-row write takes the writer slot without changing data; it\n * must run before the schema fence, graph lock, or any constraint probe fixes\n * a read snapshot. Caller-adopted backends do not expose transaction-lifetime\n * identity, so this proof deliberately runs at every constrained write rather\n * than caching connection-scoped evidence across unrelated transactions.\n */\nasync function ensureAdoptedConstraintWriterSlot(\n ctx: WriteTransactionContext,\n target: GraphBackend | TransactionBackend,\n transactionMode: WriteTransactionMode,\n fenceReason: ConstraintFenceReason | undefined,\n): Promise<void> {\n if (\n fenceReason === undefined ||\n transactionMode !== \"existing\" ||\n writeTransactionSessions.has(target) ||\n resolveWriteFencePlan(target).kind !== \"engine-serialized\"\n ) {\n return;\n }\n const statementExecution = ctx.statementExecution;\n if (statementExecution?.supported !== true) {\n throw new ConfigurationError(\n \"This engine-serialized transaction cannot prove that it holds its writer slot before a constrained write.\",\n {\n code: \"CONSTRAINT_WRITE_FENCE_UNSUPPORTED\",\n graphId: ctx.graphId,\n constraint: fenceReason,\n },\n {\n suggestion:\n \"Expose transaction-scoped statement execution, or run the constrained write through a backend transaction TypeGraph opens.\",\n },\n );\n }\n try {\n await ensureEngineSerializedWriterSlot(\n target,\n ctx.revisionSchema,\n statementExecution,\n );\n } catch (error) {\n if (!isSqliteStaleSnapshotError(error)) throw error;\n throw adoptedConstraintWriterSlotError(ctx, error);\n }\n}\n\n/**\n * Binds nested typed mutations to one caller-owned transaction commit so a\n * multi-operation `store.transaction(...)` advances its durable revision once.\n */\nexport async function withWriteTransactionSession<T>(\n target: TransactionBackend,\n ctx: WriteTransactionContext,\n fn: () => Promise<T>,\n): Promise<T> {\n const session: WriteTransactionSession = {\n lock: undefined,\n wrote: false,\n };\n writeTransactionSessions.set(target, session);\n try {\n const result = await fn();\n if (session.wrote && ctx.revisionTrackingEnabled && !ctx.historyEnabled) {\n await advanceRevisionClock(target, ctx.revisionSchema, ctx.graphId, true);\n }\n return result;\n } finally {\n writeTransactionSessions.delete(target);\n }\n}\n\n/**\n * Acquires and validates the transaction-scoped schema fence for one managed\n * Store write. This intentionally runs for every write: PostgreSQL releases\n * row locks acquired after a savepoint when the caller rolls back to that\n * savepoint, so caching an earlier acquisition could let a later write proceed\n * without a live fence.\n */\nexport async function lockSchemaVersionForStoreWrite(\n ctx: Pick<WriteTransactionContext, \"graphId\" | \"schemaVersion\">,\n backend: GraphBackend | TransactionBackend,\n): Promise<void> {\n const expectedVersion = ctx.schemaVersion;\n if (expectedVersion === undefined) return;\n\n const leases = leasedSchemaFences.get(backend);\n const leaseKey = schemaFenceLeaseKey(ctx.graphId, expectedVersion);\n const existingLease = leases?.get(leaseKey);\n if (existingLease !== undefined) return existingLease;\n\n const acquisition = lockSchemaVersionForStoreWriteUncached(ctx, backend);\n leases?.set(leaseKey, acquisition);\n try {\n await acquisition;\n } catch (error) {\n if (leases?.get(leaseKey) === acquisition) leases.delete(leaseKey);\n throw error;\n }\n}\n\nasync function lockSchemaVersionForStoreWriteUncached(\n ctx: Pick<WriteTransactionContext, \"graphId\" | \"schemaVersion\">,\n backend: GraphBackend | TransactionBackend,\n): Promise<void> {\n const expectedVersion = ctx.schemaVersion;\n if (expectedVersion === undefined) return;\n\n if (\n \"transaction\" in backend &&\n !backend.capabilities.execution.interactiveTransactions\n ) {\n // Reached from every call site above through many different fuse\n // failures (an ineligible kind, a derived backend an execution-boundary\n // proof does not cover, a provenance mismatch at the actual write\n // receiver) — this gate's own inputs (graph id, schema version) name\n // none of them. It states the plain limitation with no guessed cause;\n // a caller that HAS proven a specific `BatchWriteRefusalReason` (a\n // declared constraint, `store.transaction`, identity, history, a schema\n // commit) reports it through that reason's own enforcing gate instead of\n // this one.\n throw new ConfigurationError(\n \"Schema-managed Store writes require a transactional backend so schema \" +\n \"changes and entity writes can share one fence.\",\n {\n code: \"SCHEMA_WRITE_FENCE_UNSUPPORTED\",\n graphId: ctx.graphId,\n },\n );\n }\n\n const lockSchemaVersionForWrite = backend.lockSchemaVersionForWrite;\n if (lockSchemaVersionForWrite === undefined) {\n throw new ConfigurationError(\n \"This backend cannot fence schema-managed Store writes against a \" +\n \"concurrent schema change.\",\n {\n code: \"SCHEMA_WRITE_FENCE_UNSUPPORTED\",\n graphId: ctx.graphId,\n },\n );\n }\n\n await lockSchemaVersionForWrite({\n graphId: ctx.graphId,\n expectedVersion,\n });\n}\n\n/**\n * Interprets a no-row result from a schema-fenced INSERT without taking a\n * second schema lock. PostgreSQL's first `FOR SHARE` may wake from a\n * concurrent schema flip with no row in its statement snapshot; taking a\n * second locking read can deadlock with the next flip. The ordinary active\n * schema read observes the settled committed version and is sufficient here:\n * the fused INSERT wrote nothing when its predicate failed.\n *\n * A matching version leaves the caller to diagnose its own ordinary no-row\n * cause (such as an occupied `DO NOTHING` key or a missing edge endpoint).\n */\nexport async function diagnoseFusedSchemaFenceNoRow(\n ctx: Pick<WriteTransactionContext, \"graphId\" | \"schemaVersion\">,\n backend: GraphBackend | TransactionBackend,\n): Promise<void> {\n const expectedVersion = ctx.schemaVersion;\n if (expectedVersion === undefined) return;\n\n const active = await backend.getActiveSchema(ctx.graphId);\n const actualVersion = active?.version ?? 0;\n if (actualVersion !== expectedVersion) {\n throw new StaleVersionError({\n graphId: ctx.graphId,\n expected: expectedVersion,\n actual: actualVersion,\n });\n }\n}\n\n/**\n * How a write states whether it needs the per-graph write fence.\n *\n * `fencesConstraintProbe` is an assertion about THIS write's body: \"it runs a\n * check-then-act whose verdict no database key repeats at write time\", and it\n * names WHICH declared constraint that is. The classification lives with the\n * constraints ({@link file://../constraints.ts edgeWriteNeedsConstraintFence} /\n * `nodeWriteNeedsConstraintFence`), never inline at a call site, so a new\n * constraint kind cannot teach half the write paths about itself.\n *\n * `undefined` — the default — is an unconstrained write: a plain create of a\n * `many`-edge, a node whose uniques are all backed by the uniques primary key,\n * a delete. It takes no lock and pays no round trip for one.\n */\nexport type WriteTransactionOptions<T> = Readonly<{\n didWrite?: (result: T) => boolean;\n fencesConstraintProbe?: ConstraintFenceReason | undefined;\n /**\n * The row-work callback's first statement carries the schema fence itself.\n * This is a narrowly-scoped first-party insert optimization: callers must\n * take no graph or identity lock before that statement and must perform the\n * ordinary fence diagnostic before handling a zero-row result.\n */\n schemaFenceInFirstWrite?: boolean | undefined;\n}>;\n\n/**\n * The transaction boundary the executor selected for one write frame.\n *\n * Callers consume this decision instead of re-deriving it from a decorated\n * target's members or capability flags. Recorded capture and other backend\n * derivations may deliberately replace members while preserving the boundary\n * the executor opened, so the target object is not an honest second source.\n */\nexport type WriteTransactionMode = \"opened\" | \"existing\" | \"none\";\n\nexport function resolveWriteTransactionMode(\n backend: GraphBackend | TransactionBackend,\n): WriteTransactionMode {\n if (!(\"transaction\" in backend)) return \"existing\";\n return backend.capabilities.execution.interactiveTransactions ?\n \"opened\"\n : \"none\";\n}\n\n/**\n * Whether a write about to run through `backend` must be wrapped in\n * {@link runRetriedUnit}: the tier requires it\n * ({@link isOptimisticRetryTier}) AND this write opens its own transaction\n * ({@link resolveWriteTransactionMode} reads `\"opened\"`). A nested unit\n * running inside an existing transaction (`\"existing\"`) cannot restart a\n * transaction it does not own or replay reads made before it, so its\n * conflict propagates unchanged to the outermost owner instead; a\n * backend with no transactions at all (`\"none\"`) has nothing to retry as a\n * unit either.\n *\n * The one predicate every store-owned-unit routing site below consults —\n * `write-executor.ts`'s three plan runners, `runIdentityMutation`, and\n * `rebuildIdentityClosureWithSchemaFence` — so the gate cannot drift between\n * them.\n */\nexport function requiresOptimisticRetryUnit(\n backend: GraphBackend | TransactionBackend,\n): boolean {\n return (\n isOptimisticRetryTier(backend) &&\n resolveWriteTransactionMode(backend) === \"opened\"\n );\n}\n\n/**\n * Re-exported beside {@link constraintFenceRefusal} — the two live together\n * conceptually even though {@link resolveBatchWriteVerdict}'s implementation\n * sits in a leaf module (`backend/capabilities/batch-write-verdict.ts`) so\n * that `recorded-capture/guards.ts`, which this module itself imports\n * through the `recorded-capture` barrel, can import it without a cycle.\n * `BatchWriteRefusalReason` / `BatchWriteVerdict` are not re-exported here:\n * every current caller consumes them structurally through\n * `resolveBatchWriteVerdict`'s return type, with no call site importing\n * either type by name.\n */\nexport {\n batchRefusalDetails,\n batchRefusalSuffix,\n resolveBatchWriteVerdict,\n} from \"../../backend/capabilities/batch-write-verdict\";\n\n/** What a caller must change to make each refused constraint class writable. */\nconst CONSTRAINT_FENCE_ADVICE = {\n edgeCardinality:\n 'declare the edge `cardinality: \"many\"` and enforce the limit in application code',\n edgeMatchKeyConvergence:\n \"use `create` with a caller-chosen id, whose uniqueness the edges primary key enforces, instead of `getOrCreateByEndpoints`\",\n nodeDisjointness:\n \"drop the `disjointWith` axiom and keep ids distinct across those kinds yourself\",\n nodeUniquenessClaim:\n \"drop the unique constraint — its reservation row and the node row must commit or roll back together\",\n nodeUniquenessScope:\n 'scope the unique constraint to `\"kind\"`, which the uniques primary key enforces on its own',\n} as const satisfies Record<ConstraintFenceReason, string>;\n\n/**\n * THE refusal for a constrained write on a backend that cannot hold the fence\n * it needs — one body, one code, one advice map, for both consumers.\n *\n * **The capability test is transaction support, on both dialects, because both\n * fences ARE transaction-scoped constructs.** The lock half: SQLite's fence is\n * the `BEGIN IMMEDIATE` that admits one writer, PostgreSQL's is\n * `pg_advisory_xact_lock`, which by definition is released at the end of the\n * transaction that took it — outside one it is acquired and dropped within its\n * own implicit single-statement transaction and excludes nothing. The claim\n * half: a reservation row issued BEFORE the row it gates is undone only by a\n * rollback, so without a transaction a failed write leaves a live claim that\n * blocks its key with no repair path. Either way \"this backend can fence\" and\n * \"this write runs inside a transaction\" are the same question, and it is asked\n * exactly the way {@link lockSchemaVersionForStoreWrite} asks its own:\n * `\"transaction\" in backend` distinguishes a TOP-LEVEL backend (where\n * `transaction` is a required member) from a nested {@link TransactionBackend}\n * (which omits it and is therefore already inside one, hence already fenced).\n *\n * Refused rather than degraded, per the accepted-or-refused rule: the write\n * declared a constraint the store cannot enforce here, and enforcing it \"most\n * of the time\" is the failure mode that produced #428 and #436 in the first\n * place. A caller who wants the write anyway can have it by not declaring the\n * constraint — which is what {@link CONSTRAINT_FENCE_ADVICE} says, per class.\n *\n * UNCONSTRAINED writes on the same backend are untouched: they assert nothing\n * the engine has to serialize, so they keep working exactly as before.\n *\n * `ctx` is the one field the body reads, so the claim seam (which holds a node\n * write context) and `importGraphData` (which computes its refusal before it\n * has a write transaction context at all) can call it.\n */\nexport function constraintFenceRefusal(\n ctx: Readonly<{ graphId: string }>,\n backend: GraphBackend | TransactionBackend,\n reason: ConstraintFenceReason,\n): ConfigurationError | undefined {\n if (\n !(\"transaction\" in backend) ||\n backend.capabilities.execution.interactiveTransactions\n ) {\n return undefined;\n }\n\n const verdict = resolveBatchWriteVerdict(backend, {\n needs: \"constraint-needs-probe\",\n });\n\n return new ConfigurationError(\n \"This backend cannot fence a constrained write: enforcing a declared \" +\n \"constraint requires a transaction — to scope the per-graph write lock \" +\n \"to, and to commit a reservation row together with the row it gates — \" +\n \"and this backend has no transactions.\" +\n batchRefusalSuffix(verdict),\n {\n code: \"CONSTRAINT_WRITE_FENCE_UNSUPPORTED\",\n graphId: ctx.graphId,\n constraint: reason,\n ...batchRefusalDetails(verdict),\n },\n {\n suggestion:\n `Use a transactional backend, or ${CONSTRAINT_FENCE_ADVICE[reason]}. ` +\n \"Unconstrained writes need no fence and keep working on this backend.\",\n },\n );\n}\n\n/**\n * Runs a graph-entity mutation cascade inside a single top-level transaction.\n *\n * On a transactional backend the cascade shares one transaction so it commits\n * or rolls back atomically. A nested {@link TransactionBackend} (already inside\n * `store.transaction(...)`) omits `.transaction`, so\n * {@link runOptionallyInTransaction} runs `fn` directly against it rather than\n * opening a nested transaction. A raw Store on a non-transactional backend\n * (Cloudflare D1, `drizzle-orm/neon-http`) also runs `fn` directly and cannot\n * offer atomicity. A schema-managed Store fails closed before `fn` because the\n * backend cannot hold the schema-version fence.\n *\n * The per-graph write lock is taken inside the transaction before any row work\n * (see the module's lock order) when EITHER the store captures — history or\n * revision tracking, whose clocks must serialize — OR the caller declared the\n * body a constrained write via `fencesConstraintProbe`. The two reasons share\n * one lock because they need the same exclusion: on a capture-enabled store a\n * constrained write and a captured write must exclude each other, which two\n * keys could not arrange.\n *\n * A constrained write on a backend with no transactions FAILS CLOSED, before\n * `fn`, through {@link constraintFenceRefusal} — that backend can hold\n * no fence, and the invariant this module states is that a declared\n * constraint's probe and the write it guards commit under one per-graph mutual\n * exclusion on every backend. Fenced or refused; never quietly neither.\n * Unconstrained writes on the same backend are unaffected.\n *\n * Under the `\"optimistic-retry\"` tier ({@link requiresOptimisticRetryUnit}),\n * the WHOLE attempt below — opening the transaction, taking every lock, and\n * calling `fn` — runs through {@link runRetriedUnit}: `backend`'s `row`-\n * mechanism write fence lets two acquirers of one fence row both proceed, so\n * the loser's COMMIT fails and correctness comes from replaying the entire\n * unit, never from waiting. This is the ONE place that routes every store-\n * owned unit built on this function — both `write-executor.ts` plan\n * runners, `runIdentityMutation`, and `rebuildIdentityClosureWithSchemaFence`\n * — through the retry owner, so none of those callers re-spells the gate or\n * the wrapping. A nested unit (`transactionMode === \"existing\"`) never\n * retries here regardless of the tier: it cannot restart a transaction it\n * does not own, so its conflict propagates to the outermost owner. Under\n * `\"interactive\"` this function's behavior is unchanged: one attempt.\n */\nexport function runInWriteTransaction<T>(\n ctx: WriteTransactionContext,\n backend: GraphBackend | TransactionBackend,\n fn: (\n target: GraphBackend | TransactionBackend,\n lock: GraphWriteLock,\n transactionMode: WriteTransactionMode,\n ) => Promise<T>,\n options?: WriteTransactionOptions<T>,\n): Promise<T> {\n const transactionMode = resolveWriteTransactionMode(backend);\n const fenceReason = options?.fencesConstraintProbe;\n // Rejected rather than thrown: this function is promise-returning, and a\n // synchronous throw from it would surface differently at a caller that\n // composes it without `await` than at one that does.\n const refusal =\n fenceReason === undefined ? undefined : (\n constraintFenceRefusal(ctx, backend, fenceReason)\n );\n if (refusal !== undefined) return Promise.reject(refusal);\n\n const attempt = (): Promise<T> =>\n runInWriteTransactionAttempt(ctx, backend, fn, options, transactionMode);\n\n if (!requiresOptimisticRetryUnit(backend)) return attempt();\n return runRetriedUnit(\n {\n operation: \"runInWriteTransaction\",\n attempts: OPTIMISTIC_RETRY_ATTEMPTS,\n target: backend,\n },\n attempt,\n );\n}\n\n/**\n * One attempt of {@link runInWriteTransaction}: everything that function did\n * as one body before the `\"optimistic-retry\"` tier existed, unchanged.\n * Called once directly under `\"interactive\"`, or once per attempt\n * {@link runRetriedUnit} makes under `\"optimistic-retry\"` — every value\n * below (`held`, `combinedSchemaGraphFence`, `lock`) is built fresh on each\n * call, so a rolled-back attempt leaves nothing for the next one to read.\n */\nfunction runInWriteTransactionAttempt<T>(\n ctx: WriteTransactionContext,\n backend: GraphBackend | TransactionBackend,\n fn: (\n target: GraphBackend | TransactionBackend,\n lock: GraphWriteLock,\n transactionMode: WriteTransactionMode,\n ) => Promise<T>,\n options: WriteTransactionOptions<T> | undefined,\n transactionMode: WriteTransactionMode,\n): Promise<T> {\n const ownsWriteLock = transactionMode === \"opened\";\n const fenceReason = options?.fencesConstraintProbe;\n const needsGraphWriteLock =\n ctx.historyEnabled ||\n ctx.revisionTrackingEnabled ||\n fenceReason !== undefined;\n return runOptionallyInTransaction(backend, async (target) => {\n await ensureAdoptedConstraintWriterSlot(\n ctx,\n target,\n transactionMode,\n fenceReason,\n );\n const session =\n needsGraphWriteLock ? writeTransactionSessions.get(target) : undefined;\n // Either constructor yields the same compile-time evidence token; which one\n // ran says why no acquisition was needed. `uncapturedGraphWriteLock` covers\n // both \"this store needs no lock\" and \"an enclosing frame on this target\n // already holds it\" — in the second case the lock is genuinely held, which\n // is a stronger claim than the constructor makes, not a weaker one.\n //\n // The claim is registered SYNCHRONOUSLY, before any await: two frames on\n // one target that both reached this point would otherwise each read an\n // absent Set, each mint one, and the second `set` would orphan the first —\n // leaving the first frame's `finally` clearing a Set the map no longer\n // holds, and the graph marked held forever. Reading-and-registering with no\n // suspension point in between makes that interleaving unrepresentable.\n const held = heldGraphWriteLocks.get(target) ?? new Set<string>();\n heldGraphWriteLocks.set(target, held);\n const acquiresLock =\n needsGraphWriteLock &&\n session?.lock === undefined &&\n !held.has(ctx.graphId);\n // Marked before the acquisition rather than after it, for the same reason:\n // a sibling frame that starts while this one is still awaiting the lock\n // must see the claim, not race it. Its statements queue behind ours on the\n // one connection either way, so observing an in-flight claim as held is\n // correct. A failed acquisition retracts the claim.\n if (acquiresLock) held.add(ctx.graphId);\n const expectedSchemaVersion = ctx.schemaVersion;\n const combinedSchemaGraphFence =\n (\n !options?.schemaFenceInFirstWrite &&\n expectedSchemaVersion !== undefined &&\n acquiresLock &&\n !(\"transaction\" in target) &&\n !hasLeasedSchemaFence(ctx, target)\n ) ?\n {\n acquire: target.lockSchemaVersionAndGraphWrite,\n params: {\n graphId: ctx.graphId,\n expectedVersion: expectedSchemaVersion,\n },\n }\n : undefined;\n let lock: GraphWriteLock;\n try {\n if (combinedSchemaGraphFence?.acquire === undefined) {\n if (!options?.schemaFenceInFirstWrite) {\n await lockSchemaVersionForStoreWrite(ctx, target);\n }\n lock =\n acquiresLock ?\n await lockRecordedGraphWrite(target, ctx.graphId)\n : (session?.lock ?? uncapturedGraphWriteLock());\n } else {\n // The optional strong member owns the same canonical order as the two\n // portable calls: schema row first, graph advisory lock second. It is\n // one statement only when THIS frame owes both acquisitions; a held\n // graph lock must never suppress the per-write schema fence.\n const isolation = await combinedSchemaGraphFence.acquire(\n combinedSchemaGraphFence.params,\n );\n memoizeAcquiredRecordedGraphWriteLock(target, ctx.graphId, isolation);\n // The combined statement acquired the real advisory lock, so mint\n // graph/port-bound command coordination only after it returns.\n lock = acquiredGraphWriteLockFromCombinedFence(\n target,\n ctx.graphId,\n isolation,\n );\n }\n } catch (error) {\n if (acquiresLock) held.delete(ctx.graphId);\n throw error;\n }\n if (session !== undefined) session.lock = lock;\n const result = await (acquiresLock ?\n fn(target, lock, transactionMode).finally(() => held.delete(ctx.graphId))\n : fn(target, lock, transactionMode));\n if (session !== undefined) {\n session.wrote ||= options?.didWrite?.(result) ?? true;\n return result;\n }\n // History capture advances the same clock when it flushes its recorded\n // after-images. Live stores opt into revisions independently, so advance\n // only there and only after every row/sidecar write succeeded.\n if (\n ctx.revisionTrackingEnabled &&\n !ctx.historyEnabled &&\n (options?.didWrite?.(result) ?? true)\n ) {\n await advanceRevisionClock(\n target,\n ctx.revisionSchema,\n ctx.graphId,\n ownsWriteLock,\n );\n }\n return result;\n });\n}\n\n/**\n * The slice of an operation context {@link runHookedWriteOperation} needs:\n * the {@link WriteTransactionContext} plus the hook wrapper. Both\n * `NodeOperationContext` and `EdgeOperationContext` satisfy it.\n */\nexport type HookedWriteOperationContext = WriteTransactionContext &\n Readonly<{\n withOperationHooks: <T>(\n ctx: OperationHookContext,\n fn: () => Promise<T>,\n didWrite?: (result: T) => boolean,\n ) => Promise<T>;\n }>;\n\n/**\n * The one sanctioned composition for a hooked, non-batch write operation:\n * operation hooks WRAP the write transaction, so `onOperationEnd` observes a\n * durably committed result and a failed COMMIT surfaces through `onError` —\n * a hook that fired inside the transaction would report success for a write\n * the rollback then discards. Every hooked node/edge mutation routes through\n * this helper; composing `withOperationHooks` and `runInWriteTransaction` by\n * hand invites exactly the inverted nesting this exists to prevent.\n * (Batch operations skip hooks deliberately and call\n * {@link runInWriteTransaction} directly.)\n */\nexport function runHookedWriteOperation<T>(\n ctx: HookedWriteOperationContext,\n opContext: OperationHookContext,\n backend: GraphBackend | TransactionBackend,\n body: (\n target: GraphBackend | TransactionBackend,\n lock: GraphWriteLock,\n transactionMode: WriteTransactionMode,\n ) => Promise<T>,\n options?: WriteTransactionOptions<T>,\n): Promise<T> {\n return ctx.withOperationHooks(\n opContext,\n () => runInWriteTransaction(ctx, backend, body, options),\n options?.didWrite,\n );\n}\n"]}