@fragno-dev/db 0.3.0 → 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 (516) hide show
  1. package/.turbo/turbo-build.log +327 -160
  2. package/CHANGELOG.md +74 -0
  3. package/README.md +24 -0
  4. package/dist/adapters/adapters.d.ts +1 -1
  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/generic-sql-adapter.d.ts +0 -3
  8. package/dist/adapters/generic-sql/generic-sql-adapter.d.ts.map +1 -1
  9. package/dist/adapters/generic-sql/generic-sql-adapter.js +11 -12
  10. package/dist/adapters/generic-sql/generic-sql-adapter.js.map +1 -1
  11. package/dist/adapters/generic-sql/generic-sql-uow-executor.js +46 -6
  12. package/dist/adapters/generic-sql/generic-sql-uow-executor.js.map +1 -1
  13. package/dist/adapters/generic-sql/migration/cold-kysely.js.map +1 -1
  14. package/dist/adapters/generic-sql/migration/dialect/mysql.js +1 -1
  15. package/dist/adapters/generic-sql/migration/dialect/mysql.js.map +1 -1
  16. package/dist/adapters/generic-sql/migration/dialect/postgres.js +1 -1
  17. package/dist/adapters/generic-sql/migration/dialect/postgres.js.map +1 -1
  18. package/dist/adapters/generic-sql/migration/dialect/sqlite.js +185 -19
  19. package/dist/adapters/generic-sql/migration/dialect/sqlite.js.map +1 -1
  20. package/dist/adapters/generic-sql/migration/executor.d.ts.map +1 -1
  21. package/dist/adapters/generic-sql/migration/executor.js +30 -3
  22. package/dist/adapters/generic-sql/migration/executor.js.map +1 -1
  23. package/dist/adapters/generic-sql/migration/prepared-migrations.d.ts.map +1 -1
  24. package/dist/adapters/generic-sql/migration/prepared-migrations.js +3 -3
  25. package/dist/adapters/generic-sql/migration/prepared-migrations.js.map +1 -1
  26. package/dist/adapters/generic-sql/migration/sql-generator.js +1 -1
  27. package/dist/adapters/generic-sql/migration/sql-generator.js.map +1 -1
  28. package/dist/adapters/generic-sql/query/create-sql-query-compiler.js +1 -1
  29. package/dist/adapters/generic-sql/query/create-sql-query-compiler.js.map +1 -1
  30. package/dist/adapters/generic-sql/query/cursor-utils.js.map +1 -1
  31. package/dist/adapters/generic-sql/query/db-now-sql.js +27 -0
  32. package/dist/adapters/generic-sql/query/db-now-sql.js.map +1 -0
  33. package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js +9 -6
  34. package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js.map +1 -1
  35. package/dist/adapters/generic-sql/query/select-builder.js.map +1 -1
  36. package/dist/adapters/generic-sql/query/sql-query-compiler.js +37 -9
  37. package/dist/adapters/generic-sql/query/sql-query-compiler.js.map +1 -1
  38. package/dist/adapters/generic-sql/query/where-builder.js +24 -20
  39. package/dist/adapters/generic-sql/query/where-builder.js.map +1 -1
  40. package/dist/adapters/generic-sql/uow-decoder.js +1 -1
  41. package/dist/adapters/generic-sql/uow-decoder.js.map +1 -1
  42. package/dist/adapters/generic-sql/uow-encoder.js +8 -9
  43. package/dist/adapters/generic-sql/uow-encoder.js.map +1 -1
  44. package/dist/adapters/in-memory/condition-evaluator.js +10 -6
  45. package/dist/adapters/in-memory/condition-evaluator.js.map +1 -1
  46. package/dist/adapters/in-memory/in-memory-adapter.d.ts.map +1 -1
  47. package/dist/adapters/in-memory/in-memory-adapter.js +45 -25
  48. package/dist/adapters/in-memory/in-memory-adapter.js.map +1 -1
  49. package/dist/adapters/in-memory/in-memory-uow.js +236 -13
  50. package/dist/adapters/in-memory/in-memory-uow.js.map +1 -1
  51. package/dist/adapters/in-memory/options.d.ts +2 -0
  52. package/dist/adapters/in-memory/options.d.ts.map +1 -1
  53. package/dist/adapters/in-memory/options.js +3 -2
  54. package/dist/adapters/in-memory/options.js.map +1 -1
  55. package/dist/adapters/in-memory/reference-resolution.js.map +1 -1
  56. package/dist/adapters/in-memory/store.js +1 -1
  57. package/dist/adapters/in-memory/store.js.map +1 -1
  58. package/dist/adapters/shared/from-unit-of-work-compiler.js +51 -24
  59. package/dist/adapters/shared/from-unit-of-work-compiler.js.map +1 -1
  60. package/dist/adapters/shared/uow-operation-compiler.js.map +1 -1
  61. package/dist/browser/adapters/adapters.d.ts +61 -0
  62. package/dist/browser/adapters/adapters.d.ts.map +1 -0
  63. package/dist/browser/adapters/generic-sql/migration/executor.d.ts +15 -0
  64. package/dist/browser/adapters/generic-sql/migration/executor.d.ts.map +1 -0
  65. package/dist/browser/adapters/generic-sql/migration/prepared-migrations.d.ts +66 -0
  66. package/dist/browser/adapters/generic-sql/migration/prepared-migrations.d.ts.map +1 -0
  67. package/dist/browser/adapters/generic-sql/sqlite-storage.d.ts +11 -0
  68. package/dist/browser/adapters/generic-sql/sqlite-storage.d.ts.map +1 -0
  69. package/dist/browser/adapters/in-memory/in-memory-adapter.d.ts +5 -0
  70. package/dist/browser/adapters/in-memory/index.d.ts +2 -0
  71. package/dist/browser/adapters/in-memory/options.d.ts +1 -0
  72. package/dist/browser/db-fragment-definition-builder.d.ts +237 -0
  73. package/dist/browser/db-fragment-definition-builder.d.ts.map +1 -0
  74. package/dist/browser/durable-hooks.d.ts +3 -0
  75. package/dist/browser/fragments/internal-fragment.d.ts +317 -0
  76. package/dist/browser/fragments/internal-fragment.d.ts.map +1 -0
  77. package/dist/browser/fragments/internal-fragment.schema.d.ts +1 -0
  78. package/dist/browser/hooks/durable-hooks-logger.d.ts +10 -0
  79. package/dist/browser/hooks/durable-hooks-logger.d.ts.map +1 -0
  80. package/dist/browser/hooks/hooks.d.ts +146 -0
  81. package/dist/browser/hooks/hooks.d.ts.map +1 -0
  82. package/dist/browser/id.js +1 -0
  83. package/dist/browser/internal/adapter-registry.d.ts +4 -0
  84. package/dist/browser/internal/outbox-state.d.ts +2 -0
  85. package/dist/browser/mod.d.ts +15 -0
  86. package/dist/browser/mod.d.ts.map +1 -0
  87. package/dist/browser/mod.js +17 -0
  88. package/dist/browser/mod.js.map +1 -0
  89. package/dist/browser/mod2.d.ts +48 -0
  90. package/dist/browser/mod2.d.ts.map +1 -0
  91. package/dist/browser/naming/sql-naming.d.ts +19 -0
  92. package/dist/browser/naming/sql-naming.d.ts.map +1 -0
  93. package/dist/browser/outbox/outbox.d.ts +21 -0
  94. package/dist/browser/outbox/outbox.d.ts.map +1 -0
  95. package/dist/browser/query/column-defaults.js +1 -0
  96. package/dist/browser/query/condition-builder.d.ts +44 -0
  97. package/dist/browser/query/condition-builder.d.ts.map +1 -0
  98. package/dist/browser/query/condition-builder.js +97 -0
  99. package/dist/browser/query/condition-builder.js.map +1 -0
  100. package/dist/browser/query/cursor.d.ts +105 -0
  101. package/dist/browser/query/cursor.d.ts.map +1 -0
  102. package/dist/browser/query/cursor.js +150 -0
  103. package/dist/browser/query/cursor.js.map +1 -0
  104. package/dist/browser/query/db-now.d.ts +22 -0
  105. package/dist/browser/query/db-now.d.ts.map +1 -0
  106. package/dist/browser/query/db-now.js +33 -0
  107. package/dist/browser/query/db-now.js.map +1 -0
  108. package/dist/browser/query/orm/orm.d.ts +18 -0
  109. package/dist/browser/query/orm/orm.d.ts.map +1 -0
  110. package/dist/browser/query/simple-query-interface.d.ts +108 -0
  111. package/dist/browser/query/simple-query-interface.d.ts.map +1 -0
  112. package/dist/browser/query/unit-of-work/execute-unit-of-work.d.ts +423 -0
  113. package/dist/browser/query/unit-of-work/execute-unit-of-work.d.ts.map +1 -0
  114. package/dist/browser/query/unit-of-work/execute-unit-of-work.js +507 -0
  115. package/dist/browser/query/unit-of-work/execute-unit-of-work.js.map +1 -0
  116. package/dist/browser/query/unit-of-work/retry-policy.d.ts +23 -0
  117. package/dist/browser/query/unit-of-work/retry-policy.d.ts.map +1 -0
  118. package/dist/browser/query/unit-of-work/retry-policy.js +40 -0
  119. package/dist/browser/query/unit-of-work/retry-policy.js.map +1 -0
  120. package/dist/browser/query/unit-of-work/unit-of-work.d.ts +703 -0
  121. package/dist/browser/query/unit-of-work/unit-of-work.d.ts.map +1 -0
  122. package/dist/browser/query/unit-of-work/unit-of-work.js +1206 -0
  123. package/dist/browser/query/unit-of-work/unit-of-work.js.map +1 -0
  124. package/dist/browser/query/value-encoding.js +38 -0
  125. package/dist/browser/query/value-encoding.js.map +1 -0
  126. package/dist/browser/schema/create.d.ts +326 -0
  127. package/dist/browser/schema/create.d.ts.map +1 -0
  128. package/dist/browser/schema/create.js +89 -0
  129. package/dist/browser/schema/create.js.map +1 -0
  130. package/dist/browser/schema/generate-id.js +28 -0
  131. package/dist/browser/schema/generate-id.js.map +1 -0
  132. package/dist/browser/shared/providers.d.ts +6 -0
  133. package/dist/browser/shared/providers.d.ts.map +1 -0
  134. package/dist/browser/sql-driver/connection/connection-provider.d.ts +13 -0
  135. package/dist/browser/sql-driver/connection/connection-provider.d.ts.map +1 -0
  136. package/dist/browser/sql-driver/dialect-adapter/dialect-adapter.d.ts +7 -0
  137. package/dist/browser/sql-driver/dialect-adapter/dialect-adapter.d.ts.map +1 -0
  138. package/dist/browser/sql-driver/driver/runtime-driver.d.ts +23 -0
  139. package/dist/browser/sql-driver/driver/runtime-driver.d.ts.map +1 -0
  140. package/dist/browser/sql-driver/query-executor/plugin.d.ts +17 -0
  141. package/dist/browser/sql-driver/query-executor/plugin.d.ts.map +1 -0
  142. package/dist/browser/sql-driver/query-executor/query-executor.d.ts +36 -0
  143. package/dist/browser/sql-driver/query-executor/query-executor.d.ts.map +1 -0
  144. package/dist/browser/sql-driver/sql-driver-adapter.d.ts +29 -0
  145. package/dist/browser/sql-driver/sql-driver-adapter.d.ts.map +1 -0
  146. package/dist/browser/sql-driver/sql-driver.d.ts +38 -0
  147. package/dist/browser/sql-driver/sql-driver.d.ts.map +1 -0
  148. package/dist/browser/sync/commands.d.ts +15 -0
  149. package/dist/browser/sync/commands.d.ts.map +1 -0
  150. package/dist/browser/sync/commands.js +27 -0
  151. package/dist/browser/sync/commands.js.map +1 -0
  152. package/dist/browser/sync/types.d.ts +63 -0
  153. package/dist/browser/sync/types.d.ts.map +1 -0
  154. package/dist/browser/util/types.d.ts +8 -0
  155. package/dist/browser/util/types.d.ts.map +1 -0
  156. package/dist/browser/with-database.d.ts +29 -0
  157. package/dist/browser/with-database.d.ts.map +1 -0
  158. package/dist/client.d.ts +4 -0
  159. package/dist/client.js +5 -0
  160. package/dist/db-fragment-definition-builder.d.ts +85 -28
  161. package/dist/db-fragment-definition-builder.d.ts.map +1 -1
  162. package/dist/db-fragment-definition-builder.js +374 -46
  163. package/dist/db-fragment-definition-builder.js.map +1 -1
  164. package/dist/dispatchers/cloudflare-do/dispatcher.d.ts +20 -0
  165. package/dist/dispatchers/cloudflare-do/dispatcher.d.ts.map +1 -0
  166. package/dist/dispatchers/cloudflare-do/dispatcher.js +147 -0
  167. package/dist/dispatchers/cloudflare-do/dispatcher.js.map +1 -0
  168. package/dist/dispatchers/cloudflare-do/index.d.ts +5 -20
  169. package/dist/dispatchers/cloudflare-do/index.d.ts.map +1 -1
  170. package/dist/dispatchers/cloudflare-do/index.js +23 -55
  171. package/dist/dispatchers/cloudflare-do/index.js.map +1 -1
  172. package/dist/dispatchers/node/dispatcher.d.ts +14 -0
  173. package/dist/dispatchers/node/dispatcher.d.ts.map +1 -0
  174. package/dist/dispatchers/node/dispatcher.js +80 -0
  175. package/dist/dispatchers/node/dispatcher.js.map +1 -0
  176. package/dist/dispatchers/node/index.d.ts +5 -10
  177. package/dist/dispatchers/node/index.d.ts.map +1 -1
  178. package/dist/dispatchers/node/index.js +21 -53
  179. package/dist/dispatchers/node/index.js.map +1 -1
  180. package/dist/durable-hooks.d.ts +31 -0
  181. package/dist/durable-hooks.d.ts.map +1 -0
  182. package/dist/durable-hooks.js +23 -0
  183. package/dist/durable-hooks.js.map +1 -0
  184. package/dist/fragments/internal-fragment.d.ts +128 -27
  185. package/dist/fragments/internal-fragment.d.ts.map +1 -1
  186. package/dist/fragments/internal-fragment.js +125 -78
  187. package/dist/fragments/internal-fragment.js.map +1 -1
  188. package/dist/fragments/internal-fragment.routes.js +138 -3
  189. package/dist/fragments/internal-fragment.routes.js.map +1 -1
  190. package/dist/fragments/internal-fragment.schema.d.ts +7 -1
  191. package/dist/fragments/internal-fragment.schema.d.ts.map +1 -1
  192. package/dist/fragments/internal-fragment.schema.js +18 -1
  193. package/dist/fragments/internal-fragment.schema.js.map +1 -1
  194. package/dist/hooks/durable-hooks-logger.d.ts +10 -0
  195. package/dist/hooks/durable-hooks-logger.d.ts.map +1 -0
  196. package/dist/hooks/durable-hooks-logger.js +75 -0
  197. package/dist/hooks/durable-hooks-logger.js.map +1 -0
  198. package/dist/hooks/durable-hooks-processor.d.ts +1 -14
  199. package/dist/hooks/durable-hooks-processor.js +58 -10
  200. package/dist/hooks/durable-hooks-processor.js.map +1 -1
  201. package/dist/hooks/durable-hooks-runtime.js +44 -0
  202. package/dist/hooks/durable-hooks-runtime.js.map +1 -0
  203. package/dist/hooks/hooks.d.ts +60 -2
  204. package/dist/hooks/hooks.d.ts.map +1 -1
  205. package/dist/hooks/hooks.js +214 -53
  206. package/dist/hooks/hooks.js.map +1 -1
  207. package/dist/id.d.ts +2 -2
  208. package/dist/id.js +2 -2
  209. package/dist/internal/adapter-registry.d.ts +11 -0
  210. package/dist/internal/adapter-registry.d.ts.map +1 -0
  211. package/dist/internal/adapter-registry.js +135 -0
  212. package/dist/internal/adapter-registry.js.map +1 -0
  213. package/dist/internal/outbox-state.d.ts +2 -0
  214. package/dist/internal/outbox-state.js +26 -0
  215. package/dist/internal/outbox-state.js.map +1 -0
  216. package/dist/migration-engine/auto-from-schema.d.ts +33 -0
  217. package/dist/migration-engine/auto-from-schema.d.ts.map +1 -0
  218. package/dist/migration-engine/auto-from-schema.js +210 -27
  219. package/dist/migration-engine/auto-from-schema.js.map +1 -1
  220. package/dist/migration-engine/generation-engine.d.ts.map +1 -1
  221. package/dist/migration-engine/generation-engine.js +17 -5
  222. package/dist/migration-engine/generation-engine.js.map +1 -1
  223. package/dist/migration-engine/shared.d.ts +113 -0
  224. package/dist/migration-engine/shared.d.ts.map +1 -0
  225. package/dist/migration-engine/shared.js.map +1 -1
  226. package/dist/mod.d.ts +12 -11
  227. package/dist/mod.d.ts.map +1 -1
  228. package/dist/mod.js +10 -10
  229. package/dist/mod.js.map +1 -1
  230. package/dist/naming/sql-naming.d.ts.map +1 -1
  231. package/dist/naming/sql-naming.js.map +1 -1
  232. package/dist/outbox/outbox-builder.js.map +1 -1
  233. package/dist/outbox/outbox.d.ts +3 -1
  234. package/dist/outbox/outbox.d.ts.map +1 -1
  235. package/dist/outbox/outbox.js.map +1 -1
  236. package/dist/query/column-defaults.js.map +1 -1
  237. package/dist/query/condition-builder.d.ts +7 -1
  238. package/dist/query/condition-builder.d.ts.map +1 -1
  239. package/dist/query/condition-builder.js +5 -1
  240. package/dist/query/condition-builder.js.map +1 -1
  241. package/dist/query/cursor-client.d.ts +105 -0
  242. package/dist/query/cursor-client.d.ts.map +1 -0
  243. package/dist/query/cursor-client.js +165 -0
  244. package/dist/query/cursor-client.js.map +1 -0
  245. package/dist/query/cursor.d.ts.map +1 -1
  246. package/dist/query/cursor.js +7 -1
  247. package/dist/query/cursor.js.map +1 -1
  248. package/dist/query/db-now.d.ts +15 -1
  249. package/dist/query/db-now.d.ts.map +1 -1
  250. package/dist/query/db-now.js +30 -2
  251. package/dist/query/db-now.js.map +1 -1
  252. package/dist/query/orm/orm.js.map +1 -1
  253. package/dist/query/serialize/create-sql-serializer.js +2 -2
  254. package/dist/query/serialize/create-sql-serializer.js.map +1 -1
  255. package/dist/query/serialize/dialect/mysql-serializer.js.map +1 -1
  256. package/dist/query/serialize/dialect/postgres-serializer.js.map +1 -1
  257. package/dist/query/serialize/dialect/sqlite-serializer.js +6 -2
  258. package/dist/query/serialize/dialect/sqlite-serializer.js.map +1 -1
  259. package/dist/query/simple-query-interface.d.ts +7 -3
  260. package/dist/query/simple-query-interface.d.ts.map +1 -1
  261. package/dist/query/unit-of-work/execute-unit-of-work.d.ts +37 -2
  262. package/dist/query/unit-of-work/execute-unit-of-work.d.ts.map +1 -1
  263. package/dist/query/unit-of-work/execute-unit-of-work.js +39 -18
  264. package/dist/query/unit-of-work/execute-unit-of-work.js.map +1 -1
  265. package/dist/query/unit-of-work/unit-of-work.d.ts +42 -16
  266. package/dist/query/unit-of-work/unit-of-work.d.ts.map +1 -1
  267. package/dist/query/unit-of-work/unit-of-work.js +50 -6
  268. package/dist/query/unit-of-work/unit-of-work.js.map +1 -1
  269. package/dist/query/value-decoding.js +8 -1
  270. package/dist/query/value-decoding.js.map +1 -1
  271. package/dist/query/value-encoding.js.map +1 -1
  272. package/dist/schema/create.d.ts +69 -25
  273. package/dist/schema/create.d.ts.map +1 -1
  274. package/dist/schema/create.js +91 -16
  275. package/dist/schema/create.js.map +1 -1
  276. package/dist/schema/type-conversion/create-sql-type-mapper.js +1 -1
  277. package/dist/schema/type-conversion/create-sql-type-mapper.js.map +1 -1
  278. package/dist/schema/type-conversion/dialect/sqlite.js.map +1 -1
  279. package/dist/schema/validator.d.ts.map +1 -1
  280. package/dist/schema/validator.js.map +1 -1
  281. package/dist/schema-output/drizzle.d.ts.map +1 -1
  282. package/dist/schema-output/drizzle.js +8 -6
  283. package/dist/schema-output/drizzle.js.map +1 -1
  284. package/dist/schema-output/prisma.d.ts.map +1 -1
  285. package/dist/schema-output/prisma.js +21 -10
  286. package/dist/schema-output/prisma.js.map +1 -1
  287. package/dist/sql-driver/dialects/durable-object-dialect.js +3 -9
  288. package/dist/sql-driver/dialects/durable-object-dialect.js.map +1 -1
  289. package/dist/sql-driver/query-executor/default-query-executor.js.map +1 -1
  290. package/dist/sql-driver/query-executor/query-executor-base.js.map +1 -1
  291. package/dist/sql-driver/sql-driver-adapter.js.map +1 -1
  292. package/dist/sql-driver/sql.js.map +1 -1
  293. package/dist/sync/commands.d.ts +15 -0
  294. package/dist/sync/commands.d.ts.map +1 -0
  295. package/dist/sync/commands.js +27 -0
  296. package/dist/sync/commands.js.map +1 -0
  297. package/dist/sync/index.d.ts +4 -0
  298. package/dist/sync/index.js +4 -0
  299. package/dist/sync/read-tracking.d.ts +25 -0
  300. package/dist/sync/read-tracking.d.ts.map +1 -0
  301. package/dist/sync/read-tracking.js +148 -0
  302. package/dist/sync/read-tracking.js.map +1 -0
  303. package/dist/sync/submit.js +213 -0
  304. package/dist/sync/submit.js.map +1 -0
  305. package/dist/sync/types.d.ts +63 -0
  306. package/dist/sync/types.d.ts.map +1 -0
  307. package/dist/util/default-database-adapter.js +6 -1
  308. package/dist/util/default-database-adapter.js.map +1 -1
  309. package/dist/with-database.d.ts +3 -6
  310. package/dist/with-database.d.ts.map +1 -1
  311. package/dist/with-database.js +7 -15
  312. package/dist/with-database.js.map +1 -1
  313. package/package.json +33 -41
  314. package/src/adapters/adapters.ts +5 -4
  315. package/src/adapters/drizzle/migrate-drizzle.test.ts +46 -9
  316. package/src/adapters/drizzle/migration-parity-drizzle-kit.test.ts +5 -3
  317. package/src/adapters/drizzle/test-utils.ts +2 -1
  318. package/src/adapters/generic-sql/generic-sql-adapter.test.ts +5 -3
  319. package/src/adapters/generic-sql/generic-sql-adapter.ts +21 -24
  320. package/src/adapters/generic-sql/generic-sql-uow-executor.test.ts +1 -0
  321. package/src/adapters/generic-sql/generic-sql-uow-executor.ts +81 -15
  322. package/src/adapters/generic-sql/migration/adapter-migration-parity.test.ts +4 -2
  323. package/src/adapters/generic-sql/migration/cold-kysely.ts +1 -0
  324. package/src/adapters/generic-sql/migration/dialect/mysql.test.ts +3 -2
  325. package/src/adapters/generic-sql/migration/dialect/mysql.ts +1 -0
  326. package/src/adapters/generic-sql/migration/dialect/postgres.test.ts +5 -4
  327. package/src/adapters/generic-sql/migration/dialect/postgres.ts +2 -1
  328. package/src/adapters/generic-sql/migration/dialect/sqlite.test.ts +795 -3
  329. package/src/adapters/generic-sql/migration/dialect/sqlite.ts +385 -57
  330. package/src/adapters/generic-sql/migration/executor.test.ts +52 -0
  331. package/src/adapters/generic-sql/migration/executor.ts +47 -4
  332. package/src/adapters/generic-sql/migration/prepared-migrations.test.ts +117 -14
  333. package/src/adapters/generic-sql/migration/prepared-migrations.ts +9 -8
  334. package/src/adapters/generic-sql/migration/sql-generator.ts +5 -3
  335. package/src/adapters/generic-sql/query/create-sql-query-compiler.ts +3 -3
  336. package/src/adapters/generic-sql/query/cursor-utils.test.ts +3 -2
  337. package/src/adapters/generic-sql/query/cursor-utils.ts +1 -1
  338. package/src/adapters/generic-sql/query/db-now-sql.ts +49 -0
  339. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.test.ts +144 -8
  340. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.ts +16 -17
  341. package/src/adapters/generic-sql/query/select-builder.test.ts +1 -0
  342. package/src/adapters/generic-sql/query/select-builder.ts +2 -2
  343. package/src/adapters/generic-sql/query/sql-query-compiler.test.ts +24 -5
  344. package/src/adapters/generic-sql/query/sql-query-compiler.ts +83 -13
  345. package/src/adapters/generic-sql/query/where-builder.test.ts +7 -5
  346. package/src/adapters/generic-sql/query/where-builder.ts +48 -29
  347. package/src/adapters/generic-sql/sql-adapter-pglite-migrations.test.ts +6 -15
  348. package/src/adapters/generic-sql/sql-adapter-pglite-pagination.test.ts +52 -7
  349. package/src/adapters/generic-sql/sql-adapter-pglite-queries.test.ts +9 -6
  350. package/src/adapters/generic-sql/sql-adapter-sqlite3-driver.test.ts +273 -5
  351. package/src/adapters/generic-sql/sql-adapter-sqlite3-uow.test.ts +123 -6
  352. package/src/adapters/generic-sql/sql-adapter-sqlocal.test.ts +4 -2
  353. package/src/adapters/generic-sql/uow-decoder.test.ts +4 -3
  354. package/src/adapters/generic-sql/uow-decoder.ts +3 -3
  355. package/src/adapters/generic-sql/uow-encoder.test.ts +4 -2
  356. package/src/adapters/generic-sql/uow-encoder.ts +14 -18
  357. package/src/adapters/in-memory/condition-evaluator.test.ts +2 -1
  358. package/src/adapters/in-memory/condition-evaluator.ts +9 -4
  359. package/src/adapters/in-memory/in-memory-adapter.ts +155 -44
  360. package/src/adapters/in-memory/in-memory-uow.mutations.test.ts +50 -2
  361. package/src/adapters/in-memory/in-memory-uow.retrieval.test.ts +158 -3
  362. package/src/adapters/in-memory/in-memory-uow.ts +402 -26
  363. package/src/adapters/in-memory/options.test.ts +1 -0
  364. package/src/adapters/in-memory/options.ts +5 -1
  365. package/src/adapters/in-memory/outbox.test.ts +361 -0
  366. package/src/adapters/in-memory/reference-resolution.test.ts +3 -2
  367. package/src/adapters/in-memory/reference-resolution.ts +2 -2
  368. package/src/adapters/in-memory/sorted-array-index.test.ts +1 -0
  369. package/src/adapters/in-memory/store.test.ts +1 -0
  370. package/src/adapters/in-memory/store.ts +3 -3
  371. package/src/adapters/in-memory/value-normalization.test.ts +1 -0
  372. package/src/adapters/prisma/prisma-adapter-sqlite3.test.ts +51 -7
  373. package/src/adapters/shared/from-unit-of-work-compiler.ts +156 -46
  374. package/src/adapters/shared/uow-operation-compiler.ts +3 -3
  375. package/src/browser/mod.ts +64 -0
  376. package/src/client.ts +19 -0
  377. package/src/db-fragment-definition-builder.test.ts +821 -47
  378. package/src/db-fragment-definition-builder.ts +857 -110
  379. package/src/db-fragment-instantiator.test.ts +114 -90
  380. package/src/db-fragment-integration.test.ts +9 -6
  381. package/src/dispatchers/cloudflare-do/dispatcher.ts +204 -0
  382. package/src/dispatchers/cloudflare-do/index.test.ts +145 -12
  383. package/src/dispatchers/cloudflare-do/index.ts +49 -90
  384. package/src/dispatchers/node/dispatcher.ts +112 -0
  385. package/src/dispatchers/node/index.test.ts +43 -14
  386. package/src/dispatchers/node/index.ts +38 -75
  387. package/src/durable-hooks.test.ts +80 -0
  388. package/src/durable-hooks.ts +67 -0
  389. package/src/fragments/internal-fragment.routes.test.ts +570 -0
  390. package/src/fragments/internal-fragment.routes.ts +297 -5
  391. package/src/fragments/internal-fragment.schema.ts +45 -1
  392. package/src/fragments/internal-fragment.test.ts +223 -251
  393. package/src/fragments/internal-fragment.ts +278 -154
  394. package/src/hooks/durable-hooks-logger.ts +126 -0
  395. package/src/hooks/durable-hooks-processor.pglite.test.ts +87 -0
  396. package/src/hooks/durable-hooks-processor.test.ts +179 -14
  397. package/src/hooks/durable-hooks-processor.ts +120 -14
  398. package/src/hooks/durable-hooks-runtime.test.ts +65 -0
  399. package/src/hooks/durable-hooks-runtime.ts +81 -0
  400. package/src/hooks/hooks.test.ts +314 -53
  401. package/src/hooks/hooks.ts +360 -81
  402. package/src/id.test.ts +34 -0
  403. package/src/id.ts +1 -3
  404. package/src/internal/adapter-registry.test.ts +93 -0
  405. package/src/internal/adapter-registry.ts +239 -0
  406. package/src/internal/outbox-state.ts +43 -0
  407. package/src/migration-engine/auto-from-schema.test.ts +93 -0
  408. package/src/migration-engine/auto-from-schema.ts +360 -42
  409. package/src/migration-engine/create.test.ts +2 -1
  410. package/src/migration-engine/create.ts +1 -1
  411. package/src/migration-engine/generation-engine.test.ts +66 -9
  412. package/src/migration-engine/generation-engine.ts +31 -10
  413. package/src/migration-engine/shared.ts +13 -0
  414. package/src/mod.ts +45 -27
  415. package/src/naming/sql-naming.ts +1 -0
  416. package/src/outbox/outbox-builder.ts +2 -2
  417. package/src/outbox/outbox.test.ts +216 -45
  418. package/src/outbox/outbox.ts +3 -1
  419. package/src/query/column-defaults.ts +1 -1
  420. package/src/query/condition-builder.test.ts +15 -0
  421. package/src/query/condition-builder.ts +7 -0
  422. package/src/query/cursor-client.test.ts +70 -0
  423. package/src/query/cursor-client.ts +263 -0
  424. package/src/query/cursor.test.ts +3 -2
  425. package/src/query/cursor.ts +15 -3
  426. package/src/query/db-now.ts +69 -2
  427. package/src/query/orm/orm.ts +2 -2
  428. package/src/query/query-type.test.ts +2 -1
  429. package/src/query/serialize/create-sql-serializer.ts +3 -3
  430. package/src/query/serialize/dialect/mysql-serializer.ts +1 -1
  431. package/src/query/serialize/dialect/postgres-serializer.ts +1 -1
  432. package/src/query/serialize/dialect/sqlite-serializer.test.ts +39 -2
  433. package/src/query/serialize/dialect/sqlite-serializer.ts +18 -5
  434. package/src/query/simple-query-interface.ts +10 -4
  435. package/src/query/unit-of-work/execute-unit-of-work.test.ts +347 -9
  436. package/src/query/unit-of-work/execute-unit-of-work.ts +63 -20
  437. package/src/query/unit-of-work/retry-policy.test.ts +1 -0
  438. package/src/query/unit-of-work/tx-builder.test.ts +73 -1
  439. package/src/query/unit-of-work/unit-of-work-coordinator.test.ts +5 -4
  440. package/src/query/unit-of-work/unit-of-work-types.test.ts +41 -11
  441. package/src/query/unit-of-work/unit-of-work.test.ts +28 -2
  442. package/src/query/unit-of-work/unit-of-work.ts +105 -19
  443. package/src/query/value-decoding.test.ts +50 -2
  444. package/src/query/value-decoding.ts +17 -4
  445. package/src/query/value-encoding.test.ts +1 -0
  446. package/src/query/value-encoding.ts +1 -1
  447. package/src/schema/create.test.ts +164 -5
  448. package/src/schema/create.ts +222 -24
  449. package/src/schema/generate-id.test.ts +1 -0
  450. package/src/schema/serialize.test.ts +4 -3
  451. package/src/schema/type-conversion/create-sql-type-mapper.ts +1 -1
  452. package/src/schema/type-conversion/dialect/sqlite.ts +2 -2
  453. package/src/schema/type-conversion/type-mapping.test.ts +2 -1
  454. package/src/schema/validator.test.ts +4 -2
  455. package/src/schema/validator.ts +1 -0
  456. package/src/schema-output/drizzle.test.ts +72 -19
  457. package/src/schema-output/drizzle.ts +24 -18
  458. package/src/schema-output/prisma.test.ts +172 -14
  459. package/src/schema-output/prisma.ts +34 -14
  460. package/src/sql-driver/better-sqlite3.test.ts +5 -3
  461. package/src/sql-driver/dialects/durable-object-dialect.ts +3 -8
  462. package/src/sql-driver/query-executor/default-query-executor.ts +1 -1
  463. package/src/sql-driver/query-executor/query-executor-base.ts +1 -1
  464. package/src/sql-driver/query-executor/query-executor.ts +1 -1
  465. package/src/sql-driver/sql-driver-adapter.ts +2 -2
  466. package/src/sql-driver/sql.ts +2 -1
  467. package/src/sql-driver/sqlocal.test.ts +4 -2
  468. package/src/sync/commands.test.ts +39 -0
  469. package/src/sync/commands.ts +51 -0
  470. package/src/sync/conflict-checker.test.ts +450 -0
  471. package/src/sync/conflict-checker.ts +248 -0
  472. package/src/sync/index.ts +14 -0
  473. package/src/sync/plan.ts +9 -0
  474. package/src/sync/read-tracking.test.ts +177 -0
  475. package/src/sync/read-tracking.ts +287 -0
  476. package/src/sync/submit.test.ts +205 -0
  477. package/src/sync/submit.ts +328 -0
  478. package/src/sync/types.ts +80 -0
  479. package/src/util/default-database-adapter.ts +15 -2
  480. package/src/with-database.ts +20 -50
  481. package/tsconfig.json +1 -1
  482. package/tsdown.config.ts +38 -26
  483. package/vitest.config.ts +1 -0
  484. package/dist/hooks/durable-hooks-processor.d.ts.map +0 -1
  485. package/dist/node_modules/.pnpm/rou3@0.7.12/node_modules/rou3/dist/index.js +0 -168
  486. package/dist/node_modules/.pnpm/rou3@0.7.12/node_modules/rou3/dist/index.js.map +0 -1
  487. package/dist/packages/fragno/dist/api/bind-services.js +0 -20
  488. package/dist/packages/fragno/dist/api/bind-services.js.map +0 -1
  489. package/dist/packages/fragno/dist/api/error.js +0 -48
  490. package/dist/packages/fragno/dist/api/error.js.map +0 -1
  491. package/dist/packages/fragno/dist/api/fragment-definition-builder.js +0 -321
  492. package/dist/packages/fragno/dist/api/fragment-definition-builder.js.map +0 -1
  493. package/dist/packages/fragno/dist/api/fragment-instantiator.js +0 -669
  494. package/dist/packages/fragno/dist/api/fragment-instantiator.js.map +0 -1
  495. package/dist/packages/fragno/dist/api/fragno-response.js +0 -73
  496. package/dist/packages/fragno/dist/api/fragno-response.js.map +0 -1
  497. package/dist/packages/fragno/dist/api/internal/response-stream.js +0 -81
  498. package/dist/packages/fragno/dist/api/internal/response-stream.js.map +0 -1
  499. package/dist/packages/fragno/dist/api/internal/route.js +0 -10
  500. package/dist/packages/fragno/dist/api/internal/route.js.map +0 -1
  501. package/dist/packages/fragno/dist/api/mutable-request-state.js +0 -97
  502. package/dist/packages/fragno/dist/api/mutable-request-state.js.map +0 -1
  503. package/dist/packages/fragno/dist/api/request-context-storage.js +0 -43
  504. package/dist/packages/fragno/dist/api/request-context-storage.js.map +0 -1
  505. package/dist/packages/fragno/dist/api/request-input-context.js +0 -185
  506. package/dist/packages/fragno/dist/api/request-input-context.js.map +0 -1
  507. package/dist/packages/fragno/dist/api/request-middleware.js +0 -83
  508. package/dist/packages/fragno/dist/api/request-middleware.js.map +0 -1
  509. package/dist/packages/fragno/dist/api/request-output-context.js +0 -119
  510. package/dist/packages/fragno/dist/api/request-output-context.js.map +0 -1
  511. package/dist/packages/fragno/dist/api/route.js +0 -30
  512. package/dist/packages/fragno/dist/api/route.js.map +0 -1
  513. package/dist/packages/fragno/dist/internal/symbols.js +0 -10
  514. package/dist/packages/fragno/dist/internal/symbols.js.map +0 -1
  515. package/dist/packages/fragno/dist/internal/trace-context.js +0 -12
  516. package/dist/packages/fragno/dist/internal/trace-context.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"internal-fragment.routes.js","names":["limit: number | undefined"],"sources":["../../src/fragments/internal-fragment.routes.ts"],"sourcesContent":["import { defineRoutes } from \"@fragno-dev/core\";\nimport { internalFragmentDef } from \"./internal-fragment\";\n\nexport const internalFragmentRoutes = defineRoutes(internalFragmentDef).create(\n ({ defineRoute, services }) => [\n defineRoute({\n method: \"GET\",\n path: \"/outbox\",\n handler: async function (input, { json }) {\n // We intentionally skip input/output schemas here to keep the internal route lightweight.\n // Query params are validated manually and the response shape is stable (OutboxEntry[]),\n // while the public API surface is still gated behind adapter config.\n const afterVersionstamp = input.query.get(\"afterVersionstamp\") ?? undefined;\n const limitValue = input.query.get(\"limit\");\n let limit: number | undefined;\n\n if (limitValue !== null) {\n const parsed = Number.parseInt(limitValue, 10);\n if (!Number.isFinite(parsed) || parsed < 1) {\n return json(\n {\n error: \"Invalid limit query parameter.\",\n code: \"INVALID_LIMIT\",\n },\n { status: 400 },\n );\n }\n limit = parsed;\n }\n\n const entries = await this.handlerTx()\n .withServiceCalls(\n () => [services.outboxService.list({ afterVersionstamp, limit })] as const,\n )\n .transform(({ serviceResult: [result] }) => result)\n .execute();\n\n return json(entries);\n },\n }),\n ],\n);\n"],"mappings":";;;;AAGA,MAAa,yBAAyB,aAAa,oBAAoB,CAAC,QACrE,EAAE,aAAa,eAAe,CAC7B,YAAY;CACV,QAAQ;CACR,MAAM;CACN,SAAS,eAAgB,OAAO,EAAE,QAAQ;EAIxC,MAAM,oBAAoB,MAAM,MAAM,IAAI,oBAAoB,IAAI;EAClE,MAAM,aAAa,MAAM,MAAM,IAAI,QAAQ;EAC3C,IAAIA;AAEJ,MAAI,eAAe,MAAM;GACvB,MAAM,SAAS,OAAO,SAAS,YAAY,GAAG;AAC9C,OAAI,CAAC,OAAO,SAAS,OAAO,IAAI,SAAS,EACvC,QAAO,KACL;IACE,OAAO;IACP,MAAM;IACP,EACD,EAAE,QAAQ,KAAK,CAChB;AAEH,WAAQ;;AAUV,SAAO,KAPS,MAAM,KAAK,WAAW,CACnC,uBACO,CAAC,SAAS,cAAc,KAAK;GAAE;GAAmB;GAAO,CAAC,CAAC,CAClE,CACA,WAAW,EAAE,eAAe,CAAC,cAAc,OAAO,CAClD,SAAS,CAEQ;;CAEvB,CAAC,CACH,CACF"}
