@fragno-dev/db 0.2.2 → 0.4.1

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 (587) hide show
  1. package/.turbo/turbo-build.log +404 -175
  2. package/CHANGELOG.md +109 -0
  3. package/README.md +54 -9
  4. package/dist/adapters/adapters.d.ts +23 -21
  5. package/dist/adapters/adapters.d.ts.map +1 -1
  6. package/dist/adapters/adapters.js.map +1 -1
  7. package/dist/adapters/generic-sql/driver-config.d.ts +16 -1
  8. package/dist/adapters/generic-sql/driver-config.d.ts.map +1 -1
  9. package/dist/adapters/generic-sql/driver-config.js +23 -1
  10. package/dist/adapters/generic-sql/driver-config.js.map +1 -1
  11. package/dist/adapters/generic-sql/generic-sql-adapter.d.ts +24 -9
  12. package/dist/adapters/generic-sql/generic-sql-adapter.d.ts.map +1 -1
  13. package/dist/adapters/generic-sql/generic-sql-adapter.js +60 -22
  14. package/dist/adapters/generic-sql/generic-sql-adapter.js.map +1 -1
  15. package/dist/adapters/generic-sql/generic-sql-uow-executor.js +169 -3
  16. package/dist/adapters/generic-sql/generic-sql-uow-executor.js.map +1 -1
  17. package/dist/adapters/generic-sql/migration/cold-kysely.js.map +1 -1
  18. package/dist/adapters/generic-sql/migration/dialect/mysql.js +25 -6
  19. package/dist/adapters/generic-sql/migration/dialect/mysql.js.map +1 -1
  20. package/dist/adapters/generic-sql/migration/dialect/postgres.js +7 -6
  21. package/dist/adapters/generic-sql/migration/dialect/postgres.js.map +1 -1
  22. package/dist/adapters/generic-sql/migration/dialect/sqlite.js +193 -16
  23. package/dist/adapters/generic-sql/migration/dialect/sqlite.js.map +1 -1
  24. package/dist/adapters/generic-sql/migration/executor.d.ts.map +1 -1
  25. package/dist/adapters/generic-sql/migration/executor.js +30 -3
  26. package/dist/adapters/generic-sql/migration/executor.js.map +1 -1
  27. package/dist/adapters/generic-sql/migration/prepared-migrations.d.ts.map +1 -1
  28. package/dist/adapters/generic-sql/migration/prepared-migrations.js +9 -9
  29. package/dist/adapters/generic-sql/migration/prepared-migrations.js.map +1 -1
  30. package/dist/adapters/generic-sql/migration/sql-generator.js +75 -52
  31. package/dist/adapters/generic-sql/migration/sql-generator.js.map +1 -1
  32. package/dist/adapters/generic-sql/query/create-sql-query-compiler.js +7 -6
  33. package/dist/adapters/generic-sql/query/create-sql-query-compiler.js.map +1 -1
  34. package/dist/adapters/generic-sql/query/cursor-utils.js +42 -4
  35. package/dist/adapters/generic-sql/query/cursor-utils.js.map +1 -1
  36. package/dist/adapters/generic-sql/query/db-now-sql.js +27 -0
  37. package/dist/adapters/generic-sql/query/db-now-sql.js.map +1 -0
  38. package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js +32 -21
  39. package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js.map +1 -1
  40. package/dist/adapters/generic-sql/query/select-builder.js +5 -3
  41. package/dist/adapters/generic-sql/query/select-builder.js.map +1 -1
  42. package/dist/adapters/generic-sql/query/sql-query-compiler.js +49 -18
  43. package/dist/adapters/generic-sql/query/sql-query-compiler.js.map +1 -1
  44. package/dist/adapters/generic-sql/query/where-builder.js +43 -29
  45. package/dist/adapters/generic-sql/query/where-builder.js.map +1 -1
  46. package/dist/adapters/generic-sql/sqlite-storage.d.ts +13 -0
  47. package/dist/adapters/generic-sql/sqlite-storage.d.ts.map +1 -0
  48. package/dist/adapters/generic-sql/sqlite-storage.js +15 -0
  49. package/dist/adapters/generic-sql/sqlite-storage.js.map +1 -0
  50. package/dist/adapters/generic-sql/uow-decoder.js +6 -2
  51. package/dist/adapters/generic-sql/uow-decoder.js.map +1 -1
  52. package/dist/adapters/generic-sql/uow-encoder.js +27 -8
  53. package/dist/adapters/generic-sql/uow-encoder.js.map +1 -1
  54. package/dist/adapters/in-memory/condition-evaluator.js +135 -0
  55. package/dist/adapters/in-memory/condition-evaluator.js.map +1 -0
  56. package/dist/adapters/in-memory/errors.d.ts +13 -0
  57. package/dist/adapters/in-memory/errors.d.ts.map +1 -0
  58. package/dist/adapters/in-memory/errors.js +23 -0
  59. package/dist/adapters/in-memory/errors.js.map +1 -0
  60. package/dist/adapters/in-memory/in-memory-adapter.d.ts +27 -0
  61. package/dist/adapters/in-memory/in-memory-adapter.d.ts.map +1 -0
  62. package/dist/adapters/in-memory/in-memory-adapter.js +196 -0
  63. package/dist/adapters/in-memory/in-memory-adapter.js.map +1 -0
  64. package/dist/adapters/in-memory/in-memory-uow.js +871 -0
  65. package/dist/adapters/in-memory/in-memory-uow.js.map +1 -0
  66. package/dist/adapters/in-memory/index.d.ts +4 -0
  67. package/dist/adapters/in-memory/index.js +4 -0
  68. package/dist/adapters/in-memory/options.d.ts +30 -0
  69. package/dist/adapters/in-memory/options.d.ts.map +1 -0
  70. package/dist/adapters/in-memory/options.js +62 -0
  71. package/dist/adapters/in-memory/options.js.map +1 -0
  72. package/dist/adapters/in-memory/reference-resolution.js +26 -0
  73. package/dist/adapters/in-memory/reference-resolution.js.map +1 -0
  74. package/dist/adapters/in-memory/sorted-array-index.js +129 -0
  75. package/dist/adapters/in-memory/sorted-array-index.js.map +1 -0
  76. package/dist/adapters/in-memory/store.js +71 -0
  77. package/dist/adapters/in-memory/store.js.map +1 -0
  78. package/dist/adapters/in-memory/value-comparison.js +28 -0
  79. package/dist/adapters/in-memory/value-comparison.js.map +1 -0
  80. package/dist/adapters/shared/from-unit-of-work-compiler.js +51 -24
  81. package/dist/adapters/shared/from-unit-of-work-compiler.js.map +1 -1
  82. package/dist/adapters/shared/uow-operation-compiler.js +11 -11
  83. package/dist/adapters/shared/uow-operation-compiler.js.map +1 -1
  84. package/dist/adapters/sql/index.d.ts +5 -0
  85. package/dist/adapters/sql/index.js +4 -0
  86. package/dist/browser/adapters/adapters.d.ts +61 -0
  87. package/dist/browser/adapters/adapters.d.ts.map +1 -0
  88. package/dist/browser/adapters/generic-sql/migration/executor.d.ts +15 -0
  89. package/dist/browser/adapters/generic-sql/migration/executor.d.ts.map +1 -0
  90. package/dist/browser/adapters/generic-sql/migration/prepared-migrations.d.ts +66 -0
  91. package/dist/browser/adapters/generic-sql/migration/prepared-migrations.d.ts.map +1 -0
  92. package/dist/browser/adapters/generic-sql/sqlite-storage.d.ts +11 -0
  93. package/dist/browser/adapters/generic-sql/sqlite-storage.d.ts.map +1 -0
  94. package/dist/browser/adapters/in-memory/in-memory-adapter.d.ts +5 -0
  95. package/dist/browser/adapters/in-memory/index.d.ts +2 -0
  96. package/dist/browser/adapters/in-memory/options.d.ts +1 -0
  97. package/dist/browser/db-fragment-definition-builder.d.ts +237 -0
  98. package/dist/browser/db-fragment-definition-builder.d.ts.map +1 -0
  99. package/dist/browser/durable-hooks.d.ts +3 -0
  100. package/dist/browser/fragments/internal-fragment.d.ts +317 -0
  101. package/dist/browser/fragments/internal-fragment.d.ts.map +1 -0
  102. package/dist/browser/fragments/internal-fragment.schema.d.ts +1 -0
  103. package/dist/browser/hooks/durable-hooks-logger.d.ts +10 -0
  104. package/dist/browser/hooks/durable-hooks-logger.d.ts.map +1 -0
  105. package/dist/browser/hooks/hooks.d.ts +146 -0
  106. package/dist/browser/hooks/hooks.d.ts.map +1 -0
  107. package/dist/browser/id.js +1 -0
  108. package/dist/browser/internal/adapter-registry.d.ts +4 -0
  109. package/dist/browser/internal/outbox-state.d.ts +2 -0
  110. package/dist/browser/mod.d.ts +15 -0
  111. package/dist/browser/mod.d.ts.map +1 -0
  112. package/dist/browser/mod.js +17 -0
  113. package/dist/browser/mod.js.map +1 -0
  114. package/dist/browser/mod2.d.ts +48 -0
  115. package/dist/browser/mod2.d.ts.map +1 -0
  116. package/dist/browser/naming/sql-naming.d.ts +19 -0
  117. package/dist/browser/naming/sql-naming.d.ts.map +1 -0
  118. package/dist/browser/outbox/outbox.d.ts +21 -0
  119. package/dist/browser/outbox/outbox.d.ts.map +1 -0
  120. package/dist/browser/query/column-defaults.js +1 -0
  121. package/dist/browser/query/condition-builder.d.ts +44 -0
  122. package/dist/browser/query/condition-builder.d.ts.map +1 -0
  123. package/dist/browser/query/condition-builder.js +97 -0
  124. package/dist/browser/query/condition-builder.js.map +1 -0
  125. package/dist/browser/query/cursor.d.ts +105 -0
  126. package/dist/browser/query/cursor.d.ts.map +1 -0
  127. package/dist/browser/query/cursor.js +150 -0
  128. package/dist/browser/query/cursor.js.map +1 -0
  129. package/dist/browser/query/db-now.d.ts +22 -0
  130. package/dist/browser/query/db-now.d.ts.map +1 -0
  131. package/dist/browser/query/db-now.js +33 -0
  132. package/dist/browser/query/db-now.js.map +1 -0
  133. package/dist/browser/query/orm/orm.d.ts +18 -0
  134. package/dist/browser/query/orm/orm.d.ts.map +1 -0
  135. package/dist/browser/query/simple-query-interface.d.ts +108 -0
  136. package/dist/browser/query/simple-query-interface.d.ts.map +1 -0
  137. package/dist/browser/query/unit-of-work/execute-unit-of-work.d.ts +423 -0
  138. package/dist/browser/query/unit-of-work/execute-unit-of-work.d.ts.map +1 -0
  139. package/dist/browser/query/unit-of-work/execute-unit-of-work.js +507 -0
  140. package/dist/browser/query/unit-of-work/execute-unit-of-work.js.map +1 -0
  141. package/dist/browser/query/unit-of-work/retry-policy.d.ts +23 -0
  142. package/dist/browser/query/unit-of-work/retry-policy.d.ts.map +1 -0
  143. package/dist/browser/query/unit-of-work/retry-policy.js +40 -0
  144. package/dist/browser/query/unit-of-work/retry-policy.js.map +1 -0
  145. package/dist/browser/query/unit-of-work/unit-of-work.d.ts +703 -0
  146. package/dist/browser/query/unit-of-work/unit-of-work.d.ts.map +1 -0
  147. package/dist/browser/query/unit-of-work/unit-of-work.js +1206 -0
  148. package/dist/browser/query/unit-of-work/unit-of-work.js.map +1 -0
  149. package/dist/browser/query/value-encoding.js +38 -0
  150. package/dist/browser/query/value-encoding.js.map +1 -0
  151. package/dist/browser/schema/create.d.ts +326 -0
  152. package/dist/browser/schema/create.d.ts.map +1 -0
  153. package/dist/browser/schema/create.js +89 -0
  154. package/dist/browser/schema/create.js.map +1 -0
  155. package/dist/browser/schema/generate-id.js +28 -0
  156. package/dist/browser/schema/generate-id.js.map +1 -0
  157. package/dist/browser/shared/providers.d.ts +6 -0
  158. package/dist/browser/shared/providers.d.ts.map +1 -0
  159. package/dist/browser/sql-driver/connection/connection-provider.d.ts +13 -0
  160. package/dist/browser/sql-driver/connection/connection-provider.d.ts.map +1 -0
  161. package/dist/browser/sql-driver/dialect-adapter/dialect-adapter.d.ts +7 -0
  162. package/dist/browser/sql-driver/dialect-adapter/dialect-adapter.d.ts.map +1 -0
  163. package/dist/browser/sql-driver/driver/runtime-driver.d.ts +23 -0
  164. package/dist/browser/sql-driver/driver/runtime-driver.d.ts.map +1 -0
  165. package/dist/browser/sql-driver/query-executor/plugin.d.ts +17 -0
  166. package/dist/browser/sql-driver/query-executor/plugin.d.ts.map +1 -0
  167. package/dist/browser/sql-driver/query-executor/query-executor.d.ts +36 -0
  168. package/dist/browser/sql-driver/query-executor/query-executor.d.ts.map +1 -0
  169. package/dist/browser/sql-driver/sql-driver-adapter.d.ts +29 -0
  170. package/dist/browser/sql-driver/sql-driver-adapter.d.ts.map +1 -0
  171. package/dist/browser/sql-driver/sql-driver.d.ts +38 -0
  172. package/dist/browser/sql-driver/sql-driver.d.ts.map +1 -0
  173. package/dist/browser/sync/commands.d.ts +15 -0
  174. package/dist/browser/sync/commands.d.ts.map +1 -0
  175. package/dist/browser/sync/commands.js +27 -0
  176. package/dist/browser/sync/commands.js.map +1 -0
  177. package/dist/browser/sync/types.d.ts +63 -0
  178. package/dist/browser/sync/types.d.ts.map +1 -0
  179. package/dist/browser/util/types.d.ts +8 -0
  180. package/dist/browser/util/types.d.ts.map +1 -0
  181. package/dist/browser/with-database.d.ts +29 -0
  182. package/dist/browser/with-database.d.ts.map +1 -0
  183. package/dist/client.d.ts +4 -0
  184. package/dist/client.js +5 -0
  185. package/dist/db-fragment-definition-builder.d.ts +101 -33
  186. package/dist/db-fragment-definition-builder.d.ts.map +1 -1
  187. package/dist/db-fragment-definition-builder.js +450 -60
  188. package/dist/db-fragment-definition-builder.js.map +1 -1
  189. package/dist/dispatchers/cloudflare-do/dispatcher.d.ts +20 -0
  190. package/dist/dispatchers/cloudflare-do/dispatcher.d.ts.map +1 -0
  191. package/dist/dispatchers/cloudflare-do/dispatcher.js +147 -0
  192. package/dist/dispatchers/cloudflare-do/dispatcher.js.map +1 -0
  193. package/dist/dispatchers/cloudflare-do/index.d.ts +11 -0
  194. package/dist/dispatchers/cloudflare-do/index.d.ts.map +1 -0
  195. package/dist/dispatchers/cloudflare-do/index.js +31 -0
  196. package/dist/dispatchers/cloudflare-do/index.js.map +1 -0
  197. package/dist/dispatchers/node/dispatcher.d.ts +14 -0
  198. package/dist/dispatchers/node/dispatcher.d.ts.map +1 -0
  199. package/dist/dispatchers/node/dispatcher.js +80 -0
  200. package/dist/dispatchers/node/dispatcher.js.map +1 -0
  201. package/dist/dispatchers/node/index.d.ts +12 -0
  202. package/dist/dispatchers/node/index.d.ts.map +1 -0
  203. package/dist/dispatchers/node/index.js +27 -0
  204. package/dist/dispatchers/node/index.js.map +1 -0
  205. package/dist/durable-hooks.d.ts +31 -0
  206. package/dist/durable-hooks.d.ts.map +1 -0
  207. package/dist/durable-hooks.js +23 -0
  208. package/dist/durable-hooks.js.map +1 -0
  209. package/dist/fragments/internal-fragment.d.ts +186 -8
  210. package/dist/fragments/internal-fragment.d.ts.map +1 -1
  211. package/dist/fragments/internal-fragment.js +203 -38
  212. package/dist/fragments/internal-fragment.js.map +1 -1
  213. package/dist/fragments/internal-fragment.routes.js +164 -0
  214. package/dist/fragments/internal-fragment.routes.js.map +1 -0
  215. package/dist/fragments/internal-fragment.schema.d.ts +15 -0
  216. package/dist/fragments/internal-fragment.schema.d.ts.map +1 -0
  217. package/dist/fragments/internal-fragment.schema.js +39 -0
  218. package/dist/fragments/internal-fragment.schema.js.map +1 -0
  219. package/dist/hooks/durable-hooks-logger.d.ts +10 -0
  220. package/dist/hooks/durable-hooks-logger.d.ts.map +1 -0
  221. package/dist/hooks/durable-hooks-logger.js +75 -0
  222. package/dist/hooks/durable-hooks-logger.js.map +1 -0
  223. package/dist/hooks/durable-hooks-processor.d.ts +1 -0
  224. package/dist/hooks/durable-hooks-processor.js +80 -0
  225. package/dist/hooks/durable-hooks-processor.js.map +1 -0
  226. package/dist/hooks/durable-hooks-runtime.js +44 -0
  227. package/dist/hooks/durable-hooks-runtime.js.map +1 -0
  228. package/dist/hooks/hooks.d.ts +100 -1
  229. package/dist/hooks/hooks.d.ts.map +1 -1
  230. package/dist/hooks/hooks.js +254 -27
  231. package/dist/hooks/hooks.js.map +1 -1
  232. package/dist/id.d.ts +2 -2
  233. package/dist/id.js +2 -2
  234. package/dist/internal/adapter-registry.d.ts +11 -0
  235. package/dist/internal/adapter-registry.d.ts.map +1 -0
  236. package/dist/internal/adapter-registry.js +135 -0
  237. package/dist/internal/adapter-registry.js.map +1 -0
  238. package/dist/internal/outbox-state.d.ts +2 -0
  239. package/dist/internal/outbox-state.js +26 -0
  240. package/dist/internal/outbox-state.js.map +1 -0
  241. package/dist/migration-engine/auto-from-schema.d.ts +33 -0
  242. package/dist/migration-engine/auto-from-schema.d.ts.map +1 -0
  243. package/dist/migration-engine/auto-from-schema.js +223 -37
  244. package/dist/migration-engine/auto-from-schema.js.map +1 -1
  245. package/dist/migration-engine/generation-engine.d.ts +16 -10
  246. package/dist/migration-engine/generation-engine.d.ts.map +1 -1
  247. package/dist/migration-engine/generation-engine.js +86 -35
  248. package/dist/migration-engine/generation-engine.js.map +1 -1
  249. package/dist/migration-engine/shared.d.ts +113 -0
  250. package/dist/migration-engine/shared.d.ts.map +1 -0
  251. package/dist/migration-engine/shared.js.map +1 -1
  252. package/dist/mod.d.ts +20 -12
  253. package/dist/mod.d.ts.map +1 -1
  254. package/dist/mod.js +18 -12
  255. package/dist/mod.js.map +1 -1
  256. package/dist/naming/sql-naming.d.ts +19 -0
  257. package/dist/naming/sql-naming.d.ts.map +1 -0
  258. package/dist/naming/sql-naming.js +116 -0
  259. package/dist/naming/sql-naming.js.map +1 -0
  260. package/dist/outbox/outbox-builder.js +156 -0
  261. package/dist/outbox/outbox-builder.js.map +1 -0
  262. package/dist/outbox/outbox.d.ts +54 -0
  263. package/dist/outbox/outbox.d.ts.map +1 -0
  264. package/dist/outbox/outbox.js +37 -0
  265. package/dist/outbox/outbox.js.map +1 -0
  266. package/dist/query/column-defaults.js +20 -4
  267. package/dist/query/column-defaults.js.map +1 -1
  268. package/dist/query/condition-builder.d.ts +7 -1
  269. package/dist/query/condition-builder.d.ts.map +1 -1
  270. package/dist/query/condition-builder.js +5 -1
  271. package/dist/query/condition-builder.js.map +1 -1
  272. package/dist/query/cursor-client.d.ts +105 -0
  273. package/dist/query/cursor-client.d.ts.map +1 -0
  274. package/dist/query/cursor-client.js +165 -0
  275. package/dist/query/cursor-client.js.map +1 -0
  276. package/dist/query/cursor.d.ts +3 -1
  277. package/dist/query/cursor.d.ts.map +1 -1
  278. package/dist/query/cursor.js +51 -14
  279. package/dist/query/cursor.js.map +1 -1
  280. package/dist/query/db-now.d.ts +22 -0
  281. package/dist/query/db-now.d.ts.map +1 -0
  282. package/dist/query/db-now.js +35 -0
  283. package/dist/query/db-now.js.map +1 -0
  284. package/dist/query/orm/orm.js.map +1 -1
  285. package/dist/query/serialize/create-sql-serializer.js +5 -4
  286. package/dist/query/serialize/create-sql-serializer.js.map +1 -1
  287. package/dist/query/serialize/dialect/mysql-serializer.js +12 -6
  288. package/dist/query/serialize/dialect/mysql-serializer.js.map +1 -1
  289. package/dist/query/serialize/dialect/postgres-serializer.js +25 -7
  290. package/dist/query/serialize/dialect/postgres-serializer.js.map +1 -1
  291. package/dist/query/serialize/dialect/sqlite-serializer.js +60 -12
  292. package/dist/query/serialize/dialect/sqlite-serializer.js.map +1 -1
  293. package/dist/query/serialize/sql-serializer.js +2 -2
  294. package/dist/query/serialize/sql-serializer.js.map +1 -1
  295. package/dist/query/simple-query-interface.d.ts +13 -4
  296. package/dist/query/simple-query-interface.d.ts.map +1 -1
  297. package/dist/query/unit-of-work/execute-unit-of-work.d.ts +37 -2
  298. package/dist/query/unit-of-work/execute-unit-of-work.d.ts.map +1 -1
  299. package/dist/query/unit-of-work/execute-unit-of-work.js +50 -24
  300. package/dist/query/unit-of-work/execute-unit-of-work.js.map +1 -1
  301. package/dist/query/unit-of-work/unit-of-work.d.ts +92 -30
  302. package/dist/query/unit-of-work/unit-of-work.d.ts.map +1 -1
  303. package/dist/query/unit-of-work/unit-of-work.js +136 -11
  304. package/dist/query/unit-of-work/unit-of-work.js.map +1 -1
  305. package/dist/query/value-decoding.js +16 -6
  306. package/dist/query/value-decoding.js.map +1 -1
  307. package/dist/query/value-encoding.js +29 -9
  308. package/dist/query/value-encoding.js.map +1 -1
  309. package/dist/schema/create.d.ts +103 -35
  310. package/dist/schema/create.d.ts.map +1 -1
  311. package/dist/schema/create.js +172 -58
  312. package/dist/schema/create.js.map +1 -1
  313. package/dist/schema/generate-id.js +2 -2
  314. package/dist/schema/generate-id.js.map +1 -1
  315. package/dist/schema/type-conversion/create-sql-type-mapper.js +4 -3
  316. package/dist/schema/type-conversion/create-sql-type-mapper.js.map +1 -1
  317. package/dist/schema/type-conversion/dialect/sqlite.js +9 -0
  318. package/dist/schema/type-conversion/dialect/sqlite.js.map +1 -1
  319. package/dist/schema/validator.d.ts +10 -0
  320. package/dist/schema/validator.d.ts.map +1 -0
  321. package/dist/schema/validator.js +123 -0
  322. package/dist/schema/validator.js.map +1 -0
  323. package/dist/schema-output/drizzle.d.ts +30 -0
  324. package/dist/schema-output/drizzle.d.ts.map +1 -0
  325. package/dist/{adapters/drizzle/generate.js → schema-output/drizzle.js} +88 -60
  326. package/dist/schema-output/drizzle.js.map +1 -0
  327. package/dist/schema-output/prisma.d.ts +17 -0
  328. package/dist/schema-output/prisma.d.ts.map +1 -0
  329. package/dist/schema-output/prisma.js +307 -0
  330. package/dist/schema-output/prisma.js.map +1 -0
  331. package/dist/sql-driver/dialects/durable-object-dialect.js +3 -9
  332. package/dist/sql-driver/dialects/durable-object-dialect.js.map +1 -1
  333. package/dist/sql-driver/query-executor/default-query-executor.js.map +1 -1
  334. package/dist/sql-driver/query-executor/query-executor-base.js.map +1 -1
  335. package/dist/sql-driver/sql-driver-adapter.js.map +1 -1
  336. package/dist/sql-driver/sql.js.map +1 -1
  337. package/dist/sync/commands.d.ts +15 -0
  338. package/dist/sync/commands.d.ts.map +1 -0
  339. package/dist/sync/commands.js +27 -0
  340. package/dist/sync/commands.js.map +1 -0
  341. package/dist/sync/index.d.ts +4 -0
  342. package/dist/sync/index.js +4 -0
  343. package/dist/sync/read-tracking.d.ts +25 -0
  344. package/dist/sync/read-tracking.d.ts.map +1 -0
  345. package/dist/sync/read-tracking.js +148 -0
  346. package/dist/sync/read-tracking.js.map +1 -0
  347. package/dist/sync/submit.js +213 -0
  348. package/dist/sync/submit.js.map +1 -0
  349. package/dist/sync/types.d.ts +63 -0
  350. package/dist/sync/types.d.ts.map +1 -0
  351. package/dist/util/default-database-adapter.js +66 -0
  352. package/dist/util/default-database-adapter.js.map +1 -0
  353. package/dist/with-database.d.ts +3 -6
  354. package/dist/with-database.d.ts.map +1 -1
  355. package/dist/with-database.js +8 -7
  356. package/dist/with-database.js.map +1 -1
  357. package/package.json +62 -55
  358. package/src/adapters/adapters.ts +33 -26
  359. package/src/adapters/drizzle/migrate-drizzle.test.ts +99 -41
  360. package/src/adapters/drizzle/migration-parity-drizzle-kit.test.ts +601 -0
  361. package/src/adapters/drizzle/test-utils.ts +13 -8
  362. package/src/adapters/generic-sql/driver-config.ts +38 -0
  363. package/src/adapters/generic-sql/generic-sql-adapter.test.ts +10 -8
  364. package/src/adapters/generic-sql/generic-sql-adapter.ts +117 -34
  365. package/src/adapters/generic-sql/generic-sql-uow-executor.test.ts +55 -0
  366. package/src/adapters/generic-sql/generic-sql-uow-executor.ts +297 -3
  367. package/src/adapters/generic-sql/migration/adapter-migration-parity.test.ts +120 -0
  368. package/src/adapters/generic-sql/migration/cold-kysely.ts +1 -0
  369. package/src/adapters/generic-sql/migration/dialect/mysql.test.ts +27 -8
  370. package/src/adapters/generic-sql/migration/dialect/mysql.ts +47 -8
  371. package/src/adapters/generic-sql/migration/dialect/postgres.test.ts +28 -9
  372. package/src/adapters/generic-sql/migration/dialect/postgres.ts +9 -4
  373. package/src/adapters/generic-sql/migration/dialect/sqlite.test.ts +839 -8
  374. package/src/adapters/generic-sql/migration/dialect/sqlite.ts +396 -53
  375. package/src/adapters/generic-sql/migration/executor.test.ts +52 -0
  376. package/src/adapters/generic-sql/migration/executor.ts +47 -4
  377. package/src/adapters/generic-sql/migration/prepared-migrations.test.ts +238 -46
  378. package/src/adapters/generic-sql/migration/prepared-migrations.ts +21 -13
  379. package/src/adapters/generic-sql/migration/sql-generator.ts +145 -66
  380. package/src/adapters/generic-sql/query/create-sql-query-compiler.ts +11 -8
  381. package/src/adapters/generic-sql/query/cursor-utils.test.ts +272 -0
  382. package/src/adapters/generic-sql/query/cursor-utils.ts +42 -7
  383. package/src/adapters/generic-sql/query/db-now-sql.ts +49 -0
  384. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.test.ts +171 -35
  385. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.ts +53 -40
  386. package/src/adapters/generic-sql/query/select-builder.test.ts +16 -11
  387. package/src/adapters/generic-sql/query/select-builder.ts +7 -3
  388. package/src/adapters/generic-sql/query/sql-query-compiler.test.ts +75 -6
  389. package/src/adapters/generic-sql/query/sql-query-compiler.ts +129 -24
  390. package/src/adapters/generic-sql/query/where-builder.test.ts +96 -20
  391. package/src/adapters/generic-sql/query/where-builder.ts +112 -41
  392. package/src/adapters/{kysely/kysely-adapter-pglite.test.ts → generic-sql/sql-adapter-pglite-migrations.test.ts} +11 -20
  393. package/src/adapters/generic-sql/sql-adapter-pglite-pagination.test.ts +851 -0
  394. package/src/adapters/{drizzle/drizzle-adapter-pglite.test.ts → generic-sql/sql-adapter-pglite-queries.test.ts} +18 -15
  395. package/src/adapters/generic-sql/{test/generic-drizzle-adapter-sqlite3.test.ts → sql-adapter-sqlite3-driver.test.ts} +282 -14
  396. package/src/adapters/{drizzle/drizzle-adapter-sqlite3.test.ts → generic-sql/sql-adapter-sqlite3-uow.test.ts} +129 -12
  397. package/src/adapters/{kysely/kysely-adapter-sqlocal.test.ts → generic-sql/sql-adapter-sqlocal.test.ts} +9 -7
  398. package/src/adapters/generic-sql/sqlite-storage.ts +20 -0
  399. package/src/adapters/generic-sql/uow-decoder.test.ts +5 -4
  400. package/src/adapters/generic-sql/uow-decoder.ts +23 -5
  401. package/src/adapters/generic-sql/uow-encoder.test.ts +36 -3
  402. package/src/adapters/generic-sql/uow-encoder.ts +48 -13
  403. package/src/adapters/in-memory/condition-evaluator.test.ts +194 -0
  404. package/src/adapters/in-memory/condition-evaluator.ts +280 -0
  405. package/src/adapters/in-memory/errors.ts +20 -0
  406. package/src/adapters/in-memory/in-memory-adapter.ts +388 -0
  407. package/src/adapters/in-memory/in-memory-uow.mutations.test.ts +344 -0
  408. package/src/adapters/in-memory/in-memory-uow.retrieval.test.ts +255 -0
  409. package/src/adapters/in-memory/in-memory-uow.ts +1724 -0
  410. package/src/adapters/in-memory/index.ts +3 -0
  411. package/src/adapters/in-memory/options.test.ts +42 -0
  412. package/src/adapters/in-memory/options.ts +91 -0
  413. package/src/adapters/in-memory/outbox.test.ts +361 -0
  414. package/src/adapters/in-memory/reference-resolution.test.ts +51 -0
  415. package/src/adapters/in-memory/reference-resolution.ts +67 -0
  416. package/src/adapters/in-memory/sorted-array-index.test.ts +124 -0
  417. package/src/adapters/in-memory/sorted-array-index.ts +228 -0
  418. package/src/adapters/in-memory/store.test.ts +69 -0
  419. package/src/adapters/in-memory/store.ts +145 -0
  420. package/src/adapters/in-memory/value-comparison.ts +53 -0
  421. package/src/adapters/in-memory/value-normalization.test.ts +58 -0
  422. package/src/adapters/prisma/prisma-adapter-sqlite3.test.ts +1207 -0
  423. package/src/adapters/shared/from-unit-of-work-compiler.ts +159 -47
  424. package/src/adapters/shared/uow-operation-compiler.ts +28 -18
  425. package/src/adapters/sql/index.ts +12 -0
  426. package/src/browser/mod.ts +64 -0
  427. package/src/client.ts +19 -0
  428. package/src/db-fragment-definition-builder.test.ts +845 -53
  429. package/src/db-fragment-definition-builder.ts +911 -95
  430. package/src/db-fragment-instantiator.test.ts +210 -94
  431. package/src/db-fragment-integration.test.ts +17 -12
  432. package/src/dispatchers/cloudflare-do/dispatcher.ts +204 -0
  433. package/src/dispatchers/cloudflare-do/index.test.ts +206 -0
  434. package/src/dispatchers/cloudflare-do/index.ts +63 -0
  435. package/src/dispatchers/node/dispatcher.ts +112 -0
  436. package/src/dispatchers/node/index.test.ts +120 -0
  437. package/src/dispatchers/node/index.ts +50 -0
  438. package/src/durable-hooks.test.ts +80 -0
  439. package/src/durable-hooks.ts +67 -0
  440. package/src/fragments/internal-fragment.routes.test.ts +570 -0
  441. package/src/fragments/internal-fragment.routes.ts +334 -0
  442. package/src/fragments/internal-fragment.schema.ts +95 -0
  443. package/src/fragments/internal-fragment.test.ts +505 -83
  444. package/src/fragments/internal-fragment.ts +453 -70
  445. package/src/hooks/durable-hooks-logger.ts +126 -0
  446. package/src/hooks/durable-hooks-processor.pglite.test.ts +87 -0
  447. package/src/hooks/durable-hooks-processor.test.ts +282 -0
  448. package/src/hooks/durable-hooks-processor.ts +173 -0
  449. package/src/hooks/durable-hooks-runtime.test.ts +65 -0
  450. package/src/hooks/durable-hooks-runtime.ts +81 -0
  451. package/src/hooks/hooks.test.ts +455 -34
  452. package/src/hooks/hooks.ts +501 -34
  453. package/src/id.test.ts +34 -0
  454. package/src/id.ts +1 -3
  455. package/src/internal/adapter-registry.test.ts +93 -0
  456. package/src/internal/adapter-registry.ts +239 -0
  457. package/src/internal/outbox-state.ts +43 -0
  458. package/src/migration-engine/auto-from-schema.test.ts +107 -14
  459. package/src/migration-engine/auto-from-schema.ts +365 -44
  460. package/src/migration-engine/create.test.ts +4 -3
  461. package/src/migration-engine/create.ts +1 -1
  462. package/src/migration-engine/generation-engine.test.ts +292 -110
  463. package/src/migration-engine/generation-engine.ts +117 -66
  464. package/src/migration-engine/shared.ts +14 -0
  465. package/src/mod.ts +95 -39
  466. package/src/naming/sql-naming.ts +181 -0
  467. package/src/outbox/outbox-builder.ts +241 -0
  468. package/src/outbox/outbox.test.ts +424 -0
  469. package/src/outbox/outbox.ts +139 -0
  470. package/src/query/column-defaults.ts +42 -4
  471. package/src/query/condition-builder.test.ts +18 -3
  472. package/src/query/condition-builder.ts +7 -0
  473. package/src/query/cursor-client.test.ts +70 -0
  474. package/src/query/cursor-client.ts +263 -0
  475. package/src/query/cursor.test.ts +119 -20
  476. package/src/query/cursor.ts +88 -27
  477. package/src/query/db-now.ts +73 -0
  478. package/src/query/orm/orm.ts +2 -2
  479. package/src/query/query-type.test.ts +4 -3
  480. package/src/query/serialize/create-sql-serializer.ts +10 -5
  481. package/src/query/serialize/dialect/mysql-serializer.ts +13 -5
  482. package/src/query/serialize/dialect/postgres-serializer.ts +35 -5
  483. package/src/query/serialize/dialect/sqlite-serializer.test.ts +90 -3
  484. package/src/query/serialize/dialect/sqlite-serializer.ts +108 -12
  485. package/src/query/serialize/sql-serializer.ts +4 -4
  486. package/src/query/simple-query-interface.ts +15 -4
  487. package/src/query/unit-of-work/execute-unit-of-work.test.ts +372 -10
  488. package/src/query/unit-of-work/execute-unit-of-work.ts +87 -27
  489. package/src/query/unit-of-work/retry-policy.test.ts +1 -0
  490. package/src/query/unit-of-work/tx-builder.test.ts +73 -1
  491. package/src/query/unit-of-work/unit-of-work-coordinator.test.ts +17 -16
  492. package/src/query/unit-of-work/unit-of-work-types.test.ts +42 -12
  493. package/src/query/unit-of-work/unit-of-work.test.ts +196 -39
  494. package/src/query/unit-of-work/unit-of-work.ts +309 -38
  495. package/src/query/value-decoding.test.ts +63 -4
  496. package/src/query/value-decoding.ts +32 -6
  497. package/src/query/value-encoding.test.ts +86 -2
  498. package/src/query/value-encoding.ts +56 -6
  499. package/src/schema/create.test.ts +293 -47
  500. package/src/schema/create.ts +406 -70
  501. package/src/schema/generate-id.test.ts +3 -2
  502. package/src/schema/generate-id.ts +2 -2
  503. package/src/schema/serialize.test.ts +18 -5
  504. package/src/schema/type-conversion/create-sql-type-mapper.ts +8 -3
  505. package/src/schema/type-conversion/dialect/sqlite.ts +18 -0
  506. package/src/schema/type-conversion/type-mapping.test.ts +26 -1
  507. package/src/schema/validator.test.ts +199 -0
  508. package/src/schema/validator.ts +232 -0
  509. package/src/{adapters/drizzle/generate.test.ts → schema-output/drizzle.test.ts} +232 -129
  510. package/src/{adapters/drizzle/generate.ts → schema-output/drizzle.ts} +155 -99
  511. package/src/schema-output/prisma.test.ts +694 -0
  512. package/src/schema-output/prisma.ts +593 -0
  513. package/src/sql-driver/better-sqlite3.test.ts +5 -3
  514. package/src/sql-driver/dialects/durable-object-dialect.ts +3 -8
  515. package/src/sql-driver/query-executor/default-query-executor.ts +1 -1
  516. package/src/sql-driver/query-executor/query-executor-base.ts +1 -1
  517. package/src/sql-driver/query-executor/query-executor.ts +1 -1
  518. package/src/sql-driver/sql-driver-adapter.ts +2 -2
  519. package/src/sql-driver/sql.ts +2 -1
  520. package/src/sql-driver/sqlocal.test.ts +4 -2
  521. package/src/sync/commands.test.ts +39 -0
  522. package/src/sync/commands.ts +51 -0
  523. package/src/sync/conflict-checker.test.ts +450 -0
  524. package/src/sync/conflict-checker.ts +248 -0
  525. package/src/sync/index.ts +14 -0
  526. package/src/sync/plan.ts +9 -0
  527. package/src/sync/read-tracking.test.ts +177 -0
  528. package/src/sync/read-tracking.ts +287 -0
  529. package/src/sync/submit.test.ts +205 -0
  530. package/src/sync/submit.ts +328 -0
  531. package/src/sync/types.ts +80 -0
  532. package/src/util/default-database-adapter.ts +119 -0
  533. package/src/with-database.ts +20 -31
  534. package/tsconfig.json +1 -1
  535. package/tsdown.config.ts +38 -24
  536. package/vitest.config.ts +1 -0
  537. package/dist/adapters/drizzle/drizzle-adapter.d.ts +0 -20
  538. package/dist/adapters/drizzle/drizzle-adapter.d.ts.map +0 -1
  539. package/dist/adapters/drizzle/drizzle-adapter.js +0 -27
  540. package/dist/adapters/drizzle/drizzle-adapter.js.map +0 -1
  541. package/dist/adapters/drizzle/generate.d.ts +0 -30
  542. package/dist/adapters/drizzle/generate.d.ts.map +0 -1
  543. package/dist/adapters/drizzle/generate.js.map +0 -1
  544. package/dist/adapters/kysely/kysely-adapter.d.ts +0 -19
  545. package/dist/adapters/kysely/kysely-adapter.d.ts.map +0 -1
  546. package/dist/adapters/kysely/kysely-adapter.js +0 -17
  547. package/dist/adapters/kysely/kysely-adapter.js.map +0 -1
  548. package/dist/adapters/shared/table-name-mapper.d.ts +0 -12
  549. package/dist/adapters/shared/table-name-mapper.d.ts.map +0 -1
  550. package/dist/adapters/shared/table-name-mapper.js +0 -43
  551. package/dist/adapters/shared/table-name-mapper.js.map +0 -1
  552. package/dist/node_modules/.pnpm/rou3@0.7.10/node_modules/rou3/dist/index.js +0 -165
  553. package/dist/node_modules/.pnpm/rou3@0.7.10/node_modules/rou3/dist/index.js.map +0 -1
  554. package/dist/packages/fragno/dist/api/bind-services.js +0 -20
  555. package/dist/packages/fragno/dist/api/bind-services.js.map +0 -1
  556. package/dist/packages/fragno/dist/api/error.js +0 -48
  557. package/dist/packages/fragno/dist/api/error.js.map +0 -1
  558. package/dist/packages/fragno/dist/api/fragment-definition-builder.js +0 -320
  559. package/dist/packages/fragno/dist/api/fragment-definition-builder.js.map +0 -1
  560. package/dist/packages/fragno/dist/api/fragment-instantiator.js +0 -525
  561. package/dist/packages/fragno/dist/api/fragment-instantiator.js.map +0 -1
  562. package/dist/packages/fragno/dist/api/fragno-response.js +0 -73
  563. package/dist/packages/fragno/dist/api/fragno-response.js.map +0 -1
  564. package/dist/packages/fragno/dist/api/internal/response-stream.js +0 -81
  565. package/dist/packages/fragno/dist/api/internal/response-stream.js.map +0 -1
  566. package/dist/packages/fragno/dist/api/internal/route.js +0 -10
  567. package/dist/packages/fragno/dist/api/internal/route.js.map +0 -1
  568. package/dist/packages/fragno/dist/api/mutable-request-state.js +0 -97
  569. package/dist/packages/fragno/dist/api/mutable-request-state.js.map +0 -1
  570. package/dist/packages/fragno/dist/api/request-context-storage.js +0 -43
  571. package/dist/packages/fragno/dist/api/request-context-storage.js.map +0 -1
  572. package/dist/packages/fragno/dist/api/request-input-context.js +0 -118
  573. package/dist/packages/fragno/dist/api/request-input-context.js.map +0 -1
  574. package/dist/packages/fragno/dist/api/request-middleware.js +0 -83
  575. package/dist/packages/fragno/dist/api/request-middleware.js.map +0 -1
  576. package/dist/packages/fragno/dist/api/request-output-context.js +0 -119
  577. package/dist/packages/fragno/dist/api/request-output-context.js.map +0 -1
  578. package/dist/packages/fragno/dist/api/route.js +0 -17
  579. package/dist/packages/fragno/dist/api/route.js.map +0 -1
  580. package/dist/packages/fragno/dist/internal/symbols.js +0 -10
  581. package/dist/packages/fragno/dist/internal/symbols.js.map +0 -1
  582. package/dist/schema-generator/schema-generator.d.ts +0 -15
  583. package/dist/schema-generator/schema-generator.d.ts.map +0 -1
  584. package/src/adapters/drizzle/drizzle-adapter.ts +0 -39
  585. package/src/adapters/kysely/kysely-adapter.ts +0 -27
  586. package/src/adapters/shared/table-name-mapper.ts +0 -50
  587. package/src/schema-generator/schema-generator.ts +0 -12
