@quereus/quereus 2.9.0 → 3.0.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 (339) hide show
  1. package/README.md +224 -222
  2. package/dist/src/core/database-assertions.d.ts +36 -16
  3. package/dist/src/core/database-assertions.d.ts.map +1 -1
  4. package/dist/src/core/database-assertions.js +222 -118
  5. package/dist/src/core/database-assertions.js.map +1 -1
  6. package/dist/src/core/database-transaction.d.ts +96 -13
  7. package/dist/src/core/database-transaction.d.ts.map +1 -1
  8. package/dist/src/core/database-transaction.js +294 -35
  9. package/dist/src/core/database-transaction.js.map +1 -1
  10. package/dist/src/core/database-watchers.d.ts +58 -0
  11. package/dist/src/core/database-watchers.d.ts.map +1 -0
  12. package/dist/src/core/database-watchers.js +206 -0
  13. package/dist/src/core/database-watchers.js.map +1 -0
  14. package/dist/src/core/database.d.ts +78 -5
  15. package/dist/src/core/database.d.ts.map +1 -1
  16. package/dist/src/core/database.js +120 -20
  17. package/dist/src/core/database.js.map +1 -1
  18. package/dist/src/core/statement.d.ts +9 -0
  19. package/dist/src/core/statement.d.ts.map +1 -1
  20. package/dist/src/core/statement.js +29 -0
  21. package/dist/src/core/statement.js.map +1 -1
  22. package/dist/src/core/table-handle.d.ts +45 -0
  23. package/dist/src/core/table-handle.d.ts.map +1 -0
  24. package/dist/src/core/table-handle.js +54 -0
  25. package/dist/src/core/table-handle.js.map +1 -0
  26. package/dist/src/func/builtins/conversion.d.ts.map +1 -1
  27. package/dist/src/func/builtins/conversion.js +12 -1
  28. package/dist/src/func/builtins/conversion.js.map +1 -1
  29. package/dist/src/func/builtins/explain.d.ts.map +1 -1
  30. package/dist/src/func/builtins/explain.js +22 -8
  31. package/dist/src/func/builtins/explain.js.map +1 -1
  32. package/dist/src/func/builtins/generation.d.ts.map +1 -1
  33. package/dist/src/func/builtins/generation.js +26 -1
  34. package/dist/src/func/builtins/generation.js.map +1 -1
  35. package/dist/src/func/builtins/index.d.ts.map +1 -1
  36. package/dist/src/func/builtins/index.js +5 -1
  37. package/dist/src/func/builtins/index.js.map +1 -1
  38. package/dist/src/func/builtins/json-tvf.d.ts.map +1 -1
  39. package/dist/src/func/builtins/json-tvf.js +16 -2
  40. package/dist/src/func/builtins/json-tvf.js.map +1 -1
  41. package/dist/src/func/builtins/schema.d.ts +4 -0
  42. package/dist/src/func/builtins/schema.d.ts.map +1 -1
  43. package/dist/src/func/builtins/schema.js +270 -11
  44. package/dist/src/func/builtins/schema.js.map +1 -1
  45. package/dist/src/func/registration.d.ts +19 -1
  46. package/dist/src/func/registration.d.ts.map +1 -1
  47. package/dist/src/func/registration.js +8 -3
  48. package/dist/src/func/registration.js.map +1 -1
  49. package/dist/src/index.d.ts +7 -1
  50. package/dist/src/index.d.ts.map +1 -1
  51. package/dist/src/index.js +5 -0
  52. package/dist/src/index.js.map +1 -1
  53. package/dist/src/parser/parser.d.ts.map +1 -1
  54. package/dist/src/parser/parser.js +12 -4
  55. package/dist/src/parser/parser.js.map +1 -1
  56. package/dist/src/planner/analysis/assertion-classifier.d.ts +71 -0
  57. package/dist/src/planner/analysis/assertion-classifier.d.ts.map +1 -0
  58. package/dist/src/planner/analysis/assertion-classifier.js +286 -0
  59. package/dist/src/planner/analysis/assertion-classifier.js.map +1 -0
  60. package/dist/src/planner/analysis/assertion-hoist-cache.d.ts +34 -0
  61. package/dist/src/planner/analysis/assertion-hoist-cache.d.ts.map +1 -0
  62. package/dist/src/planner/analysis/assertion-hoist-cache.js +119 -0
  63. package/dist/src/planner/analysis/assertion-hoist-cache.js.map +1 -0
  64. package/dist/src/planner/analysis/binding-extractor.d.ts +58 -0
  65. package/dist/src/planner/analysis/binding-extractor.d.ts.map +1 -0
  66. package/dist/src/planner/analysis/binding-extractor.js +110 -0
  67. package/dist/src/planner/analysis/binding-extractor.js.map +1 -0
  68. package/dist/src/planner/analysis/change-scope.d.ts +184 -0
  69. package/dist/src/planner/analysis/change-scope.d.ts.map +1 -0
  70. package/dist/src/planner/analysis/change-scope.js +825 -0
  71. package/dist/src/planner/analysis/change-scope.js.map +1 -0
  72. package/dist/src/planner/analysis/check-extraction.d.ts +29 -0
  73. package/dist/src/planner/analysis/check-extraction.d.ts.map +1 -0
  74. package/dist/src/planner/analysis/check-extraction.js +420 -0
  75. package/dist/src/planner/analysis/check-extraction.js.map +1 -0
  76. package/dist/src/planner/analysis/constraint-extractor.d.ts +47 -7
  77. package/dist/src/planner/analysis/constraint-extractor.d.ts.map +1 -1
  78. package/dist/src/planner/analysis/constraint-extractor.js +169 -92
  79. package/dist/src/planner/analysis/constraint-extractor.js.map +1 -1
  80. package/dist/src/planner/analysis/partial-unique-extraction.d.ts +68 -0
  81. package/dist/src/planner/analysis/partial-unique-extraction.d.ts.map +1 -0
  82. package/dist/src/planner/analysis/partial-unique-extraction.js +347 -0
  83. package/dist/src/planner/analysis/partial-unique-extraction.js.map +1 -0
  84. package/dist/src/planner/analysis/predicate-conjuncts.d.ts +14 -0
  85. package/dist/src/planner/analysis/predicate-conjuncts.d.ts.map +1 -0
  86. package/dist/src/planner/analysis/predicate-conjuncts.js +31 -0
  87. package/dist/src/planner/analysis/predicate-conjuncts.js.map +1 -0
  88. package/dist/src/planner/analysis/predicate-shape.d.ts +52 -0
  89. package/dist/src/planner/analysis/predicate-shape.d.ts.map +1 -0
  90. package/dist/src/planner/analysis/predicate-shape.js +119 -0
  91. package/dist/src/planner/analysis/predicate-shape.js.map +1 -0
  92. package/dist/src/planner/analysis/sat-checker.d.ts +43 -0
  93. package/dist/src/planner/analysis/sat-checker.d.ts.map +1 -0
  94. package/dist/src/planner/analysis/sat-checker.js +393 -0
  95. package/dist/src/planner/analysis/sat-checker.js.map +1 -0
  96. package/dist/src/planner/building/table.d.ts.map +1 -1
  97. package/dist/src/planner/building/table.js +1 -1
  98. package/dist/src/planner/building/table.js.map +1 -1
  99. package/dist/src/planner/framework/characteristics.d.ts +10 -1
  100. package/dist/src/planner/framework/characteristics.d.ts.map +1 -1
  101. package/dist/src/planner/framework/characteristics.js +24 -5
  102. package/dist/src/planner/framework/characteristics.js.map +1 -1
  103. package/dist/src/planner/framework/pass.d.ts.map +1 -1
  104. package/dist/src/planner/framework/pass.js +46 -16
  105. package/dist/src/planner/framework/pass.js.map +1 -1
  106. package/dist/src/planner/framework/physical-utils.d.ts +0 -9
  107. package/dist/src/planner/framework/physical-utils.d.ts.map +1 -1
  108. package/dist/src/planner/framework/physical-utils.js +0 -31
  109. package/dist/src/planner/framework/physical-utils.js.map +1 -1
  110. package/dist/src/planner/nodes/aggregate-node.d.ts +25 -0
  111. package/dist/src/planner/nodes/aggregate-node.d.ts.map +1 -1
  112. package/dist/src/planner/nodes/aggregate-node.js +75 -8
  113. package/dist/src/planner/nodes/aggregate-node.js.map +1 -1
  114. package/dist/src/planner/nodes/alias-node.d.ts.map +1 -1
  115. package/dist/src/planner/nodes/alias-node.js +6 -1
  116. package/dist/src/planner/nodes/alias-node.js.map +1 -1
  117. package/dist/src/planner/nodes/asof-scan-node.d.ts.map +1 -1
  118. package/dist/src/planner/nodes/asof-scan-node.js +17 -3
  119. package/dist/src/planner/nodes/asof-scan-node.js.map +1 -1
  120. package/dist/src/planner/nodes/bloom-join-node.d.ts.map +1 -1
  121. package/dist/src/planner/nodes/bloom-join-node.js +19 -9
  122. package/dist/src/planner/nodes/bloom-join-node.js.map +1 -1
  123. package/dist/src/planner/nodes/distinct-node.d.ts.map +1 -1
  124. package/dist/src/planner/nodes/distinct-node.js +10 -6
  125. package/dist/src/planner/nodes/distinct-node.js.map +1 -1
  126. package/dist/src/planner/nodes/empty-relation-node.d.ts +27 -0
  127. package/dist/src/planner/nodes/empty-relation-node.d.ts.map +1 -0
  128. package/dist/src/planner/nodes/empty-relation-node.js +61 -0
  129. package/dist/src/planner/nodes/empty-relation-node.js.map +1 -0
  130. package/dist/src/planner/nodes/filter.d.ts.map +1 -1
  131. package/dist/src/planner/nodes/filter.js +65 -5
  132. package/dist/src/planner/nodes/filter.js.map +1 -1
  133. package/dist/src/planner/nodes/hash-aggregate.d.ts +1 -1
  134. package/dist/src/planner/nodes/hash-aggregate.d.ts.map +1 -1
  135. package/dist/src/planner/nodes/hash-aggregate.js +8 -6
  136. package/dist/src/planner/nodes/hash-aggregate.js.map +1 -1
  137. package/dist/src/planner/nodes/join-node.d.ts.map +1 -1
  138. package/dist/src/planner/nodes/join-node.js +12 -9
  139. package/dist/src/planner/nodes/join-node.js.map +1 -1
  140. package/dist/src/planner/nodes/join-utils.d.ts +24 -1
  141. package/dist/src/planner/nodes/join-utils.d.ts.map +1 -1
  142. package/dist/src/planner/nodes/join-utils.js +86 -0
  143. package/dist/src/planner/nodes/join-utils.js.map +1 -1
  144. package/dist/src/planner/nodes/limit-offset.d.ts.map +1 -1
  145. package/dist/src/planner/nodes/limit-offset.js +6 -1
  146. package/dist/src/planner/nodes/limit-offset.js.map +1 -1
  147. package/dist/src/planner/nodes/merge-join-node.d.ts.map +1 -1
  148. package/dist/src/planner/nodes/merge-join-node.js +19 -9
  149. package/dist/src/planner/nodes/merge-join-node.js.map +1 -1
  150. package/dist/src/planner/nodes/ordinal-slice-node.d.ts.map +1 -1
  151. package/dist/src/planner/nodes/ordinal-slice-node.js +5 -2
  152. package/dist/src/planner/nodes/ordinal-slice-node.js.map +1 -1
  153. package/dist/src/planner/nodes/plan-node-type.d.ts +1 -0
  154. package/dist/src/planner/nodes/plan-node-type.d.ts.map +1 -1
  155. package/dist/src/planner/nodes/plan-node-type.js +1 -0
  156. package/dist/src/planner/nodes/plan-node-type.js.map +1 -1
  157. package/dist/src/planner/nodes/plan-node.d.ts +186 -4
  158. package/dist/src/planner/nodes/plan-node.d.ts.map +1 -1
  159. package/dist/src/planner/nodes/plan-node.js.map +1 -1
  160. package/dist/src/planner/nodes/project-node.d.ts.map +1 -1
  161. package/dist/src/planner/nodes/project-node.js +75 -30
  162. package/dist/src/planner/nodes/project-node.js.map +1 -1
  163. package/dist/src/planner/nodes/reference.d.ts +24 -2
  164. package/dist/src/planner/nodes/reference.d.ts.map +1 -1
  165. package/dist/src/planner/nodes/reference.js +101 -1
  166. package/dist/src/planner/nodes/reference.js.map +1 -1
  167. package/dist/src/planner/nodes/retrieve-node.d.ts +9 -1
  168. package/dist/src/planner/nodes/retrieve-node.d.ts.map +1 -1
  169. package/dist/src/planner/nodes/retrieve-node.js +21 -0
  170. package/dist/src/planner/nodes/retrieve-node.js.map +1 -1
  171. package/dist/src/planner/nodes/returning-node.d.ts.map +1 -1
  172. package/dist/src/planner/nodes/returning-node.js +64 -28
  173. package/dist/src/planner/nodes/returning-node.js.map +1 -1
  174. package/dist/src/planner/nodes/scalar.d.ts +1 -0
  175. package/dist/src/planner/nodes/scalar.d.ts.map +1 -1
  176. package/dist/src/planner/nodes/scalar.js +12 -0
  177. package/dist/src/planner/nodes/scalar.js.map +1 -1
  178. package/dist/src/planner/nodes/set-operation-node.d.ts.map +1 -1
  179. package/dist/src/planner/nodes/set-operation-node.js +15 -0
  180. package/dist/src/planner/nodes/set-operation-node.js.map +1 -1
  181. package/dist/src/planner/nodes/single-row.d.ts.map +1 -1
  182. package/dist/src/planner/nodes/single-row.js +3 -1
  183. package/dist/src/planner/nodes/single-row.js.map +1 -1
  184. package/dist/src/planner/nodes/sort.d.ts.map +1 -1
  185. package/dist/src/planner/nodes/sort.js +10 -3
  186. package/dist/src/planner/nodes/sort.js.map +1 -1
  187. package/dist/src/planner/nodes/stream-aggregate.d.ts +1 -1
  188. package/dist/src/planner/nodes/stream-aggregate.d.ts.map +1 -1
  189. package/dist/src/planner/nodes/stream-aggregate.js +8 -8
  190. package/dist/src/planner/nodes/stream-aggregate.js.map +1 -1
  191. package/dist/src/planner/nodes/table-access-nodes.d.ts +3 -3
  192. package/dist/src/planner/nodes/table-access-nodes.d.ts.map +1 -1
  193. package/dist/src/planner/nodes/table-access-nodes.js +26 -8
  194. package/dist/src/planner/nodes/table-access-nodes.js.map +1 -1
  195. package/dist/src/planner/nodes/table-function-call.d.ts +4 -1
  196. package/dist/src/planner/nodes/table-function-call.d.ts.map +1 -1
  197. package/dist/src/planner/nodes/table-function-call.js +224 -14
  198. package/dist/src/planner/nodes/table-function-call.js.map +1 -1
  199. package/dist/src/planner/nodes/window-node.d.ts.map +1 -1
  200. package/dist/src/planner/nodes/window-node.js +9 -2
  201. package/dist/src/planner/nodes/window-node.js.map +1 -1
  202. package/dist/src/planner/optimizer-tuning.d.ts +29 -1
  203. package/dist/src/planner/optimizer-tuning.d.ts.map +1 -1
  204. package/dist/src/planner/optimizer-tuning.js +3 -0
  205. package/dist/src/planner/optimizer-tuning.js.map +1 -1
  206. package/dist/src/planner/optimizer.d.ts.map +1 -1
  207. package/dist/src/planner/optimizer.js +187 -0
  208. package/dist/src/planner/optimizer.js.map +1 -1
  209. package/dist/src/planner/rules/access/rule-select-access-path.d.ts.map +1 -1
  210. package/dist/src/planner/rules/access/rule-select-access-path.js +22 -7
  211. package/dist/src/planner/rules/access/rule-select-access-path.js.map +1 -1
  212. package/dist/src/planner/rules/aggregate/rule-groupby-fd-simplification.d.ts +30 -0
  213. package/dist/src/planner/rules/aggregate/rule-groupby-fd-simplification.d.ts.map +1 -0
  214. package/dist/src/planner/rules/aggregate/rule-groupby-fd-simplification.js +116 -0
  215. package/dist/src/planner/rules/aggregate/rule-groupby-fd-simplification.js.map +1 -0
  216. package/dist/src/planner/rules/distinct/rule-distinct-elimination.d.ts +7 -7
  217. package/dist/src/planner/rules/distinct/rule-distinct-elimination.d.ts.map +1 -1
  218. package/dist/src/planner/rules/distinct/rule-distinct-elimination.js +18 -16
  219. package/dist/src/planner/rules/distinct/rule-distinct-elimination.js.map +1 -1
  220. package/dist/src/planner/rules/join/rule-join-elimination.d.ts +56 -0
  221. package/dist/src/planner/rules/join/rule-join-elimination.d.ts.map +1 -0
  222. package/dist/src/planner/rules/join/rule-join-elimination.js +326 -0
  223. package/dist/src/planner/rules/join/rule-join-elimination.js.map +1 -0
  224. package/dist/src/planner/rules/join/rule-join-greedy-commute.d.ts.map +1 -1
  225. package/dist/src/planner/rules/join/rule-join-greedy-commute.js +10 -2
  226. package/dist/src/planner/rules/join/rule-join-greedy-commute.js.map +1 -1
  227. package/dist/src/planner/rules/predicate/rule-aggregate-predicate-pushdown.d.ts +20 -0
  228. package/dist/src/planner/rules/predicate/rule-aggregate-predicate-pushdown.d.ts.map +1 -0
  229. package/dist/src/planner/rules/predicate/rule-aggregate-predicate-pushdown.js +181 -0
  230. package/dist/src/planner/rules/predicate/rule-aggregate-predicate-pushdown.js.map +1 -0
  231. package/dist/src/planner/rules/predicate/rule-empty-relation-folding.d.ts +46 -0
  232. package/dist/src/planner/rules/predicate/rule-empty-relation-folding.d.ts.map +1 -0
  233. package/dist/src/planner/rules/predicate/rule-empty-relation-folding.js +156 -0
  234. package/dist/src/planner/rules/predicate/rule-empty-relation-folding.js.map +1 -0
  235. package/dist/src/planner/rules/predicate/rule-filter-contradiction.d.ts +30 -0
  236. package/dist/src/planner/rules/predicate/rule-filter-contradiction.d.ts.map +1 -0
  237. package/dist/src/planner/rules/predicate/rule-filter-contradiction.js +60 -0
  238. package/dist/src/planner/rules/predicate/rule-filter-contradiction.js.map +1 -0
  239. package/dist/src/planner/rules/predicate/rule-predicate-inference-equivalence.d.ts +45 -0
  240. package/dist/src/planner/rules/predicate/rule-predicate-inference-equivalence.d.ts.map +1 -0
  241. package/dist/src/planner/rules/predicate/rule-predicate-inference-equivalence.js +210 -0
  242. package/dist/src/planner/rules/predicate/rule-predicate-inference-equivalence.js.map +1 -0
  243. package/dist/src/planner/rules/predicate/rule-sargable-range-rewrite.d.ts +29 -0
  244. package/dist/src/planner/rules/predicate/rule-sargable-range-rewrite.d.ts.map +1 -0
  245. package/dist/src/planner/rules/predicate/rule-sargable-range-rewrite.js +161 -0
  246. package/dist/src/planner/rules/predicate/rule-sargable-range-rewrite.js.map +1 -0
  247. package/dist/src/planner/rules/sort/rule-orderby-fd-pruning.d.ts +39 -0
  248. package/dist/src/planner/rules/sort/rule-orderby-fd-pruning.d.ts.map +1 -0
  249. package/dist/src/planner/rules/sort/rule-orderby-fd-pruning.js +91 -0
  250. package/dist/src/planner/rules/sort/rule-orderby-fd-pruning.js.map +1 -0
  251. package/dist/src/planner/rules/subquery/rule-anti-join-fk-empty.d.ts +35 -0
  252. package/dist/src/planner/rules/subquery/rule-anti-join-fk-empty.d.ts.map +1 -0
  253. package/dist/src/planner/rules/subquery/rule-anti-join-fk-empty.js +74 -0
  254. package/dist/src/planner/rules/subquery/rule-anti-join-fk-empty.js.map +1 -0
  255. package/dist/src/planner/rules/subquery/rule-semi-join-fk-trivial.d.ts +27 -0
  256. package/dist/src/planner/rules/subquery/rule-semi-join-fk-trivial.d.ts.map +1 -0
  257. package/dist/src/planner/rules/subquery/rule-semi-join-fk-trivial.js +103 -0
  258. package/dist/src/planner/rules/subquery/rule-semi-join-fk-trivial.js.map +1 -0
  259. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.d.ts.map +1 -1
  260. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.js +1 -25
  261. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.js.map +1 -1
  262. package/dist/src/planner/scopes/global.js +2 -2
  263. package/dist/src/planner/scopes/global.js.map +1 -1
  264. package/dist/src/planner/type-utils.d.ts.map +1 -1
  265. package/dist/src/planner/type-utils.js +11 -0
  266. package/dist/src/planner/type-utils.js.map +1 -1
  267. package/dist/src/planner/util/fd-utils.d.ts +245 -0
  268. package/dist/src/planner/util/fd-utils.d.ts.map +1 -0
  269. package/dist/src/planner/util/fd-utils.js +1416 -0
  270. package/dist/src/planner/util/fd-utils.js.map +1 -0
  271. package/dist/src/planner/util/ind-utils.d.ts +79 -0
  272. package/dist/src/planner/util/ind-utils.d.ts.map +1 -0
  273. package/dist/src/planner/util/ind-utils.js +146 -0
  274. package/dist/src/planner/util/ind-utils.js.map +1 -0
  275. package/dist/src/planner/util/key-utils.d.ts +75 -14
  276. package/dist/src/planner/util/key-utils.d.ts.map +1 -1
  277. package/dist/src/planner/util/key-utils.js +234 -57
  278. package/dist/src/planner/util/key-utils.js.map +1 -1
  279. package/dist/src/runtime/delta-executor.d.ts +134 -0
  280. package/dist/src/runtime/delta-executor.d.ts.map +1 -0
  281. package/dist/src/runtime/delta-executor.js +382 -0
  282. package/dist/src/runtime/delta-executor.js.map +1 -0
  283. package/dist/src/runtime/emit/alter-table.d.ts.map +1 -1
  284. package/dist/src/runtime/emit/alter-table.js +52 -16
  285. package/dist/src/runtime/emit/alter-table.js.map +1 -1
  286. package/dist/src/runtime/emit/create-assertion.d.ts.map +1 -1
  287. package/dist/src/runtime/emit/create-assertion.js +3 -2
  288. package/dist/src/runtime/emit/create-assertion.js.map +1 -1
  289. package/dist/src/runtime/emit/dml-executor.d.ts.map +1 -1
  290. package/dist/src/runtime/emit/dml-executor.js +40 -13
  291. package/dist/src/runtime/emit/dml-executor.js.map +1 -1
  292. package/dist/src/runtime/emit/drop-assertion.js +1 -1
  293. package/dist/src/runtime/emit/drop-assertion.js.map +1 -1
  294. package/dist/src/runtime/emit/empty-relation.d.ts +5 -0
  295. package/dist/src/runtime/emit/empty-relation.d.ts.map +1 -0
  296. package/dist/src/runtime/emit/empty-relation.js +11 -0
  297. package/dist/src/runtime/emit/empty-relation.js.map +1 -0
  298. package/dist/src/runtime/foreign-key-actions.d.ts +16 -0
  299. package/dist/src/runtime/foreign-key-actions.d.ts.map +1 -1
  300. package/dist/src/runtime/foreign-key-actions.js +81 -1
  301. package/dist/src/runtime/foreign-key-actions.js.map +1 -1
  302. package/dist/src/runtime/register.d.ts.map +1 -1
  303. package/dist/src/runtime/register.js +2 -0
  304. package/dist/src/runtime/register.js.map +1 -1
  305. package/dist/src/schema/assertion.d.ts +8 -0
  306. package/dist/src/schema/assertion.d.ts.map +1 -1
  307. package/dist/src/schema/change-events.d.ts +5 -1
  308. package/dist/src/schema/change-events.d.ts.map +1 -1
  309. package/dist/src/schema/change-events.js.map +1 -1
  310. package/dist/src/schema/function.d.ts +65 -1
  311. package/dist/src/schema/function.d.ts.map +1 -1
  312. package/dist/src/schema/function.js +31 -0
  313. package/dist/src/schema/function.js.map +1 -1
  314. package/dist/src/schema/manager.d.ts +33 -0
  315. package/dist/src/schema/manager.d.ts.map +1 -1
  316. package/dist/src/schema/manager.js +95 -4
  317. package/dist/src/schema/manager.js.map +1 -1
  318. package/dist/src/schema/rename-rewriter.d.ts.map +1 -1
  319. package/dist/src/schema/rename-rewriter.js +303 -102
  320. package/dist/src/schema/rename-rewriter.js.map +1 -1
  321. package/dist/src/schema/table.d.ts +21 -2
  322. package/dist/src/schema/table.d.ts.map +1 -1
  323. package/dist/src/schema/table.js +17 -8
  324. package/dist/src/schema/table.js.map +1 -1
  325. package/dist/src/types/temporal-types.d.ts.map +1 -1
  326. package/dist/src/types/temporal-types.js +32 -0
  327. package/dist/src/types/temporal-types.js.map +1 -1
  328. package/dist/src/vtab/events.d.ts +9 -0
  329. package/dist/src/vtab/events.d.ts.map +1 -1
  330. package/dist/src/vtab/events.js +19 -0
  331. package/dist/src/vtab/events.js.map +1 -1
  332. package/dist/src/vtab/memory/layer/manager.d.ts.map +1 -1
  333. package/dist/src/vtab/memory/layer/manager.js +24 -5
  334. package/dist/src/vtab/memory/layer/manager.js.map +1 -1
  335. package/dist/src/vtab/memory/utils/predicate.d.ts +2 -1
  336. package/dist/src/vtab/memory/utils/predicate.d.ts.map +1 -1
  337. package/dist/src/vtab/memory/utils/predicate.js +32 -1
  338. package/dist/src/vtab/memory/utils/predicate.js.map +1 -1
  339. package/package.json +3 -3
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Database.watch infrastructure — registration, post-commit firing,
3
+ * schema-change invalidation, and txn-id minting.
4
+ *
5
+ * Watchers are the second consumer of `DeltaExecutor`. Unlike assertions,
6
+ * they run **after** commit (the change log is still alive, the
7
+ * connections have all committed), and handler errors are logged but
8
+ * never roll the commit back.
9
+ */
10
+ import { type SqlValue } from '../common/types.js';
11
+ import type { ChangeScope, Subscription, WatchHandler } from '../planner/analysis/change-scope.js';
12
+ import type { Database } from './database.js';
13
+ /**
14
+ * Database internals the watcher manager needs. Mirrors
15
+ * `AssertionEvaluatorContext` — keeps the manager testable without the
16
+ * full `Database`.
17
+ */
18
+ export interface WatcherManagerContext {
19
+ readonly schemaManager: Database['schemaManager'];
20
+ readonly optimizer: Database['optimizer'];
21
+ getChangedBaseTables(): Set<string>;
22
+ getChangedTuples(base: string, columnIndices: readonly number[], pkIndices: readonly number[]): SqlValue[][];
23
+ registerCaptureSpec(baseTable: string, spec: {
24
+ extraColumns: ReadonlySet<number>;
25
+ }): () => void;
26
+ _findTable(tableName: string, schemaName?: string): ReturnType<Database['_findTable']>;
27
+ }
28
+ /**
29
+ * Manages all `Database.watch` subscriptions for a single `Database`.
30
+ */
31
+ export declare class WatcherManager {
32
+ private readonly ctx;
33
+ private readonly executor;
34
+ private readonly active;
35
+ private nextTxnIdCounter;
36
+ private currentTxnId;
37
+ private unsubscribeSchemaChanges;
38
+ constructor(ctx: WatcherManagerContext);
39
+ private subscribeToSchemaChanges;
40
+ /**
41
+ * Register a watcher. Validates the scope synchronously, registers
42
+ * capture demand, and produces a `Subscription` handle whose
43
+ * `unsubscribe()` releases all resources.
44
+ */
45
+ watch(scope: ChangeScope, handler: WatchHandler): Subscription;
46
+ /** Fire all subscriptions impacted by the current commit. Errors from
47
+ * any single subscription's apply are logged and swallowed.
48
+ *
49
+ * Must be called by the TransactionManager after a successful commit
50
+ * but before the change log is cleared. */
51
+ runPostCommit(): Promise<void>;
52
+ dispose(): void;
53
+ private disposeActive;
54
+ private invalidateForTable;
55
+ private mintTxnId;
56
+ private nextNonce;
57
+ }
58
+ //# sourceMappingURL=database-watchers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database-watchers.d.ts","sourceRoot":"","sources":["../../../src/core/database-watchers.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,EAAc,KAAK,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAQ/D,OAAO,KAAK,EACX,WAAW,EAEX,YAAY,EACZ,YAAY,EACZ,MAAM,qCAAqC,CAAC;AAC7C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAM9C;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACrC,QAAQ,CAAC,aAAa,EAAE,QAAQ,CAAC,eAAe,CAAC,CAAC;IAClD,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;IAE1C,oBAAoB,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;IACpC,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,SAAS,MAAM,EAAE,EAAE,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,QAAQ,EAAE,EAAE,CAAC;IAC7G,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE;QAAE,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;KAAE,GAAG,MAAM,IAAI,CAAC;IAChG,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC;CACvF;AAcD;;GAEG;AACH,qBAAa,cAAc;IAOd,OAAO,CAAC,QAAQ,CAAC,GAAG;IANhC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgB;IACzC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAyC;IAChE,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,YAAY,CAAM;IAC1B,OAAO,CAAC,wBAAwB,CAA6B;gBAEhC,GAAG,EAAE,qBAAqB;IAevD,OAAO,CAAC,wBAAwB;IAUhC;;;;OAIG;IACH,KAAK,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,YAAY,GAAG,YAAY;IAmD9D;;;;gDAI4C;IACtC,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAepC,OAAO,IAAI,IAAI;IAWf,OAAO,CAAC,aAAa;IAWrB,OAAO,CAAC,kBAAkB;IAW1B,OAAO,CAAC,SAAS;IAKjB,OAAO,CAAC,SAAS;CAKjB"}
@@ -0,0 +1,206 @@
1
+ /**
2
+ * Database.watch infrastructure — registration, post-commit firing,
3
+ * schema-change invalidation, and txn-id minting.
4
+ *
5
+ * Watchers are the second consumer of `DeltaExecutor`. Unlike assertions,
6
+ * they run **after** commit (the change log is still alive, the
7
+ * connections have all committed), and handler errors are logged but
8
+ * never roll the commit back.
9
+ */
10
+ import { createLogger } from '../common/logger.js';
11
+ import { QuereusError } from '../common/errors.js';
12
+ import { StatusCode } from '../common/types.js';
13
+ import { DeltaExecutor, subscriptionFromChangeScope, } from '../runtime/delta-executor.js';
14
+ const log = createLogger('core:watchers');
15
+ const warnLog = log.extend('warn');
16
+ /**
17
+ * Manages all `Database.watch` subscriptions for a single `Database`.
18
+ */
19
+ export class WatcherManager {
20
+ ctx;
21
+ executor;
22
+ active = new Map();
23
+ nextTxnIdCounter = 0;
24
+ currentTxnId = '';
25
+ unsubscribeSchemaChanges = null;
26
+ constructor(ctx) {
27
+ this.ctx = ctx;
28
+ const executorCtx = {
29
+ getChangedBaseTables: () => ctx.getChangedBaseTables(),
30
+ getChangedTuples: (base, cols, pk) => ctx.getChangedTuples(base, cols, pk),
31
+ getRowCount: (base) => {
32
+ const [schemaName, tableName] = base.split('.');
33
+ const table = ctx._findTable(tableName, schemaName);
34
+ return table?.estimatedRows;
35
+ },
36
+ deltaPerRowFallbackRatio: ctx.optimizer.tuning.deltaPerRowFallbackRatio,
37
+ };
38
+ this.executor = new DeltaExecutor(executorCtx);
39
+ this.subscribeToSchemaChanges();
40
+ }
41
+ subscribeToSchemaChanges() {
42
+ const notifier = this.ctx.schemaManager.getChangeNotifier();
43
+ this.unsubscribeSchemaChanges = notifier.addListener((event) => {
44
+ if (event.type === 'table_removed' || event.type === 'table_modified') {
45
+ const fqName = `${event.schemaName}.${event.objectName}`.toLowerCase();
46
+ this.invalidateForTable(fqName);
47
+ }
48
+ });
49
+ }
50
+ /**
51
+ * Register a watcher. Validates the scope synchronously, registers
52
+ * capture demand, and produces a `Subscription` handle whose
53
+ * `unsubscribe()` releases all resources.
54
+ */
55
+ watch(scope, handler) {
56
+ if (scope.unboundParameters.length > 0) {
57
+ throw new QuereusError(`watch: scope has unbound parameters [${scope.unboundParameters.join(', ')}]; call bindParameters(scope, params) first`, StatusCode.MISUSE);
58
+ }
59
+ const id = mintSubscriptionId(scope, this.nextNonce());
60
+ const tables = new Set();
61
+ for (const w of scope.watches) {
62
+ tables.add(`${w.table.schema}.${w.table.table}`.toLowerCase());
63
+ }
64
+ const helperCtx = {
65
+ resolveTable: (qname) => {
66
+ const table = this.ctx._findTable(qname.table, qname.schema);
67
+ if (!table)
68
+ return undefined;
69
+ return {
70
+ columnIndexMap: table.columnIndexMap,
71
+ pkIndices: table.primaryKeyDefinition.map(d => d.index),
72
+ };
73
+ },
74
+ registerCaptureSpec: (base, spec) => this.ctx.registerCaptureSpec(base, spec),
75
+ getCurrentTxnId: () => this.currentTxnId,
76
+ };
77
+ const { subscription, captureDisposers } = subscriptionFromChangeScope(scope, handler, id, helperCtx);
78
+ const disposeFromExecutor = this.executor.register(subscription);
79
+ const entry = {
80
+ id,
81
+ tables,
82
+ disposeFromExecutor,
83
+ captureDisposers,
84
+ disposed: false,
85
+ };
86
+ this.active.set(id, entry);
87
+ const isDead = scope.watches.length === 0
88
+ && scope.nonDeterministicSources.length === 0;
89
+ if (isDead) {
90
+ warnLog('Registered dead subscription %s (no watches and no non-deterministic sources)', id);
91
+ }
92
+ return {
93
+ id,
94
+ unsubscribe: () => this.disposeActive(entry),
95
+ };
96
+ }
97
+ /** Fire all subscriptions impacted by the current commit. Errors from
98
+ * any single subscription's apply are logged and swallowed.
99
+ *
100
+ * Must be called by the TransactionManager after a successful commit
101
+ * but before the change log is cleared. */
102
+ async runPostCommit() {
103
+ if (this.active.size === 0)
104
+ return;
105
+ this.currentTxnId = this.mintTxnId();
106
+ try {
107
+ await this.executor.runAll();
108
+ }
109
+ catch (err) {
110
+ // subscriptionFromChangeScope swallows handler errors; this catch
111
+ // is defensive — if the kernel itself throws (e.g. a missing PK
112
+ // triggers a fallback log), don't propagate into the commit path.
113
+ log('Post-commit watcher run threw: %O', err);
114
+ }
115
+ finally {
116
+ this.currentTxnId = '';
117
+ }
118
+ }
119
+ dispose() {
120
+ if (this.unsubscribeSchemaChanges) {
121
+ this.unsubscribeSchemaChanges();
122
+ this.unsubscribeSchemaChanges = null;
123
+ }
124
+ for (const entry of [...this.active.values()]) {
125
+ this.disposeActive(entry);
126
+ }
127
+ this.executor.disposeAll();
128
+ }
129
+ disposeActive(entry) {
130
+ if (entry.disposed)
131
+ return;
132
+ entry.disposed = true;
133
+ this.active.delete(entry.id);
134
+ entry.disposeFromExecutor();
135
+ for (const d of entry.captureDisposers) {
136
+ try {
137
+ d();
138
+ }
139
+ catch (err) {
140
+ log('Capture-spec disposer for %s threw: %O', entry.id, err);
141
+ }
142
+ }
143
+ entry.captureDisposers.length = 0;
144
+ }
145
+ invalidateForTable(fqName) {
146
+ const toDispose = [];
147
+ for (const entry of this.active.values()) {
148
+ if (entry.tables.has(fqName))
149
+ toDispose.push(entry);
150
+ }
151
+ for (const entry of toDispose) {
152
+ warnLog('Invalidating subscription %s due to schema change on %s', entry.id, fqName);
153
+ this.disposeActive(entry);
154
+ }
155
+ }
156
+ mintTxnId() {
157
+ this.nextTxnIdCounter += 1;
158
+ return `txn:${this.nextTxnIdCounter}`;
159
+ }
160
+ nextNonce() {
161
+ // Plain Math.random is fine here — we only need uniqueness within a
162
+ // process, not crypto-grade entropy.
163
+ return Math.random().toString(36).slice(2, 10);
164
+ }
165
+ }
166
+ /**
167
+ * Hash a scope into a stable id. The id mixes a canonical serialization
168
+ * of the watch shape (so two subscriptions for the same scope hash to
169
+ * the same prefix) with a random nonce (so the id is unique per
170
+ * registration). Format: `watch:<base32-hash>:<nonce>`.
171
+ */
172
+ function mintSubscriptionId(scope, nonce) {
173
+ const canonical = canonicalizeScope(scope);
174
+ const hash = djb2Base32(canonical);
175
+ return `watch:${hash}:${nonce}`;
176
+ }
177
+ function canonicalizeScope(scope) {
178
+ const parts = [];
179
+ for (const w of scope.watches) {
180
+ parts.push(`${w.table.schema}.${w.table.table}`);
181
+ parts.push(w.columns === 'all' ? '*' : [...w.columns].sort().join(','));
182
+ parts.push(JSON.stringify(w.scope));
183
+ }
184
+ for (const n of scope.nonDeterministicSources)
185
+ parts.push(JSON.stringify(n));
186
+ for (const p of scope.unboundParameters)
187
+ parts.push(String(p));
188
+ return parts.join('|');
189
+ }
190
+ /** djb2 hash → 6 base32 chars. Fast, no crypto guarantees needed. */
191
+ function djb2Base32(s) {
192
+ let h = 5381;
193
+ for (let i = 0; i < s.length; i++) {
194
+ h = ((h << 5) + h + s.charCodeAt(i)) | 0;
195
+ }
196
+ const u = h >>> 0;
197
+ const alphabet = 'abcdefghijklmnopqrstuvwxyz234567';
198
+ let out = '';
199
+ let n = u;
200
+ for (let i = 0; i < 6; i++) {
201
+ out = alphabet[n & 31] + out;
202
+ n = n >>> 5;
203
+ }
204
+ return out;
205
+ }
206
+ //# sourceMappingURL=database-watchers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database-watchers.js","sourceRoot":"","sources":["../../../src/core/database-watchers.ts"],"names":[],"mappings":"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"}
@@ -21,6 +21,9 @@ import { type LogicalType } from '../types/logical-type.js';
21
21
  import { type DatabaseDataChangeEvent, type DatabaseSchemaChangeEvent, type DataChangeSubscriptionOptions, type SchemaChangeSubscriptionOptions } from './database-events.js';