1
+ {"version":3,"file":"internal-fragment.routes.js","names":["passthroughInputSchema: StandardSchemaV1","limit: number | undefined","result"],"sources":["../../src/fragments/internal-fragment.routes.ts"],"sourcesContent":["import { defineRoutes } from \"@fragno-dev/core\";\n\nimport type { StandardSchemaV1 } from \"@standard-schema/spec\";\n\nimport type { DatabaseHandlerContext } from \"../db-fragment-definition-builder\";\nimport type { OutboxEntry } from \"../outbox/outbox\";\nimport { submitSyncRequest, type SyncRequestRecord } from \"../sync/submit\";\nimport type { SubmitRequest, SyncCommandDefinition } from \"../sync/types\";\nimport {\n SETTINGS_NAMESPACE,\n internalFragmentDef,\n internalSchema,\n type InternalFragmentInstance,\n} from \"./internal-fragment\";\n\ntype InternalDescribeResponse = {\n adapterIdentity: string;\n fragments: Array<{ name: string; mountRoute: string }>;\n schemas: Array<{\n name: string;\n namespace: string | null;\n version: number;\n tables: string[];\n }>;\n routes: {\n internal: \"/_internal\";\n outbox?: \"/_internal/outbox\";\n };\n};\n\ntype InternalDescribeError = {\n error: {\n code: string;\n message: string;\n detail?: string;\n };\n};\n\nconst ADAPTER_IDENTITY_KEY = \"adapter_identity\" as const;\n\nconst passthroughInputSchema: StandardSchemaV1 = {\n \"~standard\": {\n version: 1,\n vendor: \"fragno\",\n validate: async (value: unknown) => ({ value }),\n },\n};\n\ntype AdapterIdentityResult =\n | { ok: true; value: string }\n | { ok: false; error: InternalDescribeError };\n\nconst getOrCreateAdapterIdentity = async (\n handlerTx: () => ReturnType<DatabaseHandlerContext[\"handlerTx\"]>,\n services: Pick<InternalFragmentInstance[\"services\"], \"settingsService\">,\n): Promise<AdapterIdentityResult> => {\n const readIdentity = async () =>\n handlerTx()\n .withServiceCalls(\n () => [services.settingsService.get(SETTINGS_NAMESPACE, ADAPTER_IDENTITY_KEY)] as const,\n )\n .transform(({ serviceResult: [result] }) => result?.value as string | undefined)\n .execute();\n\n try {\n const existingIdentity = await readIdentity();\n if (existingIdentity) {\n return { ok: true, value: existingIdentity };\n }\n\n const adapterIdentity = crypto.randomUUID();\n try {\n await handlerTx()\n .withServiceCalls(\n () =>\n [\n services.settingsService.setIfMissing(\n SETTINGS_NAMESPACE,\n ADAPTER_IDENTITY_KEY,\n adapterIdentity,\n ),\n ] as const,\n )\n .execute();\n } catch (error) {\n const recoveredIdentity = await readIdentity();\n if (recoveredIdentity) {\n return { ok: true, value: recoveredIdentity };\n }\n throw error;\n }\n\n const persistedIdentity = await readIdentity();\n return { ok: true, value: persistedIdentity ?? adapterIdentity };\n } catch (error) {\n return {\n ok: false,\n error: {\n error: {\n code: \"SETTINGS_UNAVAILABLE\",\n message: \"Internal settings table is not available.\",\n detail: error instanceof Error ? error.message : undefined,\n },\n },\n };\n }\n};\n\nexport const createInternalFragmentDescribeRoutes = () =>\n defineRoutes(internalFragmentDef).create(({ defineRoute, config, services }) => [\n defineRoute({\n method: \"GET\",\n path: \"/\",\n handler: async function (_input, { json }) {\n const registry = config.registry;\n if (!registry) {\n return json(\n {\n error: {\n code: \"REGISTRY_UNAVAILABLE\",\n message: \"Adapter registry is not configured.\",\n },\n } satisfies InternalDescribeError,\n { status: 500 },\n );\n }\n\n const adapterIdentityResult = await getOrCreateAdapterIdentity(\n () => this.handlerTx(),\n services,\n );\n if (!adapterIdentityResult.ok) {\n return json(adapterIdentityResult.error, { status: 500 });\n }\n\n const outboxEnabled = registry.isOutboxEnabled();\n const response: InternalDescribeResponse = {\n adapterIdentity: adapterIdentityResult.value,\n fragments: outboxEnabled ? registry.listOutboxFragments() : [],\n schemas: registry.listSchemas(),\n routes: {\n internal: \"/_internal\",\n outbox: outboxEnabled ? \"/_internal/outbox\" : undefined,\n },\n };\n\n return json(response);\n },\n }),\n ]);\n\nexport const createInternalFragmentOutboxRoutes = () =>\n defineRoutes(internalFragmentDef).create(({ defineRoute, services, config }) => [\n defineRoute({\n method: \"GET\",\n path: \"/outbox\",\n handler: async function (input, { json }) {\n const registry = config.registry;\n if (!registry || !registry.isOutboxEnabled()) {\n return json(\n {\n error: {\n code: \"OUTBOX_UNAVAILABLE\",\n message: \"Outbox is not enabled for this adapter.\",\n },\n },\n { status: 404 },\n );\n }\n\n // We intentionally skip input/output schemas here to keep the internal route lightweight.\n // Query params are validated manually and the response shape is stable (OutboxEntry[]),\n // while the public API surface is still gated behind adapter config.\n const afterVersionstamp = input.query.get(\"afterVersionstamp\") ?? undefined;\n const limitValue = input.query.get(\"limit\");\n let limit: number | undefined;\n\n if (limitValue !== null) {\n const parsed = Number.parseInt(limitValue, 10);\n if (!Number.isFinite(parsed) || parsed < 1) {\n return json(\n {\n error: \"Invalid limit query parameter.\",\n code: \"INVALID_LIMIT\",\n },\n { status: 400 },\n );\n }\n limit = parsed;\n }\n\n const entries = await this.handlerTx()\n .withServiceCalls(\n () => [services.outboxService.list({ afterVersionstamp, limit })] as const,\n )\n .transform(({ serviceResult: [result] }) => result)\n .execute();\n\n return json(entries);\n },\n }),\n ]);\n\ntype InternalSyncError = {\n error: {\n code: string;\n message: string;\n detail?: string;\n };\n};\n\nexport const createInternalFragmentSyncRoutes = () =>\n defineRoutes(internalFragmentDef).create(({ defineRoute, services, config }) => [\n defineRoute({\n method: \"POST\",\n path: \"/sync\",\n inputSchema: passthroughInputSchema,\n handler: async function (input, { json }) {\n const registry = config.registry;\n if (!registry || !registry.isOutboxEnabled()) {\n return json(\n {\n error: {\n code: \"SYNC_UNAVAILABLE\",\n message: \"Sync is not enabled for this adapter.\",\n },\n } satisfies InternalSyncError,\n { status: 404 },\n );\n }\n\n const adapterIdentityResult = await getOrCreateAdapterIdentity(\n () => this.handlerTx(),\n services,\n );\n if (!adapterIdentityResult.ok) {\n return json(adapterIdentityResult.error, { status: 500 });\n }\n\n const body = (await input.input?.valid()) as SubmitRequest | undefined;\n\n const result = await submitSyncRequest(body, {\n getAdapterIdentity: async () => adapterIdentityResult.value,\n listOutboxEntries: async (afterVersionstamp) =>\n await this.handlerTx()\n .withServiceCalls(\n () =>\n [services.outboxService.list({ afterVersionstamp, limit: undefined })] as const,\n )\n .transform(({ serviceResult: [entries] }) => entries as OutboxEntry[])\n .execute(),\n countOutboxMutations: async (afterVersionstamp) => {\n const count = await this.handlerTx()\n .retrieve(({ forSchema }) => {\n const builder = afterVersionstamp\n ? forSchema(internalSchema).find(\"fragno_db_outbox_mutations\", (b) =>\n b\n .whereIndex(\"idx_outbox_mutations_entry\", (eb) =>\n eb(\"entryVersionstamp\", \">\", afterVersionstamp),\n )\n .selectCount(),\n )\n : forSchema(internalSchema).find(\"fragno_db_outbox_mutations\", (b) =>\n b.whereIndex(\"idx_outbox_mutations_entry\").selectCount(),\n );\n return builder;\n })\n .transformRetrieve(([result]) => (typeof result === \"number\" ? result : 0))\n .execute();\n return count;\n },\n getSyncRequest: async (requestId) =>\n await this.handlerTx()\n .retrieve(({ forSchema }) =>\n forSchema(internalSchema).findFirst(\"fragno_db_sync_requests\", (b) =>\n b.whereIndex(\"idx_sync_request_id\", (eb) => eb(\"requestId\", \"=\", requestId)),\n ),\n )\n .transformRetrieve(([result]) => {\n if (!result) {\n return undefined;\n }\n const confirmed = Array.isArray(result.confirmedCommandIds)\n ? (result.confirmedCommandIds as string[])\n : [];\n const status = result.status === \"applied\" ? \"applied\" : \"conflict\";\n return {\n requestId: result.requestId,\n status,\n confirmedCommandIds: confirmed,\n conflictCommandId: result.conflictCommandId ?? undefined,\n baseVersionstamp: result.baseVersionstamp ?? undefined,\n lastVersionstamp: result.lastVersionstamp ?? undefined,\n } satisfies SyncRequestRecord;\n })\n .execute(),\n storeSyncRequest: async (record) => {\n await this.handlerTx()\n .mutate(({ forSchema }) => {\n forSchema(internalSchema).create(\"fragno_db_sync_requests\", {\n requestId: record.requestId,\n status: record.status,\n confirmedCommandIds: record.confirmedCommandIds,\n conflictCommandId: record.conflictCommandId ?? null,\n baseVersionstamp: record.baseVersionstamp ?? null,\n lastVersionstamp: record.lastVersionstamp ?? null,\n });\n })\n .execute();\n },\n resolveCommand: (fragment, schema, name) =>\n registry.resolveSyncCommand(fragment, schema, name) as\n | { command: SyncCommandDefinition; namespace: string | null }\n | undefined,\n createCommandContext: (command) =>\n command.createServerContext?.(this) ?? { mode: \"server\" },\n executeCommand: async (command, inputPayload, ctx) => {\n await command.handler({\n input: inputPayload,\n ctx,\n tx: (options) => this.handlerTx(options),\n });\n },\n });\n\n if (result.status === \"error\") {\n const statusCode = result.statusCode as 400 | 409 | 500;\n return json(result.body, { status: statusCode });\n }\n\n return json(result.response);\n },\n }),\n ]);\n"],"mappings":";;;;;;AAsCA,MAAM,uBAAuB;AAE7B,MAAMA,yBAA2C,EAC/C,aAAa;CACX,SAAS;CACT,QAAQ;CACR,UAAU,OAAO,WAAoB,EAAE,OAAO;CAC/C,EACF;AAMD,MAAM,6BAA6B,OACjC,WACA,aACmC;CACnC,MAAM,eAAe,YACnB,WAAW,CACR,uBACO,CAAC,SAAS,gBAAgB,IAAI,oBAAoB,qBAAqB,CAAC,CAC/E,CACA,WAAW,EAAE,eAAe,CAAC,cAAc,QAAQ,MAA4B,CAC/E,SAAS;AAEd,KAAI;EACF,MAAM,mBAAmB,MAAM,cAAc;AAC7C,MAAI,iBACF,QAAO;GAAE,IAAI;GAAM,OAAO;GAAkB;EAG9C,MAAM,kBAAkB,OAAO,YAAY;AAC3C,MAAI;AACF,SAAM,WAAW,CACd,uBAEG,CACE,SAAS,gBAAgB,aACvB,oBACA,sBACA,gBACD,CACF,CACJ,CACA,SAAS;WACL,OAAO;GACd,MAAM,oBAAoB,MAAM,cAAc;AAC9C,OAAI,kBACF,QAAO;IAAE,IAAI;IAAM,OAAO;IAAmB;AAE/C,SAAM;;AAIR,SAAO;GAAE,IAAI;GAAM,OADO,MAAM,cAAc,IACC;GAAiB;UACzD,OAAO;AACd,SAAO;GACL,IAAI;GACJ,OAAO,EACL,OAAO;IACL,MAAM;IACN,SAAS;IACT,QAAQ,iBAAiB,QAAQ,MAAM,UAAU;IAClD,EACF;GACF;;;AAIL,MAAa,6CACX,aAAa,oBAAoB,CAAC,QAAQ,EAAE,aAAa,QAAQ,eAAe,CAC9E,YAAY;CACV,QAAQ;CACR,MAAM;CACN,SAAS,eAAgB,QAAQ,EAAE,QAAQ;EACzC,MAAM,WAAW,OAAO;AACxB,MAAI,CAAC,SACH,QAAO,KACL,EACE,OAAO;GACL,MAAM;GACN,SAAS;GACV,EACF,EACD,EAAE,QAAQ,KAAK,CAChB;EAGH,MAAM,wBAAwB,MAAM,iCAC5B,KAAK,WAAW,EACtB,SACD;AACD,MAAI,CAAC,sBAAsB,GACzB,QAAO,KAAK,sBAAsB,OAAO,EAAE,QAAQ,KAAK,CAAC;EAG3D,MAAM,gBAAgB,SAAS,iBAAiB;AAWhD,SAAO,KAVoC;GACzC,iBAAiB,sBAAsB;GACvC,WAAW,gBAAgB,SAAS,qBAAqB,GAAG,EAAE;GAC9D,SAAS,SAAS,aAAa;GAC/B,QAAQ;IACN,UAAU;IACV,QAAQ,gBAAgB,sBAAsB;IAC/C;GACF,CAEoB;;CAExB,CAAC,CACH,CAAC;AAEJ,MAAa,2CACX,aAAa,oBAAoB,CAAC,QAAQ,EAAE,aAAa,UAAU,aAAa,CAC9E,YAAY;CACV,QAAQ;CACR,MAAM;CACN,SAAS,eAAgB,OAAO,EAAE,QAAQ;EACxC,MAAM,WAAW,OAAO;AACxB,MAAI,CAAC,YAAY,CAAC,SAAS,iBAAiB,CAC1C,QAAO,KACL,EACE,OAAO;GACL,MAAM;GACN,SAAS;GACV,EACF,EACD,EAAE,QAAQ,KAAK,CAChB;EAMH,MAAM,oBAAoB,MAAM,MAAM,IAAI,oBAAoB,IAAI;EAClE,MAAM,aAAa,MAAM,MAAM,IAAI,QAAQ;EAC3C,IAAIC;AAEJ,MAAI,eAAe,MAAM;GACvB,MAAM,SAAS,OAAO,SAAS,YAAY,GAAG;AAC9C,OAAI,CAAC,OAAO,SAAS,OAAO,IAAI,SAAS,EACvC,QAAO,KACL;IACE,OAAO;IACP,MAAM;IACP,EACD,EAAE,QAAQ,KAAK,CAChB;AAEH,WAAQ;;AAUV,SAAO,KAPS,MAAM,KAAK,WAAW,CACnC,uBACO,CAAC,SAAS,cAAc,KAAK;GAAE;GAAmB;GAAO,CAAC,CAAC,CAClE,CACA,WAAW,EAAE,eAAe,CAAC,cAAc,OAAO,CAClD,SAAS,CAEQ;;CAEvB,CAAC,CACH,CAAC;AAUJ,MAAa,yCACX,aAAa,oBAAoB,CAAC,QAAQ,EAAE,aAAa,UAAU,aAAa,CAC9E,YAAY;CACV,QAAQ;CACR,MAAM;CACN,aAAa;CACb,SAAS,eAAgB,OAAO,EAAE,QAAQ;EACxC,MAAM,WAAW,OAAO;AACxB,MAAI,CAAC,YAAY,CAAC,SAAS,iBAAiB,CAC1C,QAAO,KACL,EACE,OAAO;GACL,MAAM;GACN,SAAS;GACV,EACF,EACD,EAAE,QAAQ,KAAK,CAChB;EAGH,MAAM,wBAAwB,MAAM,iCAC5B,KAAK,WAAW,EACtB,SACD;AACD,MAAI,CAAC,sBAAsB,GACzB,QAAO,KAAK,sBAAsB,OAAO,EAAE,QAAQ,KAAK,CAAC;EAK3D,MAAM,SAAS,MAAM,kBAFP,MAAM,MAAM,OAAO,OAAO,EAEK;GAC3C,oBAAoB,YAAY,sBAAsB;GACtD,mBAAmB,OAAO,sBACxB,MAAM,KAAK,WAAW,CACnB,uBAEG,CAAC,SAAS,cAAc,KAAK;IAAE;IAAmB,OAAO;IAAW,CAAC,CAAC,CACzE,CACA,WAAW,EAAE,eAAe,CAAC,eAAe,QAAyB,CACrE,SAAS;GACd,sBAAsB,OAAO,sBAAsB;AAkBjD,WAjBc,MAAM,KAAK,WAAW,CACjC,UAAU,EAAE,gBAAgB;AAY3B,YAXgB,oBACZ,UAAU,eAAe,CAAC,KAAK,+BAA+B,MAC5D,EACG,WAAW,+BAA+B,OACzC,GAAG,qBAAqB,KAAK,kBAAkB,CAChD,CACA,aAAa,CACjB,GACD,UAAU,eAAe,CAAC,KAAK,+BAA+B,MAC5D,EAAE,WAAW,6BAA6B,CAAC,aAAa,CACzD;MAEL,CACD,mBAAmB,CAACC,cAAa,OAAOA,aAAW,WAAWA,WAAS,EAAG,CAC1E,SAAS;;GAGd,gBAAgB,OAAO,cACrB,MAAM,KAAK,WAAW,CACnB,UAAU,EAAE,gBACX,UAAU,eAAe,CAAC,UAAU,4BAA4B,MAC9D,EAAE,WAAW,wBAAwB,OAAO,GAAG,aAAa,KAAK,UAAU,CAAC,CAC7E,CACF,CACA,mBAAmB,CAACA,cAAY;AAC/B,QAAI,CAACA,SACH;IAEF,MAAM,YAAY,MAAM,QAAQA,SAAO,oBAAoB,GACtDA,SAAO,sBACR,EAAE;IACN,MAAM,SAASA,SAAO,WAAW,YAAY,YAAY;AACzD,WAAO;KACL,WAAWA,SAAO;KAClB;KACA,qBAAqB;KACrB,mBAAmBA,SAAO,qBAAqB;KAC/C,kBAAkBA,SAAO,oBAAoB;KAC7C,kBAAkBA,SAAO,oBAAoB;KAC9C;KACD,CACD,SAAS;GACd,kBAAkB,OAAO,WAAW;AAClC,UAAM,KAAK,WAAW,CACnB,QAAQ,EAAE,gBAAgB;AACzB,eAAU,eAAe,CAAC,OAAO,2BAA2B;MAC1D,WAAW,OAAO;MAClB,QAAQ,OAAO;MACf,qBAAqB,OAAO;MAC5B,mBAAmB,OAAO,qBAAqB;MAC/C,kBAAkB,OAAO,oBAAoB;MAC7C,kBAAkB,OAAO,oBAAoB;MAC9C,CAAC;MACF,CACD,SAAS;;GAEd,iBAAiB,UAAU,QAAQ,SACjC,SAAS,mBAAmB,UAAU,QAAQ,KAAK;GAGrD,uBAAuB,YACrB,QAAQ,sBAAsB,KAAK,IAAI,EAAE,MAAM,UAAU;GAC3D,gBAAgB,OAAO,SAAS,cAAc,QAAQ;AACpD,UAAM,QAAQ,QAAQ;KACpB,OAAO;KACP;KACA,KAAK,YAAY,KAAK,UAAU,QAAQ;KACzC,CAAC;;GAEL,CAAC;AAEF,MAAI,OAAO,WAAW,SAAS;GAC7B,MAAM,aAAa,OAAO;AAC1B,UAAO,KAAK,OAAO,MAAM,EAAE,QAAQ,YAAY,CAAC;;AAGlD,SAAO,KAAK,OAAO,SAAS;;CAE/B,CAAC,CACH,CAAC"}
@@ -3,7 +3,13 @@ import { AnyColumn, AnyRelation, Column, FragnoId, IdColumn, Index, Schema, Tabl
3
3
  import "../mod.js";
4
4
 
5
5
  //#region src/fragments/internal-fragment.schema.d.ts
6
- declare const internalSchema: Schema<Record<"fragno_db_settings", Table<Record<string, AnyColumn> & Record<"id", IdColumn<"varchar(30)", string | FragnoId | null, FragnoId>> & Record<"key", Column<"string", string, string>> & Record<"value", Column<"string", string, string>>, Record<string, AnyRelation>, Record<string, Index<AnyColumn[], readonly string[]>> & Record<"unique_key", Index<readonly [Column<"string", string, string>] & AnyColumn[], readonly ["key"]>>>> & Record<"fragno_hooks", Table<Record<string, AnyColumn> & Record<"id", IdColumn<"varchar(30)", string | FragnoId | null, FragnoId>> & Record<"namespace", Column<"string", string, string>> & Record<"hookName", Column<"string", string, string>> & Record<"payload", Column<"json", unknown, unknown>> & Record<"status", Column<"string", string, string>> & Record<"attempts", Column<"integer", number | null, number>> & Record<"maxAttempts", Column<"integer", number | null, number>> & Record<"lastAttemptAt", Column<"timestamp", (DbNow | Date) | null, Date | null>> & Record<"nextRetryAt", Column<"timestamp", (DbNow | Date) | null, Date | null>> & Record<"error", Column<"string", string | null, string | null>> & Record<"createdAt", Column<"timestamp", (DbNow | Date) | null, Date>> & Record<"nonce", Column<"string", string, string>>, Record<string, AnyRelation>, Record<string, Index<AnyColumn[], readonly string[]>> & Record<"idx_namespace_status_retry", Index<readonly [Column<"string", string, string>, Column<"string", string, string>, Column<"timestamp", (DbNow | Date) | null, Date | null>] & AnyColumn[], readonly ["namespace", "status", "nextRetryAt"]>> & Record<"idx_nonce", Index<readonly [Column<"string", string, string>] & AnyColumn[], readonly ["nonce"]>>>> & Record<"fragno_db_outbox", Table<Record<string, AnyColumn> & Record<"id", IdColumn<"varchar(30)", string | FragnoId | null, FragnoId>> & Record<"versionstamp", Column<"string", string, string>> & Record<"uowId", Column<"string", string, string>> & Record<"payload", Column<"json", unknown, unknown>> & Record<"refMap", Column<"json", unknown, unknown>> & Record<"createdAt", Column<"timestamp", (DbNow | Date) | null, Date>>, Record<string, AnyRelation>, Record<string, Index<AnyColumn[], readonly string[]>> & Record<"idx_outbox_versionstamp", Index<readonly [Column<"string", string, string>] & AnyColumn[], readonly ["versionstamp"]>> & Record<"idx_outbox_uow", Index<readonly [Column<"string", string, string>] & AnyColumn[], readonly ["uowId"]>>>>>;
6
+ declare const internalSchema: Schema<{
7
+ fragno_db_settings: Table<Record<"id", IdColumn<"varchar(128)", string | FragnoId | null, FragnoId>> & Record<"key", Column<"string", string, string>> & Record<"value", Column<"string", string, string>>, Record<string, AnyRelation>, Record<string, Index<AnyColumn[], readonly string[]>> & Record<"unique_key", Index<readonly [Column<"string", string, string>] & AnyColumn[], readonly ["key"]>>>;
8
+ fragno_hooks: Table<Record<"id", IdColumn<"varchar(128)", string | FragnoId | null, FragnoId>> & Record<"namespace", Column<"string", string, string>> & Record<"hookName", Column<"string", string, string>> & Record<"payload", Column<"json", unknown, unknown>> & Record<"status", Column<"string", string, string>> & Record<"attempts", Column<"integer", number | null, number>> & Record<"maxAttempts", Column<"integer", number | null, number>> & Record<"lastAttemptAt", Column<"timestamp", (Date | DbNow) | null, Date | null>> & Record<"nextRetryAt", Column<"timestamp", (Date | DbNow) | null, Date | null>> & Record<"error", Column<"string", string | null, string | null>> & Record<"createdAt", Column<"timestamp", (Date | DbNow) | null, Date>> & Record<"nonce", Column<"string", string, string>>, Record<string, AnyRelation>, Record<string, Index<AnyColumn[], readonly string[]>> & Record<"idx_namespace_created_at", Index<readonly [Column<"string", string, string>, Column<"timestamp", (Date | DbNow) | null, Date>, IdColumn<"varchar(128)", string | FragnoId | null, FragnoId>] & AnyColumn[], readonly ["namespace", "createdAt", "id"]>>>;
9
+ fragno_db_outbox: Table<Record<"id", IdColumn<"varchar(128)", string | FragnoId | null, FragnoId>> & Record<"versionstamp", Column<"string", string, string>> & Record<"uowId", Column<"string", string, string>> & Record<"payload", Column<"json", unknown, unknown>> & Record<"refMap", Column<"json", unknown, unknown>> & Record<"createdAt", Column<"timestamp", (Date | DbNow) | null, Date>>, Record<string, AnyRelation>, Record<string, Index<AnyColumn[], readonly string[]>> & Record<"idx_outbox_versionstamp", Index<readonly [Column<"string", string, string>] & AnyColumn[], readonly ["versionstamp"]>> & Record<"idx_outbox_uow", Index<readonly [Column<"string", string, string>] & AnyColumn[], readonly ["uowId"]>>>;
10
+ fragno_db_outbox_mutations: Table<Record<"id", IdColumn<"varchar(128)", string | FragnoId | null, FragnoId>> & Record<"entryVersionstamp", Column<"string", string, string>> & Record<"mutationVersionstamp", Column<"string", string, string>> & Record<"uowId", Column<"string", string, string>> & Record<"schema", Column<"string", string, string>> & Record<"table", Column<"string", string, string>> & Record<"externalId", Column<"string", string, string>> & Record<"op", Column<"string", string, string>> & Record<"createdAt", Column<"timestamp", (Date | DbNow) | null, Date>>, Record<string, AnyRelation>, Record<string, Index<AnyColumn[], readonly string[]>> & Record<"idx_outbox_mutations_entry", Index<readonly [Column<"string", string, string>] & AnyColumn[], readonly ["entryVersionstamp"]>> & Record<"idx_outbox_mutations_key", Index<readonly [Column<"string", string, string>, Column<"string", string, string>, Column<"string", string, string>, Column<"string", string, string>] & AnyColumn[], readonly ["schema", "table", "externalId", "entryVersionstamp"]>> & Record<"idx_outbox_mutations_uow", Index<readonly [Column<"string", string, string>] & AnyColumn[], readonly ["uowId"]>>>;
11
+ fragno_db_sync_requests: Table<Record<"id", IdColumn<"varchar(128)", string | FragnoId | null, FragnoId>> & Record<"requestId", Column<"string", string, string>> & Record<"status", Column<"string", string, string>> & Record<"confirmedCommandIds", Column<"json", unknown, unknown>> & Record<"conflictCommandId", Column<"string", string | null, string | null>> & Record<"baseVersionstamp", Column<"string", string | null, string | null>> & Record<"lastVersionstamp", Column<"string", string | null, string | null>> & Record<"createdAt", Column<"timestamp", (Date | DbNow) | null, Date>>, Record<string, AnyRelation>, Record<string, Index<AnyColumn[], readonly string[]>> & Record<"idx_sync_request_id", Index<readonly [Column<"string", string, string>] & AnyColumn[], readonly ["requestId"]>>>;
12
+ }>;
7
13
  //#endregion
8
14
  export { internalSchema };
9
15
  //# sourceMappingURL=internal-fragment.schema.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"internal-fragment.schema.d.ts","names":[],"sources":["../../src/fragments/internal-fragment.schema.ts"],"sourcesContent":[],"mappings":";;;;;cAOa,gBAAc,OAAA,6BAAA,MAAA,eA2CzB,SAAA,IA3CyB,aAAA,iCAAA,QAAA,SAAA,QAAA,KAAA,cAAA,oCAAA,gBAAA,mCAAA,eAAA,WAAA,GAAA,eAAA,MAAA,SAAA,0BAAA,qBAAA,gBAAA,oCAAA,SAAA,2BAAA,uBAAA,MAAA,eAAA,SAAA,IAAA,aAAA,iCAAA,QAAA,SAAA,QAAA,KAAA,oBAAA,oCAAA,mBAAA,oCAAA,kBAAA,oCAAA,iBAAA,oCAAA,mBAAA,4CAAA,sBAAA,4CAAA,wBAAA,qBAAA,KAAA,GAAA,cAAA,gBAAA,sBAAA,qBAAA,KAAA,GAAA,cAAA,gBAAA,gBAAA,kDAAA,oBAAA,qBAAA,KAAA,GAAA,cAAA,SAAA,gBAAA,mCAAA,eAAA,WAAA,GAAA,eAAA,MAAA,SAAA,0BAAA,qCAAA,gBAAA,kCAAA,kCAAA,qBAAA,KAAA,GAAA,cAAA,gBAAA,SAAA,wDAAA,oBAAA,gBAAA,oCAAA,SAAA,6BAAA,2BAAA,MAAA,eAAA,SAAA,IAAA,aAAA,iCAAA,QAAA,SAAA,QAAA,KAAA,uBAAA,oCAAA,gBAAA,oCAAA,kBAAA,oCAAA,iBAAA,oCAAA,oBAAA,qBAAA,KAAA,GAAA,cAAA,QAAA,eAAA,WAAA,GAAA,eAAA,MAAA,SAAA,0BAAA,kCAAA,gBAAA,oCAAA,SAAA,kCAAA,yBAAA,gBAAA,oCAAA,SAAA"}
1
+ {"version":3,"file":"internal-fragment.schema.d.ts","names":[],"sources":["../../src/fragments/internal-fragment.schema.ts"],"sourcesContent":[],"mappings":";;;;;cAOa;2EAuFX,QAAA;;EAvFW,gBAAA,OAuFX,OAAA,CAAA,IAAA,UAAA,CAAA,cAAA,EAAA,MAAA,cAAA,IAAA,WAAA,CAAA,SAAA,CAAA,cAAA,QAAA,CAAA,QAAA,EAAA,MAAA,EAAA,MAAA,CAAA,CAAA,SAAA,CAAA,OAAA,QAAA,CAAA,QAAA,EAAA,MAAA,EAAA,MAAA,CAAA,CAAA,SAAA,CAAA,SAAA,QAAA,CAAA,MAAA,EAAA,OAAA,EAAA,OAAA,CAAA,CAAA,SAAA,CAAA,QAAA,QAAA,CAAA,MAAA,EAAA,OAAA,EAAA,OAAA,CAAA,CAAA,SAAA,CAAA,WAAA,QAAA,CAAA,WAAA,EAAA,KAAA,QAAA,CAAA,GAAA,IAAA,MAAA,CAAA,CAAA,QAAA,CAAA,MAAA,cAAA,QAAA,CAAA,MAAA,OAAA,YAAA,EAAA,SAAA,MAAA,EAAA,CAAA,CAAA,SAAA,CAAA,yBAAA,OAAA,CAAA,SAAA,OAAA,CAAA,QAAA,EAAA,MAAA,EAAA,MAAA,CAAA,CAAA,cAAA,EAAA,SAAA,CAAA,cAAA,CAAA,CAAA,CAAA,SAAA,CAAA,gBAAA,OAAA,CAAA,SAAA,OAAA,CAAA,QAAA,EAAA,MAAA,EAAA,MAAA,CAAA,CAAA,cAAA,EAAA,SAAA,CAAA,OAAA,CAAA,CAAA,CAAA,CAAA;EAAA,0BAAA,OAAA,OAAA,CAAA,IAAA,UAAA,CAAA,cAAA,EAAA,MAAA,cAAA,IAAA,WAAA,CAAA,SAAA,CAAA,mBAAA,QAAA,CAAA,QAAA,EAAA,MAAA,EAAA,MAAA,CAAA,CAAA,SAAA,CAAA,sBAAA,QAAA,CAAA,QAAA,EAAA,MAAA,EAAA,MAAA,CAAA,CAAA,SAAA,CAAA,OAAA,QAAA,CAAA,QAAA,EAAA,MAAA,EAAA,MAAA,CAAA,CAAA,SAAA,CAAA,QAAA,QAAA,CAAA,QAAA,EAAA,MAAA,EAAA,MAAA,CAAA,CAAA,SAAA,CAAA,OAAA,QAAA,CAAA,QAAA,EAAA,MAAA,EAAA,MAAA,CAAA,CAAA,SAAA,CAAA,YAAA,QAAA,CAAA,QAAA,EAAA,MAAA,EAAA,MAAA,CAAA,CAAA,SAAA,CAAA,IAAA,QAAA,CAAA,QAAA,EAAA,MAAA,EAAA,MAAA,CAAA,CAAA,SAAA,CAAA,WAAA,QAAA,CAAA,WAAA,EAAA,KAAA,QAAA,CAAA,GAAA,IAAA,MAAA,CAAA,CAAA,QAAA,CAAA,MAAA,cAAA,QAAA,CAAA,MAAA,OAAA,YAAA,EAAA,SAAA,MAAA,EAAA,CAAA,CAAA,SAAA,CAAA,4BAAA,OAAA,CAAA,SAAA,OAAA,CAAA,QAAA,EAAA,MAAA,EAAA,MAAA,CAAA,CAAA,cAAA,EAAA,SAAA,CAAA,mBAAA,CAAA,CAAA,CAAA,SAAA,CAAA,0BAAA,OAAA,CAAA,SAAA,OAAA,CAAA,QAAA,EAAA,MAAA,EAAA,MAAA,CAAA,QAAA,CAAA,QAAA,EAAA,MAAA,EAAA,MAAA,CAAA,QAAA,CAAA,QAAA,EAAA,MAAA,EAAA,MAAA,CAAA,QAAA,CAAA,QAAA,EAAA,MAAA,EAAA,MAAA,CAAA,CAAA,cAAA,EAAA,SAAA,CAAA,QAAA,EAAA,OAAA,EAAA,YAAA,EAAA,mBAAA,CAAA,CAAA,CAAA,SAAA,CAAA,0BAAA,OAAA,CAAA,SAAA,OAAA,CAAA,QAAA,EAAA,MAAA,EAAA,MAAA,CAAA,CAAA,cAAA,EAAA,SAAA,CAAA,OAAA,CAAA,CAAA,CAAA,CAAA"}
@@ -14,7 +14,24 @@ const internalSchema = schema("fragno_internal", (s) => {
14
14
  ]).createIndex("idx_nonce", ["nonce"]);
15
15
  }).addTable("fragno_db_outbox", (t) => {
16
16
  return t.addColumn("id", idColumn()).addColumn("versionstamp", column("string")).addColumn("uowId", column("string")).addColumn("payload", column("json")).addColumn("refMap", column("json").nullable()).addColumn("createdAt", column("timestamp").defaultTo((b) => b.now())).createIndex("idx_outbox_versionstamp", ["versionstamp"], { unique: true }).createIndex("idx_outbox_uow", ["uowId"]);
17
- });
17
+ }).addTable("fragno_db_outbox_mutations", (t) => {
18
+ return t.addColumn("id", idColumn()).addColumn("entryVersionstamp", column("string")).addColumn("mutationVersionstamp", column("string")).addColumn("uowId", column("string")).addColumn("schema", column("string")).addColumn("table", column("string")).addColumn("externalId", column("string")).addColumn("op", column("string")).addColumn("createdAt", column("timestamp").defaultTo((b) => b.now())).createIndex("idx_outbox_mutations_entry", ["entryVersionstamp"]).createIndex("idx_outbox_mutations_key", [
19
+ "schema",
20
+ "table",
21
+ "externalId",
22
+ "entryVersionstamp"
23
+ ]).createIndex("idx_outbox_mutations_uow", ["uowId"]);
24
+ }).addTable("fragno_db_sync_requests", (t) => {
25
+ return t.addColumn("id", idColumn()).addColumn("requestId", column("string")).addColumn("status", column("string")).addColumn("confirmedCommandIds", column("json")).addColumn("conflictCommandId", column("string").nullable()).addColumn("baseVersionstamp", column("string").nullable()).addColumn("lastVersionstamp", column("string").nullable()).addColumn("createdAt", column("timestamp").defaultTo((b) => b.now())).createIndex("idx_sync_request_id", ["requestId"], { unique: true });
26
+ }).alterTable("fragno_hooks", (t) => t.createIndex("idx_namespace_status_last_attempt", [
27
+ "namespace",
28
+ "status",
29
+ "lastAttemptAt"
30
+ ])).alterTable("fragno_hooks", (t) => t.createIndex("idx_namespace_created_at", [
31
+ "namespace",
32
+ "createdAt",
33
+ "id"
34
+ ]));
18
35
  });