@@ -1,54 +1,230 @@
1
- import { createHandlerTxBuilder, createServiceTxBuilder } from "./query/unit-of-work/execute-unit-of-work.js";
2
- import { prepareHookMutations, processHooks } from "./hooks/hooks.js";
1
+ import { DurableHooksLogger } from "./hooks/durable-hooks-logger.js";
2
+ import { getDurableHooksRuntimeByConfig, getDurableHooksRuntimeByNamespace, registerDurableHooksRuntime } from "./hooks/durable-hooks-runtime.js";
3
+ import { createDurableHooksRunner, prepareHookMutations } from "./hooks/hooks.js";
4
+ import { sanitizeNamespace } from "./naming/sql-naming.js";
5
+ import { HandlerTxBuilder, createHandlerTxBuilder, createServiceTxBuilder } from "./query/unit-of-work/execute-unit-of-work.js";
6
+ import { resolveDatabaseAdapter } from "./util/default-database-adapter.js";
7
+ import { FragmentDefinitionBuilder } from "@fragno-dev/core";
8
+ import { FragnoApiError } from "@fragno-dev/core/api";
3
9
 
4
10
  //#region src/db-fragment-definition-builder.ts
5
11
  /**
6
12
  * Create database context from options.
7
13
  * This extracts the database adapter and creates the ORM instance.
8
14
  */
