@fragno-dev/db 0.1.14 → 0.2.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 (445) hide show
  1. package/.turbo/turbo-build.log +242 -139
  2. package/CHANGELOG.md +47 -0
  3. package/README.md +123 -8
  4. package/dist/adapters/adapters.d.ts +19 -5
  5. package/dist/adapters/adapters.d.ts.map +1 -1
  6. package/dist/adapters/adapters.js.map +1 -1
  7. package/dist/adapters/drizzle/drizzle-adapter.d.ts +6 -19
  8. package/dist/adapters/drizzle/drizzle-adapter.d.ts.map +1 -1
  9. package/dist/adapters/drizzle/drizzle-adapter.js +7 -47
  10. package/dist/adapters/drizzle/drizzle-adapter.js.map +1 -1
  11. package/dist/adapters/drizzle/generate.d.ts +7 -1
  12. package/dist/adapters/drizzle/generate.d.ts.map +1 -1
  13. package/dist/adapters/drizzle/generate.js +46 -45
  14. package/dist/adapters/drizzle/generate.js.map +1 -1
  15. package/dist/adapters/generic-sql/driver-config.d.ts +74 -0
  16. package/dist/adapters/generic-sql/driver-config.d.ts.map +1 -0
  17. package/dist/adapters/generic-sql/driver-config.js +94 -0
  18. package/dist/adapters/generic-sql/driver-config.js.map +1 -0
  19. package/dist/adapters/generic-sql/generic-sql-adapter.d.ts +43 -0
  20. package/dist/adapters/generic-sql/generic-sql-adapter.d.ts.map +1 -0
  21. package/dist/adapters/generic-sql/generic-sql-adapter.js +87 -0
  22. package/dist/adapters/generic-sql/generic-sql-adapter.js.map +1 -0
  23. package/dist/adapters/generic-sql/generic-sql-uow-executor.js +67 -0
  24. package/dist/adapters/generic-sql/generic-sql-uow-executor.js.map +1 -0
  25. package/dist/adapters/generic-sql/migration/cold-kysely.js +33 -0
  26. package/dist/adapters/generic-sql/migration/cold-kysely.js.map +1 -0
  27. package/dist/adapters/generic-sql/migration/dialect/mysql.js +60 -0
  28. package/dist/adapters/generic-sql/migration/dialect/mysql.js.map +1 -0
  29. package/dist/adapters/generic-sql/migration/dialect/postgres.js +59 -0
  30. package/dist/adapters/generic-sql/migration/dialect/postgres.js.map +1 -0
  31. package/dist/adapters/generic-sql/migration/dialect/sqlite.js +96 -0
  32. package/dist/adapters/generic-sql/migration/dialect/sqlite.js.map +1 -0
  33. package/dist/adapters/generic-sql/migration/executor.d.ts +15 -0
  34. package/dist/adapters/generic-sql/migration/executor.d.ts.map +1 -0
  35. package/dist/adapters/generic-sql/migration/executor.js +18 -0
  36. package/dist/adapters/generic-sql/migration/executor.js.map +1 -0
  37. package/dist/adapters/generic-sql/migration/prepared-migrations.d.ts +66 -0
  38. package/dist/adapters/generic-sql/migration/prepared-migrations.d.ts.map +1 -0
  39. package/dist/adapters/generic-sql/migration/prepared-migrations.js +68 -0
  40. package/dist/adapters/generic-sql/migration/prepared-migrations.js.map +1 -0
  41. package/dist/adapters/generic-sql/migration/sql-generator.js +212 -0
  42. package/dist/adapters/generic-sql/migration/sql-generator.js.map +1 -0
  43. package/dist/adapters/generic-sql/query/create-sql-query-compiler.js +32 -0
  44. package/dist/adapters/generic-sql/query/create-sql-query-compiler.js.map +1 -0
  45. package/dist/adapters/generic-sql/query/cursor-utils.js +37 -0
  46. package/dist/adapters/generic-sql/query/cursor-utils.js.map +1 -0
  47. package/dist/adapters/generic-sql/query/dialect/mysql.js +33 -0
  48. package/dist/adapters/generic-sql/query/dialect/mysql.js.map +1 -0
  49. package/dist/adapters/generic-sql/query/dialect/postgres.js +32 -0
  50. package/dist/adapters/generic-sql/query/dialect/postgres.js.map +1 -0
  51. package/dist/adapters/generic-sql/query/dialect/sqlite.js +32 -0
  52. package/dist/adapters/generic-sql/query/dialect/sqlite.js.map +1 -0
  53. package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js +152 -0
  54. package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js.map +1 -0
  55. package/dist/adapters/generic-sql/query/select-builder.js +69 -0
  56. package/dist/adapters/generic-sql/query/select-builder.js.map +1 -0
  57. package/dist/adapters/generic-sql/query/sql-query-compiler.js +145 -0
  58. package/dist/adapters/generic-sql/query/sql-query-compiler.js.map +1 -0
  59. package/dist/adapters/generic-sql/query/where-builder.js +129 -0
  60. package/dist/adapters/generic-sql/query/where-builder.js.map +1 -0
  61. package/dist/adapters/generic-sql/result-interpreter.js +74 -0
  62. package/dist/adapters/generic-sql/result-interpreter.js.map +1 -0
  63. package/dist/adapters/generic-sql/uow-decoder.js +105 -0
  64. package/dist/adapters/generic-sql/uow-decoder.js.map +1 -0
  65. package/dist/adapters/generic-sql/uow-encoder.js +93 -0
  66. package/dist/adapters/generic-sql/uow-encoder.js.map +1 -0
  67. package/dist/adapters/kysely/kysely-adapter.d.ts +5 -16
  68. package/dist/adapters/kysely/kysely-adapter.d.ts.map +1 -1
  69. package/dist/adapters/kysely/kysely-adapter.js +6 -159
  70. package/dist/adapters/kysely/kysely-adapter.js.map +1 -1
  71. package/dist/adapters/{drizzle/drizzle-query.js → shared/from-unit-of-work-compiler.js} +48 -62
  72. package/dist/adapters/shared/from-unit-of-work-compiler.js.map +1 -0
  73. package/dist/adapters/{kysely/kysely-shared.d.ts → shared/table-name-mapper.d.ts} +3 -2
  74. package/dist/adapters/shared/table-name-mapper.d.ts.map +1 -0
  75. package/dist/adapters/shared/table-name-mapper.js +43 -0
  76. package/dist/adapters/shared/table-name-mapper.js.map +1 -0
  77. package/dist/adapters/shared/uow-operation-compiler.js +105 -0
  78. package/dist/adapters/shared/uow-operation-compiler.js.map +1 -0
  79. package/dist/db-fragment-definition-builder.d.ts +186 -0
  80. package/dist/db-fragment-definition-builder.d.ts.map +1 -0
  81. package/dist/db-fragment-definition-builder.js +207 -0
  82. package/dist/db-fragment-definition-builder.js.map +1 -0
  83. package/dist/fragments/internal-fragment.d.ts +53 -0
  84. package/dist/fragments/internal-fragment.d.ts.map +1 -0
  85. package/dist/fragments/internal-fragment.js +111 -0
  86. package/dist/fragments/internal-fragment.js.map +1 -0
  87. package/dist/hooks/hooks.d.ts +51 -0
  88. package/dist/hooks/hooks.d.ts.map +1 -0
  89. package/dist/hooks/hooks.js +88 -0
  90. package/dist/hooks/hooks.js.map +1 -0
  91. package/dist/migration-engine/generation-engine.d.ts +0 -2
  92. package/dist/migration-engine/generation-engine.d.ts.map +1 -1
  93. package/dist/migration-engine/generation-engine.js +38 -56
  94. package/dist/migration-engine/generation-engine.js.map +1 -1
  95. package/dist/mod.d.ts +35 -23
  96. package/dist/mod.d.ts.map +1 -1
  97. package/dist/mod.js +48 -45
  98. package/dist/mod.js.map +1 -1
  99. package/dist/node_modules/.pnpm/rou3@0.7.10/node_modules/rou3/dist/index.js +165 -0
  100. package/dist/node_modules/.pnpm/rou3@0.7.10/node_modules/rou3/dist/index.js.map +1 -0
  101. package/dist/packages/fragno/dist/api/bind-services.js +20 -0
  102. package/dist/packages/fragno/dist/api/bind-services.js.map +1 -0
  103. package/dist/packages/fragno/dist/api/error.js +48 -0
  104. package/dist/packages/fragno/dist/api/error.js.map +1 -0
  105. package/dist/packages/fragno/dist/api/fragment-definition-builder.js +320 -0
  106. package/dist/packages/fragno/dist/api/fragment-definition-builder.js.map +1 -0
  107. package/dist/packages/fragno/dist/api/fragment-instantiator.js +525 -0
  108. package/dist/packages/fragno/dist/api/fragment-instantiator.js.map +1 -0
  109. package/dist/packages/fragno/dist/api/fragno-response.js +73 -0
  110. package/dist/packages/fragno/dist/api/fragno-response.js.map +1 -0
  111. package/dist/packages/fragno/dist/api/internal/response-stream.js +81 -0
  112. package/dist/packages/fragno/dist/api/internal/response-stream.js.map +1 -0
  113. package/dist/packages/fragno/dist/api/internal/route.js +10 -0
  114. package/dist/packages/fragno/dist/api/internal/route.js.map +1 -0
  115. package/dist/packages/fragno/dist/api/mutable-request-state.js +97 -0
  116. package/dist/packages/fragno/dist/api/mutable-request-state.js.map +1 -0
  117. package/dist/packages/fragno/dist/api/request-context-storage.js +43 -0
  118. package/dist/packages/fragno/dist/api/request-context-storage.js.map +1 -0
  119. package/dist/packages/fragno/dist/api/request-input-context.js +118 -0
  120. package/dist/packages/fragno/dist/api/request-input-context.js.map +1 -0
  121. package/dist/packages/fragno/dist/api/request-middleware.js +83 -0
  122. package/dist/packages/fragno/dist/api/request-middleware.js.map +1 -0
  123. package/dist/packages/fragno/dist/api/request-output-context.js +119 -0
  124. package/dist/packages/fragno/dist/api/request-output-context.js.map +1 -0
  125. package/dist/packages/fragno/dist/api/route.js +17 -0
  126. package/dist/packages/fragno/dist/api/route.js.map +1 -0
  127. package/dist/packages/fragno/dist/internal/symbols.js +10 -0
  128. package/dist/packages/fragno/dist/internal/symbols.js.map +1 -0
  129. package/dist/query/column-defaults.js +27 -0
  130. package/dist/query/column-defaults.js.map +1 -0
  131. package/dist/query/cursor.d.ts +14 -6
  132. package/dist/query/cursor.d.ts.map +1 -1
  133. package/dist/query/cursor.js +16 -7
  134. package/dist/query/cursor.js.map +1 -1
  135. package/dist/query/orm/orm.d.ts +1 -1
  136. package/dist/query/orm/orm.js.map +1 -1
  137. package/dist/query/serialize/create-sql-serializer.js +30 -0
  138. package/dist/query/serialize/create-sql-serializer.js.map +1 -0
  139. package/dist/query/serialize/dialect/mysql-serializer.js +87 -0
  140. package/dist/query/serialize/dialect/mysql-serializer.js.map +1 -0
  141. package/dist/query/serialize/dialect/postgres-serializer.js +80 -0
  142. package/dist/query/serialize/dialect/postgres-serializer.js.map +1 -0
  143. package/dist/query/serialize/dialect/sqlite-serializer.js +93 -0
  144. package/dist/query/serialize/dialect/sqlite-serializer.js.map +1 -0
  145. package/dist/query/serialize/sql-serializer.js +67 -0
  146. package/dist/query/serialize/sql-serializer.js.map +1 -0
  147. package/dist/query/{query.d.ts → simple-query-interface.d.ts} +6 -6
  148. package/dist/query/simple-query-interface.d.ts.map +1 -0
  149. package/dist/query/unit-of-work/execute-unit-of-work.d.ts +133 -0
  150. package/dist/query/unit-of-work/execute-unit-of-work.d.ts.map +1 -0
  151. package/dist/query/unit-of-work/execute-unit-of-work.js +197 -0
  152. package/dist/query/unit-of-work/execute-unit-of-work.js.map +1 -0
  153. package/dist/query/unit-of-work/retry-policy.d.ts +88 -0
  154. package/dist/query/unit-of-work/retry-policy.d.ts.map +1 -0
  155. package/dist/query/unit-of-work/retry-policy.js +61 -0
  156. package/dist/query/unit-of-work/retry-policy.js.map +1 -0
  157. package/dist/query/{unit-of-work.d.ts → unit-of-work/unit-of-work.d.ts} +145 -58
  158. package/dist/query/unit-of-work/unit-of-work.d.ts.map +1 -0
  159. package/dist/query/{unit-of-work.js → unit-of-work/unit-of-work.js} +435 -198
  160. package/dist/query/unit-of-work/unit-of-work.js.map +1 -0
  161. package/dist/query/value-decoding.js +71 -0
  162. package/dist/query/value-decoding.js.map +1 -0
  163. package/dist/query/value-encoding.js +124 -0
  164. package/dist/query/value-encoding.js.map +1 -0
  165. package/dist/schema/create.d.ts +3 -0
  166. package/dist/schema/create.d.ts.map +1 -1
  167. package/dist/schema/create.js +4 -0
  168. package/dist/schema/create.js.map +1 -1
  169. package/dist/schema/type-conversion/create-sql-type-mapper.js +29 -0
  170. package/dist/schema/type-conversion/create-sql-type-mapper.js.map +1 -0
  171. package/dist/schema/type-conversion/dialect/mysql.js +57 -0
  172. package/dist/schema/type-conversion/dialect/mysql.js.map +1 -0
  173. package/dist/schema/type-conversion/dialect/postgres.js +56 -0
  174. package/dist/schema/type-conversion/dialect/postgres.js.map +1 -0
  175. package/dist/schema/type-conversion/dialect/sqlite.js +52 -0
  176. package/dist/schema/type-conversion/dialect/sqlite.js.map +1 -0
  177. package/dist/schema/type-conversion/type-mapping.js +63 -0
  178. package/dist/schema/type-conversion/type-mapping.js.map +1 -0
  179. package/dist/sql-driver/connection/connection-provider.d.ts +13 -0
  180. package/dist/sql-driver/connection/connection-provider.d.ts.map +1 -0
  181. package/dist/sql-driver/connection/connection-provider.js +19 -0
  182. package/dist/sql-driver/connection/connection-provider.js.map +1 -0
  183. package/dist/sql-driver/connection/single-connection-provider.js +23 -0
  184. package/dist/sql-driver/connection/single-connection-provider.js.map +1 -0
  185. package/dist/sql-driver/dialect-adapter/dialect-adapter.d.ts +7 -0
  186. package/dist/sql-driver/dialect-adapter/dialect-adapter.d.ts.map +1 -0
  187. package/dist/sql-driver/dialects/dialects.d.ts +2 -0
  188. package/dist/sql-driver/dialects/dialects.js +3 -0
  189. package/dist/sql-driver/dialects/durable-object-dialect.d.ts +72 -0
  190. package/dist/sql-driver/dialects/durable-object-dialect.d.ts.map +1 -0
  191. package/dist/sql-driver/dialects/durable-object-dialect.js +130 -0
  192. package/dist/sql-driver/dialects/durable-object-dialect.js.map +1 -0
  193. package/dist/sql-driver/driver/runtime-driver.d.ts +23 -0
  194. package/dist/sql-driver/driver/runtime-driver.d.ts.map +1 -0
  195. package/dist/sql-driver/driver/runtime-driver.js +56 -0
  196. package/dist/sql-driver/driver/runtime-driver.js.map +1 -0
  197. package/dist/sql-driver/query-executor/default-query-executor.js +26 -0
  198. package/dist/sql-driver/query-executor/default-query-executor.js.map +1 -0
  199. package/dist/sql-driver/query-executor/plugin.d.ts +17 -0
  200. package/dist/sql-driver/query-executor/plugin.d.ts.map +1 -0
  201. package/dist/sql-driver/query-executor/query-executor-base.js +25 -0
  202. package/dist/sql-driver/query-executor/query-executor-base.js.map +1 -0
  203. package/dist/sql-driver/query-executor/query-executor.d.ts +36 -0
  204. package/dist/sql-driver/query-executor/query-executor.d.ts.map +1 -0
  205. package/dist/sql-driver/sql-driver-adapter.d.ts +29 -0
  206. package/dist/sql-driver/sql-driver-adapter.d.ts.map +1 -0
  207. package/dist/sql-driver/sql-driver-adapter.js +68 -0
  208. package/dist/sql-driver/sql-driver-adapter.js.map +1 -0
  209. package/dist/sql-driver/sql-driver.d.ts +38 -0
  210. package/dist/sql-driver/sql-driver.d.ts.map +1 -0
  211. package/dist/sql-driver/sql-driver.js +1 -0
  212. package/dist/sql-driver/sql.js +50 -0
  213. package/dist/sql-driver/sql.js.map +1 -0
  214. package/dist/with-database.d.ts +32 -0
  215. package/dist/with-database.d.ts.map +1 -0
  216. package/dist/with-database.js +34 -0
  217. package/dist/with-database.js.map +1 -0
  218. package/package.json +43 -9
  219. package/src/adapters/adapters.ts +23 -4
  220. package/src/adapters/drizzle/drizzle-adapter-pglite.test.ts +140 -185
  221. package/src/adapters/drizzle/{drizzle-adapter-sqlite.test.ts → drizzle-adapter-sqlite3.test.ts} +187 -55
  222. package/src/adapters/drizzle/drizzle-adapter.ts +14 -93
  223. package/src/adapters/drizzle/generate.test.ts +102 -269
  224. package/src/adapters/drizzle/generate.ts +89 -63
  225. package/src/adapters/drizzle/migrate-drizzle.test.ts +19 -0
  226. package/src/adapters/drizzle/shared.ts +0 -34
  227. package/src/adapters/drizzle/test-utils.ts +36 -5
  228. package/src/adapters/generic-sql/README.md +14 -0
  229. package/src/adapters/generic-sql/driver-config.ts +144 -0
  230. package/src/adapters/generic-sql/generic-sql-adapter.test.ts +50 -0
  231. package/src/adapters/generic-sql/generic-sql-adapter.ts +146 -0
  232. package/src/adapters/generic-sql/generic-sql-uow-executor.ts +130 -0
  233. package/src/adapters/generic-sql/migration/cold-kysely.ts +55 -0
  234. package/src/adapters/{kysely/migration/execute-mysql.test.ts → generic-sql/migration/dialect/mysql.test.ts} +342 -484
  235. package/src/adapters/generic-sql/migration/dialect/mysql.ts +104 -0
  236. package/src/adapters/generic-sql/migration/dialect/postgres.test.ts +1008 -0
  237. package/src/adapters/generic-sql/migration/dialect/postgres.ts +113 -0
  238. package/src/adapters/{kysely/migration/execute-sqlite.test.ts → generic-sql/migration/dialect/sqlite.test.ts} +307 -510
  239. package/src/adapters/generic-sql/migration/dialect/sqlite.ts +189 -0
  240. package/src/adapters/generic-sql/migration/executor.ts +33 -0
  241. package/src/adapters/generic-sql/migration/prepared-migrations.test.ts +661 -0
  242. package/src/adapters/generic-sql/migration/prepared-migrations.ts +214 -0
  243. package/src/adapters/generic-sql/migration/sql-generator.ts +413 -0
  244. package/src/adapters/generic-sql/query/create-sql-query-compiler.ts +36 -0
  245. package/src/adapters/generic-sql/query/cursor-utils.ts +56 -0
  246. package/src/adapters/generic-sql/query/dialect/mysql.ts +34 -0
  247. package/src/adapters/generic-sql/query/dialect/postgres.ts +32 -0
  248. package/src/adapters/generic-sql/query/dialect/sqlite.ts +32 -0
  249. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.test.ts +1568 -0
  250. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.ts +314 -0
  251. package/src/adapters/generic-sql/query/select-builder.test.ts +256 -0
  252. package/src/adapters/generic-sql/query/select-builder.ts +137 -0
  253. package/src/adapters/generic-sql/query/sql-query-compiler.test.ts +195 -0
  254. package/src/adapters/generic-sql/query/sql-query-compiler.ts +367 -0
  255. package/src/adapters/generic-sql/query/where-builder.test.ts +744 -0
  256. package/src/adapters/generic-sql/query/where-builder.ts +211 -0
  257. package/src/adapters/generic-sql/result-interpreter.ts +102 -0
  258. package/src/adapters/generic-sql/test/generic-drizzle-adapter-sqlite3.test.ts +899 -0
  259. package/src/adapters/generic-sql/uow-decoder.test.ts +399 -0
  260. package/src/adapters/generic-sql/uow-decoder.ts +152 -0
  261. package/src/adapters/generic-sql/uow-encoder.test.ts +183 -0
  262. package/src/adapters/generic-sql/uow-encoder.ts +131 -0
  263. package/src/adapters/kysely/kysely-adapter-pglite.test.ts +90 -96
  264. package/src/adapters/kysely/kysely-adapter-sqlocal.test.ts +215 -0
  265. package/src/adapters/kysely/kysely-adapter.ts +10 -242
  266. package/src/adapters/{drizzle/drizzle-query.ts → shared/from-unit-of-work-compiler.ts} +111 -106
  267. package/src/adapters/shared/table-name-mapper.ts +50 -0
  268. package/src/adapters/shared/uow-operation-compiler.ts +211 -0
  269. package/src/db-fragment-definition-builder.test.ts +887 -0
  270. package/src/db-fragment-definition-builder.ts +737 -0
  271. package/src/db-fragment-instantiator.test.ts +543 -0
  272. package/src/db-fragment-integration.test.ts +406 -0
  273. package/src/fragments/internal-fragment.test.ts +549 -0
  274. package/src/fragments/internal-fragment.ts +249 -0
  275. package/src/hooks/hooks.test.ts +575 -0
  276. package/src/hooks/hooks.ts +179 -0
  277. package/src/migration-engine/generation-engine.test.ts +60 -27
  278. package/src/migration-engine/generation-engine.ts +99 -92
  279. package/src/mod.ts +139 -78
  280. package/src/query/column-defaults.ts +49 -0
  281. package/src/query/cursor.test.ts +147 -3
  282. package/src/query/cursor.ts +25 -8
  283. package/src/query/orm/orm.ts +1 -1
  284. package/src/query/query-type.test.ts +9 -9
  285. package/src/query/serialize/create-sql-serializer.ts +34 -0
  286. package/src/query/serialize/dialect/mysql-serializer.ts +142 -0
  287. package/src/query/serialize/dialect/postgres-serializer.ts +129 -0
  288. package/src/query/serialize/dialect/sqlite-serializer.test.ts +251 -0
  289. package/src/query/serialize/dialect/sqlite-serializer.ts +156 -0
  290. package/src/query/serialize/sql-serializer.ts +143 -0
  291. package/src/query/{query.ts → simple-query-interface.ts} +4 -4
  292. package/src/query/unit-of-work/execute-unit-of-work.test.ts +1310 -0
  293. package/src/query/unit-of-work/execute-unit-of-work.ts +504 -0
  294. package/src/query/unit-of-work/retry-policy.test.ts +217 -0
  295. package/src/query/unit-of-work/retry-policy.ts +141 -0
  296. package/src/query/unit-of-work/unit-of-work-coordinator.test.ts +831 -0
  297. package/src/query/{unit-of-work-types.test.ts → unit-of-work/unit-of-work-types.test.ts} +7 -5
  298. package/src/query/unit-of-work/unit-of-work.test.ts +1716 -0
  299. package/src/query/{unit-of-work.ts → unit-of-work/unit-of-work.ts} +716 -420
  300. package/src/query/{result-transform.test.ts → value-decoding.test.ts} +45 -298
  301. package/src/query/value-decoding.ts +113 -0
  302. package/src/query/value-encoding.test.ts +390 -0
  303. package/src/query/value-encoding.ts +168 -0
  304. package/src/schema/create.test.ts +5 -1
  305. package/src/schema/create.ts +5 -0
  306. package/src/schema/serialize.test.ts +165 -407
  307. package/src/schema/type-conversion/create-sql-type-mapper.ts +28 -0
  308. package/src/schema/type-conversion/dialect/mysql.ts +64 -0
  309. package/src/schema/type-conversion/dialect/postgres.ts +62 -0
  310. package/src/schema/type-conversion/dialect/sqlite.ts +63 -0
  311. package/src/schema/type-conversion/type-mapping.test.ts +137 -0
  312. package/src/schema/type-conversion/type-mapping.ts +153 -0
  313. package/src/shared/connection-pool.ts +5 -5
  314. package/src/sql-driver/better-sqlite3.test.ts +126 -0
  315. package/src/sql-driver/connection/connection-provider.ts +27 -0
  316. package/src/sql-driver/connection/single-connection-provider.ts +42 -0
  317. package/src/sql-driver/dialect-adapter/dialect-adapter.ts +9 -0
  318. package/src/sql-driver/dialect-adapter/sqlite-dialect-adapter.ts +7 -0
  319. package/src/sql-driver/dialects/dialects.ts +1 -0
  320. package/src/sql-driver/dialects/durable-object-dialect.ts +260 -0
  321. package/src/sql-driver/driver/runtime-driver.ts +91 -0
  322. package/src/sql-driver/query-executor/default-query-executor.ts +38 -0
  323. package/src/sql-driver/query-executor/plugin.ts +22 -0
  324. package/src/sql-driver/query-executor/query-executor-base.ts +53 -0
  325. package/src/sql-driver/query-executor/query-executor.ts +44 -0
  326. package/src/sql-driver/sql-driver-adapter.ts +96 -0
  327. package/src/sql-driver/sql-driver.ts +53 -0
  328. package/src/sql-driver/sql.ts +57 -0
  329. package/src/sql-driver/sqlocal.test.ts +117 -0
  330. package/src/with-database.ts +152 -0
  331. package/tsdown.config.ts +8 -2
  332. package/dist/adapters/drizzle/drizzle-connection-pool.js +0 -40
  333. package/dist/adapters/drizzle/drizzle-connection-pool.js.map +0 -1
  334. package/dist/adapters/drizzle/drizzle-query.d.ts +0 -23
  335. package/dist/adapters/drizzle/drizzle-query.d.ts.map +0 -1
  336. package/dist/adapters/drizzle/drizzle-query.js.map +0 -1
  337. package/dist/adapters/drizzle/drizzle-uow-compiler.d.ts +0 -10
  338. package/dist/adapters/drizzle/drizzle-uow-compiler.d.ts.map +0 -1
  339. package/dist/adapters/drizzle/drizzle-uow-compiler.js +0 -315
  340. package/dist/adapters/drizzle/drizzle-uow-compiler.js.map +0 -1
  341. package/dist/adapters/drizzle/drizzle-uow-decoder.js +0 -116
  342. package/dist/adapters/drizzle/drizzle-uow-decoder.js.map +0 -1
  343. package/dist/adapters/drizzle/drizzle-uow-executor.js +0 -149
  344. package/dist/adapters/drizzle/drizzle-uow-executor.js.map +0 -1
  345. package/dist/adapters/drizzle/join-column-utils.js +0 -28
  346. package/dist/adapters/drizzle/join-column-utils.js.map +0 -1
  347. package/dist/adapters/drizzle/shared.d.ts +0 -14
  348. package/dist/adapters/drizzle/shared.d.ts.map +0 -1
  349. package/dist/adapters/drizzle/shared.js +0 -35
  350. package/dist/adapters/drizzle/shared.js.map +0 -1
  351. package/dist/adapters/kysely/kysely-connection-pool.js +0 -41
  352. package/dist/adapters/kysely/kysely-connection-pool.js.map +0 -1
  353. package/dist/adapters/kysely/kysely-query-builder.js +0 -321
  354. package/dist/adapters/kysely/kysely-query-builder.js.map +0 -1
  355. package/dist/adapters/kysely/kysely-query-compiler.js +0 -66
  356. package/dist/adapters/kysely/kysely-query-compiler.js.map +0 -1
  357. package/dist/adapters/kysely/kysely-query.d.ts +0 -22
  358. package/dist/adapters/kysely/kysely-query.d.ts.map +0 -1
  359. package/dist/adapters/kysely/kysely-query.js +0 -223
  360. package/dist/adapters/kysely/kysely-query.js.map +0 -1
  361. package/dist/adapters/kysely/kysely-shared.d.ts.map +0 -1
  362. package/dist/adapters/kysely/kysely-shared.js +0 -18
  363. package/dist/adapters/kysely/kysely-shared.js.map +0 -1
  364. package/dist/adapters/kysely/kysely-uow-compiler.js +0 -170
  365. package/dist/adapters/kysely/kysely-uow-compiler.js.map +0 -1
  366. package/dist/adapters/kysely/kysely-uow-executor.js +0 -89
  367. package/dist/adapters/kysely/kysely-uow-executor.js.map +0 -1
  368. package/dist/adapters/kysely/migration/execute-base.js +0 -128
  369. package/dist/adapters/kysely/migration/execute-base.js.map +0 -1
  370. package/dist/adapters/kysely/migration/execute-factory.js +0 -34
  371. package/dist/adapters/kysely/migration/execute-factory.js.map +0 -1
  372. package/dist/adapters/kysely/migration/execute-mssql.js +0 -112
  373. package/dist/adapters/kysely/migration/execute-mssql.js.map +0 -1
  374. package/dist/adapters/kysely/migration/execute-mysql.js +0 -93
  375. package/dist/adapters/kysely/migration/execute-mysql.js.map +0 -1
  376. package/dist/adapters/kysely/migration/execute-postgres.js +0 -104
  377. package/dist/adapters/kysely/migration/execute-postgres.js.map +0 -1
  378. package/dist/adapters/kysely/migration/execute-sqlite.js +0 -123
  379. package/dist/adapters/kysely/migration/execute-sqlite.js.map +0 -1
  380. package/dist/adapters/kysely/migration/execute.js +0 -34
  381. package/dist/adapters/kysely/migration/execute.js.map +0 -1
  382. package/dist/bind-services.d.ts +0 -7
  383. package/dist/bind-services.d.ts.map +0 -1
  384. package/dist/bind-services.js +0 -14
  385. package/dist/bind-services.js.map +0 -1
  386. package/dist/fragment.d.ts +0 -173
  387. package/dist/fragment.d.ts.map +0 -1
  388. package/dist/fragment.js +0 -191
  389. package/dist/fragment.js.map +0 -1
  390. package/dist/migration-engine/create.d.ts +0 -37
  391. package/dist/migration-engine/create.d.ts.map +0 -1
  392. package/dist/migration-engine/create.js +0 -58
  393. package/dist/migration-engine/create.js.map +0 -1
  394. package/dist/migration-engine/shared.d.ts +0 -112
  395. package/dist/migration-engine/shared.d.ts.map +0 -1
  396. package/dist/query/query.d.ts.map +0 -1
  397. package/dist/query/result-transform.js +0 -168
  398. package/dist/query/result-transform.js.map +0 -1
  399. package/dist/query/unit-of-work.d.ts.map +0 -1
  400. package/dist/query/unit-of-work.js.map +0 -1
  401. package/dist/schema/serialize.js +0 -106
  402. package/dist/schema/serialize.js.map +0 -1
  403. package/dist/shared/settings-schema.js +0 -36
  404. package/dist/shared/settings-schema.js.map +0 -1
  405. package/src/adapters/drizzle/drizzle-adapter.test.ts +0 -170
  406. package/src/adapters/drizzle/drizzle-connection-pool.ts +0 -66
  407. package/src/adapters/drizzle/drizzle-query.test.ts +0 -499
  408. package/src/adapters/drizzle/drizzle-uow-compiler.test.ts +0 -1383
  409. package/src/adapters/drizzle/drizzle-uow-compiler.ts +0 -636
  410. package/src/adapters/drizzle/drizzle-uow-decoder.ts +0 -218
  411. package/src/adapters/drizzle/drizzle-uow-executor.ts +0 -276
  412. package/src/adapters/drizzle/join-column-utils.test.ts +0 -79
  413. package/src/adapters/drizzle/join-column-utils.ts +0 -39
  414. package/src/adapters/kysely/kysely-connection-pool.ts +0 -70
  415. package/src/adapters/kysely/kysely-query-builder.test.ts +0 -1344
  416. package/src/adapters/kysely/kysely-query-builder.ts +0 -666
  417. package/src/adapters/kysely/kysely-query-compiler.ts +0 -132
  418. package/src/adapters/kysely/kysely-query.test.ts +0 -498
  419. package/src/adapters/kysely/kysely-query.ts +0 -390
  420. package/src/adapters/kysely/kysely-shared.ts +0 -23
  421. package/src/adapters/kysely/kysely-uow-compiler.test.ts +0 -998
  422. package/src/adapters/kysely/kysely-uow-compiler.ts +0 -318
  423. package/src/adapters/kysely/kysely-uow-executor.ts +0 -145
  424. package/src/adapters/kysely/kysely-uow-joins.test.ts +0 -811
  425. package/src/adapters/kysely/migration/execute-base.ts +0 -256
  426. package/src/adapters/kysely/migration/execute-factory.ts +0 -53
  427. package/src/adapters/kysely/migration/execute-mssql.ts +0 -250
  428. package/src/adapters/kysely/migration/execute-mysql.ts +0 -211
  429. package/src/adapters/kysely/migration/execute-postgres.test.ts +0 -2657
  430. package/src/adapters/kysely/migration/execute-postgres.ts +0 -234
  431. package/src/adapters/kysely/migration/execute-sqlite.ts +0 -247
  432. package/src/adapters/kysely/migration/execute.ts +0 -50
  433. package/src/adapters/kysely/migration/kysely-migrator.test.ts +0 -261
  434. package/src/bind-services.test.ts +0 -214
  435. package/src/bind-services.ts +0 -37
  436. package/src/db-fragment.test.ts +0 -800
  437. package/src/fragment.ts +0 -727
  438. package/src/query/result-transform.ts +0 -271
  439. package/src/query/unit-of-work-multi-schema.test.ts +0 -64
  440. package/src/query/unit-of-work.test.ts +0 -943
  441. package/src/schema/serialize.ts +0 -396
  442. package/src/shared/settings-schema.ts +0 -61
  443. package/src/uow-context-integration.test.ts +0 -102
  444. package/src/uow-context.test.ts +0 -182
  445. /package/dist/query/{query.js → simple-query-interface.js} +0 -0