19
36
 
20
37
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"internal-fragment.schema.js","names":[],"sources":["../../src/fragments/internal-fragment.schema.ts"],"sourcesContent":["import { schema, idColumn, column } from \"../schema/create\";\n\n// Constants for Fragno's internal settings table\nexport const SETTINGS_TABLE_NAME = \"fragno_db_settings\" as const;\n// FIXME: In some places we simply use empty string \"\" as namespace, which is not correct.\nexport const SETTINGS_NAMESPACE = \"fragno-db-settings\" as const;\n\nexport const internalSchema = schema(\"fragno_internal\", (s) => {\n return s\n .addTable(SETTINGS_TABLE_NAME, (t) => {\n return t\n .addColumn(\"id\", idColumn())\n .addColumn(\"key\", column(\"string\"))\n .addColumn(\"value\", column(\"string\"))\n .createIndex(\"unique_key\", [\"key\"], { unique: true });\n })\n .addTable(\"fragno_hooks\", (t) => {\n return t\n .addColumn(\"id\", idColumn())\n .addColumn(\"namespace\", column(\"string\"))\n .addColumn(\"hookName\", column(\"string\"))\n .addColumn(\"payload\", column(\"json\"))\n .addColumn(\"status\", column(\"string\")) // \"pending\" | \"processing\" | \"completed\" | \"failed\"\n .addColumn(\"attempts\", column(\"integer\").defaultTo(0))\n .addColumn(\"maxAttempts\", column(\"integer\").defaultTo(5))\n .addColumn(\"lastAttemptAt\", column(\"timestamp\").nullable())\n .addColumn(\"nextRetryAt\", column(\"timestamp\").nullable())\n .addColumn(\"error\", column(\"string\").nullable())\n .addColumn(\n \"createdAt\",\n column(\"timestamp\").defaultTo((b) => b.now()),\n )\n .addColumn(\"nonce\", column(\"string\"))\n .createIndex(\"idx_namespace_status_retry\", [\"namespace\", \"status\", \"nextRetryAt\"])\n .createIndex(\"idx_nonce\", [\"nonce\"]);\n })\n .addTable(\"fragno_db_outbox\", (t) => {\n return t\n .addColumn(\"id\", idColumn())\n .addColumn(\"versionstamp\", column(\"string\"))\n .addColumn(\"uowId\", column(\"string\"))\n .addColumn(\"payload\", column(\"json\"))\n .addColumn(\"refMap\", column(\"json\").nullable())\n .addColumn(\n \"createdAt\",\n column(\"timestamp\").defaultTo((b) => b.now()),\n )\n .createIndex(\"idx_outbox_versionstamp\", [\"versionstamp\"], { unique: true })\n .createIndex(\"idx_outbox_uow\", [\"uowId\"]);\n });\n});\n"],"mappings":";;;AAGA,MAAa,sBAAsB;AAEnC,MAAa,qBAAqB;AAElC,MAAa,iBAAiB,OAAO,oBAAoB,MAAM;AAC7D,QAAO,EACJ,SAAS,sBAAsB,MAAM;AACpC,SAAO,EACJ,UAAU,MAAM,UAAU,CAAC,CAC3B,UAAU,OAAO,OAAO,SAAS,CAAC,CAClC,UAAU,SAAS,OAAO,SAAS,CAAC,CACpC,YAAY,cAAc,CAAC,MAAM,EAAE,EAAE,QAAQ,MAAM,CAAC;GACvD,CACD,SAAS,iBAAiB,MAAM;AAC/B,SAAO,EACJ,UAAU,MAAM,UAAU,CAAC,CAC3B,UAAU,aAAa,OAAO,SAAS,CAAC,CACxC,UAAU,YAAY,OAAO,SAAS,CAAC,CACvC,UAAU,WAAW,OAAO,OAAO,CAAC,CACpC,UAAU,UAAU,OAAO,SAAS,CAAC,CACrC,UAAU,YAAY,OAAO,UAAU,CAAC,UAAU,EAAE,CAAC,CACrD,UAAU,eAAe,OAAO,UAAU,CAAC,UAAU,EAAE,CAAC,CACxD,UAAU,iBAAiB,OAAO,YAAY,CAAC,UAAU,CAAC,CAC1D,UAAU,eAAe,OAAO,YAAY,CAAC,UAAU,CAAC,CACxD,UAAU,SAAS,OAAO,SAAS,CAAC,UAAU,CAAC,CAC/C,UACC,aACA,OAAO,YAAY,CAAC,WAAW,MAAM,EAAE,KAAK,CAAC,CAC9C,CACA,UAAU,SAAS,OAAO,SAAS,CAAC,CACpC,YAAY,8BAA8B;GAAC;GAAa;GAAU;GAAc,CAAC,CACjF,YAAY,aAAa,CAAC,QAAQ,CAAC;GACtC,CACD,SAAS,qBAAqB,MAAM;AACnC,SAAO,EACJ,UAAU,MAAM,UAAU,CAAC,CAC3B,UAAU,gBAAgB,OAAO,SAAS,CAAC,CAC3C,UAAU,SAAS,OAAO,SAAS,CAAC,CACpC,UAAU,WAAW,OAAO,OAAO,CAAC,CACpC,UAAU,UAAU,OAAO,OAAO,CAAC,UAAU,CAAC,CAC9C,UACC,aACA,OAAO,YAAY,CAAC,WAAW,MAAM,EAAE,KAAK,CAAC,CAC9C,CACA,YAAY,2BAA2B,CAAC,eAAe,EAAE,EAAE,QAAQ,MAAM,CAAC,CAC1E,YAAY,kBAAkB,CAAC,QAAQ,CAAC;GAC3C;EACJ"}
1
+ {"version":3,"file":"internal-fragment.schema.js","names":[],"sources":["../../src/fragments/internal-fragment.schema.ts"],"sourcesContent":["import { schema, idColumn, column } from \"../schema/create\";\n\n// Constants for Fragno's internal settings table\nexport const SETTINGS_TABLE_NAME = \"fragno_db_settings\" as const;\n// FIXME: In some places we simply use empty string \"\" as namespace, which is not correct.\nexport const SETTINGS_NAMESPACE = \"fragno-db-settings\" as const;\n\nexport const internalSchema = schema(\"fragno_internal\", (s) => {\n return s\n .addTable(SETTINGS_TABLE_NAME, (t) => {\n return t\n .addColumn(\"id\", idColumn())\n .addColumn(\"key\", column(\"string\"))\n .addColumn(\"value\", column(\"string\"))\n .createIndex(\"unique_key\", [\"key\"], { unique: true });\n })\n .addTable(\"fragno_hooks\", (t) => {\n return t\n .addColumn(\"id\", idColumn())\n .addColumn(\"namespace\", column(\"string\"))\n .addColumn(\"hookName\", column(\"string\"))\n .addColumn(\"payload\", column(\"json\"))\n .addColumn(\"status\", column(\"string\")) // \"pending\" | \"processing\" | \"completed\" | \"failed\"\n .addColumn(\"attempts\", column(\"integer\").defaultTo(0))\n .addColumn(\"maxAttempts\", column(\"integer\").defaultTo(5))\n .addColumn(\"lastAttemptAt\", column(\"timestamp\").nullable())\n .addColumn(\"nextRetryAt\", column(\"timestamp\").nullable())\n .addColumn(\"error\", column(\"string\").nullable())\n .addColumn(\n \"createdAt\",\n column(\"timestamp\").defaultTo((b) => b.now()),\n )\n .addColumn(\"nonce\", column(\"string\"))\n .createIndex(\"idx_namespace_status_retry\", [\"namespace\", \"status\", \"nextRetryAt\"])\n .createIndex(\"idx_nonce\", [\"nonce\"]);\n })\n .addTable(\"fragno_db_outbox\", (t) => {\n return t\n .addColumn(\"id\", idColumn())\n .addColumn(\"versionstamp\", column(\"string\"))\n .addColumn(\"uowId\", column(\"string\"))\n .addColumn(\"payload\", column(\"json\"))\n .addColumn(\"refMap\", column(\"json\").nullable())\n .addColumn(\n \"createdAt\",\n column(\"timestamp\").defaultTo((b) => b.now()),\n )\n .createIndex(\"idx_outbox_versionstamp\", [\"versionstamp\"], { unique: true })\n .createIndex(\"idx_outbox_uow\", [\"uowId\"]);\n })\n .addTable(\"fragno_db_outbox_mutations\", (t) => {\n return t\n .addColumn(\"id\", idColumn())\n .addColumn(\"entryVersionstamp\", column(\"string\"))\n .addColumn(\"mutationVersionstamp\", column(\"string\"))\n .addColumn(\"uowId\", column(\"string\"))\n .addColumn(\"schema\", column(\"string\"))\n .addColumn(\"table\", column(\"string\"))\n .addColumn(\"externalId\", column(\"string\"))\n .addColumn(\"op\", column(\"string\"))\n .addColumn(\n \"createdAt\",\n column(\"timestamp\").defaultTo((b) => b.now()),\n )\n .createIndex(\"idx_outbox_mutations_entry\", [\"entryVersionstamp\"])\n .createIndex(\"idx_outbox_mutations_key\", [\n \"schema\",\n \"table\",\n \"externalId\",\n \"entryVersionstamp\",\n ])\n .createIndex(\"idx_outbox_mutations_uow\", [\"uowId\"]);\n })\n .addTable(\"fragno_db_sync_requests\", (t) => {\n return t\n .addColumn(\"id\", idColumn())\n .addColumn(\"requestId\", column(\"string\"))\n .addColumn(\"status\", column(\"string\"))\n .addColumn(\"confirmedCommandIds\", column(\"json\"))\n .addColumn(\"conflictCommandId\", column(\"string\").nullable())\n .addColumn(\"baseVersionstamp\", column(\"string\").nullable())\n .addColumn(\"lastVersionstamp\", column(\"string\").nullable())\n .addColumn(\n \"createdAt\",\n column(\"timestamp\").defaultTo((b) => b.now()),\n )\n .createIndex(\"idx_sync_request_id\", [\"requestId\"], { unique: true });\n })\n .alterTable(\"fragno_hooks\", (t) =>\n t.createIndex(\"idx_namespace_status_last_attempt\", [\"namespace\", \"status\", \"lastAttemptAt\"]),\n )\n .alterTable(\"fragno_hooks\", (t) =>\n t.createIndex(\"idx_namespace_created_at\", [\"namespace\", \"createdAt\", \"id\"]),\n );\n});\n"],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ //#region src/hooks/durable-hooks-logger.d.ts
2
+
3
+ type DurableHooksLogLevel = "off" | "error" | "warn" | "info" | "debug";
4
+ type DurableHooksLoggerConfig = {
5
+ enabled?: boolean;
6
+ level?: DurableHooksLogLevel;
7
+ };
8
+ //#endregion
9
+ export { DurableHooksLoggerConfig };
10
+ //# sourceMappingURL=durable-hooks-logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"durable-hooks-logger.d.ts","names":[],"sources":["../../src/hooks/durable-hooks-logger.ts"],"sourcesContent":[],"mappings":";;AAmBY,KAFA,oBAAA,GAEwB,KAAA,GAAA,OAE1B,GAAA,MAAA,GAAA,MAAoB,GAAA,OAAA;KAFlB,wBAAA;;UAEF"}
@@ -0,0 +1,75 @@
1
+ //#region src/hooks/durable-hooks-logger.ts
2
+ const LOG_LEVEL_PRIORITY = {
3
+ off: 0,
4
+ error: 1,
5
+ warn: 2,
6
+ info: 3,
7
+ debug: 4
8
+ };
9
+ const DEFAULT_SCOPE = {
10
+ enabled: true,
11
+ level: "warn"
12
+ };
13
+ var DurableHooksLogger = class DurableHooksLogger {
14
+ static #defaultScope = { ...DEFAULT_SCOPE };
15
+ static #namespaceScopes = /* @__PURE__ */ new Map();
16
+ static configure(config, namespace) {
17
+ if (!config) return;
18
+ const target = namespace ? DurableHooksLogger.#namespaceScopes.get(namespace) ?? { ...DurableHooksLogger.#defaultScope } : { ...DurableHooksLogger.#defaultScope };
19
+ if (config.enabled !== void 0) target.enabled = config.enabled;
20
+ if (config.level !== void 0) target.level = config.level;
21
+ if (namespace) {
22
+ DurableHooksLogger.#namespaceScopes.set(namespace, target);
23
+ return;
24
+ }
25
+ DurableHooksLogger.#defaultScope = target;
26
+ }
27
+ static enable(namespace) {
28
+ DurableHooksLogger.configure({ enabled: true }, namespace);
29
+ }
30
+ static disable(namespace) {
31
+ DurableHooksLogger.configure({ enabled: false }, namespace);
32
+ }
33
+ static setLogLevel(level, namespace) {
34
+ DurableHooksLogger.configure({ level }, namespace);
35
+ }
36
+ static debug(message, options) {
37
+ DurableHooksLogger.#log("debug", message, options);
38
+ }
39
+ static info(message, options) {
40
+ DurableHooksLogger.#log("info", message, options);
41
+ }
42
+ static warn(message, options) {
43
+ DurableHooksLogger.#log("warn", message, options);
44
+ }
45
+ static error(message, options) {
46
+ DurableHooksLogger.#log("error", message, options);
47
+ }
48
+ static toErrorMessage(error) {
49
+ return error instanceof Error ? error.message : String(error);
50
+ }
51
+ static #log(level, message, options) {
52
+ const scope = DurableHooksLogger.#resolveScope(options?.namespace);
53
+ if (!scope.enabled) return;
54
+ if (LOG_LEVEL_PRIORITY[level] > LOG_LEVEL_PRIORITY[scope.level]) return;
55
+ const fields = DurableHooksLogger.#resolveFields(options?.fields);
56
+ const payload = {
57
+ at: (/* @__PURE__ */ new Date()).toISOString(),
58
+ ...options?.namespace ? { namespace: options.namespace } : {},
59
+ ...fields
60
+ };
61
+ console[level](`[fragno-db] ${message}`, payload);
62
+ }
63
+ static #resolveScope(namespace) {
64
+ if (!namespace) return DurableHooksLogger.#defaultScope;
65
+ return DurableHooksLogger.#namespaceScopes.get(namespace) ?? DurableHooksLogger.#defaultScope;
66
+ }
67
+ static #resolveFields(fields) {
68
+ if (!fields) return {};
69
+ return typeof fields === "function" ? fields() : fields;
70
+ }
71
+ };
72
+
73
+ //#endregion
74
+ export { DurableHooksLogger };
75
+ //# sourceMappingURL=durable-hooks-logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"durable-hooks-logger.js","names":["LOG_LEVEL_PRIORITY: Record<DurableHooksLogLevel, number>","DEFAULT_SCOPE: Required<DurableHooksLoggerConfig>","#defaultScope","#namespaceScopes","#log","#resolveScope","#resolveFields"],"sources":["../../src/hooks/durable-hooks-logger.ts"],"sourcesContent":["type LogFields = Record<string, unknown>;\ntype LogFieldsInput = LogFields | (() => LogFields);\n\ntype LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\";\nconst LOG_LEVEL_PRIORITY: Record<DurableHooksLogLevel, number> = {\n off: 0,\n error: 1,\n warn: 2,\n info: 3,\n debug: 4,\n};\n\nconst DEFAULT_SCOPE: Required<DurableHooksLoggerConfig> = {\n enabled: true,\n level: \"warn\",\n};\n\nexport type DurableHooksLogLevel = \"off\" | \"error\" | \"warn\" | \"info\" | \"debug\";\n\nexport type DurableHooksLoggerConfig = {\n enabled?: boolean;\n level?: DurableHooksLogLevel;\n};\n\ntype LoggerScope = Required<DurableHooksLoggerConfig>;\n\ntype LogOptions = {\n namespace?: string;\n fields?: LogFieldsInput;\n};\n\nexport class DurableHooksLogger {\n static #defaultScope: LoggerScope = { ...DEFAULT_SCOPE };\n static #namespaceScopes = new Map<string, LoggerScope>();\n\n static configure(config?: DurableHooksLoggerConfig, namespace?: string): void {\n if (!config) {\n return;\n }\n\n const target = namespace\n ? (DurableHooksLogger.#namespaceScopes.get(namespace) ?? {\n ...DurableHooksLogger.#defaultScope,\n })\n : { ...DurableHooksLogger.#defaultScope };\n\n if (config.enabled !== undefined) {\n target.enabled = config.enabled;\n }\n if (config.level !== undefined) {\n target.level = config.level;\n }\n\n if (namespace) {\n DurableHooksLogger.#namespaceScopes.set(namespace, target);\n return;\n }\n\n DurableHooksLogger.#defaultScope = target;\n }\n\n static enable(namespace?: string): void {\n DurableHooksLogger.configure({ enabled: true }, namespace);\n }\n\n static disable(namespace?: string): void {\n DurableHooksLogger.configure({ enabled: false }, namespace);\n }\n\n static setLogLevel(level: DurableHooksLogLevel, namespace?: string): void {\n DurableHooksLogger.configure({ level }, namespace);\n }\n\n static debug(message: string, options?: LogOptions): void {\n DurableHooksLogger.#log(\"debug\", message, options);\n }\n\n static info(message: string, options?: LogOptions): void {\n DurableHooksLogger.#log(\"info\", message, options);\n }\n\n static warn(message: string, options?: LogOptions): void {\n DurableHooksLogger.#log(\"warn\", message, options);\n }\n\n static error(message: string, options?: LogOptions): void {\n DurableHooksLogger.#log(\"error\", message, options);\n }\n\n static toErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n }\n\n static #log(level: LogLevel, message: string, options?: LogOptions): void {\n const scope = DurableHooksLogger.#resolveScope(options?.namespace);\n if (!scope.enabled) {\n return;\n }\n if (LOG_LEVEL_PRIORITY[level] > LOG_LEVEL_PRIORITY[scope.level]) {\n return;\n }\n\n const fields = DurableHooksLogger.#resolveFields(options?.fields);\n const payload = {\n at: new Date().toISOString(),\n ...(options?.namespace ? { namespace: options.namespace } : {}),\n ...fields,\n };\n\n console[level](`[fragno-db] ${message}`, payload);\n }\n\n static #resolveScope(namespace?: string): LoggerScope {\n if (!namespace) {\n return DurableHooksLogger.#defaultScope;\n }\n return DurableHooksLogger.#namespaceScopes.get(namespace) ?? DurableHooksLogger.#defaultScope;\n }\n\n static #resolveFields(fields?: LogFieldsInput): LogFields {\n if (!fields) {\n return {};\n }\n return typeof fields === \"function\" ? fields() : fields;\n }\n}\n"],"mappings":";AAIA,MAAMA,qBAA2D;CAC/D,KAAK;CACL,OAAO;CACP,MAAM;CACN,MAAM;CACN,OAAO;CACR;AAED,MAAMC,gBAAoD;CACxD,SAAS;CACT,OAAO;CACR;AAgBD,IAAa,qBAAb,MAAa,mBAAmB;CAC9B,QAAOC,eAA6B,EAAE,GAAG,eAAe;CACxD,QAAOC,kCAAmB,IAAI,KAA0B;CAExD,OAAO,UAAU,QAAmC,WAA0B;AAC5E,MAAI,CAAC,OACH;EAGF,MAAM,SAAS,YACV,oBAAmBA,gBAAiB,IAAI,UAAU,IAAI,EACrD,GAAG,oBAAmBD,cACvB,GACD,EAAE,GAAG,oBAAmBA,cAAe;AAE3C,MAAI,OAAO,YAAY,OACrB,QAAO,UAAU,OAAO;AAE1B,MAAI,OAAO,UAAU,OACnB,QAAO,QAAQ,OAAO;AAGxB,MAAI,WAAW;AACb,uBAAmBC,gBAAiB,IAAI,WAAW,OAAO;AAC1D;;AAGF,sBAAmBD,eAAgB;;CAGrC,OAAO,OAAO,WAA0B;AACtC,qBAAmB,UAAU,EAAE,SAAS,MAAM,EAAE,UAAU;;CAG5D,OAAO,QAAQ,WAA0B;AACvC,qBAAmB,UAAU,EAAE,SAAS,OAAO,EAAE,UAAU;;CAG7D,OAAO,YAAY,OAA6B,WAA0B;AACxE,qBAAmB,UAAU,EAAE,OAAO,EAAE,UAAU;;CAGpD,OAAO,MAAM,SAAiB,SAA4B;AACxD,sBAAmBE,IAAK,SAAS,SAAS,QAAQ;;CAGpD,OAAO,KAAK,SAAiB,SAA4B;AACvD,sBAAmBA,IAAK,QAAQ,SAAS,QAAQ;;CAGnD,OAAO,KAAK,SAAiB,SAA4B;AACvD,sBAAmBA,IAAK,QAAQ,SAAS,QAAQ;;CAGnD,OAAO,MAAM,SAAiB,SAA4B;AACxD,sBAAmBA,IAAK,SAAS,SAAS,QAAQ;;CAGpD,OAAO,eAAe,OAAwB;AAC5C,SAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;;CAG/D,QAAOA,IAAK,OAAiB,SAAiB,SAA4B;EACxE,MAAM,QAAQ,oBAAmBC,aAAc,SAAS,UAAU;AAClE,MAAI,CAAC,MAAM,QACT;AAEF,MAAI,mBAAmB,SAAS,mBAAmB,MAAM,OACvD;EAGF,MAAM,SAAS,oBAAmBC,cAAe,SAAS,OAAO;EACjE,MAAM,UAAU;GACd,qBAAI,IAAI,MAAM,EAAC,aAAa;GAC5B,GAAI,SAAS,YAAY,EAAE,WAAW,QAAQ,WAAW,GAAG,EAAE;GAC9D,GAAG;GACJ;AAED,UAAQ,OAAO,eAAe,WAAW,QAAQ;;CAGnD,QAAOD,aAAc,WAAiC;AACpD,MAAI,CAAC,UACH,QAAO,oBAAmBH;AAE5B,SAAO,oBAAmBC,gBAAiB,IAAI,UAAU,IAAI,oBAAmBD;;CAGlF,QAAOI,cAAe,QAAoC;AACxD,MAAI,CAAC,OACH,QAAO,EAAE;AAEX,SAAO,OAAO,WAAW,aAAa,QAAQ,GAAG"}
@@ -1,14 +1 @@
1
- import { AnySchema } from "../schema/create.js";
2
- import { AnyFragnoInstantiatedDatabaseFragment } from "../mod.js";
3
-
4
- //#region src/hooks/durable-hooks-processor.d.ts
5
- type DurableHooksProcessor = {
6
- process: () => Promise<number>;
7
- getNextWakeAt: () => Promise<Date | null>;
8
- drain: () => Promise<void>;
9
- namespace: string;
10
- };
11
- declare function createDurableHooksProcessor<TSchema extends AnySchema>(fragment: AnyFragnoInstantiatedDatabaseFragment<TSchema>): DurableHooksProcessor | null;
12
- //#endregion
13
- export { DurableHooksProcessor, createDurableHooksProcessor };
14
- //# sourceMappingURL=durable-hooks-processor.d.ts.map
1
+ import "../mod.js";
@@ -1,4 +1,5 @@
1
- import { createHookScheduler } from "./hooks.js";
1
+ import { getDurableHooksRuntimeByToken } from "./durable-hooks-runtime.js";
2
+ import { createDurableHooksRunner } from "./hooks.js";
2
3
 