22
22
  import { type TransactionManagerContext } from './database-transaction.js';
23
23
  import { type AssertionEvaluatorContext } from './database-assertions.js';
24
+ import { type WatcherManagerContext } from './database-watchers.js';
25
+ import type { ChangeScope, Subscription, WatchHandler } from '../planner/analysis/change-scope.js';
26
+ import { Table } from './table-handle.js';
24
27
  /** Result from _buildPlan containing both the plan tree and its schema dependencies. */
25
28
  export interface BuildPlanResult {
26
29
  plan: BlockNode;
@@ -30,7 +33,7 @@ export interface BuildPlanResult {
30
33
  * Represents a connection to an Quereus database (in-memory in this port).
31
34
  * Manages schema, prepared statements, virtual tables, and functions.
32
35
  */
33
- export declare class Database implements TransactionManagerContext, AssertionEvaluatorContext {
36
+ export declare class Database implements TransactionManagerContext, AssertionEvaluatorContext, WatcherManagerContext {
34
37
  readonly schemaManager: SchemaManager;
35
38
  readonly declaredSchemaManager: DeclaredSchemaManager;
36
39
  private isOpen;
@@ -53,6 +56,8 @@ export declare class Database implements TransactionManagerContext, AssertionEva
53
56
  private readonly transactionManager;
54
57
  /** Assertion evaluation */
55
58
  private readonly assertionEvaluator;
59
+ /** Post-commit watcher dispatch */
60
+ private readonly watcherManager;
56
61
  /** Per-database collation registry — comparator + optional key normalizer.
57
62
  * The normalizer is required for index participation; comparator-only
58
63
  * collations may still be used in ORDER BY but cannot back a compound index. */
@@ -62,6 +67,19 @@ export declare class Database implements TransactionManagerContext, AssertionEva
62
67
  getChangedBaseTables(): Set<string>;
63
68
  /** Get changed PK tuples for a specific base table */
64
69
  getChangedKeyTuples(base: string): SqlValue[][];
70
+ /**
71
+ * Get changed value tuples projected onto `columnIndices` for a specific
72
+ * base table. The columns must have been registered for capture via
73
+ * `registerCaptureSpec` (PK columns are always captured implicitly).
74
+ */
75
+ getChangedTuples(base: string, columnIndices: readonly number[], pkIndices: readonly number[]): SqlValue[][];
76
+ /**
77
+ * Register projection capture demand for a base table. Returns a dispose
78
+ * handle that removes the spec when called.
79
+ */
80
+ registerCaptureSpec(baseTable: string, spec: {
81
+ extraColumns: ReadonlySet<number>;
82
+ }): () => void;
65
83
  /**
66
84
  * Prepares an SQL statement for execution.
67
85
  *
@@ -339,10 +357,13 @@ export declare class Database implements TransactionManagerContext, AssertionEva
339
357
  getInstructionTracer(): InstructionTracer | undefined;
340
358
  _queueDeferredConstraintRow(baseTable: string, constraintName: string, row: Row, descriptor: RowDescriptor, evaluator: (ctx: RuntimeContext) => OutputValue, connectionId?: string, contextRow?: Row, contextDescriptor?: RowDescriptor): void;
341
359
  runDeferredRowConstraints(): Promise<void>;
342
- /** Public API used by DML emitters to record changes */
343
- _recordInsert(baseTable: string, newKey: SqlValue[]): void;
344
- _recordDelete(baseTable: string, oldKey: SqlValue[]): void;
345
- _recordUpdate(baseTable: string, oldKey: SqlValue[], newKey: SqlValue[]): void;
360
+ /** Public API used by DML emitters to record changes. The full row plus
361
+ * PK column indices are passed so the change capture can project the
362
+ * columns that any active DeltaExecutor subscription has registered
363
+ * demand for. */
364
+ _recordInsert(baseTable: string, newRow: Row, pkIndices: readonly number[]): void;
365
+ _recordDelete(baseTable: string, oldRow: Row, pkIndices: readonly number[]): void;
366
+ _recordUpdate(baseTable: string, oldRow: Row, newRow: Row, pkIndices: readonly number[]): void;
346
367
  /** Create a named savepoint, returning its depth index */
347
368
  _createSavepoint(name: string): number;
348
369
  /** Release a named savepoint (merges layers down to target), returns target depth */
@@ -397,6 +418,36 @@ export declare class Database implements TransactionManagerContext, AssertionEva
397
418
  * @returns A Statement with debug capabilities.
398
419
  */
399
420
  prepareDebug(sql: string, debug: DebugOptions): Statement;
421
+ /**
422
+ * Returns a public handle to a table for inspection and per-table event
423
+ * subscription. Returns `undefined` if the table does not exist or its
424
+ * owning module is not registered.
425
+ *
426
+ * The returned {@link Table} is a snapshot: its `schema` reference is
427
+ * frozen at acquisition time. If the table is dropped or recreated, the
428
+ * handle keeps the original schema, but no further events for that name
429
+ * will arrive. Re-acquire after schema changes if you need fresh state.
430
+ *
431
+ * After {@link Database.close}, the handle's event emitter reference
432
+ * remains valid (the module instance outlives the database) but the
433
+ * database-level aggregator is unhooked, so local subscriptions on the
434
+ * module emitter still fire only as long as the module itself remains
435
+ * active.
436
+ *
437
+ * @param schemaName The schema name ('main', 'temp', or an attached
438
+ * schema). Pass `undefined` to use the current default schema.
439
+ * @param tableName The table name (case-insensitive resolution).
440
+ *
441
+ * @example
442
+ * ```typescript
443
+ * const table = db.getTable('main', 'users');
444
+ * const tableEmitter = table?.getEventEmitter();
445
+ * const off = tableEmitter?.onDataChange?.((event) => {
446
+ * if (event.tableName === 'users') console.log(event);
447
+ * });
448
+ * ```
449
+ */
450
+ getTable(schemaName: string | undefined, tableName: string): Table | undefined;
400
451
  /**
401
452
  * Disconnects and removes all active connections.
402
453
  * Called during database close.
@@ -404,5 +455,27 @@ export declare class Database implements TransactionManagerContext, AssertionEva
404
455
  private disconnectAllConnections;
405
456
  private checkOpen;
406
457
  runGlobalAssertions(): Promise<void>;
458
+ /**
459
+ * Subscribe to changes described by a {@link ChangeScope}.
460
+ *
461
+ * The watcher fires its handler **after** a transaction commits (mirrors
462
+ * assertion COMMIT eval), once per commit, with all matching watches in
463
+ * a single {@link WatchEvent}. Handler errors are caught and logged —
464
+ * they do not roll the commit back (assertions own that contract).
465
+ *
466
+ * Validation is synchronous:
467
+ * - Throws if `scope.unboundParameters` is non-empty (caller must
468
+ * `bindParameters(scope, params)` first).
469
+ * - Throws if any referenced table or column does not exist in the
470
+ * current schema.
471
+ *
472
+ * If the table or any column the scope mentions is later dropped or
473
+ * altered, the subscription is **invalidated and disposed**; re-subscribe
474
+ * to continue watching.
475
+ *
476
+ * @returns A {@link Subscription} handle whose `unsubscribe()` is
477
+ * idempotent and releases capture-spec demand.
478
+ */
479
+ watch(scope: ChangeScope, handler: WatchHandler): Subscription;
407
480
  }
408
481
  //# sourceMappingURL=database.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../../src/core/database.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../../src/core/database.ts"],"names":[],"mappings":"AAEA,OAAO,EAAc,KAAK,aAAa,EAAE,KAAK,QAAQ,EAAE,KAAK,GAAG,EAAE,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC/G,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAM5D,OAAO,EAAuD,KAAK,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAGpH,OAAO,KAAK,GAAG,MAAM,kBAAkB,CAAC;AAIxC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAEtD,OAAO,EAAE,0BAA0B,EAAE,MAAM,gCAAgC,CAAC;AAG5E,OAAO,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AAGzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAEnE,OAAO,EAAE,SAAS,EAAkB,MAAM,yBAAyB,CAAC;AAGpE,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sCAAsC,CAAC;AAE7E,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAK5D,OAAO,EAEN,KAAK,uBAAuB,EAC5B,KAAK,yBAAyB,EAC9B,KAAK,6BAA6B,EAClC,KAAK,+BAA+B,EACpC,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAsB,KAAK,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AAC/F,OAAO,EAAsB,KAAK,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AAC9F,OAAO,EAAkB,KAAK,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AACpF,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,qCAAqC,CAAC;AAEnG,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAK1C,wFAAwF;AACxF,MAAM,WAAW,eAAe;IAC/B,IAAI,EAAE,SAAS,CAAC;IAChB,kBAAkB,EAAE,0BAA0B,CAAC;CAC/C;AASD;;;GAGG;AACH,qBAAa,QAAS,YAAW,yBAAyB,EAAE,yBAAyB,EAAE,qBAAqB;IAC3G,SAAgB,aAAa,EAAE,aAAa,CAAC;IAC7C,SAAgB,qBAAqB,EAAE,qBAAqB,CAAC;IAC7D,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,UAAU,CAAwB;IAC1C,OAAO,CAAC,iBAAiB,CAA6C;IACtE,SAAgB,SAAS,EAAE,SAAS,CAAC;IACrC,SAAgB,OAAO,EAAE,sBAAsB,CAAC;IAChD,OAAO,CAAC,iBAAiB,CAAgC;IACzD,2CAA2C;IAC3C,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAqC;IACzE;;;;OAIG;IACH,OAAO,CAAC,SAAS,CAAoC;IACrD,0DAA0D;IAC1D,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA8B;IAC3D,6BAA6B;IAC7B,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAqB;IACxD,2BAA2B;IAC3B,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAqB;IACxD,mCAAmC;IACnC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiB;IAChD;;qFAEiF;IACjF,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA4F;;IAmDvH,yCAAyC;IACzC,oBAAoB,IAAI,GAAG,CAAC,MAAM,CAAC;IAInC,sDAAsD;IACtD,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,EAAE,EAAE;IAI/C;;;;OAIG;IACH,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,SAAS,MAAM,EAAE,EAAE,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,QAAQ,EAAE,EAAE;IAI5G;;;OAGG;IACH,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE;QAAE,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;KAAE,GAAG,MAAM,IAAI;IAiH/F;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,aAAa,GAAG,QAAQ,EAAE,GAAG,GAAG,CAAC,MAAM,GAAG,MAAM,EAAE,UAAU,CAAC,GAAG,SAAS;IAW9G;;;;;;;;;OASG;IACG,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,QAAQ,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,SAAS,CAAC;IA8L1G;;OAEG;IACH,OAAO,CAAC,SAAS;IAQjB;;;;;;;;;;;OAWG;IACG,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAmD9D;;;;;OAKG;IACH,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,qBAAqB,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI;IAuCpF;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,YAAY,CACX,QAAQ,EAAE,CAAC,KAAK,EAAE,uBAAuB,KAAK,IAAI,EAClD,OAAO,CAAC,EAAE,6BAA6B,GACrC,MAAM,IAAI;IAKb;;;;;;;;;;;;;;;;;;;OAmBG;IACH,cAAc,CACb,QAAQ,EAAE,CAAC,KAAK,EAAE,yBAAyB,KAAK,IAAI,EACpD,OAAO,CAAC,EAAE,+BAA+B,GACvC,MAAM,IAAI;IAKb;;OAEG;IACH,gBAAgB,IAAI,OAAO;IAI3B;;OAEG;IACH,kBAAkB,IAAI,OAAO;IAY7B;;OAEG;IACG,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IAUvC;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAU7B;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAU/B;;;OAGG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAqC5B;;OAEG;IACH,aAAa,IAAI,OAAO;IAKxB;;;;OAIG;IACH,WAAW,CAAC,UAAU,EAAE,WAAW,GAAG,IAAI;IAS1C,8EAA8E;IAC9E,OAAO,CAAC,iCAAiC;IAmBzC;;;;;;OAMG;IACH,oBAAoB,CACnB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE;QACR,OAAO,EAAE,MAAM,CAAC;QAChB,aAAa,CAAC,EAAE,OAAO,CAAC;QACxB,KAAK,CAAC,EAAE,MAAM,CAAC;KACf,EACD,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,QAAQ,EAAE,KAAK,QAAQ,GACrC,IAAI;IAgBP;;;;;;;OAOG;IACH,uBAAuB,CACtB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE;QACR,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,YAAY,CAAC,EAAE,OAAO,CAAC;KACvB,EACD,QAAQ,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,KAAK,OAAO,EACxD,SAAS,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,QAAQ,GACnC,IAAI;IAgBP;;;;;OAKG;IACH,gBAAgB,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI;IA+B9C,gDAAgD;IAChD,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAKtC,sCAAsC;IACtC,kBAAkB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,IAAI;IAWxD;;;OAGG;IACH,oBAAoB,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;KAAE;IAKxE;;;;;;;;;;;OAWG;IACH,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI;IAMpC;;;;;;;;;;OAUG;IACH,aAAa,IAAI,MAAM,EAAE;IAKzB;;;;OAIG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;IAK/C;;;;OAIG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAKlC,uCAAuC;IACvC,OAAO,CAAC,qBAAqB;IAI7B;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,EAAE,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI;IAqBlG;;;;;;;;;;;;;;;OAeG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,GAAG,IAAI;IAmCzD;;;;OAIG;IACH,oBAAoB,CAAC,MAAM,EAAE,iBAAiB,GAAG,SAAS,GAAG,IAAI;IAKjE;;;OAGG;IACH,oBAAoB,IAAI,iBAAiB,GAAG,SAAS;IAuB9C,2BAA2B,CAAC,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,UAAU,EAAE,aAAa,EAAE,SAAS,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,WAAW,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,GAAG,EAAE,iBAAiB,CAAC,EAAE,aAAa,GAAG,IAAI;IAIxO,yBAAyB,IAAI,OAAO,CAAC,IAAI,CAAC;IAcvD;;;sBAGkB;IACX,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI;IAIjF,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI;IAIjF,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI;IAIrG,0DAA0D;IACnD,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAI7C,qFAAqF;IAC9E,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAI9C,qEAAqE;IAC9D,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAI1C,eAAe,IAAI,IAAI;IAI9B;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACH,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,QAAQ,EAAE,GAAG,qBAAqB,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAqDvG,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,GAAG,CAAC,OAAO,GAAG,QAAQ;IA2BjD;;;;;OAKG;IACH,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,OAAO,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM;IAkB7G;;;;;OAKG;IACH,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,SAAS;IAuBzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,EAAE,SAAS,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS;IA0J9E;;;OAGG;YACW,wBAAwB;IAgBtC,OAAO,CAAC,SAAS;IAIJ,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IAIjD;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,KAAK,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,YAAY,GAAG,YAAY;CAe9D"}
@@ -32,6 +32,9 @@ import { wrapAsyncIterator } from '../util/async-iterator.js';
32
32
  import { DatabaseEventEmitter, } from './database-events.js';
33
33
  import { TransactionManager } from './database-transaction.js';
34
34
  import { AssertionEvaluator } from './database-assertions.js';
35
+ import { WatcherManager } from './database-watchers.js';
36
+ import { tryGetEventEmitter } from '../vtab/events.js';
37
+ import { Table } from './table-handle.js';
35
38
  const log = createLogger('core:database');
36
39
  const errorLog = log.extend('error');
37
40
  /** Parse a comma-separated schema path string into an array of trimmed, non-empty names. */
@@ -41,19 +44,6 @@ function parseSchemaPath(pathString) {
41
44
  const parts = pathString.split(',').map(s => s.trim()).filter(s => s.length > 0);
42
45
  return parts.length > 0 ? parts : undefined;
43
46
  }
44
- /** Extract a VTableEventEmitter from a module if it supports one. */
45
- function tryGetEventEmitter(module) {
46
- const asSource = module;
47
- if (typeof asSource.getEventEmitter !== 'function')
48
- return undefined;
49
- const emitter = asSource.getEventEmitter();
50
- if (!emitter || typeof emitter !== 'object')
51
- return undefined;
52
- const typed = emitter;
53
- if (typeof typed.onDataChange !== 'function' && typeof typed.onSchemaChange !== 'function')
54
- return undefined;
55
- return emitter;
56
- }
57
47
  /**
58
48
  * Represents a connection to an Quereus database (in-memory in this port).
59
49
  * Manages schema, prepared statements, virtual tables, and functions.
@@ -81,6 +71,8 @@ export class Database {
81
71
  transactionManager;
82
72
  /** Assertion evaluation */
83
73
  assertionEvaluator;
74
+ /** Post-commit watcher dispatch */
75
+ watcherManager;
84
76
  /** Per-database collation registry — comparator + optional key normalizer.
85
77
  * The normalizer is required for index participation; comparator-only
86
78
  * collations may still be used in ORDER BY but cannot back a compound index. */
@@ -103,6 +95,7 @@ export class Database {
103
95
  // Initialize transaction manager and assertion evaluator
104
96
  this.transactionManager = new TransactionManager(this);
105
97
  this.assertionEvaluator = new AssertionEvaluator(this);
98
+ this.watcherManager = new WatcherManager(this);
106
99
  // Set up option change listeners
107
100
  this.setupOptionListeners();
108
101
  }
@@ -128,6 +121,21 @@ export class Database {
128
121
  getChangedKeyTuples(base) {
129
122
  return this.transactionManager.getChangedKeyTuples(base);
130
123
  }
124
+ /**
125
+ * Get changed value tuples projected onto `columnIndices` for a specific
126
+ * base table. The columns must have been registered for capture via
127
+ * `registerCaptureSpec` (PK columns are always captured implicitly).
128
+ */
129
+ getChangedTuples(base, columnIndices, pkIndices) {
130
+ return this.transactionManager.getChangedTuples(base, columnIndices, pkIndices);
131
+ }
132
+ /**
133
+ * Register projection capture demand for a base table. Returns a dispose
134
+ * handle that removes the spec when called.
135
+ */
136
+ registerCaptureSpec(baseTable, spec) {
137
+ return this.transactionManager.registerCaptureSpec(baseTable, spec);
138
+ }
131
139
  /** @internal Set up listeners for option changes */
132
140
  setupOptionListeners() {
133
141
  // Register core database options with their change handlers
@@ -668,6 +676,8 @@ export class Database {
668
676
  this.statements.clear();
669
677
  // Clean up assertion evaluator (unsubscribe schema change listener, clear plan cache)
670
678
  this.assertionEvaluator.dispose();
679
+ // Clean up watcher manager (dispose all subscriptions + schema listener)
680
+ this.watcherManager.dispose();
671
681
  // Clear schemas, ensuring VTabs are potentially disconnected
672
682
  // This will also call destroy on VTabs via SchemaManager.clearAll -> schema.clearTables -> schemaManager.dropTable
673
683
  this.schemaManager.clearAll();
@@ -991,15 +1001,18 @@ export class Database {
991
1001
  _inCoordinatedCommit() {
992
1002
  return this.transactionManager.isInCoordinatedCommit();
993
1003
  }
994
- /** Public API used by DML emitters to record changes */
995
- _recordInsert(baseTable, newKey) {
996
- this.transactionManager.recordInsert(baseTable, newKey);
1004
+ /** Public API used by DML emitters to record changes. The full row plus
1005
+ * PK column indices are passed so the change capture can project the
1006
+ * columns that any active DeltaExecutor subscription has registered
1007
+ * demand for. */
1008
+ _recordInsert(baseTable, newRow, pkIndices) {
1009
+ this.transactionManager.recordInsert(baseTable, newRow, pkIndices);
997
1010
  }
998
- _recordDelete(baseTable, oldKey) {
999
- this.transactionManager.recordDelete(baseTable, oldKey);
1011
+ _recordDelete(baseTable, oldRow, pkIndices) {
1012
+ this.transactionManager.recordDelete(baseTable, oldRow, pkIndices);
1000
1013
  }
1001
- _recordUpdate(baseTable, oldKey, newKey) {
1002
- this.transactionManager.recordUpdate(baseTable, oldKey, newKey);
1014
+ _recordUpdate(baseTable, oldRow, newRow, pkIndices) {
1015
+ this.transactionManager.recordUpdate(baseTable, oldRow, newRow, pkIndices);
1003
1016
  }
1004
1017
  /** Create a named savepoint, returning its depth index */
1005
1018
  _createSavepoint(name) {
@@ -1163,6 +1176,48 @@ export class Database {
1163
1176
  _findTable(tableName, dbName) {
1164
1177
  return this.schemaManager.findTable(tableName, dbName);
1165
1178
  }
1179
+ /**
1180
+ * Returns a public handle to a table for inspection and per-table event
1181
+ * subscription. Returns `undefined` if the table does not exist or its
1182
+ * owning module is not registered.
1183
+ *
1184
+ * The returned {@link Table} is a snapshot: its `schema` reference is
1185
+ * frozen at acquisition time. If the table is dropped or recreated, the
1186
+ * handle keeps the original schema, but no further events for that name
1187
+ * will arrive. Re-acquire after schema changes if you need fresh state.
1188
+ *
1189
+ * After {@link Database.close}, the handle's event emitter reference
1190
+ * remains valid (the module instance outlives the database) but the
1191
+ * database-level aggregator is unhooked, so local subscriptions on the
1192
+ * module emitter still fire only as long as the module itself remains
1193
+ * active.
1194
+ *
1195
+ * @param schemaName The schema name ('main', 'temp', or an attached
1196
+ * schema). Pass `undefined` to use the current default schema.
1197
+ * @param tableName The table name (case-insensitive resolution).
1198
+ *
1199
+ * @example
1200
+ * ```typescript
1201
+ * const table = db.getTable('main', 'users');
1202
+ * const tableEmitter = table?.getEventEmitter();
1203
+ * const off = tableEmitter?.onDataChange?.((event) => {
1204
+ * if (event.tableName === 'users') console.log(event);
1205
+ * });
1206
+ * ```
1207
+ */
1208
+ getTable(schemaName, tableName) {
1209
+ this.checkOpen();
1210
+ const tableSchema = this.schemaManager.getTable(schemaName, tableName);
1211
+ if (!tableSchema)
1212
+ return undefined;
1213
+ const moduleName = tableSchema.vtabModuleName;
1214
+ if (!moduleName)
1215
+ return undefined;
1216
+ const moduleInfo = this.schemaManager.getModule(moduleName);
1217
+ if (!moduleInfo)
1218
+ return undefined;
1219
+ return new Table(tableSchema, moduleName, moduleInfo.module);
1220
+ }
1166
1221
  /** @internal */
1167
1222
  _findFunction(funcName, nArg) {
1168
1223
  return this.schemaManager.findFunction(funcName, nArg);
@@ -1214,6 +1269,21 @@ export class Database {
1214
1269
  errorLog(`Error starting transaction on newly registered connection ${connection.connectionId}: %O`, error);
1215
1270
  // Don't throw here - just log the error to avoid breaking connection registration
1216
1271
  }
1272
+ // Replay the active savepoint stack onto this connection so subsequent
1273
+ // release/rollback-to broadcasts targeting earlier depths are in-range.
1274
+ // Without this, modules that register connections lazily (memory, isolation,
1275
+ // any vtab whose connection appears on first read/write) see an empty stack
1276
+ // while the DB broadcasts depths > 0 — silently no-op'ing on a real depth.
1277
+ const activeDepth = this.transactionManager.getActiveSavepointDepth();
1278
+ for (let depth = 0; depth < activeDepth; depth++) {
1279
+ try {
1280
+ await connection.createSavepoint(depth);
1281
+ }
1282
+ catch (error) {
1283
+ errorLog(`Error replaying savepoint depth ${depth} on newly registered connection ${connection.connectionId}: %O`, error);
1284
+ // Continue replaying remaining depths — see comment above on registration robustness.
1285
+ }
1286
+ }
1217
1287
  }
1218
1288
  else if (this.transactionManager.isEvaluatingDeferredConstraints()) {
1219
1289
  log(`Skipped transaction begin on connection ${connection.connectionId} (evaluating deferred constraints)`);
@@ -1303,6 +1373,36 @@ export class Database {
1303
1373
  async runGlobalAssertions() {
1304
1374
  await this.assertionEvaluator.runGlobalAssertions();
1305
1375
  }
1376
+ /**
1377
+ * Subscribe to changes described by a {@link ChangeScope}.
1378
+ *
1379
+ * The watcher fires its handler **after** a transaction commits (mirrors
1380
+ * assertion COMMIT eval), once per commit, with all matching watches in
1381
+ * a single {@link WatchEvent}. Handler errors are caught and logged —
1382
+ * they do not roll the commit back (assertions own that contract).
1383
+ *
1384
+ * Validation is synchronous:
1385
+ * - Throws if `scope.unboundParameters` is non-empty (caller must
1386
+ * `bindParameters(scope, params)` first).
1387
+ * - Throws if any referenced table or column does not exist in the
1388
+ * current schema.
1389
+ *
1390
+ * If the table or any column the scope mentions is later dropped or
1391
+ * altered, the subscription is **invalidated and disposed**; re-subscribe
1392
+ * to continue watching.
1393
+ *
1394
+ * @returns A {@link Subscription} handle whose `unsubscribe()` is
1395
+ * idempotent and releases capture-spec demand.
1396
+ */
1397
+ watch(scope, handler) {
1398
+ this.checkOpen();
1399
+ return this.watcherManager.watch(scope, handler);
1400
+ }
1401
+ /** @internal Invoked by the TransactionManager after a successful commit
1402
+ * and before the change log is cleared. */
1403
+ async runPostCommitWatchers() {
1404
+ await this.watcherManager.runPostCommit();
1405
+ }
1306
1406
  /** @internal Invalidate cached assertion plan (called on DROP ASSERTION) */
1307
1407
  invalidateAssertionCache(name) {
1308
1408
  this.assertionEvaluator.invalidateAssertion(name);