@@ -1,8 +1,8 @@
1
- import { FragnoId } from "../schema/create.js";
2
- import { Cursor } from "./cursor.js";
3
- import { buildCondition } from "./condition-builder.js";
1
+ import { FragnoId } from "../../schema/create.js";
2
+ import { buildCondition } from "../condition-builder.js";
3
+ import { Cursor } from "../cursor.js";
4
4
 
5
- //#region src/query/unit-of-work.ts
5
+ //#region src/query/unit-of-work/unit-of-work.ts
6
6
  /**
7
7
  * Builder for find operations in Unit of Work
8
8
  */
@@ -83,8 +83,10 @@ var FindBuilder = class {
83
83
  }
84
84
  /**
85
85
  * Set the number of results per page
86
+ * @throws {RangeError} If size is not a positive integer
86
87
  */
87
88
  pageSize(size) {
89
+ if (!Number.isInteger(size) || size <= 0) throw new RangeError(`pageSize must be a positive integer, received: ${size}`);
88
90
  this.#pageSizeValue = size;
89
91
  return this;
90
92
  }
@@ -260,8 +262,10 @@ var JoinFindBuilder = class {
260
262
  }
261
263
  /**
262
264
  * Set the number of results to return
265
+ * @throws {RangeError} If size is not a positive integer
263
266
  */