3
4
  //#region src/hooks/durable-hooks-processor.ts
4
5
  const DEFAULT_STUCK_PROCESSING_TIMEOUT_MINUTES = 10;
@@ -7,26 +8,73 @@ function resolveStuckProcessingTimeoutMinutes(value) {
7
8
  if (typeof value === "number") return value > 0 ? value : false;
8
9
  return DEFAULT_STUCK_PROCESSING_TIMEOUT_MINUTES;
9
10
  }
11
+ function hasDurableHooksConfigured(fragment) {
12
+ const internal = fragment.$internal;
13
+ return Boolean(internal?.durableHooksToken);
14
+ }
10
15
  function createDurableHooksProcessor(fragment) {
11
- const durableHooks = fragment.$internal.durableHooks;
12
- if (!durableHooks) return null;
16
+ const durableHooksToken = fragment.$internal.durableHooksToken;
17
+ if (!durableHooksToken) throw new Error(`[fragno-db] Durable hooks not configured for fragment "${fragment.name}".`);
18
+ const runtime = getDurableHooksRuntimeByToken(durableHooksToken);
19
+ if (!runtime) throw new Error(`[fragno-db] Durable hooks runtime missing for fragment "${fragment.name}".`);
20
+ runtime.dispatcherRegistered = true;
21
+ const durableHooks = runtime.config;
13
22
  const { namespace, internalFragment } = durableHooks;
14
23
  const stuckProcessingTimeoutMinutes = resolveStuckProcessingTimeoutMinutes(durableHooks.stuckProcessingTimeoutMinutes);
15
- const scheduler = durableHooks.scheduler ?? (durableHooks.scheduler = createHookScheduler(durableHooks));
24
+ const runner = durableHooks.runner ?? (durableHooks.runner = durableHooks.scheduler ? {
25
+ processDue: () => durableHooks.scheduler.schedule(),
26
+ drain: () => durableHooks.scheduler.drain()
27
+ } : createDurableHooksRunner(durableHooks));
16
28
  return {
17
29
  namespace,
18
- process: async () => scheduler.schedule(),
19
- drain: async () => scheduler.drain(),
30
+ processDue: async () => runner.processDue(),
31
+ process: async () => runner.processDue(),
32
+ drain: async () => runner.drain(),
20
33
  getNextWakeAt: async () => {
21
- const services = internalFragment.services;
22
- const now = services.getDbNow ? await services.getDbNow() : /* @__PURE__ */ new Date();
23
34
  return await internalFragment.inContext(async function() {
24
- return await this.handlerTx().withServiceCalls(() => [internalFragment.services.hookService.getNextHookWakeAt(namespace, stuckProcessingTimeoutMinutes, now)]).transform(({ serviceResult: [result] }) => result).execute();
35
+ return await this.handlerTx().withServiceCalls(() => [internalFragment.services.hookService.getNextHookWakeAt(namespace, stuckProcessingTimeoutMinutes)]).transform(({ serviceResult: [result] }) => result).execute();
25
36
  });
26
37
  }
27
38
  };
28
39
  }