9
- function createDatabaseContext(options, schema, namespace) {
10
- const databaseAdapter = options.databaseAdapter;
11
- if (!databaseAdapter) throw new Error("Database fragment requires a database adapter to be provided in options.databaseAdapter");
15
+ function createDatabaseContext(options, schema) {
16
+ const databaseAdapter = resolveDatabaseAdapter(options, schema);
17
+ const namespace = resolveDatabaseNamespace(options, schema);
12
18
  return {
13
19
  databaseAdapter,
14
20
  db: databaseAdapter.createQueryEngine(schema, namespace)
15
21
  };
16
22
  }
23
+ function resolveDatabaseNamespace(options, schema) {
24
+ return options.databaseNamespace !== void 0 ? options.databaseNamespace ?? null : sanitizeNamespace(schema.name);
25
+ }
26
+ function resolveMountRoute(name, mountRoute) {
27
+ const resolved = mountRoute ?? `/api/${name}`;
28
+ return resolved.endsWith("/") ? resolved.slice(0, -1) : resolved;
29
+ }
30
+ const dbRoundtripGuardStateSymbol = Symbol("fragno-db-roundtrip-guard");
31
+ const requestSourceSymbol = Symbol.for("fragno-request-source");
32
+ const requestRouteSymbol = Symbol.for("fragno-request-route");
33
+ const requestWaitUntilSymbol = Symbol.for("fragno-request-wait-until");
34
+ const roundtripGuardDocsUrl = "https://fragno.dev/docs/fragno/for-library-authors/rules-of-fragno";
35
+ function wrapHandlerTxBuilderWithRoundtripGuard(builder, onExecute) {
36
+ const wrappedBuilders = /* @__PURE__ */ new WeakSet();
37
+ const applyExecuteGuard = (target) => {
38
+ if (wrappedBuilders.has(target)) return target;
39
+ wrappedBuilders.add(target);
40
+ const execute = target.execute.bind(target);
41
+ target.execute = () => {
42
+ onExecute();
43
+ return execute();
44
+ };
45
+ return target;
46
+ };
47
+ const wrap = (target) => {
48
+ const guarded = applyExecuteGuard(target);
49
+ return new Proxy(guarded, { get(obj, prop, receiver) {
50
+ const value = Reflect.get(obj, prop, receiver);
51
+ if (typeof value !== "function") return value;
52
+ if (prop === "execute") return value;
53
+ return (...args) => {
54
+ const result = value.apply(obj, args);
55
+ if (result instanceof HandlerTxBuilder) return wrap(result);
56
+ return result;
57
+ };
58
+ } });
59
+ };
60
+ return wrap(builder);
61
+ }
62
+ function buildDurableHooksLogContext(context) {
63
+ const logContext = {};
64
+ if (context?.route !== void 0) logContext["route"] = context.route;
65
+ if (context?.source !== void 0) logContext["source"] = context.source;
66
+ return logContext;
67
+ }
68
+ function notifyDurableHooks(notifier, namespace, notifyContext, logContextFields, options) {
69
+ const suffix = options?.crossNamespace ?? false ? " (cross-namespace)" : "";
70
+ const notifyStart = Date.now();
71
+ DurableHooksLogger.debug(`Durable hooks notify requested${suffix}`, {
72
+ namespace,
73
+ fields: logContextFields
74
+ });
75
+ const notifyPromise = Promise.resolve().then(() => notifier.notify(notifyContext)).then((processed) => {
76
+ DurableHooksLogger.debug(`Durable hooks notify completed${suffix}`, {
77
+ namespace,
78
+ fields: {
79
+ result: processed === void 0 ? null : processed,
80
+ ms: Date.now() - notifyStart,
81
+ ...logContextFields
82
+ }
83
+ });
84
+ }).catch((error) => {
85
+ DurableHooksLogger.error(`Durable hooks notify failed${suffix}`, {
86
+ namespace,
87
+ fields: {
88
+ error: DurableHooksLogger.toErrorMessage(error),
89
+ ...logContextFields
90
+ }
91
+ });
92
+ });
93
+ if (notifyContext.waitUntil) {
94
+ notifyContext.waitUntil(notifyPromise);
95
+ return;
96
+ }
97
+ }
98
+ function notifyDurableHooksAfterMutate({ uow, hooksConfig, internalFragment, autoSchedule, planMode, logContext }) {
99
+ if (planMode) return;
100
+ const notifyContext = {
101
+ source: logContext?.source ?? "request",
102
+ route: logContext?.route,
103
+ waitUntil: logContext?.waitUntil
104
+ };
105
+ const logContextFields = buildDurableHooksLogContext(logContext);
106
+ const triggeredHooks = uow.getTriggeredHooks();
107
+ const ownNamespaceTriggeredCount = hooksConfig ? triggeredHooks.filter((hook) => hook.namespace === hooksConfig.namespace).length : 0;
108
+ if (hooksConfig?.notifier && autoSchedule && ownNamespaceTriggeredCount > 0) notifyDurableHooks(hooksConfig.notifier, hooksConfig.namespace, notifyContext, logContextFields);
109
+ else if (hooksConfig && !autoSchedule && ownNamespaceTriggeredCount > 0) DurableHooksLogger.debug("Durable hooks notify skipped (autoSchedule=false)", {
110
+ namespace: hooksConfig.namespace,
111
+ fields: {
112
+ queued: ownNamespaceTriggeredCount,
113
+ ...logContextFields
114
+ }
115
+ });
116
+ else if (hooksConfig && !hooksConfig.notifier && ownNamespaceTriggeredCount > 0) DurableHooksLogger.debug("Durable hooks notify skipped (notifier missing)", {
117
+ namespace: hooksConfig.namespace,
118
+ fields: {
119
+ queued: ownNamespaceTriggeredCount,
120
+ ...logContextFields
121
+ }
122
+ });
123
+ if (triggeredHooks.length === 0) return;
124
+ const namespaces = /* @__PURE__ */ new Set();
125
+ const triggeredCountByNamespace = /* @__PURE__ */ new Map();
126
+ for (const hook of triggeredHooks) {
127
+ namespaces.add(hook.namespace);
128
+ triggeredCountByNamespace.set(hook.namespace, (triggeredCountByNamespace.get(hook.namespace) ?? 0) + 1);
129
+ }
130
+ if (hooksConfig) namespaces.delete(hooksConfig.namespace);
131
+ for (const namespace of namespaces) {
132
+ if (!internalFragment) {
133
+ DurableHooksLogger.debug("Durable hooks notifier missing scope for namespace", {
134
+ namespace,
135
+ fields: logContextFields
136
+ });
137
+ continue;
138
+ }
139
+ const runtime = getDurableHooksRuntimeByNamespace(namespace, internalFragment);
140
+ if (!runtime) {
141
+ DurableHooksLogger.debug("Durable hooks notifier missing for namespace", {
142
+ namespace,
143
+ fields: logContextFields
144
+ });
145
+ continue;
146
+ }
147
+ if (runtime.config.autoSchedule === false) {
148
+ DurableHooksLogger.debug("Durable hooks notify skipped (autoSchedule=false)", {
149
+ namespace,
150
+ fields: {
151
+ queued: triggeredCountByNamespace.get(namespace) ?? 0,
152
+ ...logContextFields
153
+ }
154
+ });
155
+ continue;
156
+ }
157
+ const notifier = runtime.config.notifier;
158
+ if (!notifier) {
159
+ DurableHooksLogger.debug("Durable hooks notifier missing for namespace", {
160
+ namespace,
161
+ fields: logContextFields
162
+ });
163
+ continue;
164
+ }
165
+ notifyDurableHooks(notifier, namespace, notifyContext, logContextFields, { crossNamespace: true });
166
+ }
167
+ }
168
+ function resolveDbRoundtripGuard(options) {
169
+ const guard = options.dbRoundtripGuard;
170
+ if (!guard) return null;
171
+ if (guard === true) return {
172
+ retrieveCount: 0,
173
+ mutateCount: 0,
174
+ maxRoundtrips: 1
175
+ };
176
+ return {
177
+ retrieveCount: 0,
178
+ mutateCount: 0,
179
+ maxRoundtrips: guard.maxRoundtrips ?? 1
180
+ };
181
+ }
182
+ function getDbRoundtripGuardState(storage, guard) {
183
+ const storageWithGuard = storage;
184
+ if (!storageWithGuard[dbRoundtripGuardStateSymbol]) storageWithGuard[dbRoundtripGuardStateSymbol] = { ...guard };
185
+ else storageWithGuard[dbRoundtripGuardStateSymbol].maxRoundtrips = guard.maxRoundtrips;
186
+ return storageWithGuard[dbRoundtripGuardStateSymbol];
187
+ }
188
+ function isRouteRequest(storage) {
189
+ return storage[requestSourceSymbol] === "route";
190
+ }
17
191
  /**
18
192
  * Builder for database fragments that wraps the core fragment builder
19
193
  * and provides database-specific functionality.
20
194
  *
21
- * Database fragments always require FragnoPublicConfigWithDatabase (which includes databaseAdapter).
195
+ * Database fragments use FragnoPublicConfigWithDatabase and default the adapter when possible.
22
196
  */
23
197
  var DatabaseFragmentDefinitionBuilder = class DatabaseFragmentDefinitionBuilder {
24
198
  #baseBuilder;
25
199
  #schema;
26
- #namespace;
27
200
  #hooksFactory;
28
- constructor(baseBuilder, schema, namespace, hooksFactory) {
201
+ #syncRegistry;
202
+ #registryResolver;
203
+ constructor(baseBuilder, schema, hooksFactory, syncRegistry, registryResolver) {
29
204
  this.#baseBuilder = baseBuilder;
30
205
  this.#schema = schema;
31
- this.#namespace = namespace ?? baseBuilder.name;
32
206
  this.#hooksFactory = hooksFactory;
207
+ this.#syncRegistry = syncRegistry;
208
+ this.#registryResolver = registryResolver;
33
209
  }
34
210
  /**
35
211
  * Define dependencies for this database fragment.
36
- * The context includes database adapter and ORM instance.
212
+ * The context includes the database adapter.
37
213
  */
38
214
  withDependencies(fn) {
39
215
  const wrappedFn = (context) => {
40
- const dbContext = createDatabaseContext(context.options, this.#schema, this.#namespace);
216
+ const dbContext = createDatabaseContext(context.options, this.#schema);
217
+ const namespace = resolveDatabaseNamespace(context.options, this.#schema);
41
218
  const userDeps = fn({
42
219
  config: context.config,
43
220
  options: context.options,
44
- db: dbContext.db,
45
221
  databaseAdapter: dbContext.databaseAdapter
46
222
  });
47
223
  const createUow = () => dbContext.db.createUnitOfWork();
48
224
  const implicitDeps = {
49
- db: dbContext.db,
225
+ databaseAdapter: dbContext.databaseAdapter,
50
226
  schema: this.#schema,
51
- namespace: this.#namespace,
227
+ namespace,
52
228
  createUnitOfWork: createUow
53
229
  };
54
230
  return {
@@ -56,13 +232,13 @@ var DatabaseFragmentDefinitionBuilder = class DatabaseFragmentDefinitionBuilder
56
232
  ...implicitDeps
57
233
  };
58
234
  };
59
- return new DatabaseFragmentDefinitionBuilder(this.#baseBuilder.withDependencies(wrappedFn), this.#schema, this.#namespace, this.#hooksFactory);
235
+ return new DatabaseFragmentDefinitionBuilder(this.#baseBuilder.withDependencies(wrappedFn), this.#schema, this.#hooksFactory, this.#syncRegistry, this.#registryResolver);
60
236
  }
61
237
  providesBaseService(fn) {
62
- return new DatabaseFragmentDefinitionBuilder(this.#baseBuilder.providesBaseService(fn), this.#schema, this.#namespace, this.#hooksFactory);
238
+ return new DatabaseFragmentDefinitionBuilder(this.#baseBuilder.providesBaseService(fn), this.#schema, this.#hooksFactory, this.#syncRegistry, this.#registryResolver);
63
239
  }
64
240
  providesService(serviceName, fn) {
65
- return new DatabaseFragmentDefinitionBuilder(this.#baseBuilder.providesService(serviceName, fn), this.#schema, this.#namespace, this.#hooksFactory);
241
+ return new DatabaseFragmentDefinitionBuilder(this.#baseBuilder.providesService(serviceName, fn), this.#schema, this.#hooksFactory, this.#syncRegistry, this.#registryResolver);
66
242
  }
67
243
  /**
68
244
  * Provide a private service that is only accessible to the fragment author.
@@ -72,7 +248,7 @@ var DatabaseFragmentDefinitionBuilder = class DatabaseFragmentDefinitionBuilder
72
248
  * to later ones.
73
249
  */
74
250
  providesPrivateService(serviceName, fn) {
75
- return new DatabaseFragmentDefinitionBuilder(this.#baseBuilder.providesPrivateService(serviceName, fn), this.#schema, this.#namespace, this.#hooksFactory);
251
+ return new DatabaseFragmentDefinitionBuilder(this.#baseBuilder.providesPrivateService(serviceName, fn), this.#schema, this.#hooksFactory, this.#syncRegistry, this.#registryResolver);
76
252
  }
77
253
  /**
78
254
  * Define durable hooks for this fragment.
@@ -99,26 +275,36 @@ var DatabaseFragmentDefinitionBuilder = class DatabaseFragmentDefinitionBuilder
99
275
  return fn({
100
276
  config: context.config,
101
277
  options: context.options,
278
+ deps: context.deps,
279
+ services: context.services,
280
+ serviceDeps: context.serviceDeps,
102
281
  defineHook
103
282
  });
104
283
  };
105
- const newBuilder = new DatabaseFragmentDefinitionBuilder(this.#baseBuilder, this.#schema, this.#namespace);
284
+ const newBuilder = new DatabaseFragmentDefinitionBuilder(this.#baseBuilder, this.#schema, this.#hooksFactory, this.#syncRegistry, this.#registryResolver);
106
285
  newBuilder.#hooksFactory = hooksFactory;
107
286
  return newBuilder;
108
287
  }
109
288
  /**
289
+ * Register sync command definitions for this fragment.
290
+ */
291
+ withSyncCommands(registry) {
292
+ if (registry.schemaName !== this.#schema.name) throw new Error(`Sync command registry schema name "${registry.schemaName}" does not match fragment schema "${this.#schema.name}".`);
293
+ return new DatabaseFragmentDefinitionBuilder(this.#baseBuilder, this.#schema, this.#hooksFactory, registry, this.#registryResolver);
294
+ }
295
+ /**
110
296
  * Declare that this fragment uses a required service provided by the runtime.
111
297
  * Delegates to the base builder.
112
298
  */
113
299
  usesService(serviceName) {
114
- return new DatabaseFragmentDefinitionBuilder(this.#baseBuilder.usesService(serviceName), this.#schema, this.#namespace, this.#hooksFactory);
300
+ return new DatabaseFragmentDefinitionBuilder(this.#baseBuilder.usesService(serviceName), this.#schema, this.#hooksFactory, this.#syncRegistry, this.#registryResolver);
115
301
  }
116
302
  /**
117
303
  * Declare that this fragment uses an optional service provided by the runtime.
118
304
  * Delegates to the base builder.
119
305
  */
120
306
  usesOptionalService(serviceName) {
121
- return new DatabaseFragmentDefinitionBuilder(this.#baseBuilder.usesOptionalService(serviceName), this.#schema, this.#namespace, this.#hooksFactory);
307
+ return new DatabaseFragmentDefinitionBuilder(this.#baseBuilder.usesOptionalService(serviceName), this.#schema, this.#hooksFactory, this.#syncRegistry, this.#registryResolver);
122
308
  }
123
309
  /**
124
310
  * Build the final database fragment definition.
@@ -137,11 +323,34 @@ var DatabaseFragmentDefinitionBuilder = class DatabaseFragmentDefinitionBuilder
137
323
  userDeps = {};
138
324
  } else throw error;
139
325
  }
140
- const { db } = createDatabaseContext(context.options, this.#schema, this.#namespace);
326
+ const dbContext = createDatabaseContext(context.options, this.#schema);
327
+ const { db } = dbContext;
328
+ const namespace = resolveDatabaseNamespace(context.options, this.#schema);
329
+ const dryRun = process.env["FRAGNO_INIT_DRY_RUN"] === "true";
330
+ const isInternalFragment$1 = baseDef.name === "$fragno-internal-fragment";
331
+ if (!dryRun && !isInternalFragment$1 && this.#registryResolver) {
332
+ const registry = this.#registryResolver.getRegistryForAdapterSync(dbContext.databaseAdapter);
333
+ const outboxEnabled = context.options.outbox?.enabled ?? false;
334
+ registry.registerSchema({
335
+ name: this.#schema.name,
336
+ namespace,
337
+ version: this.#schema.version,
338
+ tables: Object.keys(this.#schema.tables).sort()
339
+ }, {
340
+ name: baseDef.name,
341
+ mountRoute: resolveMountRoute(baseDef.name, context.options.mountRoute)
342
+ }, { outboxEnabled });
343
+ if (this.#syncRegistry) registry.registerSyncCommands({
344
+ fragmentName: baseDef.name,
345
+ schemaName: this.#syncRegistry.schemaName,
346
+ namespace,
347
+ commands: this.#syncRegistry.commands
348
+ });
349
+ }
141
350
  const implicitDeps = {
142
- db,
351
+ databaseAdapter: dbContext.databaseAdapter,
143
352
  schema: this.#schema,
144
- namespace: this.#namespace,
353
+ namespace,
145
354
  createUnitOfWork: () => db.createUnitOfWork()
146
355
  };
147
356
  return {
@@ -150,57 +359,238 @@ var DatabaseFragmentDefinitionBuilder = class DatabaseFragmentDefinitionBuilder
150
359
  };
151
360
  };
152
361
  const builderWithStorage = this.#baseBuilder.withExternalRequestStorage(({ options }) => {
153
- return createDatabaseContext(options, this.#schema, this.#namespace).databaseAdapter.contextStorage;
362
+ return createDatabaseContext(options, this.#schema).databaseAdapter.contextStorage;
154
363
  }).withRequestStorage(({ options }) => {
155
- return { uow: createDatabaseContext(options, this.#schema, this.#namespace).db.createUnitOfWork() };
364
+ return { uow: createDatabaseContext(options, this.#schema).db.createBaseUnitOfWork() };
156
365
  });
157
- const internalFragmentFactory = baseDef.linkedFragments?.["_fragno_internal"];
158
- return {
159
- ...builderWithStorage.withThisContext(({ storage, config, options }) => {
160
- const hooksConfig = this.#hooksFactory ? {
161
- hooks: this.#hooksFactory({
162
- config,
163
- options
164
- }),
165
- namespace: this.#namespace,
166
- internalFragment: internalFragmentFactory({
167
- config,
168
- options
169
- })
170
- } : void 0;
171
- function serviceTx(schema) {
172
- const uow = storage.getStore()?.uow;
173
- if (!uow) throw new Error("No UnitOfWork in context. Service must be called within a route handler OR using `withUnitOfWork`.");
174
- return createServiceTxBuilder(schema, uow, hooksConfig?.hooks);
175
- }
176
- const serviceContext = { serviceTx };
177
- function handlerTx(execOptions) {
178
- const currentStorage = storage.getStore();
179
- if (!currentStorage) throw new Error("No storage in context. Handler must be called within a request context.");
366
+ const hooksConfigCache = /* @__PURE__ */ new WeakMap();
367
+ const createHooksConfig = (context) => {
368
+ if (!this.#hooksFactory) return;
369
+ const depsKey = typeof context.deps === "object" && context.deps !== null ? context.deps : void 0;
370
+ const namespaceKey = resolveDatabaseNamespace(context.options, this.#schema) ?? this.#schema.name;
371
+ const durableHooksOptions = context.options.durableHooks;
372
+ DurableHooksLogger.configure(durableHooksOptions?.logging, namespaceKey);
373
+ const cachedHooksConfig = depsKey ? hooksConfigCache.get(depsKey) : void 0;
374
+ if (cachedHooksConfig) {
375
+ if (!cachedHooksConfig.hooks && context.services) cachedHooksConfig.hooks = this.#hooksFactory({
376
+ config: context.config,
377
+ options: context.options,
378
+ deps: context.deps,
379
+ services: context.services,
380
+ serviceDeps: context.serviceDeps ?? {}
381
+ });
382
+ return cachedHooksConfig;
383
+ }
384
+ const autoSchedule = durableHooksOptions?.autoSchedule !== false;
385
+ const baseAdapter = resolveDatabaseAdapter(context.options, this.#schema);
386
+ const hookAdapter = baseAdapter.getHookProcessingAdapter?.() ?? baseAdapter;
387
+ const hookOptions = hookAdapter === baseAdapter ? context.options : {
388
+ ...context.options,
389
+ databaseAdapter: hookAdapter
390
+ };
391
+ const registryResolver = this.#registryResolver;
392
+ if (!registryResolver) throw new Error("Adapter registry resolver is missing for durable hooks.");
393
+ const dbContextForHooks = createDatabaseContext(hookOptions, this.#schema);
394
+ const hookContextStorage = dbContextForHooks.databaseAdapter.contextStorage;
395
+ const hooksConfig = {
396
+ hooks: context.services ? this.#hooksFactory({
397
+ config: context.config,
398
+ options: context.options,
399
+ deps: context.deps,
400
+ services: context.services,
401
+ serviceDeps: context.serviceDeps ?? {}
402
+ }) : void 0,
403
+ namespace: namespaceKey,
404
+ internalFragment: registryResolver.getInternalFragment(hookAdapter),
405
+ autoSchedule,
406
+ handlerTx: (execOptions) => {
180
407
  const userOnBeforeMutate = execOptions?.onBeforeMutate;
181
408
  const userOnAfterMutate = execOptions?.onAfterMutate;
409
+ const planMode = execOptions?.planMode ?? false;
410
+ let storageRef = null;
411
+ const getHookWaitUntil = () => {
412
+ if (!hookContextStorage.hasStore()) return;
413
+ return hookContextStorage.getStore()[requestWaitUntilSymbol];
414
+ };
182
415
  return createHandlerTxBuilder({
183
416
  ...execOptions,
184
417
  createUnitOfWork: () => {
185
- currentStorage.uow.reset();
186
- if (hooksConfig) currentStorage.uow.registerSchema(hooksConfig.internalFragment.$internal.deps.schema, hooksConfig.internalFragment.$internal.deps.namespace);
187
- return currentStorage.uow;
418
+ const baseUow = dbContextForHooks.db.createBaseUnitOfWork();
419
+ baseUow.registerSchema(hooksConfig.internalFragment.$internal.deps.schema, hooksConfig.internalFragment.$internal.deps.namespace);
420
+ if (storageRef) storageRef.uow = baseUow;
421
+ return baseUow;
188
422
  },
189
423
  onBeforeMutate: (uow) => {
190
- if (hooksConfig) prepareHookMutations(uow, hooksConfig);
424
+ if (!planMode) prepareHookMutations(uow, hooksConfig.internalFragment, hooksConfig.defaultRetryPolicy);
191
425
  if (userOnBeforeMutate) userOnBeforeMutate(uow);
192
426
  },
193
427
  onAfterMutate: async (uow) => {
194
- if (hooksConfig) await processHooks(hooksConfig);
428
+ notifyDurableHooksAfterMutate({
429
+ uow,
430
+ hooksConfig,
431
+ internalFragment: hooksConfig.internalFragment,
432
+ autoSchedule,
433
+ planMode,
434
+ logContext: {
435
+ source: "hook",
436
+ waitUntil: getHookWaitUntil()
437
+ }
438
+ });
195
439
  if (userOnAfterMutate) await userOnAfterMutate(uow);
196
440
  }
197
- });
198
- }
199
- return {
200
- serviceContext,
201
- handlerContext: { handlerTx }
441
+ }, void 0, (run) => hookContextStorage.runWithInitializer(() => {
442
+ const inheritedWaitUntil = getHookWaitUntil();
443
+ storageRef = { uow: null };
444
+ if (inheritedWaitUntil) storageRef[requestWaitUntilSymbol] = inheritedWaitUntil;
445
+ return storageRef;
446
+ }, run));
447
+ },
448
+ stuckProcessingTimeoutMinutes: durableHooksOptions?.stuckProcessingTimeoutMinutes,
449
+ onStuckProcessingHooks: durableHooksOptions?.onStuckProcessingHooks
450
+ };
451
+ hooksConfig.runner = createDurableHooksRunner(hooksConfig);
452
+ registerDurableHooksRuntime(hooksConfig);
453
+ if (depsKey) hooksConfigCache.set(depsKey, hooksConfig);
454
+ return hooksConfig;
455
+ };
456
+ const isInternalFragment = baseDef.name === "$fragno-internal-fragment";
457
+ const finalDef = builderWithStorage.withThisContext(({ storage, config, options, deps }) => {
458
+ const hooksConfig = createHooksConfig({
459
+ config,
460
+ options,
461
+ deps
462
+ });
463
+ const autoSchedule = options.durableHooks?.autoSchedule !== false;
464
+ const registryResolver = this.#registryResolver;
465
+ const databaseAdapter = deps.databaseAdapter ?? resolveDatabaseAdapter(options, this.#schema);
466
+ const internalFragment = isInternalFragment ? void 0 : hooksConfig?.internalFragment ?? registryResolver?.getInternalFragment(databaseAdapter);
467
+ function serviceTx(schema) {
468
+ const uow = storage.getStore()?.uow;
469
+ if (!uow) throw new Error("No UnitOfWork in context. Service must be called within a route handler OR using `withUnitOfWork`.");
470
+ return createServiceTxBuilder(schema, uow, hooksConfig?.hooks);
471
+ }
472
+ const serviceContext = { serviceTx };
473
+ function handlerTx(execOptions) {
474
+ const currentStorage = storage.getStore();
475
+ if (!currentStorage) throw new Error("No storage in context. Handler must be called within a request context.");
476
+ const userOnBeforeMutate = execOptions?.onBeforeMutate;
477
+ const userOnAfterMutate = execOptions?.onAfterMutate;
478
+ const userOnAfterRetrieve = execOptions?.onAfterRetrieve;
479
+ const planMode = execOptions?.planMode ?? false;
480
+ const roundtripGuard = isRouteRequest(currentStorage) ? resolveDbRoundtripGuard(options) : null;
481
+ const roundtripState = roundtripGuard ? getDbRoundtripGuardState(currentStorage, roundtripGuard) : null;
482
+ const routeInfo = currentStorage[requestRouteSymbol];
483
+ const routeWaitUntil = currentStorage[requestWaitUntilSymbol];
484
+ const routeLabel = routeInfo && routeInfo.method && routeInfo.path ? `${routeInfo.method} ${routeInfo.path}` : null;
485
+ const routeSuffix = routeLabel ? ` (route: ${routeLabel})` : "";
486
+ const buildRoundtripError = (kind) => new FragnoApiError({
487
+ message: `[fragno-db] Fragment "${baseDef.name}" executed more than ${roundtripState?.maxRoundtrips ?? 1} ${kind} database roundtrip(s) in a single request${routeSuffix}. Combine reads/writes into one handlerTx() or increase dbRoundtripGuard. See ${roundtripGuardDocsUrl}`,
488
+ code: "DB_ROUNDTRIP_LIMIT_EXCEEDED"
489
+ }, 500);
490
+ const roundtripExecutionState = roundtripState ? {
491
+ countedRetrieve: false,
492
+ countedMutate: false
493
+ } : null;
494
+ const resetRoundtripExecutionState = () => {
495
+ if (!roundtripExecutionState) return;
496
+ roundtripExecutionState.countedRetrieve = false;
497
+ roundtripExecutionState.countedMutate = false;
202
498
  };
203
- }).build(),
499
+ const guardOnAfterRetrieve = roundtripState ? async (uow, results) => {
500
+ if (roundtripExecutionState && !roundtripExecutionState.countedRetrieve && uow.getRetrievalOperations().length > 0) {
501
+ roundtripExecutionState.countedRetrieve = true;
502
+ roundtripState.retrieveCount += 1;
503
+ if (roundtripState.retrieveCount > roundtripState.maxRoundtrips) throw buildRoundtripError("retrieve");
504
+ }
505
+ if (userOnAfterRetrieve) await userOnAfterRetrieve(uow, results);
506
+ } : userOnAfterRetrieve;
507
+ const builder = createHandlerTxBuilder({
508
+ ...execOptions,
509
+ createUnitOfWork: () => {
510
+ currentStorage.uow.reset();
511
+ if (internalFragment) currentStorage.uow.registerSchema(internalFragment.$internal.deps.schema, internalFragment.$internal.deps.namespace);
512
+ return currentStorage.uow;
513
+ },
514
+ onBeforeMutate: (uow) => {
515
+ if (internalFragment && !planMode) prepareHookMutations(uow, internalFragment, hooksConfig?.defaultRetryPolicy);
516
+ if (userOnBeforeMutate) userOnBeforeMutate(uow);
517
+ if (roundtripState && roundtripExecutionState && !roundtripExecutionState.countedMutate && uow.getMutationOperations().length > 0) {
518
+ roundtripExecutionState.countedMutate = true;
519
+ roundtripState.mutateCount += 1;
520
+ if (roundtripState.mutateCount > roundtripState.maxRoundtrips) throw buildRoundtripError("mutate");
521
+ }
522
+ },
523
+ onAfterRetrieve: guardOnAfterRetrieve,
524
+ onAfterMutate: async (uow) => {
525
+ notifyDurableHooksAfterMutate({
526
+ uow,
527
+ hooksConfig,
528
+ internalFragment,
529
+ autoSchedule,
530
+ planMode,
531
+ logContext: {
532
+ route: routeLabel,
533
+ source: "request",
534
+ waitUntil: routeWaitUntil
535
+ }
536
+ });
537
+ if (hooksConfig && !planMode) {
538
+ const runtimeState = getDurableHooksRuntimeByConfig(hooksConfig);
539
+ if (runtimeState && !runtimeState.dispatcherRegistered && !runtimeState.dispatcherWarningEmitted) {
540
+ if (uow.getTriggeredHooks().some((hook) => hook.namespace === hooksConfig.namespace)) {
541
+ runtimeState.dispatcherWarningEmitted = true;
542
+ DurableHooksLogger.warn("Durable hooks dispatcher not configured for fragment", {
543
+ namespace: hooksConfig.namespace,
544
+ fields: { guidance: "Hooks will only run during requests; scheduled/retry hooks may stall. Create a dispatcher with createDurableHooksProcessor([...]) from `@fragno-dev/db/dispatchers/node` or `@fragno-dev/db/dispatchers/cloudflare-do`." }
545
+ });
546
+ }
547
+ }
548
+ }
549
+ if (userOnAfterMutate) await userOnAfterMutate(uow);
550
+ }
551
+ });
552
+ if (roundtripState) return wrapHandlerTxBuilderWithRoundtripGuard(builder, resetRoundtripExecutionState);
553
+ return builder;
554
+ }
555
+ function callServices(serviceCalls) {
556
+ let callWasArray = false;
557
+ return handlerTx().withServiceCalls(() => {
558
+ const calls = serviceCalls();
559
+ callWasArray = Array.isArray(calls);
560
+ return callWasArray ? calls : [calls];
561
+ }).execute().then((result) => callWasArray ? result : result[0]);
562
+ }
563
+ return {
564
+ serviceContext,
565
+ handlerContext: {
566
+ handlerTx,
567
+ callServices
568
+ }
569
+ };
570
+ }).build();
571
+ if (this.#hooksFactory) finalDef.internalDataFactory = ({ config, options, deps, services, serviceDeps }) => {
572
+ const hooksConfig = createHooksConfig({
573
+ config,
574
+ options,
575
+ deps,
576
+ services,
577
+ serviceDeps
578
+ });
579
+ if (!hooksConfig) return {};
580
+ return { durableHooksToken: registerDurableHooksRuntime(hooksConfig) };
581
+ };
582
+ if (this.#registryResolver) {
583
+ const registryInternalRoutes = ({ deps }) => {
584
+ const databaseAdapter = deps.databaseAdapter;
585
+ if (!databaseAdapter) throw new Error("Database adapter is missing for internal routes.");
586
+ const internalFragment = this.#registryResolver.getInternalFragment(databaseAdapter);
587
+ if (!internalFragment) return [];
588
+ return internalFragment.routes ?? [];
589
+ };
590
+ finalDef.internalRoutes = [...finalDef.internalRoutes ?? [], registryInternalRoutes];
591
+ }
592
+ return {
593
+ ...finalDef,
204
594
  dependencies
205
595
  };
206
596
  }