264
267
  pageSize(size) {
268
+ if (!Number.isInteger(size) || size <= 0) throw new RangeError(`pageSize must be a positive integer, received: ${size}`);
265
269
  this.#pageSizeValue = size;
266
270
  return this;
267
271
  }
@@ -338,29 +342,188 @@ function buildJoinIndexed(table, fn) {
338
342
  fn(builder);
339
343
  return compiled;
340
344
  }
341
- function createUnitOfWork(schema, compiler, executor, decoder, name) {
342
- return new UnitOfWork(schema, compiler, executor, decoder, name);
345
+ function createUnitOfWork(compiler, executor, decoder, schemaNamespaceMap, name) {
346
+ return new UnitOfWork(compiler, executor, decoder, name, void 0, schemaNamespaceMap);
343
347
  }
344
348
  /**
349
+ * Encapsulates a promise with its resolver/rejecter functions.
350
+ * Simplifies management of deferred promises with built-in error handling.
351
+ */
352
+ var DeferredPromise = class {
353
+ #resolve;
354
+ #reject;
355
+ #promise;
356
+ constructor() {
357
+ const { promise, resolve, reject } = Promise.withResolvers();
358
+ this.#promise = promise;
359
+ this.#resolve = resolve;
360
+ this.#reject = reject;
361
+ this.#promise.catch(() => {});
362
+ }
363
+ get promise() {
364
+ return this.#promise;
365
+ }
366
+ resolve(value) {
367
+ this.#resolve?.(value);
368
+ }
369
+ reject(error) {
370
+ this.#reject?.(error);
371
+ }
372
+ /**
373
+ * Reset to a new promise
374
+ */
375
+ reset() {
376
+ const { promise, resolve, reject } = Promise.withResolvers();
377
+ this.#promise = promise;
378
+ this.#resolve = resolve;
379
+ this.#reject = reject;
380
+ this.#promise.catch(() => {});
381
+ }
382
+ };
383
+ /**
384
+ * Tracks readiness signals from a group of children.
385
+ * Maintains a promise that resolves when all registered children have signaled.
386
+ */
387
+ var ReadinessTracker = class {
388
+ #expectedCount = 0;
389
+ #signalCount = 0;
390
+ #resolve;
391
+ #promise = Promise.resolve();
392
+ get promise() {
393
+ return this.#promise;
394
+ }
395
+ /**
396
+ * Register that we're expecting a signal from a child
397
+ */
398
+ registerChild() {
399
+ if (this.#expectedCount === 0) {
400
+ const { promise, resolve } = Promise.withResolvers();
401
+ this.#promise = promise;
402
+ this.#resolve = resolve;
403
+ }
404
+ this.#expectedCount++;
405
+ }
406
+ /**
407
+ * Signal that one child is ready
408
+ */
409
+ signal() {
410
+ this.#signalCount++;
411
+ if (this.#signalCount >= this.#expectedCount && this.#resolve) this.#resolve();
412
+ }
413
+ /**
414
+ * Reset to initial state
415
+ */
416
+ reset() {
417
+ this.#expectedCount = 0;
418
+ this.#signalCount = 0;
419
+ this.#resolve = void 0;
420
+ this.#promise = Promise.resolve();
421
+ }
422
+ };
423
+ /**
424
+ * Manages parent-child relationships and readiness coordination for Unit of Work instances.
425
+ * This allows parent UOWs to wait for all child UOWs to signal readiness before executing phases.
426
+ */
427
+ var UOWChildCoordinator = class {
428
+ #parent = null;
429
+ #parentCoordinator = null;
430
+ #children = /* @__PURE__ */ new Set();
431
+ #isRestricted = false;
432
+ #retrievalTracker = new ReadinessTracker();
433
+ #mutationTracker = new ReadinessTracker();
434
+ get isRestricted() {
435
+ return this.#isRestricted;
436
+ }
437
+ get parent() {
438
+ return this.#parent;
439
+ }
440
+ get children() {
441
+ return this.#children;
442
+ }
443
+ get retrievalReadinessPromise() {
444
+ return this.#retrievalTracker.promise;
445
+ }
446
+ get mutationReadinessPromise() {
447
+ return this.#mutationTracker.promise;
448
+ }
449
+ /**
450
+ * Mark this UOW as a restricted child of the given parent
451
+ */
452
+ setAsRestricted(parent, parentCoordinator) {
453
+ this.#parent = parent;
454
+ this.#parentCoordinator = parentCoordinator;
455
+ this.#isRestricted = true;
456
+ }
457
+ /**
458
+ * Register a child UOW
459
+ */
460
+ addChild(child) {
461
+ this.#children.add(child);
462
+ this.#retrievalTracker.registerChild();
463
+ this.#mutationTracker.registerChild();
464
+ }
465
+ /**
466
+ * Signal that this child is ready for retrieval phase execution.
467
+ * Only valid for restricted (child) UOWs.
468
+ */
469
+ signalReadyForRetrieval() {
470
+ if (!this.#parentCoordinator) throw new Error("signalReadyForRetrieval() can only be called on restricted child UOWs");
471
+ this.#parentCoordinator.notifyChildReadyForRetrieval();
472
+ }
473
+ /**
474
+ * Signal that this child is ready for mutation phase execution.
475
+ * Only valid for restricted (child) UOWs.
476
+ */
477
+ signalReadyForMutation() {
478
+ if (!this.#parentCoordinator) throw new Error("signalReadyForMutation() can only be called on restricted child UOWs");
479
+ this.#parentCoordinator.notifyChildReadyForMutation();
480
+ }
481
+ /**
482
+ * Notify this coordinator that a child is ready for retrieval (internal use).
483
+ * Called by child UOWs when they signal readiness.
484
+ */
485
+ notifyChildReadyForRetrieval() {
486
+ this.#retrievalTracker.signal();
487
+ }
488
+ /**
489
+ * Notify this coordinator that a child is ready for mutation (internal use).
490
+ * Called by child UOWs when they signal readiness.
491
+ */
492
+ notifyChildReadyForMutation() {
493
+ this.#mutationTracker.signal();
494
+ }
495
+ /**
496
+ * Reset coordination state for retry support
497
+ */
498
+ reset() {
499
+ this.#children.clear();
500
+ this.#retrievalTracker.reset();
501
+ this.#mutationTracker.reset();
502
+ }
503
+ };
504
+ /**
345
505
  * Unit of Work implementation with optimistic concurrency control
346
506
  *
347
507
  * UOW has two phases:
348
508
  * 1. Retrieval phase: Read operations to fetch entities with their versions
349
509
  * 2. Mutation phase: Write operations that check versions before committing
350
510
  *
511
+ * This is the untyped base storage. Use TypedUnitOfWork for type-safe operations.
512
+ *
351
513
  * @example
352
514
  * ```ts
353
515
  * const uow = queryEngine.createUnitOfWork("update-user-balance");
516
+ * const typedUow = uow.forSchema(mySchema);
354
517
  *
355
518
  * // Retrieval phase
356
- * uow.find("users", (b) => b.where("primary", (eb) => eb("id", "=", userId)));
519
+ * typedUow.find("users", (b) => b.whereIndex("primary", (eb) => eb("id", "=", userId)));
357
520
  *
358
521
  * // Execute retrieval and transition to mutation phase
359
522
  * const [users] = await uow.executeRetrieve();
360
523
  *
361
524
  * // Mutation phase with version check
362
525
  * const user = users[0];
363
- * uow.update("users", user.id, (b) => b.set({ balance: newBalance }).check());
526
+ * typedUow.update("users", user.id, (b) => b.set({ balance: newBalance }).check());
364
527
  *
365
528
  * // Execute mutations
366
529
  * const { success } = await uow.executeMutations();
@@ -369,10 +532,10 @@ function createUnitOfWork(schema, compiler, executor, decoder, name) {
369
532
  * }
370
533
  * ```
371
534
  */
372
- var UnitOfWork = class {
373
- #schema;
535
+ var UnitOfWork = class UnitOfWork {
374
536
  #name;
375
537
  #config;
538
+ #nonce;
376
539
  #state = "building-retrieval";
377
540
  #retrievalOps = [];
378
541
  #mutationOps = [];
@@ -382,39 +545,112 @@ var UnitOfWork = class {
382
545
  #schemaNamespaceMap;
383
546
  #retrievalResults;
384
547
  #createdInternalIds = [];
385
- #retrievalPhaseResolve;
386
- #mutationPhaseResolve;
387
- #retrievalPhasePromise;
388
- #mutationPhasePromise;
389
- constructor(schema, compiler, executor, decoder, name, config, schemaNamespaceMap) {
390
- this.#schema = schema;
548
+ #retrievalPhaseDeferred = new DeferredPromise();
549
+ #mutationPhaseDeferred = new DeferredPromise();
550
+ #retrievalError = null;
551
+ #mutationError = null;
552
+ #coordinator = new UOWChildCoordinator();
553
+ #triggeredHooks = [];
554
+ constructor(compiler, executor, decoder, name, config, schemaNamespaceMap) {
391
555
  this.#compiler = compiler;
392
556
  this.#executor = executor;
393
557
  this.#decoder = decoder;
558
+ this.#schemaNamespaceMap = schemaNamespaceMap ?? /* @__PURE__ */ new WeakMap();
394
559
  this.#name = name;
395
560
  this.#config = config;
396
- this.#schemaNamespaceMap = schemaNamespaceMap;
397
- this.#retrievalPhasePromise = new Promise((resolve) => {
398
- this.#retrievalPhaseResolve = resolve;
399
- });
400
- this.#mutationPhasePromise = new Promise((resolve) => {
401
- this.#mutationPhaseResolve = resolve;
402
- });
403
- }
404
- get schema() {
405
- return this.#schema;
561
+ this.#nonce = config?.nonce ?? crypto.randomUUID();
406
562
  }
407
- get $results() {
408
- throw new Error("type only");
563
+ /**
564
+ * Register a schema with its namespace for cross-fragment operations.
565
+ * This is used for internal fragments like hooks that need to create
566
+ * records in a different schema during the same transaction.
567
+ */
568
+ registerSchema(schema, namespace) {
569
+ this.#schemaNamespaceMap.set(schema, namespace);
409
570
  }
410
571
  /**
411
- * Get a schema-specific view of this UOW for type-safe operations
412
- * Returns a wrapper that uses a different schema for operations.
572
+ * Get a schema-specific typed view of this UOW for type-safe operations.
573
+ * Returns a wrapper that provides typed operations for the given schema.
413
574
  * The namespace is automatically resolved from the schema-namespace map.
575
+ * The optional hooks parameter is for type inference only - pass your hooks map
576
+ * to get proper typing for triggerHook. The value is not used at runtime.
577
+ */
578
+ forSchema(schema, _hooks) {
579
+ return new TypedUnitOfWork(schema, this.#schemaNamespaceMap.get(schema), this);
580
+ }
581
+ /**
582
+ * Create a restricted child UOW that cannot execute phases.
583
+ * The child shares the same operation storage but must signal readiness
584
+ * before the parent can execute each phase.
585
+ */
586
+ restrict() {
587
+ const child = new UnitOfWork(this.#compiler, this.#executor, this.#decoder, this.#name, {
588
+ ...this.#config,
589
+ nonce: this.#nonce
590
+ }, this.#schemaNamespaceMap);
591
+ child.#coordinator.setAsRestricted(this, this.#coordinator);
592
+ child.#state = this.#state;
593
+ child.#retrievalOps = this.#retrievalOps;
594
+ child.#mutationOps = this.#mutationOps;
595
+ child.#retrievalResults = this.#retrievalResults;
596
+ child.#createdInternalIds = this.#createdInternalIds;
597
+ child.#retrievalPhaseDeferred = this.#retrievalPhaseDeferred;
598
+ child.#mutationPhaseDeferred = this.#mutationPhaseDeferred;
599
+ child.#retrievalError = this.#retrievalError;
600
+ child.#mutationError = this.#mutationError;
601
+ child.#triggeredHooks = this.#triggeredHooks;
602
+ this.#coordinator.addChild(child);
603
+ child.signalReadyForRetrieval();
604
+ child.signalReadyForMutation();
605
+ return child;
606
+ }
607
+ /**
608
+ * Signal that this child is ready for retrieval phase execution.
609
+ * Only valid for restricted (child) UOWs.
610
+ */
611
+ signalReadyForRetrieval() {
612
+ this.#coordinator.signalReadyForRetrieval();
613
+ }
614
+ /**
615
+ * Signal that this child is ready for mutation phase execution.
616
+ * Only valid for restricted (child) UOWs.
617
+ */
618
+ signalReadyForMutation() {
619
+ this.#coordinator.signalReadyForMutation();
620
+ }
621
+ /**
622
+ * Reset the UOW to initial state for retry support.
623
+ * Clears operations, resets state, and resets phase promises.
624
+ */
625
+ reset() {
626
+ if (this.#coordinator.isRestricted) throw new Error("reset() cannot be called on restricted child UOWs");
627
+ this.#retrievalOps = [];
628
+ this.#mutationOps = [];
629
+ this.#retrievalResults = void 0;
630
+ this.#createdInternalIds = [];
631
+ this.#state = "building-retrieval";
632
+ this.#retrievalError = null;
633
+ this.#mutationError = null;
634
+ this.#retrievalPhaseDeferred.reset();
635
+ this.#mutationPhaseDeferred.reset();
636
+ this.#coordinator.reset();
637
+ this.#triggeredHooks = [];
638
+ }
639
+ /**
640
+ * Trigger a hook to be executed after the transaction commits.
641
+ */
642
+ triggerHook(hookName, payload, options) {
643
+ this.#triggeredHooks.push({
644
+ hookName,
645
+ payload,
646
+ options
647
+ });
648
+ }
649
+ /**
650
+ * Get all triggered hooks for this UOW.
414
651
  */
415
- forSchema(schema) {
416
- const resolvedNamespace = this.#schemaNamespaceMap?.get(schema);
417
- return new UnitOfWorkSchemaView(schema, resolvedNamespace, this);
652
+ getTriggeredHooks() {
653
+ return this.#triggeredHooks;
418
654
  }
419
655
  get state() {
420
656
  return this.#state;
@@ -422,175 +658,93 @@ var UnitOfWork = class {
422
658
  get name() {
423
659
  return this.#name;
424
660
  }
661
+ get nonce() {
662
+ return this.#nonce;
663
+ }
425
664
  /**
426
665
  * Promise that resolves when the retrieval phase is executed
427
666
  * Service methods can await this to coordinate multi-phase logic
428
667
  */
429
668
  get retrievalPhase() {
430
- return this.#retrievalPhasePromise;
669
+ return this.#retrievalPhaseDeferred.promise;
431
670
  }
432
671
  /**
433
672
  * Promise that resolves when the mutation phase is executed
434
673
  * Service methods can await this to coordinate multi-phase logic
435
674
  */
436
675
  get mutationPhase() {
437
- return this.#mutationPhasePromise;
676
+ return this.#mutationPhaseDeferred.promise;
438
677
  }
439
678
  /**
440
679
  * Execute the retrieval phase and transition to mutation phase
441
680
  * Returns all results from find operations
442
681
  */
443
682
  async executeRetrieve() {
683
+ if (this.#coordinator.isRestricted) throw new Error("executeRetrieve() cannot be called on restricted child UOWs");
444
684
  if (this.#state !== "building-retrieval") throw new Error(`Cannot execute retrieval from state ${this.#state}. Must be in building-retrieval state.`);
445
- if (this.#retrievalOps.length === 0) {
446
- this.#state = "building-mutation";
447
- const emptyResults = [];
448
- this.#retrievalPhaseResolve?.(emptyResults);
449
- return emptyResults;
450
- }
451
- const retrievalBatch = [];
452
- for (const op of this.#retrievalOps) {
453
- const compiled = this.#compiler.compileRetrievalOperation(op);
454
- if (compiled !== null) {
455
- this.#config?.onQuery?.(compiled);
456
- retrievalBatch.push(compiled);
685
+ try {
686
+ await this.#coordinator.retrievalReadinessPromise;
687
+ if (this.#retrievalOps.length === 0) {
688
+ this.#state = "building-mutation";
689
+ const emptyResults = [];
690
+ this.#retrievalPhaseDeferred.resolve(emptyResults);
691
+ return emptyResults;
457
692
  }
693
+ const retrievalBatch = [];
694
+ for (const op of this.#retrievalOps) {
695
+ const compiled = this.#compiler.compileRetrievalOperation(op);
696
+ if (compiled !== null) {
697
+ this.#config?.onQuery?.(compiled);
698
+ retrievalBatch.push(compiled);
699
+ }
700
+ }
701
+ if (this.#config?.dryRun) {
702
+ this.#state = "executed";
703
+ const emptyResults = [];
704
+ this.#retrievalPhaseDeferred.resolve(emptyResults);
705
+ return emptyResults;
706
+ }
707
+ const rawResults = await this.#executor.executeRetrievalPhase(retrievalBatch);
708
+ this.#retrievalResults = this.#decoder.decode(rawResults, this.#retrievalOps);
709
+ this.#state = "building-mutation";
710
+ this.#retrievalPhaseDeferred.resolve(this.#retrievalResults);
711
+ return this.#retrievalResults;
712
+ } catch (error) {
713
+ this.#retrievalError = error instanceof Error ? error : new Error(String(error));
714
+ throw error;
458
715
  }
459
- if (this.#config?.dryRun) {
460
- this.#state = "executed";
461
- return [];
462
- }
463
- const rawResults = await this.#executor.executeRetrievalPhase(retrievalBatch);
464
- this.#retrievalResults = this.#decoder(rawResults, this.#retrievalOps);
465
- this.#state = "building-mutation";
466
- this.#retrievalPhaseResolve?.(this.#retrievalResults);
467
- return this.#retrievalResults;
468
- }
469
- find(tableName, builderFn) {
470
- if (this.#state !== "building-retrieval") throw new Error(`find() can only be called during retrieval phase. Current state: ${this.#state}`);
471
- const table = this.#schema.tables[tableName];
472
- if (!table) throw new Error(`Table ${tableName} not found in schema`);
473
- const builder = new FindBuilder(tableName, table);
474
- if (builderFn) builderFn(builder);
475
- else builder.whereIndex("primary");
476
- const { indexName, options, type } = builder.build();
477
- this.#retrievalOps.push({
478
- type,
479
- schema: this.#schema,
480
- table,
481
- indexName,
482
- options
483
- });
484
- return this;
485
- }
486
- /**
487
- * Add a find operation with cursor metadata (retrieval phase only)
488
- */
489
- findWithCursor(tableName, builderFn) {
490
- if (this.#state !== "building-retrieval") throw new Error(`findWithCursor() can only be called during retrieval phase. Current state: ${this.#state}`);
491
- const table = this.#schema.tables[tableName];
492
- if (!table) throw new Error(`Table ${tableName} not found in schema`);
493
- const builder = new FindBuilder(tableName, table);
494
- builderFn(builder);
495
- const { indexName, options, type } = builder.build();
496
- this.#retrievalOps.push({
497
- type,
498
- schema: this.#schema,
499
- table,
500
- indexName,
501
- options,
502
- withCursor: true
503
- });
504
- return this;
505
- }
506
- /**
507
- * Add a create operation (mutation phase only)
508
- * Returns a FragnoId with the external ID that can be used immediately in subsequent operations
509
- */
510
- create(table, values) {
511
- if (this.#state === "executed") throw new Error(`create() can only be called during mutation phase.`);
512
- const tableSchema = this.#schema.tables[table];
513
- if (!tableSchema) throw new Error(`Table ${table} not found in schema`);
514
- const idColumn = tableSchema.getIdColumn();
515
- let externalId;
516
- let updatedValues = values;
517
- const providedIdValue = values[idColumn.ormName];
518
- if (providedIdValue !== void 0) if (typeof providedIdValue === "object" && providedIdValue !== null && "externalId" in providedIdValue) externalId = providedIdValue.externalId;
519
- else externalId = providedIdValue;
520
- else {
521
- const generated = idColumn.generateDefaultValue();
522
- if (generated === void 0) throw new Error(`No ID value provided and ID column ${idColumn.ormName} has no default generator`);
523
- externalId = generated;
524
- updatedValues = {
525
- ...values,
526
- [idColumn.ormName]: externalId
527
- };
528
- }
529
- this.#mutationOps.push({
530
- type: "create",
531
- schema: this.#schema,
532
- table,
533
- values: updatedValues,
534
- generatedExternalId: externalId
535
- });
536
- return FragnoId.fromExternal(externalId, 0);
537
- }
538
- /**
539
- * Add an update operation using a builder callback (mutation phase only)
540
- */
541
- update(table, id, builderFn) {
542
- if (this.#state === "executed") throw new Error(`update() can only be called during mutation phase.`);
543
- const builder = new UpdateBuilder(table, id);
544
- builderFn(builder);
545
- const { id: opId, checkVersion, set } = builder.build();
546
- this.#mutationOps.push({
547
- type: "update",
548
- schema: this.#schema,
549
- table,
550
- id: opId,
551
- checkVersion,
552
- set
553
- });
554
- }
555
- /**
556
- * Add a delete operation using a builder callback (mutation phase only)
557
- */
558
- delete(table, id, builderFn) {
559
- if (this.#state === "executed") throw new Error(`delete() can only be called during mutation phase.`);
560
- const builder = new DeleteBuilder(table, id);
561
- builderFn?.(builder);
562
- const { id: opId, checkVersion } = builder.build();
563
- this.#mutationOps.push({
564
- type: "delete",
565
- schema: this.#schema,
566
- table,
567
- id: opId,
568
- checkVersion
569
- });
570
716
  }
571
717
  /**
572
718
  * Execute the mutation phase
573
719
  * Returns success flag indicating if mutations completed without conflicts
574
720
  */
575
721
  async executeMutations() {
722
+ if (this.#coordinator.isRestricted) throw new Error("executeMutations() cannot be called on restricted child UOWs");
576
723
  if (this.#state === "executed") throw new Error(`Cannot execute mutations from state ${this.#state}.`);
577
- const mutationBatch = [];
578
- for (const op of this.#mutationOps) {
579
- const compiled = this.#compiler.compileMutationOperation(op);
580
- if (compiled !== null) {
581
- this.#config?.onQuery?.(compiled);
582
- mutationBatch.push(compiled);
724
+ try {
725
+ await this.#coordinator.mutationReadinessPromise;
726
+ const mutationBatch = [];
727
+ for (const op of this.#mutationOps) {
728
+ const compiled = this.#compiler.compileMutationOperation(op);
729
+ if (compiled !== null) {
730
+ this.#config?.onQuery?.(compiled);
731
+ mutationBatch.push(compiled);
732
+ }
583
733
  }
584
- }
585
- if (this.#config?.dryRun) {
734
+ if (this.#config?.dryRun) {
735
+ this.#state = "executed";
736
+ this.#mutationPhaseDeferred.resolve();
737
+ return { success: true };
738
+ }
739
+ const result = await this.#executor.executeMutationPhase(mutationBatch);
586
740
  this.#state = "executed";
587
- return { success: true };
741
+ if (result.success) this.#createdInternalIds = result.createdInternalIds;
742
+ this.#mutationPhaseDeferred.resolve();
743
+ return { success: result.success };
744
+ } catch (error) {
745
+ this.#mutationError = error instanceof Error ? error : new Error(String(error));
746
+ throw error;
588
747
  }
589
- const result = await this.#executor.executeMutationPhase(mutationBatch);
590
- this.#state = "executed";
591
- if (result.success) this.#createdInternalIds = result.createdInternalIds;
592
- this.#mutationPhaseResolve?.();
593
- return { success: result.success };
594
748
  }
595
749
  /**
596
750
  * Get the retrieval operations (for inspection/debugging)
@@ -606,17 +760,19 @@ var UnitOfWork = class {
606
760
  }
607
761
  /**
608
762
  * @internal
609
- * Add a retrieval operation (used by SchemaView)
763
+ * Add a retrieval operation (used by TypedUnitOfWork)
610
764
  */
611
765
  addRetrievalOperation(op) {
766
+ if (this.#state !== "building-retrieval") throw new Error(`Cannot add retrieval operation in state ${this.#state}. Must be in building-retrieval state.`);
612
767
  this.#retrievalOps.push(op);
613
768
  return this.#retrievalOps.length - 1;
614
769
  }
615
770
  /**
616
771
  * @internal
617
- * Add a mutation operation (used by SchemaView)
772
+ * Add a mutation operation (used by TypedUnitOfWork)
618
773
  */
619
774
  addMutationOperation(op) {
775
+ if (this.#state === "executed") throw new Error(`Cannot add mutation operation in executed state.`);
620
776
  this.#mutationOps.push(op);
621
777
  }
622
778
  /**
@@ -665,18 +821,20 @@ var UnitOfWork = class {
665
821
  }
666
822
  };
667
823
  /**
668
- * A lightweight wrapper around a parent UOW that provides type-safe operations for a different schema.
669
- * All operations are stored in the parent UOW, but this wrapper ensures the correct schema is used.
824
+ * A typed facade around a UnitOfWork that provides type-safe operations for a specific schema.
825
+ * All operations are stored in the underlying UOW, but this facade ensures type safety and
826
+ * filters retrieval results to only include operations added through this facade.
670
827
  */
671
- var UnitOfWorkSchemaView = class {
828
+ var TypedUnitOfWork = class {
672
829
  #schema;
673
830
  #namespace;
674
- #parent;
831
+ #uow;
675
832
  #operationIndices = [];
676
- constructor(schema, namespace, parent) {
833
+ #cachedRetrievalPhase;
834
+ constructor(schema, namespace, uow) {
677
835
  this.#schema = schema;
678
836
  this.#namespace = namespace;
679
- this.#parent = parent;
837
+ this.#uow = uow;
680
838
  }
681
839
  get $results() {
682
840
  throw new Error("type only");
@@ -685,33 +843,58 @@ var UnitOfWorkSchemaView = class {
685
843
  return this.#schema;
686
844
  }
687
845
  get name() {
688
- return this.#parent.name;
846
+ return this.#uow.name;
847
+ }
848
+ get nonce() {
849
+ return this.#uow.nonce;
689
850
  }
690
851
  get state() {
691
- return this.#parent.state;
852
+ return this.#uow.state;
692
853
  }
693
854
  get retrievalPhase() {
694
- return this.#parent.retrievalPhase.then((allResults) => {
695
- return this.#operationIndices.map((index) => allResults[index]);
855
+ if (!this.#cachedRetrievalPhase) this.#cachedRetrievalPhase = this.#uow.retrievalPhase.then((allResults) => {
856
+ const allOperations = this.#uow.getRetrievalOperations();
857
+ return this.#operationIndices.map((opIndex) => {
858
+ const result = allResults[opIndex];
859
+ const operation = allOperations[opIndex];
860
+ if (operation?.type === "find" && operation.withSingleResult) return Array.isArray(result) ? result[0] ?? null : result;
861
+ return result;
862
+ });
696
863
  });
864
+ return this.#cachedRetrievalPhase;
697
865
  }
698
866
  get mutationPhase() {
699
- return this.#parent.mutationPhase;
867
+ return this.#uow.mutationPhase;
700
868
  }
701
869
  getRetrievalOperations() {
702
- return this.#parent.getRetrievalOperations();
870
+ return this.#uow.getRetrievalOperations();
703
871
  }
704
872
  getMutationOperations() {
705
- return this.#parent.getMutationOperations();
873
+ return this.#uow.getMutationOperations();
706
874
  }
707
875
  getCreatedIds() {
708
- return this.#parent.getCreatedIds();
876
+ return this.#uow.getCreatedIds();
709
877
  }
710
878
  async executeRetrieve() {
711
- return this.#parent.executeRetrieve();
879
+ return this.#uow.executeRetrieve();
712
880
  }
713
881
  async executeMutations() {
714
- return this.#parent.executeMutations();
882
+ return this.#uow.executeMutations();
883
+ }
884
+ restrict() {
885
+ return this.#uow.restrict();
886
+ }
887
+ reset() {
888
+ return this.#uow.reset();
889
+ }
890
+ forSchema(schema, hooks) {
891
+ return this.#uow.forSchema(schema, hooks);
892
+ }
893
+ registerSchema(schema, namespace) {
894
+ this.#uow.registerSchema(schema, namespace);
895
+ }
896
+ compile(compiler) {
897
+ return this.#uow.compile(compiler);
715
898
  }
716
899
  find(tableName, builderFn) {
717
900
  const table = this.#schema.tables[tableName];
@@ -720,7 +903,7 @@ var UnitOfWorkSchemaView = class {
720
903
  if (builderFn) builderFn(builder);
721
904
  else builder.whereIndex("primary");
722
905
  const { indexName, options, type } = builder.build();
723
- const operationIndex = this.#parent.addRetrievalOperation({
906
+ const operationIndex = this.#uow.addRetrievalOperation({
724
907
  type,
725
908
  schema: this.#schema,
726
909
  namespace: this.#namespace,
@@ -731,13 +914,33 @@ var UnitOfWorkSchemaView = class {
731
914
  this.#operationIndices.push(operationIndex);
732
915
  return this;
733
916
  }
917
+ findFirst(tableName, builderFn) {
918
+ const table = this.#schema.tables[tableName];
919
+ if (!table) throw new Error(`Table ${tableName} not found in schema`);
920
+ const builder = new FindBuilder(tableName, table);
921
+ if (builderFn) builderFn(builder);
922
+ else builder.whereIndex("primary");
923
+ builder.pageSize(1);
924
+ const { indexName, options, type } = builder.build();
925
+ const operationIndex = this.#uow.addRetrievalOperation({
926
+ type,
927
+ schema: this.#schema,
928
+ namespace: this.#namespace,
929
+ table,
930
+ indexName,
931
+ options,
932
+ withSingleResult: true
933
+ });
934
+ this.#operationIndices.push(operationIndex);
935
+ return this;
936
+ }
734
937
  findWithCursor(tableName, builderFn) {
735
938
  const table = this.#schema.tables[tableName];
736
939
  if (!table) throw new Error(`Table ${tableName} not found in schema`);
737
940
  const builder = new FindBuilder(tableName, table);
738
941
  builderFn(builder);
739
942
  const { indexName, options, type } = builder.build();
740
- const operationIndex = this.#parent.addRetrievalOperation({
943
+ const operationIndex = this.#uow.addRetrievalOperation({
741
944
  type,
742
945
  schema: this.#schema,
743
946
  namespace: this.#namespace,
@@ -767,7 +970,7 @@ var UnitOfWorkSchemaView = class {
767
970
  [idColumn.ormName]: externalId
768
971
  };
769
972
  }
770
- this.#parent.addMutationOperation({
973
+ this.#uow.addMutationOperation({
771
974
  type: "create",
772
975
  schema: this.#schema,
773
976
  namespace: this.#namespace,
@@ -781,7 +984,7 @@ var UnitOfWorkSchemaView = class {
781
984
  const builder = new UpdateBuilder(tableName, id);
782
985
  builderFn(builder);
783
986
  const { id: opId, checkVersion, set } = builder.build();
784
- this.#parent.addMutationOperation({
987
+ this.#uow.addMutationOperation({
785
988
  type: "update",
786
989
  schema: this.#schema,
787
990
  namespace: this.#namespace,
@@ -795,7 +998,7 @@ var UnitOfWorkSchemaView = class {
795
998
  const builder = new DeleteBuilder(tableName, id);
796
999
  builderFn?.(builder);
797
1000
  const { id: opId, checkVersion } = builder.build();
798
- this.#parent.addMutationOperation({
1001
+ this.#uow.addMutationOperation({
799
1002
  type: "delete",
800
1003
  schema: this.#schema,
801
1004
  namespace: this.#namespace,
@@ -804,11 +1007,45 @@ var UnitOfWorkSchemaView = class {
804
1007
  checkVersion
805
1008
  });
806
1009
  }
807
- forSchema(schema) {
808
- return this.#parent.forSchema(schema);
1010
+ /**
1011
+ * Check that a record's version hasn't changed since retrieval.
1012
+ * This is useful for ensuring related records remain unchanged during a transaction.
1013
+ *
1014
+ * @param tableName - The table name
1015
+ * @param id - The FragnoId with version information (string IDs are not allowed)
1016
+ * @throws Error if the ID is a string without version information
1017
+ *
1018
+ * @example
1019
+ * ```ts
1020
+ * // Ensure both accounts haven't changed before creating a transfer
1021
+ * uow.check("accounts", fromAccount.id);
1022
+ * uow.check("accounts", toAccount.id);
1023
+ * uow.create("transactions", { fromAccountId, toAccountId, amount });
1024
+ * ```
1025
+ */
1026
+ check(tableName, id) {
1027
+ this.#uow.addMutationOperation({
1028
+ type: "check",
1029
+ schema: this.#schema,
1030
+ namespace: this.#namespace,
1031
+ table: tableName,
1032
+ id
1033
+ });
1034
+ }
1035
+ get $hooks() {
1036
+ throw new Error("type only");
1037
+ }
1038
+ /**
1039
+ * Trigger a hook to be executed after the transaction commits.
1040
+ */
1041
+ triggerHook(hookName, payload, options) {
1042
+ this.#uow.triggerHook(hookName, payload, options);
1043
+ }
1044
+ getTriggeredHooks() {
1045
+ return this.#uow.getTriggeredHooks();
809
1046
  }
810
1047
  };
811
1048
 
812
1049
  //#endregion
813
- export { DeleteBuilder, FindBuilder, JoinFindBuilder, UnitOfWork, UnitOfWorkSchemaView, UpdateBuilder, buildJoinIndexed, createUnitOfWork };
1050
+ export { DeleteBuilder, FindBuilder, JoinFindBuilder, TypedUnitOfWork, UnitOfWork, UpdateBuilder, buildJoinIndexed, createUnitOfWork };
814
1051
  //# sourceMappingURL=unit-of-work.js.map