40
+ function createDurableHooksProcessorGroup(fragments, options = {}) {
41
+ const configuredFragments = fragments.filter(hasDurableHooksConfigured);
42
+ if (configuredFragments.length === 0) throw new Error("[fragno-db] No fragments provided for durable hooks processing.");
43
+ return createDurableHooksProcessorGroupFromProcessors(configuredFragments.map((fragment) => createDurableHooksProcessor(fragment)), options);
44
+ }
45
+ function createDurableHooksProcessorGroupFromProcessors(processors, options = {}) {
46
+ if (processors.length === 0) throw new Error("[fragno-db] No processors provided for durable hooks processing.");
47
+ if (processors.length === 1) return processors[0];
48
+ const onError = options.onError ?? (() => {});
49
+ const namespace = processors.map((processor) => processor.namespace).join(",");
50
+ const processDue = async () => {
51
+ const results = await Promise.allSettled(processors.map(async (processor) => await processor.processDue()));
52
+ let processed = 0;
53
+ for (const result of results) if (result.status === "fulfilled") processed += result.value;
54
+ else onError(result.reason);
55
+ return processed;
56
+ };
57
+ return {
58
+ namespace,
59
+ processDue,
60
+ process: processDue,
61
+ drain: async () => {
62
+ const results = await Promise.allSettled(processors.map(async (processor) => await processor.drain()));
63
+ for (const result of results) if (result.status === "rejected") onError(result.reason);
64
+ },
65
+ getNextWakeAt: async () => {
66
+ const results = await Promise.allSettled(processors.map(async (processor) => await processor.getNextWakeAt()));
67
+ let nextWakeAt = null;
68
+ for (const result of results) if (result.status === "fulfilled") {
69
+ const wakeAt = result.value;
70
+ if (!wakeAt) continue;
71
+ if (!nextWakeAt || wakeAt.getTime() < nextWakeAt.getTime()) nextWakeAt = wakeAt;
72
+ } else onError(result.reason);
73
+ return nextWakeAt;
74
+ }
75
+ };
76
+ }
29
77
 
30
78
  //#endregion
31
- export { createDurableHooksProcessor };
79
+ export { createDurableHooksProcessorGroup };
32
80
  //# sourceMappingURL=durable-hooks-processor.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"durable-hooks-processor.js","names":[],"sources":["../../src/hooks/durable-hooks-processor.ts"],"sourcesContent":["import type { AnySchema } from \"../schema/create\";\nimport type { AnyFragnoInstantiatedDatabaseFragment } from \"../mod\";\nimport { createHookScheduler, type HookProcessorConfig } from \"./hooks\";\n\nexport type DurableHooksProcessor = {\n process: () => Promise<number>;\n getNextWakeAt: () => Promise<Date | null>;\n drain: () => Promise<void>;\n namespace: string;\n};\n\ntype DurableHooksInternal = {\n durableHooks?: HookProcessorConfig;\n};\n\nconst DEFAULT_STUCK_PROCESSING_TIMEOUT_MINUTES = 10;\n\nfunction resolveStuckProcessingTimeoutMinutes(value: number | false | undefined): number | false {\n if (value === false) {\n return false;\n }\n if (typeof value === \"number\") {\n return value > 0 ? value : false;\n }\n return DEFAULT_STUCK_PROCESSING_TIMEOUT_MINUTES;\n}\n\nexport function createDurableHooksProcessor<TSchema extends AnySchema>(\n fragment: AnyFragnoInstantiatedDatabaseFragment<TSchema>,\n): DurableHooksProcessor | null {\n const durableHooks = (fragment.$internal as DurableHooksInternal).durableHooks;\n if (!durableHooks) {\n return null;\n }\n\n const { namespace, internalFragment } = durableHooks;\n const stuckProcessingTimeoutMinutes = resolveStuckProcessingTimeoutMinutes(\n durableHooks.stuckProcessingTimeoutMinutes,\n );\n const scheduler =\n durableHooks.scheduler ?? (durableHooks.scheduler = createHookScheduler(durableHooks));\n\n return {\n namespace,\n process: async () => scheduler.schedule(),\n drain: async () => scheduler.drain(),\n getNextWakeAt: async () => {\n const services = internalFragment.services as { getDbNow?: () => Promise<Date> };\n const now = services.getDbNow ? await services.getDbNow() : new Date();\n return await internalFragment.inContext(async function () {\n return await this.handlerTx()\n .withServiceCalls(\n () =>\n [\n internalFragment.services.hookService.getNextHookWakeAt(\n namespace,\n stuckProcessingTimeoutMinutes,\n now,\n ),\n ] as const,\n )\n .transform(({ serviceResult: [result] }) => result)\n .execute();\n });\n },\n };\n}\n"],"mappings":";;;AAeA,MAAM,2CAA2C;AAEjD,SAAS,qCAAqC,OAAmD;AAC/F,KAAI,UAAU,MACZ,QAAO;AAET,KAAI,OAAO,UAAU,SACnB,QAAO,QAAQ,IAAI,QAAQ;AAE7B,QAAO;;AAGT,SAAgB,4BACd,UAC8B;CAC9B,MAAM,eAAgB,SAAS,UAAmC;AAClE,KAAI,CAAC,aACH,QAAO;CAGT,MAAM,EAAE,WAAW,qBAAqB;CACxC,MAAM,gCAAgC,qCACpC,aAAa,8BACd;CACD,MAAM,YACJ,aAAa,cAAc,aAAa,YAAY,oBAAoB,aAAa;AAEvF,QAAO;EACL;EACA,SAAS,YAAY,UAAU,UAAU;EACzC,OAAO,YAAY,UAAU,OAAO;EACpC,eAAe,YAAY;GACzB,MAAM,WAAW,iBAAiB;GAClC,MAAM,MAAM,SAAS,WAAW,MAAM,SAAS,UAAU,mBAAG,IAAI,MAAM;AACtE,UAAO,MAAM,iBAAiB,UAAU,iBAAkB;AACxD,WAAO,MAAM,KAAK,WAAW,CAC1B,uBAEG,CACE,iBAAiB,SAAS,YAAY,kBACpC,WACA,+BACA,IACD,CACF,CACJ,CACA,WAAW,EAAE,eAAe,CAAC,cAAc,OAAO,CAClD,SAAS;KACZ;;EAEL"}
1
+ {"version":3,"file":"durable-hooks-processor.js","names":["nextWakeAt: Date | null"],"sources":["../../src/hooks/durable-hooks-processor.ts"],"sourcesContent":["import type { AnyFragnoInstantiatedDatabaseFragment } from \"../mod\";\nimport type { AnySchema } from \"../schema/create\";\nimport { getDurableHooksRuntimeByToken } from \"./durable-hooks-runtime\";\nimport { createDurableHooksRunner } from \"./hooks\";\n\nexport type DurableHooksProcessor = {\n processDue: () => Promise<number>;\n /**\n * @deprecated Use processDue().\n */\n process: () => Promise<number>;\n getNextWakeAt: () => Promise<Date | null>;\n drain: () => Promise<void>;\n namespace: string;\n};\n\nexport type DurableHooksProcessorGroupOptions = {\n onError?: (error: unknown) => void;\n};\n\ntype DurableHooksInternal = {\n durableHooksToken?: object;\n};\n\nconst DEFAULT_STUCK_PROCESSING_TIMEOUT_MINUTES = 10;\n\nfunction resolveStuckProcessingTimeoutMinutes(value: number | false | undefined): number | false {\n if (value === false) {\n return false;\n }\n if (typeof value === \"number\") {\n return value > 0 ? value : false;\n }\n return DEFAULT_STUCK_PROCESSING_TIMEOUT_MINUTES;\n}\n\nfunction hasDurableHooksConfigured(\n fragment: AnyFragnoInstantiatedDatabaseFragment,\n): fragment is AnyFragnoInstantiatedDatabaseFragment {\n const internal = fragment.$internal as DurableHooksInternal | undefined;\n return Boolean(internal?.durableHooksToken);\n}\n\nexport function createDurableHooksProcessor<TSchema extends AnySchema>(\n fragment: AnyFragnoInstantiatedDatabaseFragment<TSchema>,\n): DurableHooksProcessor {\n const durableHooksToken = (fragment.$internal as DurableHooksInternal).durableHooksToken;\n if (!durableHooksToken) {\n throw new Error(`[fragno-db] Durable hooks not configured for fragment \"${fragment.name}\".`);\n }\n const runtime = getDurableHooksRuntimeByToken(durableHooksToken);\n if (!runtime) {\n throw new Error(`[fragno-db] Durable hooks runtime missing for fragment \"${fragment.name}\".`);\n }\n runtime.dispatcherRegistered = true;\n\n const durableHooks = runtime.config;\n\n const { namespace, internalFragment } = durableHooks;\n const stuckProcessingTimeoutMinutes = resolveStuckProcessingTimeoutMinutes(\n durableHooks.stuckProcessingTimeoutMinutes,\n );\n const runner =\n durableHooks.runner ??\n (durableHooks.runner = durableHooks.scheduler\n ? {\n processDue: () => durableHooks.scheduler!.schedule(),\n drain: () => durableHooks.scheduler!.drain(),\n }\n : createDurableHooksRunner(durableHooks));\n\n return {\n namespace,\n processDue: async () => runner.processDue(),\n process: async () => runner.processDue(),\n drain: async () => runner.drain(),\n getNextWakeAt: async () => {\n return await internalFragment.inContext(async function () {\n return await this.handlerTx()\n .withServiceCalls(\n () =>\n [\n internalFragment.services.hookService.getNextHookWakeAt(\n namespace,\n stuckProcessingTimeoutMinutes,\n ),\n ] as const,\n )\n .transform(({ serviceResult: [result] }) => result)\n .execute();\n });\n },\n };\n}\n\nexport function createDurableHooksProcessorGroup(\n fragments: readonly AnyFragnoInstantiatedDatabaseFragment[],\n options: DurableHooksProcessorGroupOptions = {},\n): DurableHooksProcessor {\n const configuredFragments = fragments.filter(hasDurableHooksConfigured);\n if (configuredFragments.length === 0) {\n throw new Error(\"[fragno-db] No fragments provided for durable hooks processing.\");\n }\n const processors = configuredFragments.map((fragment) => createDurableHooksProcessor(fragment));\n\n return createDurableHooksProcessorGroupFromProcessors(processors, options);\n}\n\nexport function createDurableHooksProcessorGroupFromProcessors(\n processors: readonly DurableHooksProcessor[],\n options: DurableHooksProcessorGroupOptions = {},\n): DurableHooksProcessor {\n if (processors.length === 0) {\n throw new Error(\"[fragno-db] No processors provided for durable hooks processing.\");\n }\n if (processors.length === 1) {\n return processors[0];\n }\n\n const onError = options.onError ?? (() => {});\n const namespace = processors.map((processor) => processor.namespace).join(\",\");\n\n const processDue = async () => {\n const results = await Promise.allSettled(\n processors.map(async (processor) => await processor.processDue()),\n );\n let processed = 0;\n for (const result of results) {\n if (result.status === \"fulfilled\") {\n processed += result.value;\n } else {\n onError(result.reason);\n }\n }\n return processed;\n };\n\n return {\n namespace,\n processDue,\n process: processDue,\n drain: async () => {\n const results = await Promise.allSettled(\n processors.map(async (processor) => await processor.drain()),\n );\n for (const result of results) {\n if (result.status === \"rejected\") {\n onError(result.reason);\n }\n }\n },\n getNextWakeAt: async () => {\n const results = await Promise.allSettled(\n processors.map(async (processor) => await processor.getNextWakeAt()),\n );\n let nextWakeAt: Date | null = null;\n for (const result of results) {\n if (result.status === \"fulfilled\") {\n const wakeAt = result.value;\n if (!wakeAt) {\n continue;\n }\n if (!nextWakeAt || wakeAt.getTime() < nextWakeAt.getTime()) {\n nextWakeAt = wakeAt;\n }\n } else {\n onError(result.reason);\n }\n }\n return nextWakeAt;\n },\n };\n}\n"],"mappings":";;;;AAwBA,MAAM,2CAA2C;AAEjD,SAAS,qCAAqC,OAAmD;AAC/F,KAAI,UAAU,MACZ,QAAO;AAET,KAAI,OAAO,UAAU,SACnB,QAAO,QAAQ,IAAI,QAAQ;AAE7B,QAAO;;AAGT,SAAS,0BACP,UACmD;CACnD,MAAM,WAAW,SAAS;AAC1B,QAAO,QAAQ,UAAU,kBAAkB;;AAG7C,SAAgB,4BACd,UACuB;CACvB,MAAM,oBAAqB,SAAS,UAAmC;AACvE,KAAI,CAAC,kBACH,OAAM,IAAI,MAAM,0DAA0D,SAAS,KAAK,IAAI;CAE9F,MAAM,UAAU,8BAA8B,kBAAkB;AAChE,KAAI,CAAC,QACH,OAAM,IAAI,MAAM,2DAA2D,SAAS,KAAK,IAAI;AAE/F,SAAQ,uBAAuB;CAE/B,MAAM,eAAe,QAAQ;CAE7B,MAAM,EAAE,WAAW,qBAAqB;CACxC,MAAM,gCAAgC,qCACpC,aAAa,8BACd;CACD,MAAM,SACJ,aAAa,WACZ,aAAa,SAAS,aAAa,YAChC;EACE,kBAAkB,aAAa,UAAW,UAAU;EACpD,aAAa,aAAa,UAAW,OAAO;EAC7C,GACD,yBAAyB,aAAa;AAE5C,QAAO;EACL;EACA,YAAY,YAAY,OAAO,YAAY;EAC3C,SAAS,YAAY,OAAO,YAAY;EACxC,OAAO,YAAY,OAAO,OAAO;EACjC,eAAe,YAAY;AACzB,UAAO,MAAM,iBAAiB,UAAU,iBAAkB;AACxD,WAAO,MAAM,KAAK,WAAW,CAC1B,uBAEG,CACE,iBAAiB,SAAS,YAAY,kBACpC,WACA,8BACD,CACF,CACJ,CACA,WAAW,EAAE,eAAe,CAAC,cAAc,OAAO,CAClD,SAAS;KACZ;;EAEL;;AAGH,SAAgB,iCACd,WACA,UAA6C,EAAE,EACxB;CACvB,MAAM,sBAAsB,UAAU,OAAO,0BAA0B;AACvE,KAAI,oBAAoB,WAAW,EACjC,OAAM,IAAI,MAAM,kEAAkE;AAIpF,QAAO,+CAFY,oBAAoB,KAAK,aAAa,4BAA4B,SAAS,CAAC,EAE7B,QAAQ;;AAG5E,SAAgB,+CACd,YACA,UAA6C,EAAE,EACxB;AACvB,KAAI,WAAW,WAAW,EACxB,OAAM,IAAI,MAAM,mEAAmE;AAErF,KAAI,WAAW,WAAW,EACxB,QAAO,WAAW;CAGpB,MAAM,UAAU,QAAQ,kBAAkB;CAC1C,MAAM,YAAY,WAAW,KAAK,cAAc,UAAU,UAAU,CAAC,KAAK,IAAI;CAE9E,MAAM,aAAa,YAAY;EAC7B,MAAM,UAAU,MAAM,QAAQ,WAC5B,WAAW,IAAI,OAAO,cAAc,MAAM,UAAU,YAAY,CAAC,CAClE;EACD,IAAI,YAAY;AAChB,OAAK,MAAM,UAAU,QACnB,KAAI,OAAO,WAAW,YACpB,cAAa,OAAO;MAEpB,SAAQ,OAAO,OAAO;AAG1B,SAAO;;AAGT,QAAO;EACL;EACA;EACA,SAAS;EACT,OAAO,YAAY;GACjB,MAAM,UAAU,MAAM,QAAQ,WAC5B,WAAW,IAAI,OAAO,cAAc,MAAM,UAAU,OAAO,CAAC,CAC7D;AACD,QAAK,MAAM,UAAU,QACnB,KAAI,OAAO,WAAW,WACpB,SAAQ,OAAO,OAAO;;EAI5B,eAAe,YAAY;GACzB,MAAM,UAAU,MAAM,QAAQ,WAC5B,WAAW,IAAI,OAAO,cAAc,MAAM,UAAU,eAAe,CAAC,CACrE;GACD,IAAIA,aAA0B;AAC9B,QAAK,MAAM,UAAU,QACnB,KAAI,OAAO,WAAW,aAAa;IACjC,MAAM,SAAS,OAAO;AACtB,QAAI,CAAC,OACH;AAEF,QAAI,CAAC,cAAc,OAAO,SAAS,GAAG,WAAW,SAAS,CACxD,cAAa;SAGf,SAAQ,OAAO,OAAO;AAG1B,UAAO;;EAEV"}
@@ -0,0 +1,44 @@
1
+ import { DurableHooksLogger } from "./durable-hooks-logger.js";
2
+
3
+ //#region src/hooks/durable-hooks-runtime.ts
4
+ const runtimeByToken = /* @__PURE__ */ new WeakMap();
5
+ const runtimeByConfig = /* @__PURE__ */ new WeakMap();
6
+ const runtimesByInternalFragment = /* @__PURE__ */ new WeakMap();
7
+ function getNamespaceRuntimeMap(internalFragment, createIfMissing = false) {
8
+ const existing = runtimesByInternalFragment.get(internalFragment);
9
+ if (existing || !createIfMissing) return existing;
10
+ const created = /* @__PURE__ */ new Map();
11
+ runtimesByInternalFragment.set(internalFragment, created);
12
+ return created;
13
+ }
14
+ function registerDurableHooksRuntime(config) {
15
+ const existing = runtimeByConfig.get(config);
16
+ if (existing) return existing.token;
17
+ const token = {};
18
+ const runtime = {
19
+ token,
20
+ config,
21
+ dispatcherRegistered: false,
22
+ dispatcherWarningEmitted: false
23
+ };
24
+ runtimeByToken.set(token, runtime);
25
+ runtimeByConfig.set(config, runtime);
26
+ const runtimeByNamespace = getNamespaceRuntimeMap(config.internalFragment, true);
27
+ const existingForNamespace = runtimeByNamespace?.get(config.namespace);
28
+ if (existingForNamespace && existingForNamespace.config !== config) DurableHooksLogger.warn("Durable hooks runtime already registered for namespace", { namespace: config.namespace });
29
+ runtimeByNamespace?.set(config.namespace, runtime);
30
+ return token;
31
+ }
32
+ function getDurableHooksRuntimeByToken(token) {
33
+ return runtimeByToken.get(token);
34
+ }
35
+ function getDurableHooksRuntimeByConfig(config) {
36
+ return runtimeByConfig.get(config);
37
+ }
38
+ function getDurableHooksRuntimeByNamespace(namespace, internalFragment) {
39
+ return getNamespaceRuntimeMap(internalFragment)?.get(namespace);
40
+ }
41
+
42
+ //#endregion
43
+ export { getDurableHooksRuntimeByConfig, getDurableHooksRuntimeByNamespace, getDurableHooksRuntimeByToken, registerDurableHooksRuntime };
44
+ //# sourceMappingURL=durable-hooks-runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"durable-hooks-runtime.js","names":["runtime: DurableHooksRuntimeState"],"sources":["../../src/hooks/durable-hooks-runtime.ts"],"sourcesContent":["import { DurableHooksLogger } from \"./durable-hooks-logger\";\nimport type { HookProcessorConfig } from \"./hooks\";\n\ntype DurableHooksRuntimeState = {\n token: object;\n config: HookProcessorConfig;\n dispatcherRegistered: boolean;\n dispatcherWarningEmitted: boolean;\n};\n\nconst runtimeByToken = new WeakMap<object, DurableHooksRuntimeState>();\nconst runtimeByConfig = new WeakMap<HookProcessorConfig, DurableHooksRuntimeState>();\nconst runtimesByInternalFragment = new WeakMap<\n HookProcessorConfig[\"internalFragment\"],\n Map<string, DurableHooksRuntimeState>\n>();\n\nfunction getNamespaceRuntimeMap(\n internalFragment: HookProcessorConfig[\"internalFragment\"],\n createIfMissing = false,\n) {\n const existing = runtimesByInternalFragment.get(internalFragment);\n if (existing || !createIfMissing) {\n return existing;\n }\n const created = new Map<string, DurableHooksRuntimeState>();\n runtimesByInternalFragment.set(internalFragment, created);\n return created;\n}\n\nexport function registerDurableHooksRuntime(config: HookProcessorConfig): object {\n const existing = runtimeByConfig.get(config);\n if (existing) {\n return existing.token;\n }\n\n const token = {};\n const runtime: DurableHooksRuntimeState = {\n token,\n config,\n dispatcherRegistered: false,\n dispatcherWarningEmitted: false,\n };\n\n runtimeByToken.set(token, runtime);\n runtimeByConfig.set(config, runtime);\n const runtimeByNamespace = getNamespaceRuntimeMap(config.internalFragment, true);\n const existingForNamespace = runtimeByNamespace?.get(config.namespace);\n if (existingForNamespace && existingForNamespace.config !== config) {\n DurableHooksLogger.warn(\"Durable hooks runtime already registered for namespace\", {\n namespace: config.namespace,\n });\n }\n runtimeByNamespace?.set(config.namespace, runtime);\n\n return token;\n}\n\nexport function getDurableHooksRuntimeByToken(token: object): DurableHooksRuntimeState | undefined {\n return runtimeByToken.get(token);\n}\n\nexport function getDurableHooksRuntimeByConfig(\n config: HookProcessorConfig,\n): DurableHooksRuntimeState | undefined {\n return runtimeByConfig.get(config);\n}\n\nexport function getDurableHooksRuntimeByNamespace(\n namespace: string,\n internalFragment: HookProcessorConfig[\"internalFragment\"],\n): DurableHooksRuntimeState | undefined {\n return getNamespaceRuntimeMap(internalFragment)?.get(namespace);\n}\n\nexport function getDurableHooksNotifierByNamespace(\n namespace: string,\n internalFragment: HookProcessorConfig[\"internalFragment\"],\n) {\n return getNamespaceRuntimeMap(internalFragment)?.get(namespace)?.config.notifier;\n}\n"],"mappings":";;;AAUA,MAAM,iCAAiB,IAAI,SAA2C;AACtE,MAAM,kCAAkB,IAAI,SAAwD;AACpF,MAAM,6CAA6B,IAAI,SAGpC;AAEH,SAAS,uBACP,kBACA,kBAAkB,OAClB;CACA,MAAM,WAAW,2BAA2B,IAAI,iBAAiB;AACjE,KAAI,YAAY,CAAC,gBACf,QAAO;CAET,MAAM,0BAAU,IAAI,KAAuC;AAC3D,4BAA2B,IAAI,kBAAkB,QAAQ;AACzD,QAAO;;AAGT,SAAgB,4BAA4B,QAAqC;CAC/E,MAAM,WAAW,gBAAgB,IAAI,OAAO;AAC5C,KAAI,SACF,QAAO,SAAS;CAGlB,MAAM,QAAQ,EAAE;CAChB,MAAMA,UAAoC;EACxC;EACA;EACA,sBAAsB;EACtB,0BAA0B;EAC3B;AAED,gBAAe,IAAI,OAAO,QAAQ;AAClC,iBAAgB,IAAI,QAAQ,QAAQ;CACpC,MAAM,qBAAqB,uBAAuB,OAAO,kBAAkB,KAAK;CAChF,MAAM,uBAAuB,oBAAoB,IAAI,OAAO,UAAU;AACtE,KAAI,wBAAwB,qBAAqB,WAAW,OAC1D,oBAAmB,KAAK,0DAA0D,EAChF,WAAW,OAAO,WACnB,CAAC;AAEJ,qBAAoB,IAAI,OAAO,WAAW,QAAQ;AAElD,QAAO;;AAGT,SAAgB,8BAA8B,OAAqD;AACjG,QAAO,eAAe,IAAI,MAAM;;AAGlC,SAAgB,+BACd,QACsC;AACtC,QAAO,gBAAgB,IAAI,OAAO;;AAGpC,SAAgB,kCACd,WACA,kBACsC;AACtC,QAAO,uBAAuB,iBAAiB,EAAE,IAAI,UAAU"}
@@ -1,7 +1,9 @@
1
+ import { DbNow } from "../query/db-now.js";
1
2
  import { FragnoId } from "../schema/create.js";
2
3
  import { RetryPolicy } from "../query/unit-of-work/retry-policy.js";
3
4
  import { ExecuteTxOptions, HandlerTxBuilder } from "../query/unit-of-work/execute-unit-of-work.js";
4
5
  import "../fragments/internal-fragment.js";
6
+ import { DurableHooksLoggerConfig } from "./durable-hooks-logger.js";
5
7
  import "../query/unit-of-work/unit-of-work.js";
6
8
 
7
9
  //#region src/hooks/hooks.d.ts
@@ -16,11 +18,45 @@ interface HookContext {
16
18
  * Use this for idempotency checks in your hook implementation.
17
19
  */
18
20
  idempotencyKey: string;
21
+ /**
22
+ * Hook event identifier (versioned FragnoId).
23
+ */
24
+ hookId: FragnoId;
25
+ /**
26
+ * Hook name for this event.
27
+ */
28
+ hookName: string;
29
+ /**
30
+ * Current status of the hook event.
31
+ */
32
+ status: HookStatus;
33
+ /**
34
+ * Attempt count for this hook event.
35
+ */
36
+ attempts: number;
37
+ /**
38
+ * Maximum attempts configured for this hook event.
39
+ */
40
+ maxAttempts: number;
41
+ /**
42
+ * Timestamp of the last attempt (if any).
43
+ */
44
+ lastAttemptAt: Date | null;
45
+ /**
46
+ * Next scheduled retry timestamp (if any).
47
+ */
48
+ nextRetryAt: Date | null;
49
+ /**
50
+ * When the hook event was created.
51
+ */
52
+ createdAt: Date;
19
53
  /**
20
54
  * Create a handler transaction builder to run atomic operations.
21
55
  */
22
56
  handlerTx: HookHandlerTx;
23
57
  }
58
+ declare const hookStatusValues: readonly ["pending", "processing", "completed", "failed"];
59
+ type HookStatus = (typeof hookStatusValues)[number];
24
60
  /**
25
61
  * A hook function signature.
26
62
  * Hooks receive a typed payload and access context via `this`.
@@ -44,21 +80,33 @@ interface TriggerHookOptions {
44
80
  * If not provided, uses the default retry policy.
45
81
  */
46
82
  retryPolicy?: RetryPolicy;
83
+ /**
84
+ * Optional hook event ID. When provided, the hook insert will fail if a hook
85
+ * with the same ID already exists.
86
+ */
87
+ id?: string | FragnoId;
47
88
  /**
48
89
  * Absolute time for the first attempt. If in the future, the hook is
49
90
  * scheduled for that time; if in the past, it runs immediately.
50
91
  */
51
- processAt?: Date;
92
+ processAt?: Date | DbNow;
52
93
  }
53
94
  /**
54
95
  * Internal representation of a triggered hook.
55
96
  * Stored in the Unit of Work before execution.
56
97
  */
57
98
  interface TriggeredHook {
99
+ namespace: string;
58
100
  hookName: string;
59
101
  payload: unknown;
60
102
  options?: TriggerHookOptions;
61
103
  }
104
+ type HookNotifySource = "request" | "hook" | "alarm";
105
+ type HookNotifyContext = {
106
+ source: HookNotifySource;
107
+ route?: string | null;
108
+ waitUntil?: (promise: Promise<unknown>) => void;
109
+ };
62
110
  type StuckHookProcessingTimeoutMinutes = number | false;
63
111
  type StuckHookProcessingEvent = {
64
112
  id: FragnoId;
@@ -82,13 +130,23 @@ type DurableHooksProcessingOptions = {
82
130
  * Default: 10 minutes.
83
131
  */
84
132
  stuckProcessingTimeoutMinutes?: StuckHookProcessingTimeoutMinutes;
133
+ /**
134
+ * Automatically schedule hook processing after successful mutations.
135
+ * Defaults to true. Set false to disable auto scheduling (manual drain only).
136
+ */
137
+ autoSchedule?: boolean;
85
138
  /**
86
139
  * Called when stuck processing hooks are detected and re-queued.
87
140
  * Invoked after the hooks are moved back to `pending`.
88
141
  */
89
142
  onStuckProcessingHooks?: (info: StuckHookProcessingInfo) => void;
143
+ /**
144
+ * Durable hooks logging controls.
145
+ * Defaults: enabled=true, level="warn".
146
+ */
147
+ logging?: DurableHooksLoggerConfig;
90
148
  };
91
149
  type HookHandlerTx = (execOptions?: Omit<ExecuteTxOptions, "createUnitOfWork">) => HandlerTxBuilder<readonly [], [], [], unknown, unknown, false, false, false, false, HooksMap>;
92
150
  //#endregion
93
- export { DurableHooksProcessingOptions, HookContext, HookFn, HookPayload, HooksMap, StuckHookProcessingEvent, StuckHookProcessingInfo, StuckHookProcessingTimeoutMinutes, TriggerHookOptions, TriggeredHook };
151
+ export { DurableHooksProcessingOptions, HookContext, HookFn, HookHandlerTx, HookNotifyContext, HookPayload, HookStatus, HooksMap, StuckHookProcessingEvent, StuckHookProcessingInfo, StuckHookProcessingTimeoutMinutes, TriggerHookOptions, TriggeredHook };
94
152
  //# sourceMappingURL=hooks.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"hooks.d.ts","names":[],"sources":["../../src/hooks/hooks.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;AAeA;AAgBA;AAOY,UAvBK,WAAA,CAuBqB;EAK1B;;;;EAA8C,cAAA,EAAA,MAAA;EAKzC;AAiBjB;AAuCA;EAEY,SAAA,EAlFC,aAkFD;;;;;AASZ;AAMY,KA1FA,MA0FA,CAAA,WAAA,OAA6B,CAAA,GAAA,CAAA,OAQP,EAlGiB,QAkGjB,EAAA,GAAA,IAAA,GAlGqC,OAkGrC,CAAA,IAAA,CAKA;AAGlC;;;;AAEK,KArGO,QAAA,GAAW,MAqGlB,CAAA,MAAA,EArGiC,MAqGjC,CAAA,GAAA,CAAA,CAAA;;;;KAhGO,iBAAiB,UAAU,kBAAkB;;;;UAKxC,kBAAA;;;;;gBAKD;;;;;cAKF;;;;;;UAOG,aAAA;;;YAGL;;KAoCA,iCAAA;KAEA,wBAAA;MACN;;;;iBAIW;eACF;;KAGH,uBAAA;;;UAGF;;KAGE,6BAAA;;;;;;;;kCAQsB;;;;;kCAKA;;KAGtB,aAAA,kBACI,KAAK,0CAChB,oFAAoF"}
1
+ {"version":3,"file":"hooks.d.ts","names":[],"sources":["../../src/hooks/hooks.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;AAgBA;;AAiBU,UAjBO,WAAA,CAiBP;EAYO;;;;EAYS,cAAA,EAAA,MAAA;EAGb;AAEb;AAgBA;EAOY,MAAA,EA5DF,QA4DU;EAKR;;;EAA6C,QAAA,EAAA,MAAA;EAAC;AAK1D;;EAUgB,MAAA,EAxEN,UAwEM;EAKF;;;EAOG,QAAA,EAAA,MAAa;EAOlB;AAEZ;AAgEA;EAEY,WAAA,EAAA,MAAA;EACN;;;EAKa,aAAA,EAzJF,IAyJE,GAAA,IAAA;EAGP;AAMZ;;EAkBkC,WAAA,EAhLnB,IAgLmB,GAAA,IAAA;EAKtB;;AAGZ;EACqB,SAAA,EArLR,IAqLQ;EAAL;;;EACK,SAAA,EAlLR,aAkLQ;;cA/KR;KAED,UAAA,WAAqB;;;;;KAgBrB,uCAAuC,oBAAoB;;;;;KAO3D,QAAA,GAAW,eAAe;;;;KAK1B,iBAAiB,UAAU,kBAAkB;;;;UAKxC,kBAAA;;;;;gBAKD;;;;;gBAKA;;;;;cAKF,OAAO;;;;;;UAOJ,aAAA;;;;YAIL;;KAGA,gBAAA;KAEA,iBAAA;UACF;;wBAEc;;KA6DZ,iCAAA;KAEA,wBAAA;MACN;;;;iBAIW;eACF;;KAGH,uBAAA;;;UAGF;;KAGE,6BAAA;;;;;;;;kCAQsB;;;;;;;;;;kCAUA;;;;;YAKtB;;KAGA,aAAA,kBACI,KAAK,0CAChB,oFAAoF"}