@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
@@ -0,0 +1,113 @@
1
+ //#region src/migration-engine/shared.d.ts
2
+ interface ForeignKeyInfo {
3
+ name: string;
4
+ columns: string[];
5
+ referencedTable: string;
6
+ referencedColumns: string[];
7
+ }
8
+ /**
9
+ * Provider-specific metadata that can be attached to operations during preprocessing.
10
+ * This allows providers to add additional context without polluting the core operation types.
11
+ */
12
+ interface MigrationOperationMetadata {
13
+ [key: string]: unknown;
14
+ }
15
+ interface ColumnInfo {
16
+ name: string;
17
+ type: "string" | "integer" | "bigint" | "decimal" | "bool" | "date" | "timestamp" | "json" | "binary" | `varchar(${number})`;
18
+ isNullable: boolean;
19
+ role: "external-id" | "internal-id" | "version" | "reference" | "regular";
20
+ default?: {
21
+ value: unknown;
22
+ } | {
23
+ dbSpecial: "now";
24
+ } | {
25
+ runtime: "cuid" | "now";
26
+ };
27
+ }
28
+ type MigrationOperation<TMeta extends MigrationOperationMetadata = MigrationOperationMetadata> = (TableOperation & {
29
+ metadata?: TMeta;
30
+ }) | ({
31
+ type: "add-foreign-key";
32
+ table: string;
33
+ value: ForeignKeyInfo;
34
+ } & {
35
+ metadata?: TMeta;
36
+ }) | ({
37
+ type: "drop-foreign-key";
38
+ table: string;
39
+ name: string;
40
+ referencedTable: string;
41
+ } & {
42
+ metadata?: TMeta;
43
+ }) | ({
44
+ type: "drop-index";
45
+ table: string;
46
+ name: string;
47
+ } & {
48
+ metadata?: TMeta;
49
+ }) | ({
50
+ type: "add-index";
51
+ table: string;
52
+ columns: string[];
53
+ name: string;
54
+ unique: boolean;
55
+ } & {
56
+ metadata?: TMeta;
57
+ }) | (CustomOperation & {
58
+ metadata?: TMeta;
59
+ });
60
+ type CustomOperation = {
61
+ type: "custom";
62
+ } & Record<string, unknown>;
63
+ type TableOperation = {
64
+ type: "create-table";
65
+ name: string;
66
+ columns: ColumnInfo[];
67
+ } | {
68
+ type: "drop-table";
69
+ name: string;
70
+ } | {
71
+ type: "alter-table";
72
+ name: string;
73
+ value: ColumnOperation[];
74
+ } | {
75
+ type: "rename-table";
76
+ from: string;
77
+ to: string;
78
+ };
79
+ type ColumnOperation = {
80
+ type: "rename-column";
81
+ from: string;
82
+ to: string;
83
+ } | {
84
+ type: "drop-column";
85
+ name: string;
86
+ } | {
87
+ /**
88
+ * Note: unique constraints are not created, please use dedicated operations like `add-index` instead
89
+ */
90
+ type: "create-column";
91
+ value: ColumnInfo;
92
+ } | {
93
+ /**
94
+ * warning: Not supported by SQLite
95
+ */
96
+ type: "update-column";
97
+ name: string;
98
+ /**
99
+ * For databases like MySQL, it requires the full definition for any modify column statement.
100
+ * Hence, you need to specify the full information of your column here.
101
+ *
102
+ * Then, opt-in for in-detail modification for other databases that supports changing data type/nullable/default separately, such as PostgreSQL.
103
+ *
104
+ * Note: unique constraints are not updated, please use dedicated operations like `add-index` instead
105
+ */
106
+ value: ColumnInfo;
107
+ updateNullable: boolean;
108
+ updateDefault: boolean;
109
+ updateDataType: boolean;
110
+ };
111
+ //#endregion
112
+ export { MigrationOperation };
113
+ //# sourceMappingURL=shared.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.d.ts","names":[],"sources":["../../src/migration-engine/shared.ts"],"sourcesContent":[],"mappings":";UAAiB,cAAA;EAAA,IAAA,EAAA,MAAA;EAWA,OAAA,EAAA,MAAA,EAAA;EAYA,eAAU,EAAA,MAAA;EA+Bf,iBAAA,EAAA,MAAkB,EAAA;;;;;;AAST,UApDJ,0BAAA,CAoDI;EAOA,CAAA,GAAA,EAAA,MAAA,CAAA,EAAA,OAAA;;UA/CJ,UAAA;;;;;;;;;;;;;KA+BL,iCACI,6BAA6B,+BAExC;aAA8B;;;;SAKtB;;aACQ;;;;;;;aAOA;;;;;;aAKA;;;;;;;;aAOA;MAChB;aAA+B;;KAExB,eAAA;;IAER;KAEQ,cAAA;;;WAIG;;;;;;;SASF;;;;;;KAQD,eAAA;;;;;;;;;;;;SAeC;;;;;;;;;;;;;;;SAgBA"}
@@ -1 +1 @@
1
- {"version":3,"file":"shared.js","names":[],"sources":["../../src/migration-engine/shared.ts"],"sourcesContent":["export interface ForeignKeyInfo {\n name: string;\n columns: string[];\n referencedTable: string;\n referencedColumns: string[];\n}\n\n/**\n * Provider-specific metadata that can be attached to operations during preprocessing.\n * This allows providers to add additional context without polluting the core operation types.\n */\nexport interface MigrationOperationMetadata {\n [key: string]: unknown;\n}\n\n/**\n * SQLite-specific metadata for create-table operations.\n * Includes foreign keys that should be created inline with the table.\n */\nexport interface SqliteCreateTableMetadata extends MigrationOperationMetadata {\n inlineForeignKeys?: ForeignKeyInfo[];\n}\n\nexport interface ColumnInfo {\n name: string;\n type:\n | \"string\"\n | \"integer\"\n | \"bigint\"\n | \"decimal\"\n | \"bool\"\n | \"date\"\n | \"timestamp\"\n | \"json\"\n | \"binary\"\n | `varchar(${number})`;\n isNullable: boolean;\n role: \"external-id\" | \"internal-id\" | \"version\" | \"reference\" | \"regular\";\n default?: { value: unknown } | { dbSpecial: \"now\" } | { runtime: \"cuid\" | \"now\" };\n}\n\nexport type MigrationOperation<\n TMeta extends MigrationOperationMetadata = MigrationOperationMetadata,\n> =\n | (TableOperation & { metadata?: TMeta })\n | ({\n // warning: not supported by SQLite\n type: \"add-foreign-key\";\n table: string;\n value: ForeignKeyInfo;\n } & { metadata?: TMeta })\n | ({\n // warning: not supported by SQLite\n type: \"drop-foreign-key\";\n table: string;\n name: string;\n referencedTable: string;\n } & { metadata?: TMeta })\n | ({\n type: \"drop-index\";\n table: string;\n name: string;\n } & { metadata?: TMeta })\n | ({\n type: \"add-index\";\n table: string;\n columns: string[];\n name: string;\n unique: boolean;\n } & { metadata?: TMeta })\n | (CustomOperation & { metadata?: TMeta });\n\nexport type CustomOperation = {\n type: \"custom\";\n} & Record<string, unknown>;\n\nexport type TableOperation =\n | {\n type: \"create-table\";\n name: string;\n columns: ColumnInfo[];\n }\n | {\n type: \"drop-table\";\n name: string;\n }\n | {\n type: \"alter-table\";\n name: string;\n value: ColumnOperation[];\n }\n | {\n type: \"rename-table\";\n from: string;\n to: string;\n };\n\nexport type ColumnOperation =\n | {\n type: \"rename-column\";\n from: string;\n to: string;\n }\n | {\n type: \"drop-column\";\n name: string;\n }\n | {\n /**\n * Note: unique constraints are not created, please use dedicated operations like `add-index` instead\n */\n type: \"create-column\";\n value: ColumnInfo;\n }\n | {\n /**\n * warning: Not supported by SQLite\n */\n type: \"update-column\";\n name: string;\n /**\n * For databases like MySQL, it requires the full definition for any modify column statement.\n * Hence, you need to specify the full information of your column here.\n *\n * Then, opt-in for in-detail modification for other databases that supports changing data type/nullable/default separately, such as PostgreSQL.\n *\n * Note: unique constraints are not updated, please use dedicated operations like `add-index` instead\n */\n value: ColumnInfo;\n\n updateNullable: boolean;\n updateDefault: boolean;\n updateDataType: boolean;\n };\n\nexport function isUpdated(op: Extract<ColumnOperation, { type: \"update-column\" }>): boolean {\n return op.updateDataType || op.updateDefault || op.updateNullable;\n}\n"],"mappings":";AAuIA,SAAgB,UAAU,IAAkE;AAC1F,QAAO,GAAG,kBAAkB,GAAG,iBAAiB,GAAG"}
1
+ {"version":3,"file":"shared.js","names":[],"sources":["../../src/migration-engine/shared.ts"],"sourcesContent":["export interface ForeignKeyInfo {\n name: string;\n columns: string[];\n referencedTable: string;\n referencedColumns: string[];\n}\n\n/**\n * Provider-specific metadata that can be attached to operations during preprocessing.\n * This allows providers to add additional context without polluting the core operation types.\n */\nexport interface MigrationOperationMetadata {\n [key: string]: unknown;\n}\n\n/**\n * SQLite-specific metadata for create-table operations.\n * Includes foreign keys that should be created inline with the table.\n */\nexport interface SqliteCreateTableMetadata extends MigrationOperationMetadata {\n inlineForeignKeys?: ForeignKeyInfo[];\n}\n\nexport interface ColumnInfo {\n name: string;\n type:\n | \"string\"\n | \"integer\"\n | \"bigint\"\n | \"decimal\"\n | \"bool\"\n | \"date\"\n | \"timestamp\"\n | \"json\"\n | \"binary\"\n | `varchar(${number})`;\n isNullable: boolean;\n role: \"external-id\" | \"internal-id\" | \"version\" | \"reference\" | \"regular\";\n default?: { value: unknown } | { dbSpecial: \"now\" } | { runtime: \"cuid\" | \"now\" };\n}\n\nexport interface SqliteRecreateTableInfo {\n columns: ColumnInfo[];\n copyColumns: SqliteCopyColumn[];\n indexes: { name: string; columns: string[]; unique: boolean }[];\n foreignKeys: ForeignKeyInfo[];\n}\n\nexport type SqliteCopyColumn = string | { from: string; to: string };\n\nexport interface SqliteAlterTableMetadata extends MigrationOperationMetadata {\n recreateTable?: SqliteRecreateTableInfo;\n}\n\nexport type MigrationOperation<\n TMeta extends MigrationOperationMetadata = MigrationOperationMetadata,\n> =\n | (TableOperation & { metadata?: TMeta })\n | ({\n // warning: not supported by SQLite\n type: \"add-foreign-key\";\n table: string;\n value: ForeignKeyInfo;\n } & { metadata?: TMeta })\n | ({\n // warning: not supported by SQLite\n type: \"drop-foreign-key\";\n table: string;\n name: string;\n referencedTable: string;\n } & { metadata?: TMeta })\n | ({\n type: \"drop-index\";\n table: string;\n name: string;\n } & { metadata?: TMeta })\n | ({\n type: \"add-index\";\n table: string;\n columns: string[];\n name: string;\n unique: boolean;\n } & { metadata?: TMeta })\n | (CustomOperation & { metadata?: TMeta });\n\nexport type CustomOperation = {\n type: \"custom\";\n} & Record<string, unknown>;\n\nexport type TableOperation =\n | {\n type: \"create-table\";\n name: string;\n columns: ColumnInfo[];\n }\n | {\n type: \"drop-table\";\n name: string;\n }\n | {\n type: \"alter-table\";\n name: string;\n value: ColumnOperation[];\n }\n | {\n type: \"rename-table\";\n from: string;\n to: string;\n };\n\nexport type ColumnOperation =\n | {\n type: \"rename-column\";\n from: string;\n to: string;\n }\n | {\n type: \"drop-column\";\n name: string;\n }\n | {\n /**\n * Note: unique constraints are not created, please use dedicated operations like `add-index` instead\n */\n type: \"create-column\";\n value: ColumnInfo;\n }\n | {\n /**\n * warning: Not supported by SQLite\n */\n type: \"update-column\";\n name: string;\n /**\n * For databases like MySQL, it requires the full definition for any modify column statement.\n * Hence, you need to specify the full information of your column here.\n *\n * Then, opt-in for in-detail modification for other databases that supports changing data type/nullable/default separately, such as PostgreSQL.\n *\n * Note: unique constraints are not updated, please use dedicated operations like `add-index` instead\n */\n value: ColumnInfo;\n\n updateNullable: boolean;\n updateDefault: boolean;\n updateDataType: boolean;\n };\n\nexport function isUpdated(op: Extract<ColumnOperation, { type: \"update-column\" }>): boolean {\n return op.updateDataType || op.updateDefault || op.updateNullable;\n}\n"],"mappings":";AAoJA,SAAgB,UAAU,IAAkE;AAC1F,QAAO,GAAG,kBAAkB,GAAG,iBAAiB,GAAG"}
package/dist/mod.d.ts CHANGED
@@ -1,21 +1,24 @@
1
- import { DbNow, dbNow } from "./query/db-now.js";
1
+ import { DbInterval, DbIntervalInput, DbNow, dbInterval, dbNow } from "./query/db-now.js";
2
2
  import { AnySchema } from "./schema/create.js";
3
3
  import { Cursor, CursorData, CursorResult, decodeCursor } from "./query/cursor.js";
4
4
  import { ExponentialBackoffRetryPolicy, LinearBackoffRetryPolicy, NoRetryPolicy, RetryPolicy } from "./query/unit-of-work/retry-policy.js";
5
- import { BuilderTransformContextWithMutate, BuilderTransformContextWithoutMutate, ConcurrencyConflictError, ExtractServiceFinalResults, ExtractServiceRetrieveResults, HandlerBuilderMutateContext, HandlerTxBuilder, ServiceBuilderMutateContext, ServiceTxBuilder, TxResult, createHandlerTxBuilder, createServiceTxBuilder } from "./query/unit-of-work/execute-unit-of-work.js";
6
- import { DatabaseFragmentContext, DatabaseFragmentDefinitionBuilder, DatabaseHandlerContext, DatabaseServiceContext, FragnoPublicConfigWithDatabase, ImplicitDatabaseDependencies } from "./db-fragment-definition-builder.js";
5
+ import { BuilderTransformContextWithMutate, BuilderTransformContextWithoutMutate, ConcurrencyConflictError, ExtractServiceFinalResults, ExtractServiceRetrieveResults, HandlerBuilderMutateContext, HandlerTxBuilder, HandlerTxContext, ServiceBuilderMutateContext, ServiceTxBuilder, TxResult, createHandlerTxBuilder, createServiceTxBuilder, serviceCalls } from "./query/unit-of-work/execute-unit-of-work.js";
6
+ import { OutboxConfig, OutboxEntry, OutboxMutation, OutboxPayload, OutboxRefMap } from "./outbox/outbox.js";
7
+ import { SubmitAppliedResponse, SubmitConflictReason, SubmitConflictResponse, SubmitRequest, SubmitResponse, SyncCommandDefinition, SyncCommandHandler, SyncCommandRegistry, SyncCommandTxFactory } from "./sync/types.js";
8
+ import { DatabaseFragmentContext, DatabaseFragmentDefinitionBuilder, DatabaseHandlerContext, DatabaseServiceContext, DbRoundtripGuardConfig, FragnoPublicConfigWithDatabase, ImplicitDatabaseDependencies } from "./db-fragment-definition-builder.js";
7
9
  import { InMemoryAdapterOptions } from "./adapters/in-memory/options.js";
8
10
  import { InMemoryAdapter } from "./adapters/in-memory/in-memory-adapter.js";
9
11
  import "./adapters/in-memory/index.js";
12
+ import { getInternalFragment } from "./internal/adapter-registry.js";
10
13
  import { withDatabase } from "./with-database.js";
11
- import { OutboxConfig, OutboxEntry, OutboxMutation, OutboxPayload, OutboxRefMap } from "./outbox/outbox.js";
12
- import { DurableHooksProcessor, createDurableHooksProcessor } from "./hooks/durable-hooks-processor.js";
14
+ import { defineSyncCommands } from "./sync/commands.js";
15
+ import { DurableHookRecord, DurableHookStatus, DurableHooksAccessor, DurableHooksService, getDurableHooksService } from "./durable-hooks.js";
13
16
  import { internalSchema } from "./fragments/internal-fragment.schema.js";
14
17
  import { InternalFragmentInstance, internalFragmentDef } from "./fragments/internal-fragment.js";
15
- import { DurableHooksProcessingOptions, HookContext, HookFn, HookPayload, HooksMap, StuckHookProcessingEvent, StuckHookProcessingInfo, StuckHookProcessingTimeoutMinutes, TriggerHookOptions } from "./hooks/hooks.js";
18
+ import { DurableHooksProcessingOptions, HookContext, HookFn, HookHandlerTx, HookPayload, HooksMap, StuckHookProcessingEvent, StuckHookProcessingInfo, StuckHookProcessingTimeoutMinutes, TriggerHookOptions } from "./hooks/hooks.js";
16
19
  import { IUnitOfWork, IUnitOfWorkRestricted, TypedUnitOfWork, UOWCompiler, UOWDecoder, UOWExecutor, UnitOfWork, createUnitOfWork } from "./query/unit-of-work/unit-of-work.js";
17
20
  import { DatabaseAdapter } from "./adapters/adapters.js";
18
- import { AnyFragnoInstantiatedFragment, BoundServices, FragnoInstantiatedFragment } from "@fragno-dev/core";
21
+ import { BoundServices, FragnoInstantiatedFragment } from "@fragno-dev/core";
19
22
 
20
23
  //#region src/mod.d.ts
21
24
  declare const fragnoDatabaseFakeSymbol: "$fragno-database";
@@ -41,9 +44,7 @@ declare class FragnoDatabase<const T extends AnySchema, TUOWConfig = void> {
41
44
  get schema(): T;
42
45
  get adapter(): DatabaseAdapter<TUOWConfig>;
43
46
  }
44
- type AnyFragnoInstantiatedDatabaseFragment<TSchema extends AnySchema = AnySchema> = FragnoInstantiatedFragment<any, ImplicitDatabaseDependencies<TSchema>, any, any, any, any, FragnoPublicConfigWithDatabase, {
45
- _fragno_internal: InternalFragmentInstance;
46
- } & Record<string, AnyFragnoInstantiatedFragment>>;
47
+ type AnyFragnoInstantiatedDatabaseFragment<TSchema extends AnySchema = AnySchema> = FragnoInstantiatedFragment<any, ImplicitDatabaseDependencies<TSchema>, any, any, DatabaseHandlerContext, any, FragnoPublicConfigWithDatabase>;
47
48
  /**
48
49
  * Helper function to run migrations for a database fragment.
49
50
  * Extracts the database adapter, schema, and namespace from the fragment and runs migrations.
@@ -68,5 +69,5 @@ type AnyFragnoInstantiatedDatabaseFragment<TSchema extends AnySchema = AnySchema
68
69
  */
69
70
  declare function migrate<TSchema extends AnySchema>(fragment: AnyFragnoInstantiatedDatabaseFragment<TSchema>): Promise<void>;
70
71
  //#endregion
71
- export { AnyFragnoInstantiatedDatabaseFragment, type BoundServices, type BuilderTransformContextWithMutate, type BuilderTransformContextWithoutMutate, ConcurrencyConflictError, CreateFragnoDatabaseDefinitionOptions, Cursor, type CursorData, type CursorResult, type DatabaseAdapter, type DatabaseFragmentContext, DatabaseFragmentDefinitionBuilder, type DatabaseHandlerContext as DatabaseRequestContext, type DatabaseServiceContext, type DbNow, type DurableHooksProcessingOptions, type DurableHooksProcessor, ExponentialBackoffRetryPolicy, type ExtractServiceFinalResults, type ExtractServiceRetrieveResults, FragnoDatabase, type FragnoPublicConfigWithDatabase, type HandlerBuilderMutateContext, HandlerTxBuilder, type HookContext, type HookFn, type HookPayload, type HooksMap, type IUnitOfWork, type IUnitOfWorkRestricted, type ImplicitDatabaseDependencies, InMemoryAdapter, type InMemoryAdapterOptions, type InternalFragmentInstance, LinearBackoffRetryPolicy, NoRetryPolicy, type OutboxConfig, type OutboxEntry, type OutboxMutation, type OutboxPayload, type OutboxRefMap, type RetryPolicy, type ServiceBuilderMutateContext, ServiceTxBuilder, type StuckHookProcessingEvent, type StuckHookProcessingInfo, type StuckHookProcessingTimeoutMinutes, type TriggerHookOptions, type TxResult, TypedUnitOfWork, type UOWCompiler, type UOWDecoder, type UOWExecutor, UnitOfWork, createDurableHooksProcessor, createHandlerTxBuilder, createServiceTxBuilder, createUnitOfWork, dbNow, decodeCursor, fragnoDatabaseFakeSymbol, fragnoDatabaseLibraryVersion, internalFragmentDef, internalSchema, isFragnoDatabase, migrate, withDatabase };
72
+ export { AnyFragnoInstantiatedDatabaseFragment, type BoundServices, type BuilderTransformContextWithMutate, type BuilderTransformContextWithoutMutate, ConcurrencyConflictError, CreateFragnoDatabaseDefinitionOptions, Cursor, type CursorData, type CursorResult, type DatabaseAdapter, type DatabaseFragmentContext, DatabaseFragmentDefinitionBuilder, type DatabaseHandlerContext as DatabaseRequestContext, type DatabaseServiceContext, type DbInterval, type DbIntervalInput, type DbNow, type DbRoundtripGuardConfig, type DurableHookRecord, type DurableHookStatus, type DurableHooksAccessor, type DurableHooksProcessingOptions, type DurableHooksService, ExponentialBackoffRetryPolicy, type ExtractServiceFinalResults, type ExtractServiceRetrieveResults, FragnoDatabase, type FragnoPublicConfigWithDatabase, type HandlerBuilderMutateContext, HandlerTxBuilder, type HandlerTxContext, type HookContext, type HookFn, type HookHandlerTx, type HookPayload, type HooksMap, type IUnitOfWork, type IUnitOfWorkRestricted, type ImplicitDatabaseDependencies, InMemoryAdapter, type InMemoryAdapterOptions, type InternalFragmentInstance, LinearBackoffRetryPolicy, NoRetryPolicy, type OutboxConfig, type OutboxEntry, type OutboxMutation, type OutboxPayload, type OutboxRefMap, type RetryPolicy, type ServiceBuilderMutateContext, ServiceTxBuilder, type StuckHookProcessingEvent, type StuckHookProcessingInfo, type StuckHookProcessingTimeoutMinutes, type SubmitAppliedResponse, type SubmitConflictReason, type SubmitConflictResponse, type SubmitRequest, type SubmitResponse, type SyncCommandDefinition, type SyncCommandHandler, type SyncCommandRegistry, type SyncCommandTxFactory, type TriggerHookOptions, type TxResult, TypedUnitOfWork, type UOWCompiler, type UOWDecoder, type UOWExecutor, UnitOfWork, createHandlerTxBuilder, createServiceTxBuilder, createUnitOfWork, dbInterval, dbNow, decodeCursor, defineSyncCommands, fragnoDatabaseFakeSymbol, fragnoDatabaseLibraryVersion, getDurableHooksService, getInternalFragment, internalFragmentDef, internalSchema, isFragnoDatabase, migrate, serviceCalls, withDatabase };
72
73
  //# sourceMappingURL=mod.d.ts.map
package/dist/mod.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"mod.d.ts","names":[],"sources":["../src/mod.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;;;;;;;cAuBa;cACA;UAEI,gDAAgD;;UAEvD;;AALG,iBAQG,gBAAA,CARmD,KAAA,EAAA,OAAA,CAAA,EAAA,KAAA,IAQR,cARQ,CAQO,SARP,CAAA;AACnE;AAEA;AAKA;AAmBA;AAA4C,cAA/B,cAA+B,CAAA,gBAAA,SAAA,EAAA,aAAA,IAAA,CAAA,CAAA;EAOhC,CAAA,OAAA;EACiB,WAAA,CAAA,OAAA,EAAA;IAAhB,SAAA,EAAA,MAAA,GAAA,IAAA;IAO8B,MAAA,EAR/B,CAQ+B;IAApC,OAAA,EAPM,eAON,CAPsB,UAOtB,CAAA;EAQK,CAAA;EAIqB,KAZ1B,wBAAA,GAY0B,EAAA,OAZU,wBAYV;EAAhB,IAAA,SAAA,CAAA,CAAA,EAAA,MAAA,GAAA,IAAA;EAAe,IAAA,MAAA,CAAA,CAAA,EAJpB,CAIoB;EAiFpB,IAAA,OAAA,CAAA,CAAA,EAjFK,eAiFL,CAjFqB,UAiFgB,CAAA;;AAyCrC,KAzCA,qCAyCA,CAAA,gBAzCsD,SAyCtD,GAzCkE,SAyClE,CAAA,GAxCV,0BAwCU,CAAA,GAAA,EArCR,4BAqCQ,CArCqB,OAqCrB,CAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EA5BR,8BA4BQ,EAAA;EACT,gBAAA,EA3BqB,wBA2BrB;CAAO,GA3B2C,MA2B3C,CAAA,MAAA,EA3B0D,6BA2B1D,CAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;iBAFY,wBAAwB,qBAClC,sCAAsC,WAC/C"}
1
+ {"version":3,"file":"mod.d.ts","names":[],"sources":["../src/mod.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;cA6Ba;cACA;UAEI,gDAAgD;;UAEvD;;iBAGM,gBAAA,2BAA2C,eAAe;;;AAR1E;AACA;AAEiB,cAwBJ,cAxBI,CAAA,gBAwB2B,SAxBqB,EAAA,aAEtD,IAAA,CAAA,CAAA;EAGK,CAAA,OAAA;EAmBH,WAAA,CAAA,OAAc,EAAA;IAAiB,SAAA,EAAA,MAAA,GAAA,IAAA;IAOhC,MAAA,EAAA,CAAA;IACiB,OAAA,EAAhB,eAAgB,CAAA,UAAA,CAAA;EAAhB,CAAA;EAO8B,KAApC,wBAAA,GAAoC,EAAA,OAAA,wBAAA;EAApC,IAAA,SAAA,CAAA,CAAA,EAAA,MAAA,GAAA,IAAA;EAQK,IAAA,MAAA,CAAA,CAAA,EAAA,CAAA;EAIqB,IAAA,OAAA,CAAA,CAAA,EAAhB,eAAgB,CAAA,UAAA,CAAA;;AA2IvB,KAvCE,qCAuCF,CAAA,gBAvCwD,SAuCxD,GAvCoE,SAuCpE,CAAA,GAtCR,0BAsCQ,CAAA,GAAA,EAnCN,4BAmCM,CAnCuB,OAmCvB,CAAA,EAAA,GAAA,EAAA,GAAA,EA9BN,sBA8BM,EAAA,GAAA,EA3BN,8BA2BM,CAAA;;;;;;;;;;;;;;;;;;;;;;;iBAFY,wBAAwB,qBAClC,sCAAsC,WAC/C"}
package/dist/mod.js CHANGED
@@ -1,16 +1,17 @@
1
+ import { dbInterval, dbNow } from "./query/db-now.js";
1
2
  import { ExponentialBackoffRetryPolicy, LinearBackoffRetryPolicy, NoRetryPolicy } from "./query/unit-of-work/retry-policy.js";
2
- import { ConcurrencyConflictError, HandlerTxBuilder, ServiceTxBuilder, createHandlerTxBuilder, createServiceTxBuilder } from "./query/unit-of-work/execute-unit-of-work.js";
3
- import { internalSchema } from "./fragments/internal-fragment.schema.js";
3
+ import { ConcurrencyConflictError, HandlerTxBuilder, ServiceTxBuilder, createHandlerTxBuilder, createServiceTxBuilder, serviceCalls } from "./query/unit-of-work/execute-unit-of-work.js";
4
4
  import { Cursor, decodeCursor } from "./query/cursor.js";
5
- import { dbNow } from "./query/db-now.js";
6
5
  import { TypedUnitOfWork, UnitOfWork, createUnitOfWork } from "./query/unit-of-work/unit-of-work.js";
7
- import { resolveDatabaseAdapter } from "./util/default-database-adapter.js";
6
+ import { internalSchema } from "./fragments/internal-fragment.schema.js";
8
7
  import { DatabaseFragmentDefinitionBuilder } from "./db-fragment-definition-builder.js";
9
8
  import { getSchemaVersionFromDatabase, internalFragmentDef } from "./fragments/internal-fragment.js";
9
+ import { getInternalFragment } from "./internal/adapter-registry.js";
10
+ import { getDurableHooksService } from "./durable-hooks.js";
10
11
  import { InMemoryAdapter } from "./adapters/in-memory/in-memory-adapter.js";
11
12
  import "./adapters/in-memory/index.js";
12
13
  import { withDatabase } from "./with-database.js";
13
- import { createDurableHooksProcessor } from "./hooks/durable-hooks-processor.js";
14
+ import { defineSyncCommands } from "./sync/commands.js";
14
15
 
15
16
  //#region src/mod.ts
16
17
  const fragnoDatabaseFakeSymbol = "$fragno-database";
@@ -69,13 +70,12 @@ var FragnoDatabase = class {
69
70
  * ```
70
71
  */
71
72
  async function migrate(fragment) {
72
- const { options, deps, linkedFragments } = fragment.$internal;
73
- const adapter = resolveDatabaseAdapter(options, deps.schema);
73
+ const { deps } = fragment.$internal;
74
+ const adapter = deps.databaseAdapter;
74
75
  if (!adapter.prepareMigrations) throw new Error("Database adapter does not support prepareMigrations. Please use an adapter that implements this method.");
75
76
  const schema = deps.schema;
76
77
  const namespace = deps.namespace ?? schema.name;
77
- const internalFragment = linkedFragments._fragno_internal;
78
- if (!internalFragment) throw new Error("Internal fragment not found. Please ensure the internal fragment is linked.");
78
+ const internalFragment = getInternalFragment(adapter);
79
79
  if (!await adapter.isConnectionHealthy()) throw new Error("Database connection is not healthy. Please check your database connection and try again.");
80
80
  const internalDeps = internalFragment.$internal.deps;
81
81
  const internalSchema$1 = internalDeps.schema;
@@ -90,5 +90,5 @@ async function migrate(fragment) {
90
90
  }
91
91
 
92
92
  //#endregion
93
- export { ConcurrencyConflictError, Cursor, DatabaseFragmentDefinitionBuilder, ExponentialBackoffRetryPolicy, FragnoDatabase, HandlerTxBuilder, InMemoryAdapter, LinearBackoffRetryPolicy, NoRetryPolicy, ServiceTxBuilder, TypedUnitOfWork, UnitOfWork, createDurableHooksProcessor, createHandlerTxBuilder, createServiceTxBuilder, createUnitOfWork, dbNow, decodeCursor, fragnoDatabaseFakeSymbol, fragnoDatabaseLibraryVersion, internalFragmentDef, internalSchema, isFragnoDatabase, migrate, withDatabase };
93
+ export { ConcurrencyConflictError, Cursor, DatabaseFragmentDefinitionBuilder, ExponentialBackoffRetryPolicy, FragnoDatabase, HandlerTxBuilder, InMemoryAdapter, LinearBackoffRetryPolicy, NoRetryPolicy, ServiceTxBuilder, TypedUnitOfWork, UnitOfWork, createHandlerTxBuilder, createServiceTxBuilder, createUnitOfWork, dbInterval, dbNow, decodeCursor, defineSyncCommands, fragnoDatabaseFakeSymbol, fragnoDatabaseLibraryVersion, getDurableHooksService, getInternalFragment, internalFragmentDef, internalSchema, isFragnoDatabase, migrate, serviceCalls, withDatabase };
94
94
  //# sourceMappingURL=mod.js.map
package/dist/mod.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"mod.js","names":["#namespace","#schema","#adapter","internalSchema"],"sources":["../src/mod.ts"],"sourcesContent":["import type { DatabaseAdapter } from \"./adapters/adapters\";\nimport type { AnySchema } from \"./schema/create\";\nimport type { CursorResult } from \"./query/cursor\";\nimport { Cursor } from \"./query/cursor\";\nimport { dbNow, type DbNow } from \"./query/db-now\";\nimport type { FragnoInstantiatedFragment, AnyFragnoInstantiatedFragment } from \"@fragno-dev/core\";\nimport type {\n FragnoPublicConfigWithDatabase,\n ImplicitDatabaseDependencies,\n} from \"./db-fragment-definition-builder\";\nimport {\n getSchemaVersionFromDatabase,\n type InternalFragmentInstance,\n} from \"./fragments/internal-fragment\";\nimport { resolveDatabaseAdapter } from \"./util/default-database-adapter\";\n\nexport type { DatabaseAdapter, CursorResult };\nexport { Cursor };\nexport { dbNow };\nexport type { DbNow };\nexport { InMemoryAdapter, type InMemoryAdapterOptions } from \"./adapters/in-memory\";\nexport { internalSchema } from \"./fragments/internal-fragment\";\n\nexport const fragnoDatabaseFakeSymbol = \"$fragno-database\" as const;\nexport const fragnoDatabaseLibraryVersion = \"0.1\" as const;\n\nexport interface CreateFragnoDatabaseDefinitionOptions<T extends AnySchema> {\n namespace: string | null;\n schema: T;\n}\n\nexport function isFragnoDatabase(value: unknown): value is FragnoDatabase<AnySchema> {\n if (value instanceof FragnoDatabase) {\n return true;\n }\n\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n\n return (\n fragnoDatabaseFakeSymbol in value &&\n value[fragnoDatabaseFakeSymbol] === fragnoDatabaseFakeSymbol\n );\n}\n\n/**\n * A Fragno database instance with a bound adapter.\n * Created from a FragnoDatabaseDefinition by calling .create(adapter).\n */\nexport class FragnoDatabase<const T extends AnySchema, TUOWConfig = void> {\n #namespace: string | null;\n #schema: T;\n #adapter: DatabaseAdapter<TUOWConfig>;\n\n constructor(options: {\n namespace: string | null;\n schema: T;\n adapter: DatabaseAdapter<TUOWConfig>;\n }) {\n this.#namespace = options.namespace;\n this.#schema = options.schema;\n this.#adapter = options.adapter;\n }\n\n get [fragnoDatabaseFakeSymbol](): typeof fragnoDatabaseFakeSymbol {\n return fragnoDatabaseFakeSymbol;\n }\n\n get namespace() {\n return this.#namespace;\n }\n\n get schema() {\n return this.#schema;\n }\n\n get adapter(): DatabaseAdapter<TUOWConfig> {\n return this.#adapter;\n }\n}\n\nexport {\n DatabaseFragmentDefinitionBuilder,\n type FragnoPublicConfigWithDatabase,\n type DatabaseFragmentContext,\n type DatabaseServiceContext,\n type DatabaseHandlerContext as DatabaseRequestContext,\n type ImplicitDatabaseDependencies,\n} from \"./db-fragment-definition-builder\";\n\nexport { withDatabase } from \"./with-database\";\n\nexport { decodeCursor, type CursorData } from \"./query/cursor\";\n\nexport {\n createUnitOfWork,\n UnitOfWork,\n TypedUnitOfWork,\n type IUnitOfWork,\n type IUnitOfWorkRestricted,\n type UOWCompiler,\n type UOWExecutor,\n type UOWDecoder,\n} from \"./query/unit-of-work/unit-of-work\";\n\nexport {\n type RetryPolicy,\n NoRetryPolicy,\n ExponentialBackoffRetryPolicy,\n LinearBackoffRetryPolicy,\n} from \"./query/unit-of-work/retry-policy\";\n\nexport {\n ConcurrencyConflictError,\n // Builder pattern exports\n ServiceTxBuilder,\n HandlerTxBuilder,\n createServiceTxBuilder,\n createHandlerTxBuilder,\n type TxResult,\n // Builder context types\n type ServiceBuilderMutateContext,\n type HandlerBuilderMutateContext,\n type BuilderTransformContextWithMutate,\n type BuilderTransformContextWithoutMutate,\n type ExtractServiceRetrieveResults,\n type ExtractServiceFinalResults,\n} from \"./query/unit-of-work/execute-unit-of-work\";\n\nexport type { BoundServices } from \"@fragno-dev/core\";\n\nexport { internalFragmentDef } from \"./fragments/internal-fragment\";\nexport type { InternalFragmentInstance } from \"./fragments/internal-fragment\";\nexport type {\n OutboxConfig,\n OutboxEntry,\n OutboxPayload,\n OutboxMutation,\n OutboxRefMap,\n} from \"./outbox/outbox\";\n\nexport type {\n HookContext,\n HooksMap,\n HookFn,\n HookPayload,\n TriggerHookOptions,\n DurableHooksProcessingOptions,\n StuckHookProcessingInfo,\n StuckHookProcessingEvent,\n StuckHookProcessingTimeoutMinutes,\n} from \"./hooks/hooks\";\nexport {\n createDurableHooksProcessor,\n type DurableHooksProcessor,\n} from \"./hooks/durable-hooks-processor\";\n\nexport type AnyFragnoInstantiatedDatabaseFragment<TSchema extends AnySchema = AnySchema> =\n FragnoInstantiatedFragment<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any,\n ImplicitDatabaseDependencies<TSchema>,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any,\n FragnoPublicConfigWithDatabase,\n // Ensure the fragment has the internal fragment linked\n { _fragno_internal: InternalFragmentInstance } & Record<string, AnyFragnoInstantiatedFragment>\n >;\n\n/**\n * Helper function to run migrations for a database fragment.\n * Extracts the database adapter, schema, and namespace from the fragment and runs migrations.\n * This function:\n * 1. Ensures the internal settings fragment is migrated first\n * 2. Retrieves the current database version from the internal fragment\n * 3. Runs migration from current version to target version\n *\n * @param fragment - The instantiated fragment to run migrations for\n * @throws Error if the fragment doesn't have database support or the adapter doesn't support migrations\n *\n * @example\n * ```typescript\n * const fragment = instantiate(myFragmentDef)\n * .withConfig({})\n * .withRoutes([])\n * .withOptions({ databaseAdapter: myAdapter })\n * .build();\n *\n * await migrate(fragment);\n * ```\n */\nexport async function migrate<TSchema extends AnySchema>(\n fragment: AnyFragnoInstantiatedDatabaseFragment<TSchema>,\n): Promise<void> {\n const { options, deps, linkedFragments } = fragment.$internal;\n const adapter = resolveDatabaseAdapter(options, deps.schema);\n\n // Check if adapter supports prepareMigrations\n if (!adapter.prepareMigrations) {\n throw new Error(\n \"Database adapter does not support prepareMigrations. Please use an adapter that implements this method.\",\n );\n }\n\n const schema = deps.schema;\n const namespace = deps.namespace ?? schema.name;\n\n // Step 1: Ensure the internal fragment (settings table) is migrated first\n const internalFragment = linkedFragments._fragno_internal;\n\n if (!internalFragment) {\n throw new Error(\"Internal fragment not found. Please ensure the internal fragment is linked.\");\n }\n\n if (!(await adapter.isConnectionHealthy())) {\n throw new Error(\n \"Database connection is not healthy. Please check your database connection and try again.\",\n );\n }\n\n const internalDeps = internalFragment.$internal.deps;\n const internalSchema = internalDeps.schema;\n // Internal fragment uses databaseNamespace: null (no table suffix).\n // Version tracking uses empty string so the key is \".schema_version\",\n // which matches both the legacy format and how the internal fragment was designed.\n const internalNamespace = internalDeps.namespace ?? \"\";\n\n const internalCurrentVersion = await getSchemaVersionFromDatabase(\n internalFragment,\n internalNamespace,\n );\n\n // Migrate internal fragment if needed\n if (internalCurrentVersion < internalSchema.version) {\n const internalMigrations = adapter.prepareMigrations(internalSchema, internalNamespace);\n await internalMigrations.execute(internalCurrentVersion, internalSchema.version);\n }\n\n // Step 2: Get current database version for this fragment's namespace\n const currentVersion = await getSchemaVersionFromDatabase(internalFragment, namespace);\n\n // Step 3: Run the migration from current version to target version\n const targetVersion = schema.version;\n\n if (currentVersion === targetVersion) {\n return;\n }\n\n if (currentVersion > targetVersion) {\n throw new Error(\n `Cannot migrate backwards: current version (${currentVersion}) > target version (${targetVersion})`,\n );\n }\n\n const migrations = adapter.prepareMigrations(schema, namespace);\n await migrations.execute(currentVersion, targetVersion);\n}\n"],"mappings":";;;;;;;;;;;;;;;AAuBA,MAAa,2BAA2B;AACxC,MAAa,+BAA+B;AAO5C,SAAgB,iBAAiB,OAAoD;AACnF,KAAI,iBAAiB,eACnB,QAAO;AAGT,KAAI,OAAO,UAAU,YAAY,UAAU,KACzC,QAAO;AAGT,QACE,4BAA4B,SAC5B,MAAM,8BAA8B;;;;;;AAQxC,IAAa,iBAAb,MAA0E;CACxE;CACA;CACA;CAEA,YAAY,SAIT;AACD,QAAKA,YAAa,QAAQ;AAC1B,QAAKC,SAAU,QAAQ;AACvB,QAAKC,UAAW,QAAQ;;CAG1B,KAAK,4BAA6D;AAChE,SAAO;;CAGT,IAAI,YAAY;AACd,SAAO,MAAKF;;CAGd,IAAI,SAAS;AACX,SAAO,MAAKC;;CAGd,IAAI,UAAuC;AACzC,SAAO,MAAKC;;;;;;;;;;;;;;;;;;;;;;;;;AAwHhB,eAAsB,QACpB,UACe;CACf,MAAM,EAAE,SAAS,MAAM,oBAAoB,SAAS;CACpD,MAAM,UAAU,uBAAuB,SAAS,KAAK,OAAO;AAG5D,KAAI,CAAC,QAAQ,kBACX,OAAM,IAAI,MACR,0GACD;CAGH,MAAM,SAAS,KAAK;CACpB,MAAM,YAAY,KAAK,aAAa,OAAO;CAG3C,MAAM,mBAAmB,gBAAgB;AAEzC,KAAI,CAAC,iBACH,OAAM,IAAI,MAAM,8EAA8E;AAGhG,KAAI,CAAE,MAAM,QAAQ,qBAAqB,CACvC,OAAM,IAAI,MACR,2FACD;CAGH,MAAM,eAAe,iBAAiB,UAAU;CAChD,MAAMC,mBAAiB,aAAa;CAIpC,MAAM,oBAAoB,aAAa,aAAa;CAEpD,MAAM,yBAAyB,MAAM,6BACnC,kBACA,kBACD;AAGD,KAAI,yBAAyBA,iBAAe,QAE1C,OAD2B,QAAQ,kBAAkBA,kBAAgB,kBAAkB,CAC9D,QAAQ,wBAAwBA,iBAAe,QAAQ;CAIlF,MAAM,iBAAiB,MAAM,6BAA6B,kBAAkB,UAAU;CAGtF,MAAM,gBAAgB,OAAO;AAE7B,KAAI,mBAAmB,cACrB;AAGF,KAAI,iBAAiB,cACnB,OAAM,IAAI,MACR,8CAA8C,eAAe,sBAAsB,cAAc,GAClG;AAIH,OADmB,QAAQ,kBAAkB,QAAQ,UAAU,CAC9C,QAAQ,gBAAgB,cAAc"}
1
+ {"version":3,"file":"mod.js","names":["#namespace","#schema","#adapter","internalSchema"],"sources":["../src/mod.ts"],"sourcesContent":["import type { FragnoInstantiatedFragment } from \"@fragno-dev/core\";\n\nimport type { DatabaseAdapter } from \"./adapters/adapters\";\nimport type {\n FragnoPublicConfigWithDatabase,\n ImplicitDatabaseDependencies,\n DatabaseHandlerContext,\n} from \"./db-fragment-definition-builder\";\nimport { getSchemaVersionFromDatabase } from \"./fragments/internal-fragment\";\nimport { getInternalFragment } from \"./internal/adapter-registry\";\nimport type { CursorResult } from \"./query/cursor\";\nimport { Cursor } from \"./query/cursor\";\nimport {\n dbInterval,\n dbNow,\n type DbInterval,\n type DbIntervalInput,\n type DbNow,\n} from \"./query/db-now\";\nimport type { AnySchema } from \"./schema/create\";\n\nexport type { DatabaseAdapter, CursorResult };\nexport { Cursor };\nexport { dbNow, dbInterval };\nexport type { DbNow, DbInterval, DbIntervalInput };\nexport { InMemoryAdapter, type InMemoryAdapterOptions } from \"./adapters/in-memory\";\nexport { internalSchema } from \"./fragments/internal-fragment\";\nexport { getInternalFragment } from \"./internal/adapter-registry\";\n\nexport const fragnoDatabaseFakeSymbol = \"$fragno-database\" as const;\nexport const fragnoDatabaseLibraryVersion = \"0.1\" as const;\n\nexport interface CreateFragnoDatabaseDefinitionOptions<T extends AnySchema> {\n namespace: string | null;\n schema: T;\n}\n\nexport function isFragnoDatabase(value: unknown): value is FragnoDatabase<AnySchema> {\n if (value instanceof FragnoDatabase) {\n return true;\n }\n\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n\n return (\n fragnoDatabaseFakeSymbol in value &&\n value[fragnoDatabaseFakeSymbol] === fragnoDatabaseFakeSymbol\n );\n}\n\n/**\n * A Fragno database instance with a bound adapter.\n * Created from a FragnoDatabaseDefinition by calling .create(adapter).\n */\nexport class FragnoDatabase<const T extends AnySchema, TUOWConfig = void> {\n #namespace: string | null;\n #schema: T;\n #adapter: DatabaseAdapter<TUOWConfig>;\n\n constructor(options: {\n namespace: string | null;\n schema: T;\n adapter: DatabaseAdapter<TUOWConfig>;\n }) {\n this.#namespace = options.namespace;\n this.#schema = options.schema;\n this.#adapter = options.adapter;\n }\n\n get [fragnoDatabaseFakeSymbol](): typeof fragnoDatabaseFakeSymbol {\n return fragnoDatabaseFakeSymbol;\n }\n\n get namespace() {\n return this.#namespace;\n }\n\n get schema() {\n return this.#schema;\n }\n\n get adapter(): DatabaseAdapter<TUOWConfig> {\n return this.#adapter;\n }\n}\n\nexport {\n DatabaseFragmentDefinitionBuilder,\n type DbRoundtripGuardConfig,\n type FragnoPublicConfigWithDatabase,\n type DatabaseFragmentContext,\n type DatabaseServiceContext,\n type DatabaseHandlerContext as DatabaseRequestContext,\n type ImplicitDatabaseDependencies,\n} from \"./db-fragment-definition-builder\";\n\nexport { withDatabase } from \"./with-database\";\n\nexport { decodeCursor, type CursorData } from \"./query/cursor\";\n\nexport {\n createUnitOfWork,\n UnitOfWork,\n TypedUnitOfWork,\n type IUnitOfWork,\n type IUnitOfWorkRestricted,\n type UOWCompiler,\n type UOWExecutor,\n type UOWDecoder,\n} from \"./query/unit-of-work/unit-of-work\";\n\nexport {\n type RetryPolicy,\n NoRetryPolicy,\n ExponentialBackoffRetryPolicy,\n LinearBackoffRetryPolicy,\n} from \"./query/unit-of-work/retry-policy\";\n\nexport {\n ConcurrencyConflictError,\n // Builder pattern exports\n ServiceTxBuilder,\n HandlerTxBuilder,\n createServiceTxBuilder,\n createHandlerTxBuilder,\n serviceCalls,\n type TxResult,\n // Builder context types\n type HandlerTxContext,\n type ServiceBuilderMutateContext,\n type HandlerBuilderMutateContext,\n type BuilderTransformContextWithMutate,\n type BuilderTransformContextWithoutMutate,\n type ExtractServiceRetrieveResults,\n type ExtractServiceFinalResults,\n} from \"./query/unit-of-work/execute-unit-of-work\";\n\nexport type { BoundServices } from \"@fragno-dev/core\";\n\nexport { internalFragmentDef } from \"./fragments/internal-fragment\";\nexport type { InternalFragmentInstance } from \"./fragments/internal-fragment\";\nexport type {\n OutboxConfig,\n OutboxEntry,\n OutboxPayload,\n OutboxMutation,\n OutboxRefMap,\n} from \"./outbox/outbox\";\n\nexport type {\n HookContext,\n HooksMap,\n HookFn,\n HookHandlerTx,\n HookPayload,\n TriggerHookOptions,\n DurableHooksProcessingOptions,\n StuckHookProcessingInfo,\n StuckHookProcessingEvent,\n StuckHookProcessingTimeoutMinutes,\n} from \"./hooks/hooks\";\nexport { defineSyncCommands } from \"./sync/commands\";\nexport type {\n DurableHookRecord,\n DurableHookStatus,\n DurableHooksAccessor,\n DurableHooksService,\n} from \"./durable-hooks\";\nexport { getDurableHooksService } from \"./durable-hooks\";\nexport type {\n SubmitAppliedResponse,\n SubmitConflictReason,\n SubmitConflictResponse,\n SubmitRequest,\n SubmitResponse,\n SyncCommandDefinition,\n SyncCommandHandler,\n SyncCommandRegistry,\n SyncCommandTxFactory,\n} from \"./sync/types\";\n\nexport type AnyFragnoInstantiatedDatabaseFragment<TSchema extends AnySchema = AnySchema> =\n FragnoInstantiatedFragment<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any,\n ImplicitDatabaseDependencies<TSchema>,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any,\n DatabaseHandlerContext,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any,\n FragnoPublicConfigWithDatabase\n >;\n\n/**\n * Helper function to run migrations for a database fragment.\n * Extracts the database adapter, schema, and namespace from the fragment and runs migrations.\n * This function:\n * 1. Ensures the internal settings fragment is migrated first\n * 2. Retrieves the current database version from the internal fragment\n * 3. Runs migration from current version to target version\n *\n * @param fragment - The instantiated fragment to run migrations for\n * @throws Error if the fragment doesn't have database support or the adapter doesn't support migrations\n *\n * @example\n * ```typescript\n * const fragment = instantiate(myFragmentDef)\n * .withConfig({})\n * .withRoutes([])\n * .withOptions({ databaseAdapter: myAdapter })\n * .build();\n *\n * await migrate(fragment);\n * ```\n */\nexport async function migrate<TSchema extends AnySchema>(\n fragment: AnyFragnoInstantiatedDatabaseFragment<TSchema>,\n): Promise<void> {\n const { deps } = fragment.$internal;\n const adapter = deps.databaseAdapter;\n\n // Check if adapter supports prepareMigrations\n if (!adapter.prepareMigrations) {\n throw new Error(\n \"Database adapter does not support prepareMigrations. Please use an adapter that implements this method.\",\n );\n }\n\n const schema = deps.schema;\n const namespace = deps.namespace ?? schema.name;\n\n // Step 1: Ensure the internal fragment (settings table) is migrated first\n const internalFragment = getInternalFragment(adapter);\n\n if (!(await adapter.isConnectionHealthy())) {\n throw new Error(\n \"Database connection is not healthy. Please check your database connection and try again.\",\n );\n }\n\n const internalDeps = internalFragment.$internal.deps;\n const internalSchema = internalDeps.schema;\n // Internal fragment uses databaseNamespace: null (no table suffix).\n // Version tracking uses empty string so the key is \".schema_version\",\n // which matches both the legacy format and how the internal fragment was designed.\n const internalNamespace = internalDeps.namespace ?? \"\";\n\n const internalCurrentVersion = await getSchemaVersionFromDatabase(\n internalFragment,\n internalNamespace,\n );\n\n // Migrate internal fragment if needed\n if (internalCurrentVersion < internalSchema.version) {\n const internalMigrations = adapter.prepareMigrations(internalSchema, internalNamespace);\n await internalMigrations.execute(internalCurrentVersion, internalSchema.version);\n }\n\n // Step 2: Get current database version for this fragment's namespace\n const currentVersion = await getSchemaVersionFromDatabase(internalFragment, namespace);\n\n // Step 3: Run the migration from current version to target version\n const targetVersion = schema.version;\n\n if (currentVersion === targetVersion) {\n return;\n }\n\n if (currentVersion > targetVersion) {\n throw new Error(\n `Cannot migrate backwards: current version (${currentVersion}) > target version (${targetVersion})`,\n );\n }\n\n const migrations = adapter.prepareMigrations(schema, namespace);\n await migrations.execute(currentVersion, targetVersion);\n}\n"],"mappings":";;;;;;;;;;;;;;;;AA6BA,MAAa,2BAA2B;AACxC,MAAa,+BAA+B;AAO5C,SAAgB,iBAAiB,OAAoD;AACnF,KAAI,iBAAiB,eACnB,QAAO;AAGT,KAAI,OAAO,UAAU,YAAY,UAAU,KACzC,QAAO;AAGT,QACE,4BAA4B,SAC5B,MAAM,8BAA8B;;;;;;AAQxC,IAAa,iBAAb,MAA0E;CACxE;CACA;CACA;CAEA,YAAY,SAIT;AACD,QAAKA,YAAa,QAAQ;AAC1B,QAAKC,SAAU,QAAQ;AACvB,QAAKC,UAAW,QAAQ;;CAG1B,KAAK,4BAA6D;AAChE,SAAO;;CAGT,IAAI,YAAY;AACd,SAAO,MAAKF;;CAGd,IAAI,SAAS;AACX,SAAO,MAAKC;;CAGd,IAAI,UAAuC;AACzC,SAAO,MAAKC;;;;;;;;;;;;;;;;;;;;;;;;;AAwIhB,eAAsB,QACpB,UACe;CACf,MAAM,EAAE,SAAS,SAAS;CAC1B,MAAM,UAAU,KAAK;AAGrB,KAAI,CAAC,QAAQ,kBACX,OAAM,IAAI,MACR,0GACD;CAGH,MAAM,SAAS,KAAK;CACpB,MAAM,YAAY,KAAK,aAAa,OAAO;CAG3C,MAAM,mBAAmB,oBAAoB,QAAQ;AAErD,KAAI,CAAE,MAAM,QAAQ,qBAAqB,CACvC,OAAM,IAAI,MACR,2FACD;CAGH,MAAM,eAAe,iBAAiB,UAAU;CAChD,MAAMC,mBAAiB,aAAa;CAIpC,MAAM,oBAAoB,aAAa,aAAa;CAEpD,MAAM,yBAAyB,MAAM,6BACnC,kBACA,kBACD;AAGD,KAAI,yBAAyBA,iBAAe,QAE1C,OAD2B,QAAQ,kBAAkBA,kBAAgB,kBAAkB,CAC9D,QAAQ,wBAAwBA,iBAAe,QAAQ;CAIlF,MAAM,iBAAiB,MAAM,6BAA6B,kBAAkB,UAAU;CAGtF,MAAM,gBAAgB,OAAO;AAE7B,KAAI,mBAAmB,cACrB;AAGF,KAAI,iBAAiB,cACnB,OAAM,IAAI,MACR,8CAA8C,eAAe,sBAAsB,cAAc,GAClG;AAIH,OADmB,QAAQ,kBAAkB,QAAQ,UAAU,CAC9C,QAAQ,gBAAgB,cAAc"}
@@ -1 +1 @@
1
- {"version":3,"file":"sql-naming.d.ts","names":[],"sources":["../../src/naming/sql-naming.ts"],"sourcesContent":[],"mappings":";AAGY,KAAA,cAAA,GAAc,QAAA,GAAA,QAAA;AAET,UAAA,iBAAA,CAAiB;kBAChB"}
1
+ {"version":3,"file":"sql-naming.d.ts","names":[],"sources":["../../src/naming/sql-naming.ts"],"sourcesContent":[],"mappings":";AAIY,KAAA,cAAA,GAAc,QAAA,GAAA,QAAA;AAET,UAAA,iBAAA,CAAiB;kBAChB"}
@@ -1 +1 @@
1
- {"version":3,"file":"sql-naming.js","names":["suffixNamingStrategy: SqlNamingStrategy","schemaNamingStrategy: SqlNamingStrategy","#namespace","#strategy","#tableNameMap","#columnNameMaps","columnMap: Record<string, string>"],"sources":["../../src/naming/sql-naming.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport type { AnySchema, AnyTable } from \"../schema/create\";\n\nexport type NamespaceScope = \"suffix\" | \"schema\";\n\nexport interface SqlNamingStrategy {\n namespaceScope: NamespaceScope;\n namespaceToSchema: (namespace: string) => string;\n\n tableName: (logicalTable: string, namespace: string | null) => string;\n columnName: (logicalColumn: string, logicalTable: string) => string;\n\n indexName: (logicalIndex: string, logicalTable: string, namespace: string | null) => string;\n uniqueIndexName: (logicalIndex: string, logicalTable: string, namespace: string | null) => string;\n foreignKeyName: (params: {\n logicalTable: string;\n logicalReferencedTable: string;\n referenceName: string;\n namespace: string | null;\n }) => string;\n}\n\nconst normalizeNamespace = (namespace: string | null) =>\n namespace && namespace.length > 0 ? namespace : null;\n\nconst buildNamespaceSuffix = (namespace: string | null) => {\n const sanitized = normalizeNamespace(namespace);\n return sanitized ? `_${sanitized}` : \"\";\n};\n\nconst MAX_IDENTIFIER_LENGTH = 63;\nconst HASH_LENGTH = 8;\n\nconst withHash = (value: string) => {\n const hash = createHash(\"sha1\").update(value).digest(\"hex\").slice(0, 8);\n return `${value}_${hash}`;\n};\n\nconst truncateWithHash = (value: string) => {\n if (value.length <= MAX_IDENTIFIER_LENGTH) {\n return value;\n }\n const hash = createHash(\"sha1\").update(value).digest(\"hex\").slice(0, HASH_LENGTH);\n return `${value.slice(0, MAX_IDENTIFIER_LENGTH - HASH_LENGTH)}${hash}`;\n};\n\nconst buildIndexName = (\n prefix: \"idx\" | \"uidx\",\n logicalIndex: string,\n logicalTable: string,\n namespace: string | null,\n) => {\n const base = `${logicalTable}_${logicalIndex}${buildNamespaceSuffix(namespace)}`;\n return `${prefix}_${withHash(base)}`;\n};\n\nexport const suffixNamingStrategy: SqlNamingStrategy = {\n namespaceScope: \"suffix\",\n namespaceToSchema: (namespace) => namespace,\n tableName: (logicalTable, namespace) => {\n const sanitized = normalizeNamespace(namespace);\n return truncateWithHash(sanitized ? `${logicalTable}_${sanitized}` : logicalTable);\n },\n columnName: (logicalColumn) => logicalColumn,\n indexName: (logicalIndex, logicalTable, namespace) =>\n truncateWithHash(buildIndexName(\"idx\", logicalIndex, logicalTable, namespace)),\n uniqueIndexName: (logicalIndex, logicalTable, namespace) =>\n truncateWithHash(buildIndexName(\"uidx\", logicalIndex, logicalTable, namespace)),\n foreignKeyName: ({ logicalTable, logicalReferencedTable, referenceName, namespace }) => {\n const base = `${logicalTable}_${logicalReferencedTable}_${referenceName}${buildNamespaceSuffix(namespace)}`;\n return truncateWithHash(`fk_${withHash(base)}`);\n },\n};\n\nexport const schemaNamingStrategy: SqlNamingStrategy = {\n namespaceScope: \"schema\",\n namespaceToSchema: (namespace) => namespace,\n tableName: (logicalTable) => truncateWithHash(logicalTable),\n columnName: (logicalColumn) => logicalColumn,\n indexName: (logicalIndex) => truncateWithHash(logicalIndex),\n uniqueIndexName: (logicalIndex) => truncateWithHash(logicalIndex),\n foreignKeyName: ({ logicalTable, logicalReferencedTable, referenceName }) =>\n truncateWithHash(`fk_${logicalTable}_${logicalReferencedTable}_${referenceName}`),\n};\n\nexport class NamingResolver {\n readonly #namespace: string | null;\n readonly #strategy: SqlNamingStrategy;\n readonly #tableNameMap: Record<string, string> = {};\n readonly #columnNameMaps = new Map<string, Record<string, string>>();\n\n constructor(schema: AnySchema, namespace: string | null, strategy: SqlNamingStrategy) {\n this.#namespace = namespace;\n this.#strategy = strategy;\n\n for (const table of Object.values(schema.tables)) {\n const physicalTable = this.getTableName(table.name);\n this.#tableNameMap[physicalTable] = table.name;\n\n const columnMap: Record<string, string> = {};\n for (const column of Object.values(table.columns)) {\n const physicalColumn = this.getColumnName(table.name, column.name);\n columnMap[physicalColumn] = column.name;\n }\n this.#columnNameMaps.set(table.name, columnMap);\n }\n }\n\n get namespace(): string | null {\n return this.#namespace;\n }\n\n get strategy(): SqlNamingStrategy {\n return this.#strategy;\n }\n\n getSchemaName(): string | null {\n if (this.#strategy.namespaceScope !== \"schema\") {\n return null;\n }\n if (!this.#namespace || this.#namespace.length === 0) {\n return null;\n }\n return this.#strategy.namespaceToSchema(this.#namespace);\n }\n\n getTableName(logicalTable: string): string {\n return this.#strategy.tableName(logicalTable, this.#namespace);\n }\n\n getColumnName(logicalTable: string, logicalColumn: string): string {\n return this.#strategy.columnName(logicalColumn, logicalTable);\n }\n\n getIndexName(logicalIndex: string, logicalTable: string): string {\n return this.#strategy.indexName(logicalIndex, logicalTable, this.#namespace);\n }\n\n getUniqueIndexName(logicalIndex: string, logicalTable: string): string {\n return this.#strategy.uniqueIndexName(logicalIndex, logicalTable, this.#namespace);\n }\n\n getForeignKeyName(params: {\n logicalTable: string;\n logicalReferencedTable: string;\n referenceName: string;\n }): string {\n return this.#strategy.foreignKeyName({\n ...params,\n namespace: this.#namespace,\n });\n }\n\n getTableNameMap(): Record<string, string> {\n return { ...this.#tableNameMap };\n }\n\n getColumnNameMap(table: AnyTable | string): Record<string, string> {\n const tableName = typeof table === \"string\" ? table : table.name;\n const map = this.#columnNameMaps.get(tableName);\n return map ? { ...map } : {};\n }\n}\n\nexport const createNamingResolver = (\n schema: AnySchema,\n namespace: string | null,\n strategy: SqlNamingStrategy,\n): NamingResolver => new NamingResolver(schema, namespace, strategy);\n\n/**\n * Sanitizes a namespace for use in SQL identifiers and TypeScript exports.\n * Converts dashes to underscores to ensure compatibility with SQL identifiers.\n *\n * @example\n * sanitizeNamespace(\"my-fragment\") // => \"my_fragment\"\n */\nexport function sanitizeNamespace(namespace: string): string {\n return namespace.replace(/-/g, \"_\");\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"sql-naming.js","names":["suffixNamingStrategy: SqlNamingStrategy","schemaNamingStrategy: SqlNamingStrategy","#namespace","#strategy","#tableNameMap","#columnNameMaps","columnMap: Record<string, string>"],"sources":["../../src/naming/sql-naming.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\n\nimport type { AnySchema, AnyTable } from \"../schema/create\";\n\nexport type NamespaceScope = \"suffix\" | \"schema\";\n\nexport interface SqlNamingStrategy {\n namespaceScope: NamespaceScope;\n namespaceToSchema: (namespace: string) => string;\n\n tableName: (logicalTable: string, namespace: string | null) => string;\n columnName: (logicalColumn: string, logicalTable: string) => string;\n\n indexName: (logicalIndex: string, logicalTable: string, namespace: string | null) => string;\n uniqueIndexName: (logicalIndex: string, logicalTable: string, namespace: string | null) => string;\n foreignKeyName: (params: {\n logicalTable: string;\n logicalReferencedTable: string;\n referenceName: string;\n namespace: string | null;\n }) => string;\n}\n\nconst normalizeNamespace = (namespace: string | null) =>\n namespace && namespace.length > 0 ? namespace : null;\n\nconst buildNamespaceSuffix = (namespace: string | null) => {\n const sanitized = normalizeNamespace(namespace);\n return sanitized ? `_${sanitized}` : \"\";\n};\n\nconst MAX_IDENTIFIER_LENGTH = 63;\nconst HASH_LENGTH = 8;\n\nconst withHash = (value: string) => {\n const hash = createHash(\"sha1\").update(value).digest(\"hex\").slice(0, 8);\n return `${value}_${hash}`;\n};\n\nconst truncateWithHash = (value: string) => {\n if (value.length <= MAX_IDENTIFIER_LENGTH) {\n return value;\n }\n const hash = createHash(\"sha1\").update(value).digest(\"hex\").slice(0, HASH_LENGTH);\n return `${value.slice(0, MAX_IDENTIFIER_LENGTH - HASH_LENGTH)}${hash}`;\n};\n\nconst buildIndexName = (\n prefix: \"idx\" | \"uidx\",\n logicalIndex: string,\n logicalTable: string,\n namespace: string | null,\n) => {\n const base = `${logicalTable}_${logicalIndex}${buildNamespaceSuffix(namespace)}`;\n return `${prefix}_${withHash(base)}`;\n};\n\nexport const suffixNamingStrategy: SqlNamingStrategy = {\n namespaceScope: \"suffix\",\n namespaceToSchema: (namespace) => namespace,\n tableName: (logicalTable, namespace) => {\n const sanitized = normalizeNamespace(namespace);\n return truncateWithHash(sanitized ? `${logicalTable}_${sanitized}` : logicalTable);\n },\n columnName: (logicalColumn) => logicalColumn,\n indexName: (logicalIndex, logicalTable, namespace) =>\n truncateWithHash(buildIndexName(\"idx\", logicalIndex, logicalTable, namespace)),\n uniqueIndexName: (logicalIndex, logicalTable, namespace) =>\n truncateWithHash(buildIndexName(\"uidx\", logicalIndex, logicalTable, namespace)),\n foreignKeyName: ({ logicalTable, logicalReferencedTable, referenceName, namespace }) => {\n const base = `${logicalTable}_${logicalReferencedTable}_${referenceName}${buildNamespaceSuffix(namespace)}`;\n return truncateWithHash(`fk_${withHash(base)}`);\n },\n};\n\nexport const schemaNamingStrategy: SqlNamingStrategy = {\n namespaceScope: \"schema\",\n namespaceToSchema: (namespace) => namespace,\n tableName: (logicalTable) => truncateWithHash(logicalTable),\n columnName: (logicalColumn) => logicalColumn,\n indexName: (logicalIndex) => truncateWithHash(logicalIndex),\n uniqueIndexName: (logicalIndex) => truncateWithHash(logicalIndex),\n foreignKeyName: ({ logicalTable, logicalReferencedTable, referenceName }) =>\n truncateWithHash(`fk_${logicalTable}_${logicalReferencedTable}_${referenceName}`),\n};\n\nexport class NamingResolver {\n readonly #namespace: string | null;\n readonly #strategy: SqlNamingStrategy;\n readonly #tableNameMap: Record<string, string> = {};\n readonly #columnNameMaps = new Map<string, Record<string, string>>();\n\n constructor(schema: AnySchema, namespace: string | null, strategy: SqlNamingStrategy) {\n this.#namespace = namespace;\n this.#strategy = strategy;\n\n for (const table of Object.values(schema.tables)) {\n const physicalTable = this.getTableName(table.name);\n this.#tableNameMap[physicalTable] = table.name;\n\n const columnMap: Record<string, string> = {};\n for (const column of Object.values(table.columns)) {\n const physicalColumn = this.getColumnName(table.name, column.name);\n columnMap[physicalColumn] = column.name;\n }\n this.#columnNameMaps.set(table.name, columnMap);\n }\n }\n\n get namespace(): string | null {\n return this.#namespace;\n }\n\n get strategy(): SqlNamingStrategy {\n return this.#strategy;\n }\n\n getSchemaName(): string | null {\n if (this.#strategy.namespaceScope !== \"schema\") {\n return null;\n }\n if (!this.#namespace || this.#namespace.length === 0) {\n return null;\n }\n return this.#strategy.namespaceToSchema(this.#namespace);\n }\n\n getTableName(logicalTable: string): string {\n return this.#strategy.tableName(logicalTable, this.#namespace);\n }\n\n getColumnName(logicalTable: string, logicalColumn: string): string {\n return this.#strategy.columnName(logicalColumn, logicalTable);\n }\n\n getIndexName(logicalIndex: string, logicalTable: string): string {\n return this.#strategy.indexName(logicalIndex, logicalTable, this.#namespace);\n }\n\n getUniqueIndexName(logicalIndex: string, logicalTable: string): string {\n return this.#strategy.uniqueIndexName(logicalIndex, logicalTable, this.#namespace);\n }\n\n getForeignKeyName(params: {\n logicalTable: string;\n logicalReferencedTable: string;\n referenceName: string;\n }): string {\n return this.#strategy.foreignKeyName({\n ...params,\n namespace: this.#namespace,\n });\n }\n\n getTableNameMap(): Record<string, string> {\n return { ...this.#tableNameMap };\n }\n\n getColumnNameMap(table: AnyTable | string): Record<string, string> {\n const tableName = typeof table === \"string\" ? table : table.name;\n const map = this.#columnNameMaps.get(tableName);\n return map ? { ...map } : {};\n }\n}\n\nexport const createNamingResolver = (\n schema: AnySchema,\n namespace: string | null,\n strategy: SqlNamingStrategy,\n): NamingResolver => new NamingResolver(schema, namespace, strategy);\n\n/**\n * Sanitizes a namespace for use in SQL identifiers and TypeScript exports.\n * Converts dashes to underscores to ensure compatibility with SQL identifiers.\n *\n * @example\n * sanitizeNamespace(\"my-fragment\") // => \"my_fragment\"\n */\nexport function sanitizeNamespace(namespace: string): string {\n return namespace.replace(/-/g, \"_\");\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"outbox-builder.js","names":["drafts: OutboxMutationDraft[]","lookups: OutboxRefLookup[]","output: Record<string, unknown>"],"sources":["../../src/outbox/outbox-builder.ts"],"sourcesContent":["import type { MutationOperation } from \"../query/unit-of-work/unit-of-work\";\nimport type { AnySchema, AnyTable } from \"../schema/create\";\nimport { FragnoId, FragnoReference } from \"../schema/create\";\nimport { internalSchema } from \"../fragments/internal-fragment.schema\";\nimport type { OutboxRefLookup, OutboxPayload, OutboxMutation } from \"./outbox\";\nimport { encodeVersionstamp, versionstampToHex } from \"./outbox\";\n\nconst INTERNAL_TABLE_NAMES = new Set(Object.keys(internalSchema.tables));\n\ntype OutboxMutationDraft = OutboxMutation extends infer T\n ? T extends OutboxMutation\n ? Omit<T, \"versionstamp\"> & { versionstamp?: string }\n : never\n : never;\n\nexport type OutboxPlan = {\n drafts: OutboxMutationDraft[];\n lookups: OutboxRefLookup[];\n};\n\nexport function buildOutboxPlan(operations: MutationOperation<AnySchema>[]): OutboxPlan {\n const drafts: OutboxMutationDraft[] = [];\n const lookups: OutboxRefLookup[] = [];\n\n for (const op of operations) {\n if (op.type === \"check\") {\n continue;\n }\n\n if (isInternalMutation(op)) {\n continue;\n }\n\n const table = getTable(op.schema, op.table);\n const schemaName = op.namespace ?? \"\";\n const namespace = op.namespace ? op.namespace : undefined;\n const mutationIndex = drafts.length;\n\n if (op.type === \"create\") {\n drafts.push({\n op: \"create\",\n schema: schemaName,\n namespace,\n table: op.table,\n externalId: op.generatedExternalId,\n values: encodeOutboxValues({\n table,\n values: op.values,\n mutationIndex,\n namespace,\n lookups,\n }),\n });\n continue;\n }\n\n if (op.type === \"update\") {\n drafts.push({\n op: \"update\",\n schema: schemaName,\n namespace,\n table: op.table,\n externalId: getExternalId(op.id),\n set: encodeOutboxValues({\n table,\n values: op.set,\n mutationIndex,\n namespace,\n lookups,\n }),\n checkVersion: op.checkVersion && op.id instanceof FragnoId ? op.id.version : undefined,\n });\n continue;\n }\n\n if (op.type === \"delete\") {\n drafts.push({\n op: \"delete\",\n schema: schemaName,\n namespace,\n table: op.table,\n externalId: getExternalId(op.id),\n checkVersion: op.checkVersion && op.id instanceof FragnoId ? op.id.version : undefined,\n });\n }\n }\n\n return { drafts, lookups };\n}\n\nexport function finalizeOutboxPayload(plan: OutboxPlan, transactionVersion: bigint): OutboxPayload {\n const mutations: OutboxMutation[] = plan.drafts.map((draft, index) => {\n const versionstamp = versionstampToHex(encodeVersionstamp(transactionVersion, index));\n return { ...draft, versionstamp } as OutboxMutation;\n });\n\n return {\n version: 1,\n mutations,\n };\n}\n\nfunction encodeOutboxValues(options: {\n table: AnyTable;\n values: Record<string, unknown>;\n mutationIndex: number;\n namespace?: string;\n lookups: OutboxRefLookup[];\n}): Record<string, unknown> {\n const { table, values, mutationIndex, namespace, lookups } = options;\n const output: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(values)) {\n if (value === undefined) {\n continue;\n }\n\n const column = table.columns[key];\n\n if (column?.role === \"reference\") {\n const resolved = resolveReferenceValue({\n value,\n mutationIndex,\n columnName: key,\n table,\n namespace,\n lookups,\n });\n output[key] = resolved;\n continue;\n }\n\n if (value instanceof FragnoId) {\n output[key] = value.externalId;\n continue;\n }\n\n output[key] = value;\n }\n\n return output;\n}\n\nfunction resolveReferenceValue(options: {\n value: unknown;\n mutationIndex: number;\n columnName: string;\n table: AnyTable;\n namespace?: string;\n lookups: OutboxRefLookup[];\n}): unknown {\n const { value, mutationIndex, columnName, table, namespace, lookups } = options;\n\n if (value === null) {\n return null;\n }\n\n if (value instanceof FragnoId) {\n return value.externalId;\n }\n\n if (typeof value === \"string\") {\n return value;\n }\n\n if (value instanceof FragnoReference) {\n return createReferencePlaceholder({\n internalId: value.internalId,\n mutationIndex,\n columnName,\n table,\n namespace,\n lookups,\n });\n }\n\n if (typeof value === \"bigint\" || typeof value === \"number\") {\n return createReferencePlaceholder({\n internalId: value,\n mutationIndex,\n columnName,\n table,\n namespace,\n lookups,\n });\n }\n\n return value;\n}\n\nfunction createReferencePlaceholder(options: {\n internalId: bigint | number;\n mutationIndex: number;\n columnName: string;\n table: AnyTable;\n namespace?: string;\n lookups: OutboxRefLookup[];\n}): { __fragno_ref: string } {\n const { internalId, mutationIndex, columnName, table, namespace, lookups } = options;\n const key = `${mutationIndex}.${columnName}`;\n const referencedTable = resolveReferencedTable(table, columnName);\n\n lookups.push({\n key,\n internalId,\n table: referencedTable,\n namespace,\n });\n\n return { __fragno_ref: key };\n}\n\nfunction resolveReferencedTable(table: AnyTable, columnName: string): AnyTable {\n for (const relation of Object.values(table.relations)) {\n if (relation.on.some(([localColumn]) => localColumn === columnName)) {\n return relation.table;\n }\n }\n\n throw new Error(`Reference column ${columnName} not found in table ${table.name}`);\n}\n\nfunction getExternalId(id: FragnoId | string): string {\n return typeof id === \"string\" ? id : id.externalId;\n}\n\nfunction isInternalMutation(op: MutationOperation<AnySchema>): boolean {\n if (op.schema === internalSchema) {\n return true;\n }\n\n return op.namespace === \"\" && INTERNAL_TABLE_NAMES.has(op.table);\n}\n\nfunction getTable(schema: AnySchema, tableName: string): AnyTable {\n const table = schema.tables[tableName];\n if (!table) {\n throw new Error(`Invalid table name ${tableName}.`);\n }\n return table;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"outbox-builder.js","names":["drafts: OutboxMutationDraft[]","lookups: OutboxRefLookup[]","output: Record<string, unknown>"],"sources":["../../src/outbox/outbox-builder.ts"],"sourcesContent":["import { internalSchema } from \"../fragments/internal-fragment.schema\";\nimport type { MutationOperation } from \"../query/unit-of-work/unit-of-work\";\nimport type { AnySchema, AnyTable } from \"../schema/create\";\nimport { FragnoId, FragnoReference } from \"../schema/create\";\nimport type { OutboxRefLookup, OutboxPayload, OutboxMutation } from \"./outbox\";\nimport { encodeVersionstamp, versionstampToHex } from \"./outbox\";\n\nconst INTERNAL_TABLE_NAMES = new Set(Object.keys(internalSchema.tables));\n\ntype OutboxMutationDraft = OutboxMutation extends infer T\n ? T extends OutboxMutation\n ? Omit<T, \"versionstamp\"> & { versionstamp?: string }\n : never\n : never;\n\nexport type OutboxPlan = {\n drafts: OutboxMutationDraft[];\n lookups: OutboxRefLookup[];\n};\n\nexport function buildOutboxPlan(operations: MutationOperation<AnySchema>[]): OutboxPlan {\n const drafts: OutboxMutationDraft[] = [];\n const lookups: OutboxRefLookup[] = [];\n\n for (const op of operations) {\n if (op.type === \"check\") {\n continue;\n }\n\n if (isInternalMutation(op)) {\n continue;\n }\n\n const table = getTable(op.schema, op.table);\n const schemaName = op.namespace ?? \"\";\n const namespace = op.namespace ? op.namespace : undefined;\n const mutationIndex = drafts.length;\n\n if (op.type === \"create\") {\n drafts.push({\n op: \"create\",\n schema: schemaName,\n namespace,\n table: op.table,\n externalId: op.generatedExternalId,\n values: encodeOutboxValues({\n table,\n values: op.values,\n mutationIndex,\n namespace,\n lookups,\n }),\n });\n continue;\n }\n\n if (op.type === \"update\") {\n drafts.push({\n op: \"update\",\n schema: schemaName,\n namespace,\n table: op.table,\n externalId: getExternalId(op.id),\n set: encodeOutboxValues({\n table,\n values: op.set,\n mutationIndex,\n namespace,\n lookups,\n }),\n checkVersion: op.checkVersion && op.id instanceof FragnoId ? op.id.version : undefined,\n });\n continue;\n }\n\n if (op.type === \"delete\") {\n drafts.push({\n op: \"delete\",\n schema: schemaName,\n namespace,\n table: op.table,\n externalId: getExternalId(op.id),\n checkVersion: op.checkVersion && op.id instanceof FragnoId ? op.id.version : undefined,\n });\n }\n }\n\n return { drafts, lookups };\n}\n\nexport function finalizeOutboxPayload(plan: OutboxPlan, transactionVersion: bigint): OutboxPayload {\n const mutations: OutboxMutation[] = plan.drafts.map((draft, index) => {\n const versionstamp = versionstampToHex(encodeVersionstamp(transactionVersion, index));\n return { ...draft, versionstamp };\n });\n\n return {\n version: 1,\n mutations,\n };\n}\n\nfunction encodeOutboxValues(options: {\n table: AnyTable;\n values: Record<string, unknown>;\n mutationIndex: number;\n namespace?: string;\n lookups: OutboxRefLookup[];\n}): Record<string, unknown> {\n const { table, values, mutationIndex, namespace, lookups } = options;\n const output: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(values)) {\n if (value === undefined) {\n continue;\n }\n\n const column = table.columns[key];\n\n if (column?.role === \"reference\") {\n const resolved = resolveReferenceValue({\n value,\n mutationIndex,\n columnName: key,\n table,\n namespace,\n lookups,\n });\n output[key] = resolved;\n continue;\n }\n\n if (value instanceof FragnoId) {\n output[key] = value.externalId;\n continue;\n }\n\n output[key] = value;\n }\n\n return output;\n}\n\nfunction resolveReferenceValue(options: {\n value: unknown;\n mutationIndex: number;\n columnName: string;\n table: AnyTable;\n namespace?: string;\n lookups: OutboxRefLookup[];\n}): unknown {\n const { value, mutationIndex, columnName, table, namespace, lookups } = options;\n\n if (value === null) {\n return null;\n }\n\n if (value instanceof FragnoId) {\n return value.externalId;\n }\n\n if (typeof value === \"string\") {\n return value;\n }\n\n if (value instanceof FragnoReference) {\n return createReferencePlaceholder({\n internalId: value.internalId,\n mutationIndex,\n columnName,\n table,\n namespace,\n lookups,\n });\n }\n\n if (typeof value === \"bigint\" || typeof value === \"number\") {\n return createReferencePlaceholder({\n internalId: value,\n mutationIndex,\n columnName,\n table,\n namespace,\n lookups,\n });\n }\n\n return value;\n}\n\nfunction createReferencePlaceholder(options: {\n internalId: bigint | number;\n mutationIndex: number;\n columnName: string;\n table: AnyTable;\n namespace?: string;\n lookups: OutboxRefLookup[];\n}): { __fragno_ref: string } {\n const { internalId, mutationIndex, columnName, table, namespace, lookups } = options;\n const key = `${mutationIndex}.${columnName}`;\n const referencedTable = resolveReferencedTable(table, columnName);\n\n lookups.push({\n key,\n internalId,\n table: referencedTable,\n namespace,\n });\n\n return { __fragno_ref: key };\n}\n\nfunction resolveReferencedTable(table: AnyTable, columnName: string): AnyTable {\n for (const relation of Object.values(table.relations)) {\n if (relation.on.some(([localColumn]) => localColumn === columnName)) {\n return relation.table;\n }\n }\n\n throw new Error(`Reference column ${columnName} not found in table ${table.name}`);\n}\n\nfunction getExternalId(id: FragnoId | string): string {\n return typeof id === \"string\" ? id : id.externalId;\n}\n\nfunction isInternalMutation(op: MutationOperation<AnySchema>): boolean {\n if (op.schema === internalSchema) {\n return true;\n }\n\n return op.namespace === \"\" && INTERNAL_TABLE_NAMES.has(op.table);\n}\n\nfunction getTable(schema: AnySchema, tableName: string): AnyTable {\n const table = schema.tables[tableName];\n if (!table) {\n throw new Error(`Invalid table name ${tableName}.`);\n }\n return table;\n}\n"],"mappings":"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"}
@@ -1,8 +1,10 @@
1
- import { FragnoId } from "../schema/create.js";
1
+ import { AnySchema, FragnoId } from "../schema/create.js";
2
+ import { MutationOperation } from "../query/unit-of-work/unit-of-work.js";
2
3
 
3
4
  //#region src/outbox/outbox.d.ts
4
5
  type OutboxConfig = {
5
6
  enabled: boolean;
7
+ shouldInclude?: (operation: MutationOperation<AnySchema>) => boolean;
6
8
  };
7
9
  type OutboxPayload = {
8
10
  version: 1;
@@ -1 +1 @@
1
- {"version":3,"file":"outbox.d.ts","names":[],"sources":["../../src/outbox/outbox.ts"],"sourcesContent":[],"mappings":";;;KAEY,YAAA;;AAAZ,CAAA;AAcY,KALA,aAAA,GAKc;EA8Bd,OAAA,EAAA,CAAA;EAEA,SAAA,EAnCC,cAmCD,EAAuB;AAKnC,CAAA;AACM,KAtCM,cAAA,GAsCN;EAGK,EAAA,EAAA,QAAA;EACA,MAAA,EAAA,MAAA;EACE,SAAA,CAAA,EAAA,MAAA;EAAI,KAAA,EAAA,MAAA;;;UAnCH;;;;;;;;OASH;;;;;;;;;;;KAaC,YAAA,GAAe;KAEf,uBAAA;;SAEH;;KAGG,WAAA;MACN;;;WAGK;WACA;aACE"}
1
+ {"version":3,"file":"outbox.d.ts","names":[],"sources":["../../src/outbox/outbox.ts"],"sourcesContent":[],"mappings":";;;;KAGY,YAAA;;EAAA,aAAA,CAAA,EAAY,CAAA,SAAA,EAEM,iBAAA,CAAkB,SAAlB,CAAA,EAAiB,GAAA,OAAA;AAQ/C,CAAA;AAmCY,KAnCA,aAAA,GAmCY;EAEZ,OAAA,EAAA,CAAA;EAKA,SAAA,EAxCC,cAwCU,EAAA;CACjB;AAGK,KAzCC,cAAA,GAyCD;EACA,EAAA,EAAA,QAAA;EACE,MAAA,EAAA,MAAA;EAAI,SAAA,CAAA,EAAA,MAAA;;;;UAnCH;;;;;;;;OASH;;;;;;;;;;;KAaC,YAAA,GAAe;KAEf,uBAAA;;SAEH;;KAGG,WAAA;MACN;;;WAGK;WACA;aACE"}
@@ -1 +1 @@
1
- {"version":3,"file":"outbox.js","names":[],"sources":["../../src/outbox/outbox.ts"],"sourcesContent":["import type { AnyTable, FragnoId } from \"../schema/create\";\n\nexport type OutboxConfig = {\n enabled: boolean;\n};\n\nexport type OutboxVersionstampStrategy =\n | \"update-returning\"\n | \"insert-on-conflict-returning\"\n | \"insert-on-duplicate-last-insert-id\";\n\nexport type OutboxPayload = {\n version: 1;\n mutations: OutboxMutation[];\n};\n\nexport type OutboxMutation =\n | {\n op: \"create\";\n schema: string;\n namespace?: string;\n table: string;\n externalId: string;\n versionstamp: string;\n values: Record<string, unknown>;\n }\n | {\n op: \"update\";\n schema: string;\n namespace?: string;\n table: string;\n externalId: string;\n versionstamp: string;\n set: Record<string, unknown>;\n checkVersion?: number;\n }\n | {\n op: \"delete\";\n schema: string;\n namespace?: string;\n table: string;\n externalId: string;\n versionstamp: string;\n checkVersion?: number;\n };\n\nexport type OutboxRefMap = Record<string, string>;\n\nexport type OutboxPayloadSerialized = {\n json: unknown;\n meta?: Record<string, unknown>;\n};\n\nexport type OutboxEntry = {\n id: FragnoId;\n versionstamp: string;\n uowId: string;\n payload: OutboxPayloadSerialized;\n refMap?: OutboxRefMap;\n createdAt: Date;\n};\n\nexport type OutboxRefLookup = {\n key: string;\n internalId: bigint | number;\n table: AnyTable;\n namespace?: string;\n};\n\nexport function encodeVersionstamp(transactionVersion: bigint, userVersion: number): Uint8Array {\n if (userVersion < 0 || userVersion > 0xffff) {\n throw new Error(`Invalid outbox user version: ${userVersion}`);\n }\n\n const txBytes = bigintToBytes(transactionVersion, 10);\n const userBytes = new Uint8Array(2);\n userBytes[0] = (userVersion >> 8) & 0xff;\n userBytes[1] = userVersion & 0xff;\n\n const combined = new Uint8Array(12);\n combined.set(txBytes, 0);\n combined.set(userBytes, 10);\n\n return combined;\n}\n\nexport function versionstampToHex(bytes: Uint8Array): string {\n let hex = \"\";\n for (const byte of bytes) {\n hex += byte.toString(16).padStart(2, \"0\");\n }\n return hex;\n}\n\nexport function hexToVersionstamp(hex: string): Uint8Array {\n if (hex.length % 2 !== 0) {\n throw new Error(`Invalid versionstamp hex length: ${hex.length}`);\n }\n\n const bytes = new Uint8Array(hex.length / 2);\n for (let i = 0; i < hex.length; i += 2) {\n bytes[i / 2] = Number.parseInt(hex.slice(i, i + 2), 16);\n }\n return bytes;\n}\n\nexport function parseOutboxVersionValue(value: unknown): bigint {\n if (typeof value === \"bigint\") {\n return value;\n }\n\n if (typeof value === \"number\") {\n return BigInt(value);\n }\n\n if (typeof value === \"string\") {\n return BigInt(value);\n }\n\n throw new Error(`Invalid outbox version value: ${String(value)}`);\n}\n\nfunction bigintToBytes(value: bigint, length: number): Uint8Array {\n const bytes = new Uint8Array(length);\n let remaining = value;\n\n for (let i = length - 1; i >= 0; i -= 1) {\n bytes[i] = Number(remaining & 0xffn);\n remaining >>= 8n;\n }\n\n if (remaining !== 0n) {\n throw new Error(`Outbox version ${value} exceeds ${length * 8} bits`);\n }\n\n return bytes;\n}\n"],"mappings":";AAqEA,SAAgB,mBAAmB,oBAA4B,aAAiC;AAC9F,KAAI,cAAc,KAAK,cAAc,MACnC,OAAM,IAAI,MAAM,gCAAgC,cAAc;CAGhE,MAAM,UAAU,cAAc,oBAAoB,GAAG;CACrD,MAAM,YAAY,IAAI,WAAW,EAAE;AACnC,WAAU,KAAM,eAAe,IAAK;AACpC,WAAU,KAAK,cAAc;CAE7B,MAAM,WAAW,IAAI,WAAW,GAAG;AACnC,UAAS,IAAI,SAAS,EAAE;AACxB,UAAS,IAAI,WAAW,GAAG;AAE3B,QAAO;;AAGT,SAAgB,kBAAkB,OAA2B;CAC3D,IAAI,MAAM;AACV,MAAK,MAAM,QAAQ,MACjB,QAAO,KAAK,SAAS,GAAG,CAAC,SAAS,GAAG,IAAI;AAE3C,QAAO;;AAeT,SAAgB,wBAAwB,OAAwB;AAC9D,KAAI,OAAO,UAAU,SACnB,QAAO;AAGT,KAAI,OAAO,UAAU,SACnB,QAAO,OAAO,MAAM;AAGtB,KAAI,OAAO,UAAU,SACnB,QAAO,OAAO,MAAM;AAGtB,OAAM,IAAI,MAAM,iCAAiC,OAAO,MAAM,GAAG;;AAGnE,SAAS,cAAc,OAAe,QAA4B;CAChE,MAAM,QAAQ,IAAI,WAAW,OAAO;CACpC,IAAI,YAAY;AAEhB,MAAK,IAAI,IAAI,SAAS,GAAG,KAAK,GAAG,KAAK,GAAG;AACvC,QAAM,KAAK,OAAO,YAAY,KAAM;AACpC,gBAAc;;AAGhB,KAAI,cAAc,GAChB,OAAM,IAAI,MAAM,kBAAkB,MAAM,WAAW,SAAS,EAAE,OAAO;AAGvE,QAAO"}
1
+ {"version":3,"file":"outbox.js","names":[],"sources":["../../src/outbox/outbox.ts"],"sourcesContent":["import type { MutationOperation } from \"../query/unit-of-work/unit-of-work\";\nimport type { AnySchema, AnyTable, FragnoId } from \"../schema/create\";\n\nexport type OutboxConfig = {\n enabled: boolean;\n shouldInclude?: (operation: MutationOperation<AnySchema>) => boolean;\n};\n\nexport type OutboxVersionstampStrategy =\n | \"update-returning\"\n | \"insert-on-conflict-returning\"\n | \"insert-on-duplicate-last-insert-id\";\n\nexport type OutboxPayload = {\n version: 1;\n mutations: OutboxMutation[];\n};\n\nexport type OutboxMutation =\n | {\n op: \"create\";\n schema: string;\n namespace?: string;\n table: string;\n externalId: string;\n versionstamp: string;\n values: Record<string, unknown>;\n }\n | {\n op: \"update\";\n schema: string;\n namespace?: string;\n table: string;\n externalId: string;\n versionstamp: string;\n set: Record<string, unknown>;\n checkVersion?: number;\n }\n | {\n op: \"delete\";\n schema: string;\n namespace?: string;\n table: string;\n externalId: string;\n versionstamp: string;\n checkVersion?: number;\n };\n\nexport type OutboxRefMap = Record<string, string>;\n\nexport type OutboxPayloadSerialized = {\n json: unknown;\n meta?: Record<string, unknown>;\n};\n\nexport type OutboxEntry = {\n id: FragnoId;\n versionstamp: string;\n uowId: string;\n payload: OutboxPayloadSerialized;\n refMap?: OutboxRefMap;\n createdAt: Date;\n};\n\nexport type OutboxRefLookup = {\n key: string;\n internalId: bigint | number;\n table: AnyTable;\n namespace?: string;\n};\n\nexport function encodeVersionstamp(transactionVersion: bigint, userVersion: number): Uint8Array {\n if (userVersion < 0 || userVersion > 0xffff) {\n throw new Error(`Invalid outbox user version: ${userVersion}`);\n }\n\n const txBytes = bigintToBytes(transactionVersion, 10);\n const userBytes = new Uint8Array(2);\n userBytes[0] = (userVersion >> 8) & 0xff;\n userBytes[1] = userVersion & 0xff;\n\n const combined = new Uint8Array(12);\n combined.set(txBytes, 0);\n combined.set(userBytes, 10);\n\n return combined;\n}\n\nexport function versionstampToHex(bytes: Uint8Array): string {\n let hex = \"\";\n for (const byte of bytes) {\n hex += byte.toString(16).padStart(2, \"0\");\n }\n return hex;\n}\n\nexport function hexToVersionstamp(hex: string): Uint8Array {\n if (hex.length % 2 !== 0) {\n throw new Error(`Invalid versionstamp hex length: ${hex.length}`);\n }\n\n const bytes = new Uint8Array(hex.length / 2);\n for (let i = 0; i < hex.length; i += 2) {\n bytes[i / 2] = Number.parseInt(hex.slice(i, i + 2), 16);\n }\n return bytes;\n}\n\nexport function parseOutboxVersionValue(value: unknown): bigint {\n if (typeof value === \"bigint\") {\n return value;\n }\n\n if (typeof value === \"number\") {\n return BigInt(value);\n }\n\n if (typeof value === \"string\") {\n return BigInt(value);\n }\n\n throw new Error(`Invalid outbox version value: ${String(value)}`);\n}\n\nfunction bigintToBytes(value: bigint, length: number): Uint8Array {\n const bytes = new Uint8Array(length);\n let remaining = value;\n\n for (let i = length - 1; i >= 0; i -= 1) {\n bytes[i] = Number(remaining & 0xffn);\n remaining >>= 8n;\n }\n\n if (remaining !== 0n) {\n throw new Error(`Outbox version ${value} exceeds ${length * 8} bits`);\n }\n\n return bytes;\n}\n"],"mappings":";AAuEA,SAAgB,mBAAmB,oBAA4B,aAAiC;AAC9F,KAAI,cAAc,KAAK,cAAc,MACnC,OAAM,IAAI,MAAM,gCAAgC,cAAc;CAGhE,MAAM,UAAU,cAAc,oBAAoB,GAAG;CACrD,MAAM,YAAY,IAAI,WAAW,EAAE;AACnC,WAAU,KAAM,eAAe,IAAK;AACpC,WAAU,KAAK,cAAc;CAE7B,MAAM,WAAW,IAAI,WAAW,GAAG;AACnC,UAAS,IAAI,SAAS,EAAE;AACxB,UAAS,IAAI,WAAW,GAAG;AAE3B,QAAO;;AAGT,SAAgB,kBAAkB,OAA2B;CAC3D,IAAI,MAAM;AACV,MAAK,MAAM,QAAQ,MACjB,QAAO,KAAK,SAAS,GAAG,CAAC,SAAS,GAAG,IAAI;AAE3C,QAAO;;AAeT,SAAgB,wBAAwB,OAAwB;AAC9D,KAAI,OAAO,UAAU,SACnB,QAAO;AAGT,KAAI,OAAO,UAAU,SACnB,QAAO,OAAO,MAAM;AAGtB,KAAI,OAAO,UAAU,SACnB,QAAO,OAAO,MAAM;AAGtB,OAAM,IAAI,MAAM,iCAAiC,OAAO,MAAM,GAAG;;AAGnE,SAAS,cAAc,OAAe,QAA4B;CAChE,MAAM,QAAQ,IAAI,WAAW,OAAO;CACpC,IAAI,YAAY;AAEhB,MAAK,IAAI,IAAI,SAAS,GAAG,KAAK,GAAG,KAAK,GAAG;AACvC,QAAM,KAAK,OAAO,YAAY,KAAM;AACpC,gBAAc;;AAGhB,KAAI,cAAc,GAChB,OAAM,IAAI,MAAM,kBAAkB,MAAM,WAAW,SAAS,EAAE,OAAO;AAGvE,QAAO"}
@@ -1 +1 @@
1
- {"version":3,"file":"column-defaults.js","names":[],"sources":["../../src/query/column-defaults.ts"],"sourcesContent":["import type { AnyColumn } from \"../schema/create\";\nimport { createId } from \"../id\";\n\nexport type RuntimeDefaultContext = {\n now?: () => Date;\n createId?: () => string;\n};\n\n/**\n * Generate a runtime default value for a column that has defaultTo$()\n *\n * Only generates values for runtime defaults (defaultTo$), NOT static defaults (defaultTo).\n * Static defaults should be handled by the database via DEFAULT constraints.\n *\n * @param column - The column with a default value configuration\n * @returns The generated default value, or undefined if the column has no runtime default\n *\n * @internal\n */\nexport function generateRuntimeDefault(\n column: AnyColumn,\n context: RuntimeDefaultContext = {},\n): unknown {\n // Check if column has a default value configuration\n if (!column.default) {\n return undefined;\n }\n\n // If it's a static default value (defaultTo), return undefined\n // as the database should handle this via DEFAULT constraint\n if (\"value\" in column.default) {\n return undefined;\n }\n\n // If it's a database-level special function (defaultTo(b => b.now())), return undefined\n // as the database should handle this via DEFAULT NOW() or equivalent\n if (\"dbSpecial\" in column.default) {\n return undefined;\n }\n\n // Handle runtime defaults (defaultTo$)\n const runtime = column.default.runtime;\n\n if (runtime === \"cuid\") {\n return (context.createId ?? createId)();\n }\n\n if (runtime === \"now\") {\n return (context.now ?? (() => new Date()))();\n }\n\n if (typeof runtime === \"function\") {\n return runtime();\n }\n\n return undefined;\n}\n\n/**\n * Generate a fallback value for database-level defaults.\n *\n * This is used by adapters that cannot rely on database DEFAULT constraints,\n * such as the in-memory adapter.\n *\n * @internal\n */\nexport function generateDatabaseDefault(\n column: AnyColumn,\n context: RuntimeDefaultContext = {},\n): unknown {\n if (!column.default) {\n return undefined;\n }\n\n if (\"value\" in column.default) {\n return column.default.value;\n }\n\n if (\"dbSpecial\" in column.default) {\n if (column.default.dbSpecial === \"now\") {\n return (context.now ?? (() => new Date()))();\n }\n return undefined;\n }\n\n return undefined;\n}\n"],"mappings":";;;;;;;;;;;;;;AAmBA,SAAgB,uBACd,QACA,UAAiC,EAAE,EAC1B;AAET,KAAI,CAAC,OAAO,QACV;AAKF,KAAI,WAAW,OAAO,QACpB;AAKF,KAAI,eAAe,OAAO,QACxB;CAIF,MAAM,UAAU,OAAO,QAAQ;AAE/B,KAAI,YAAY,OACd,SAAQ,QAAQ,YAAY,WAAW;AAGzC,KAAI,YAAY,MACd,SAAQ,QAAQ,8BAAc,IAAI,MAAM,IAAI;AAG9C,KAAI,OAAO,YAAY,WACrB,QAAO,SAAS;;;;;;;;;;AAcpB,SAAgB,wBACd,QACA,UAAiC,EAAE,EAC1B;AACT,KAAI,CAAC,OAAO,QACV;AAGF,KAAI,WAAW,OAAO,QACpB,QAAO,OAAO,QAAQ;AAGxB,KAAI,eAAe,OAAO,SAAS;AACjC,MAAI,OAAO,QAAQ,cAAc,MAC/B,SAAQ,QAAQ,8BAAc,IAAI,MAAM,IAAI;AAE9C"}
1
+ {"version":3,"file":"column-defaults.js","names":[],"sources":["../../src/query/column-defaults.ts"],"sourcesContent":["import { createId } from \"../id\";\nimport type { AnyColumn } from \"../schema/create\";\n\nexport type RuntimeDefaultContext = {\n now?: () => Date;\n createId?: () => string;\n};\n\n/**\n * Generate a runtime default value for a column that has defaultTo$()\n *\n * Only generates values for runtime defaults (defaultTo$), NOT static defaults (defaultTo).\n * Static defaults should be handled by the database via DEFAULT constraints.\n *\n * @param column - The column with a default value configuration\n * @returns The generated default value, or undefined if the column has no runtime default\n *\n * @internal\n */\nexport function generateRuntimeDefault(\n column: AnyColumn,\n context: RuntimeDefaultContext = {},\n): unknown {\n // Check if column has a default value configuration\n if (!column.default) {\n return undefined;\n }\n\n // If it's a static default value (defaultTo), return undefined\n // as the database should handle this via DEFAULT constraint\n if (\"value\" in column.default) {\n return undefined;\n }\n\n // If it's a database-level special function (defaultTo(b => b.now())), return undefined\n // as the database should handle this via DEFAULT NOW() or equivalent\n if (\"dbSpecial\" in column.default) {\n return undefined;\n }\n\n // Handle runtime defaults (defaultTo$)\n const runtime = column.default.runtime;\n\n if (runtime === \"cuid\") {\n return (context.createId ?? createId)();\n }\n\n if (runtime === \"now\") {\n return (context.now ?? (() => new Date()))();\n }\n\n if (typeof runtime === \"function\") {\n return runtime();\n }\n\n return undefined;\n}\n\n/**\n * Generate a fallback value for database-level defaults.\n *\n * This is used by adapters that cannot rely on database DEFAULT constraints,\n * such as the in-memory adapter.\n *\n * @internal\n */\nexport function generateDatabaseDefault(\n column: AnyColumn,\n context: RuntimeDefaultContext = {},\n): unknown {\n if (!column.default) {\n return undefined;\n }\n\n if (\"value\" in column.default) {\n return column.default.value;\n }\n\n if (\"dbSpecial\" in column.default) {\n if (column.default.dbSpecial === \"now\") {\n return (context.now ?? (() => new Date()))();\n }\n return undefined;\n }\n\n return undefined;\n}\n"],"mappings":";;;;;;;;;;;;;;AAmBA,SAAgB,uBACd,QACA,UAAiC,EAAE,EAC1B;AAET,KAAI,CAAC,OAAO,QACV;AAKF,KAAI,WAAW,OAAO,QACpB;AAKF,KAAI,eAAe,OAAO,QACxB;CAIF,MAAM,UAAU,OAAO,QAAQ;AAE/B,KAAI,YAAY,OACd,SAAQ,QAAQ,YAAY,WAAW;AAGzC,KAAI,YAAY,MACd,SAAQ,QAAQ,8BAAc,IAAI,MAAM,IAAI;AAG9C,KAAI,OAAO,YAAY,WACrB,QAAO,SAAS;;;;;;;;;;AAcpB,SAAgB,wBACd,QACA,UAAiC,EAAE,EAC1B;AACT,KAAI,CAAC,OAAO,QACV;AAGF,KAAI,WAAW,OAAO,QACpB,QAAO,OAAO,QAAQ;AAGxB,KAAI,eAAe,OAAO,SAAS;AACjC,MAAI,OAAO,QAAQ,cAAc,MAC/B,SAAQ,QAAQ,8BAAc,IAAI,MAAM,IAAI;AAE9C"}
@@ -1,6 +1,8 @@
1
+ import { DbInterval, DbIntervalInput, DbNow } from "./db-now.js";
1
2
  import { AnyColumn, FragnoId, IdColumn } from "../schema/create.js";
2
3
 
3
4
  //#region src/query/condition-builder.d.ts
5
+ type ConditionType = "compare" | "and" | "or" | "not";
4
6
  type Condition = {
5
7
  type: "compare";
6
8
  a: AnyColumn;
@@ -30,12 +32,16 @@ type ConditionBuilder<Columns extends Record<string, AnyColumn>> = {
30
32
  not: (v: Condition | boolean) => Condition | boolean;
31
33
  isNull: (a: keyof Columns) => Condition;
32
34
  isNotNull: (a: keyof Columns) => Condition;
35
+ now: () => DbNow;
36
+ interval: (input: DbIntervalInput) => DbInterval;
33
37
  };
34
38
  declare const stringOperators: readonly ["contains", "starts with", "ends with", "not contains", "not starts with", "not ends with"];
35
39
  declare const arrayOperators: readonly ["in", "not in"];
36
40
  declare const valueOperators: readonly ["=", "!=", ">", ">=", "<", "<=", "is", "is not"];
37
41
  declare const operators: readonly ["=", "!=", ">", ">=", "<", "<=", "is", "is not", "in", "not in", "contains", "starts with", "ends with", "not contains", "not starts with", "not ends with"];
38
42
  type Operator = (typeof operators)[number];
43
+ declare function createBuilder<Columns extends Record<string, AnyColumn>>(columns: Columns): ConditionBuilder<Columns>;
44
+ declare function buildCondition<T, Columns extends Record<string, AnyColumn>>(columns: Columns, input: (builder: ConditionBuilder<Columns>) => T): T;
39
45
  //#endregion
40
- export { Condition, ConditionBuilder };
46
+ export { Condition, ConditionBuilder, ConditionType, Operator, buildCondition, createBuilder, operators };
41
47
  //# sourceMappingURL=condition-builder.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"condition-builder.d.ts","names":[],"sources":["../../src/query/condition-builder.ts"],"sourcesContent":[],"mappings":";;;KAIY,SAAA;EAAA,IAAA,EAAA,SAAS;EAGZ,CAAA,EAAA,SAAA;EACO,QAAA,EAAA,QAAA;EACP,CAAA,EAAA,SAAA,GAAA,OAAA,GAAA,IAAA;CAII,GAAA;EAID,IAAA,EAAA,IAAA,GAAA,KAAA;EAAS,KAAA,EAJR,SAIQ,EAAA;AACf,CAAA,GAQD;EAA0B,IAAA,EAAA,KAAA;EAAa,IAAA,EAThC,SASgC;CAAU;;;;;KAAjD,eAGY,CAAA,UAHc,SAGd,CAAA,GAH2B,CAG3B,SAHqC,QAGrC,GAFb,CAEa,CAAA,KAAA,CAAA,GAFF,QAEE,GADb,CACa,CAAA,KAAA,CAAA,SAAA,MAAA,GAAX,CAAW,CAAA,KAAA,CAAA,GAAA,QAAA,GACX,CADW,CAAA,KAAA,CAAA;AACX,KAEM,gBAFN,CAAA,gBAEuC,MAFvC,CAAA,MAAA,EAEsD,SAFtD,CAAA,CAAA,GAAA;EAAC,CAAA,gBAAA,MAGkB,OAHlB,CAAA,CAAA,CAAA,EAIA,OAJA,EAAA,QAAA,EAAA,CAAA,OAKe,cALf,CAAA,CAAA,MAAA,CAAA,GAAA,CAAA,OAKiD,eALjD,CAAA,CAAA,MAAA,CAAA,EAAA,CAAA,EAMA,eANA,CAMgB,OANhB,CAMwB,OANxB,CAAA,CAAA,GAAA,IAAA,CAAA,EAOF,SAPE;EAEK,CAAA,gBAAA,MAOa,OAPG,CAAA,CAAA,CAAA,EAQrB,OARqB,EAAA,QAAA,EAAA,CAAA,OASN,cATM,CAAA,CAAA,MAAA,CAAA,EAAA,CAAA,EAUrB,eAVqB,CAUL,OAVK,CAUG,OAVH,CAAA,CAAA,EAAA,CAAA,EAWvB,SAXuB;EAAgC;;;EAErD,CAAA,gBAAA,MAckB,OAdlB,CAAA,CAAA,CAAA,EAc8B,OAd9B,CAAA,EAcwC,SAdxC;EACe,GAAA,EAAA,CAAA,GAAA,CAAA,EAAA,CAeP,SAfO,GAAA,OAAA,CAAA,EAAA,EAAA,GAeoB,SAfpB,GAAA,OAAA;EAAkC,EAAA,EAAA,CAAA,GAAA,CAAA,EAAA,CAgB1C,SAhB0C,GAAA,OAAA,CAAA,EAAA,EAAA,GAgBf,SAhBe,GAAA,OAAA;EACjC,GAAA,EAAA,CAAA,CAAA,EAgBZ,SAhBY,GAAA,OAAA,EAAA,GAgBY,SAhBZ,GAAA,OAAA;EAAQ,MAAA,EAAA,CAAA,CAAA,EAAA,MAkBX,OAlBW,EAAA,GAkBC,SAlBD;EAAxB,SAAA,EAAA,CAAA,CAAA,EAAA,MAmBgB,OAnBhB,EAAA,GAmB4B,SAnB5B;CACF;cAsBC,eApBmB,EAAA,SAAA,CAAA,UAAA,EAAA,aAAA,EAAA,WAAA,EAAA,cAAA,EAAA,iBAAA,EAAA,eAAA,CAAA;cA+BnB,cA9BC,EAAA,SAAA,CAAA,IAAA,EAAA,QAAA,CAAA;cAgCD,cA/BgB,EAAA,SAAA,CAAA,GAAA,EAAA,IAAA,EAAA,GAAA,EAAA,IAAA,EAAA,GAAA,EAAA,IAAA,EAAA,IAAA,EAAA,QAAA,CAAA;AACC,cAmCV,SAnCU,EAAA,SAAA,CAAA,GAAA,EAAA,IAAA,EAAA,GAAA,EAAA,IAAA,EAAA,GAAA,EAAA,IAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,QAAA,EAAA,UAAA,EAAA,aAAA,EAAA,WAAA,EAAA,cAAA,EAAA,iBAAA,EAAA,eAAA,CAAA;AAAQ,KAqCnB,QAAA,GArCmB,CAAA,OAqCA,SArCA,CAAA,CAAA,MAAA,CAAA"}
1
+ {"version":3,"file":"condition-builder.d.ts","names":[],"sources":["../../src/query/condition-builder.ts"],"sourcesContent":[],"mappings":"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"}
@@ -1,3 +1,5 @@
1
+ import { dbInterval, dbNow } from "./db-now.js";
2
+
1
3
  //#region src/query/condition-builder.ts
2
4
  const stringOperators = [
3
5
  "contains",
@@ -49,6 +51,8 @@ function createBuilder(columns) {
49
51
  };
50
52
  builder.isNull = (a) => builder(a, "is", null);
51
53
  builder.isNotNull = (a) => builder(a, "is not", null);
54
+ builder.now = () => dbNow();
55
+ builder.interval = (input) => dbInterval(input);
52
56
  builder.not = (condition) => {
53
57
  if (typeof condition === "boolean") return !condition;
54
58
  return {
@@ -89,5 +93,5 @@ function buildCondition(columns, input) {
89
93
  }
90
94
 
91
95
  //#endregion
92
- export { buildCondition };
96
+ export { buildCondition, createBuilder, operators };
93
97
  //# sourceMappingURL=condition-builder.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"condition-builder.js","names":["builder: ConditionBuilder<Columns>"],"sources":["../../src/query/condition-builder.ts"],"sourcesContent":["import type { AnyColumn, FragnoId, IdColumn } from \"../schema/create\";\n\nexport type ConditionType = \"compare\" | \"and\" | \"or\" | \"not\";\n\nexport type Condition =\n | {\n type: \"compare\";\n a: AnyColumn;\n operator: Operator;\n b: AnyColumn | unknown | null;\n }\n | {\n type: \"or\" | \"and\";\n items: Condition[];\n }\n | {\n type: \"not\";\n item: Condition;\n };\n\n// TODO: we temporarily dropped support for comparing against another column, because Prisma ORM still have problems with it.\n\n/**\n * Helper type that allows FragnoId for ID columns and reference columns (bigint).\n * Used in ConditionBuilder to accept FragnoId values in where conditions.\n */\ntype AcceptsFragnoId<T extends AnyColumn> = T extends IdColumn\n ? T[\"$in\"] | FragnoId\n : T[\"$in\"] extends bigint\n ? T[\"$in\"] | FragnoId\n : T[\"$in\"];\n\nexport type ConditionBuilder<Columns extends Record<string, AnyColumn>> = {\n <ColName extends keyof Columns>(\n a: ColName,\n operator: (typeof valueOperators)[number] | (typeof stringOperators)[number],\n b: AcceptsFragnoId<Columns[ColName]> | null,\n ): Condition;\n\n <ColName extends keyof Columns>(\n a: ColName,\n operator: (typeof arrayOperators)[number],\n b: AcceptsFragnoId<Columns[ColName]>[],\n ): Condition;\n\n /**\n * Boolean values\n */\n <ColName extends keyof Columns>(a: ColName): Condition;\n\n and: (...v: (Condition | boolean)[]) => Condition | boolean;\n or: (...v: (Condition | boolean)[]) => Condition | boolean;\n not: (v: Condition | boolean) => Condition | boolean;\n\n isNull: (a: keyof Columns) => Condition;\n isNotNull: (a: keyof Columns) => Condition;\n};\n\n// replacement for `like` (Prisma doesn't support `like`)\nconst stringOperators = [\n \"contains\",\n \"starts with\",\n \"ends with\",\n\n \"not contains\",\n \"not starts with\",\n \"not ends with\",\n // excluded `regexp` since MSSQL doesn't support it, may re-consider\n] as const;\n\nconst arrayOperators = [\"in\", \"not in\"] as const;\n\nconst valueOperators = [\"=\", \"!=\", \">\", \">=\", \"<\", \"<=\", \"is\", \"is not\"] as const;\n\n// JSON specific operators are not included, some databases don't support them\n// `match` requires additional extensions & configurations on SQLite and PostgreSQL\n// MySQL & SQLite requires workarounds to support `ilike`\nexport const operators = [...valueOperators, ...arrayOperators, ...stringOperators] as const;\n\nexport type Operator = (typeof operators)[number];\n\nexport function createBuilder<Columns extends Record<string, AnyColumn>>(\n columns: Columns,\n): ConditionBuilder<Columns> {\n function col(name: keyof Columns) {\n const out = columns[name];\n if (!out) {\n throw new Error(`Invalid column name ${String(name)}`);\n }\n\n return out;\n }\n\n const builder: ConditionBuilder<Columns> = (...args: [string, Operator, unknown] | [string]) => {\n if (args.length === 3) {\n const [a, operator, b] = args;\n\n if (!operators.includes(operator)) {\n throw new Error(`Unsupported operator: ${operator}`);\n }\n\n return {\n type: \"compare\",\n a: col(a),\n b,\n operator,\n };\n }\n\n return {\n type: \"compare\",\n a: col(args[0]),\n operator: \"=\",\n b: true,\n };\n };\n\n builder.isNull = (a) => builder(a, \"is\", null);\n builder.isNotNull = (a) => builder(a, \"is not\", null);\n builder.not = (condition) => {\n if (typeof condition === \"boolean\") {\n return !condition;\n }\n\n return {\n type: \"not\",\n item: condition,\n };\n };\n\n builder.or = (...conditions) => {\n const out = {\n type: \"or\",\n items: [] as Condition[],\n } as const;\n\n for (const item of conditions) {\n if (item === true) {\n return true;\n }\n if (item === false) {\n continue;\n }\n\n out.items.push(item);\n }\n\n if (out.items.length === 0) {\n return false;\n }\n return out;\n };\n\n builder.and = (...conditions) => {\n const out = {\n type: \"and\",\n items: [] as Condition[],\n } as const;\n\n for (const item of conditions) {\n if (item === true) {\n continue;\n }\n if (item === false) {\n return false;\n }\n\n out.items.push(item);\n }\n\n if (out.items.length === 0) {\n return true;\n }\n return out;\n };\n\n return builder;\n}\n\nexport function buildCondition<T, Columns extends Record<string, AnyColumn>>(\n columns: Columns,\n input: (builder: ConditionBuilder<Columns>) => T,\n): T {\n return input(createBuilder(columns));\n}\n\n/**\n * Create a ConditionBuilder that only allows comparisons on indexed columns.\n * Used in Unit of Work to ensure queries can leverage indexes for optimal performance.\n *\n * @param columns - The full set of columns from the table\n * @param indexedColumnNames - Set of column names that are part of indexes\n * @returns A ConditionBuilder restricted to indexed columns only\n *\n * @example\n * ```ts\n * const builder = createIndexedBuilder(\n * table.columns,\n * new Set([\"id\", \"userId\", \"createdAt\"])\n * );\n * const condition = builder(\"userId\", \"=\", \"123\");\n * ```\n */\nexport function createIndexedBuilder<Columns extends Record<string, AnyColumn>>(\n columns: Columns,\n indexedColumnNames: Set<string>,\n): ConditionBuilder<Columns> {\n function col(name: keyof Columns) {\n const columnName = String(name);\n\n if (!indexedColumnNames.has(columnName)) {\n throw new Error(\n `Column \"${columnName}\" is not indexed. Only indexed columns can be used in Unit of Work queries. ` +\n `Available indexed columns: ${Array.from(indexedColumnNames).join(\", \")}`,\n );\n }\n\n const out = columns[name];\n if (!out) {\n throw new Error(`Invalid column name ${columnName}`);\n }\n\n return out;\n }\n\n const builder: ConditionBuilder<Columns> = (...args: [string, Operator, unknown] | [string]) => {\n if (args.length === 3) {\n const [a, operator, b] = args;\n\n if (!operators.includes(operator)) {\n throw new Error(`Unsupported operator: ${operator}`);\n }\n\n return {\n type: \"compare\",\n a: col(a),\n b,\n operator,\n };\n }\n\n return {\n type: \"compare\",\n a: col(args[0]),\n operator: \"=\",\n b: true,\n };\n };\n\n builder.isNull = (a) => builder(a, \"is\", null);\n builder.isNotNull = (a) => builder(a, \"is not\", null);\n builder.not = (condition) => {\n if (typeof condition === \"boolean\") {\n return !condition;\n }\n\n return {\n type: \"not\",\n item: condition,\n };\n };\n\n builder.or = (...conditions) => {\n const out = {\n type: \"or\",\n items: [] as Condition[],\n } as const;\n\n for (const item of conditions) {\n if (item === true) {\n return true;\n }\n if (item === false) {\n continue;\n }\n\n out.items.push(item);\n }\n\n if (out.items.length === 0) {\n return false;\n }\n return out;\n };\n\n builder.and = (...conditions) => {\n const out = {\n type: \"and\",\n items: [] as Condition[],\n } as const;\n\n for (const item of conditions) {\n if (item === true) {\n continue;\n }\n if (item === false) {\n return false;\n }\n\n out.items.push(item);\n }\n\n if (out.items.length === 0) {\n return true;\n }\n return out;\n };\n\n return builder;\n}\n"],"mappings":";AA2DA,MAAM,kBAAkB;CACtB;CACA;CACA;CAEA;CACA;CACA;CAED;AAED,MAAM,iBAAiB,CAAC,MAAM,SAAS;AAEvC,MAAM,iBAAiB;CAAC;CAAK;CAAM;CAAK;CAAM;CAAK;CAAM;CAAM;CAAS;AAKxE,MAAa,YAAY;CAAC,GAAG;CAAgB,GAAG;CAAgB,GAAG;CAAgB;AAInF,SAAgB,cACd,SAC2B;CAC3B,SAAS,IAAI,MAAqB;EAChC,MAAM,MAAM,QAAQ;AACpB,MAAI,CAAC,IACH,OAAM,IAAI,MAAM,uBAAuB,OAAO,KAAK,GAAG;AAGxD,SAAO;;CAGT,MAAMA,WAAsC,GAAG,SAAiD;AAC9F,MAAI,KAAK,WAAW,GAAG;GACrB,MAAM,CAAC,GAAG,UAAU,KAAK;AAEzB,OAAI,CAAC,UAAU,SAAS,SAAS,CAC/B,OAAM,IAAI,MAAM,yBAAyB,WAAW;AAGtD,UAAO;IACL,MAAM;IACN,GAAG,IAAI,EAAE;IACT;IACA;IACD;;AAGH,SAAO;GACL,MAAM;GACN,GAAG,IAAI,KAAK,GAAG;GACf,UAAU;GACV,GAAG;GACJ;;AAGH,SAAQ,UAAU,MAAM,QAAQ,GAAG,MAAM,KAAK;AAC9C,SAAQ,aAAa,MAAM,QAAQ,GAAG,UAAU,KAAK;AACrD,SAAQ,OAAO,cAAc;AAC3B,MAAI,OAAO,cAAc,UACvB,QAAO,CAAC;AAGV,SAAO;GACL,MAAM;GACN,MAAM;GACP;;AAGH,SAAQ,MAAM,GAAG,eAAe;EAC9B,MAAM,MAAM;GACV,MAAM;GACN,OAAO,EAAE;GACV;AAED,OAAK,MAAM,QAAQ,YAAY;AAC7B,OAAI,SAAS,KACX,QAAO;AAET,OAAI,SAAS,MACX;AAGF,OAAI,MAAM,KAAK,KAAK;;AAGtB,MAAI,IAAI,MAAM,WAAW,EACvB,QAAO;AAET,SAAO;;AAGT,SAAQ,OAAO,GAAG,eAAe;EAC/B,MAAM,MAAM;GACV,MAAM;GACN,OAAO,EAAE;GACV;AAED,OAAK,MAAM,QAAQ,YAAY;AAC7B,OAAI,SAAS,KACX;AAEF,OAAI,SAAS,MACX,QAAO;AAGT,OAAI,MAAM,KAAK,KAAK;;AAGtB,MAAI,IAAI,MAAM,WAAW,EACvB,QAAO;AAET,SAAO;;AAGT,QAAO;;AAGT,SAAgB,eACd,SACA,OACG;AACH,QAAO,MAAM,cAAc,QAAQ,CAAC"}
1
+ {"version":3,"file":"condition-builder.js","names":["builder: ConditionBuilder<Columns>"],"sources":["../../src/query/condition-builder.ts"],"sourcesContent":["import type { AnyColumn, FragnoId, IdColumn } from \"../schema/create\";\nimport { dbInterval, dbNow, type DbInterval, type DbIntervalInput, type DbNow } from \"./db-now\";\n\nexport type ConditionType = \"compare\" | \"and\" | \"or\" | \"not\";\n\nexport type Condition =\n | {\n type: \"compare\";\n a: AnyColumn;\n operator: Operator;\n b: AnyColumn | unknown | null;\n }\n | {\n type: \"or\" | \"and\";\n items: Condition[];\n }\n | {\n type: \"not\";\n item: Condition;\n };\n\n// TODO: we temporarily dropped support for comparing against another column, because Prisma ORM still have problems with it.\n\n/**\n * Helper type that allows FragnoId for ID columns and reference columns (bigint).\n * Used in ConditionBuilder to accept FragnoId values in where conditions.\n */\ntype AcceptsFragnoId<T extends AnyColumn> = T extends IdColumn\n ? T[\"$in\"] | FragnoId\n : T[\"$in\"] extends bigint\n ? T[\"$in\"] | FragnoId\n : T[\"$in\"];\n\nexport type ConditionBuilder<Columns extends Record<string, AnyColumn>> = {\n <ColName extends keyof Columns>(\n a: ColName,\n operator: (typeof valueOperators)[number] | (typeof stringOperators)[number],\n b: AcceptsFragnoId<Columns[ColName]> | null,\n ): Condition;\n\n <ColName extends keyof Columns>(\n a: ColName,\n operator: (typeof arrayOperators)[number],\n b: AcceptsFragnoId<Columns[ColName]>[],\n ): Condition;\n\n /**\n * Boolean values\n */\n <ColName extends keyof Columns>(a: ColName): Condition;\n\n and: (...v: (Condition | boolean)[]) => Condition | boolean;\n or: (...v: (Condition | boolean)[]) => Condition | boolean;\n not: (v: Condition | boolean) => Condition | boolean;\n\n isNull: (a: keyof Columns) => Condition;\n isNotNull: (a: keyof Columns) => Condition;\n now: () => DbNow;\n interval: (input: DbIntervalInput) => DbInterval;\n};\n\n// replacement for `like` (Prisma doesn't support `like`)\nconst stringOperators = [\n \"contains\",\n \"starts with\",\n \"ends with\",\n\n \"not contains\",\n \"not starts with\",\n \"not ends with\",\n // excluded `regexp` since MSSQL doesn't support it, may re-consider\n] as const;\n\nconst arrayOperators = [\"in\", \"not in\"] as const;\n\nconst valueOperators = [\"=\", \"!=\", \">\", \">=\", \"<\", \"<=\", \"is\", \"is not\"] as const;\n\n// JSON specific operators are not included, some databases don't support them\n// `match` requires additional extensions & configurations on SQLite and PostgreSQL\n// MySQL & SQLite requires workarounds to support `ilike`\nexport const operators = [...valueOperators, ...arrayOperators, ...stringOperators] as const;\n\nexport type Operator = (typeof operators)[number];\n\nexport function createBuilder<Columns extends Record<string, AnyColumn>>(\n columns: Columns,\n): ConditionBuilder<Columns> {\n function col(name: keyof Columns) {\n const out = columns[name];\n if (!out) {\n throw new Error(`Invalid column name ${String(name)}`);\n }\n\n return out;\n }\n\n const builder: ConditionBuilder<Columns> = (...args: [string, Operator, unknown] | [string]) => {\n if (args.length === 3) {\n const [a, operator, b] = args;\n\n if (!operators.includes(operator)) {\n throw new Error(`Unsupported operator: ${operator}`);\n }\n\n return {\n type: \"compare\",\n a: col(a),\n b,\n operator,\n };\n }\n\n return {\n type: \"compare\",\n a: col(args[0]),\n operator: \"=\",\n b: true,\n };\n };\n\n builder.isNull = (a) => builder(a, \"is\", null);\n builder.isNotNull = (a) => builder(a, \"is not\", null);\n builder.now = () => dbNow();\n builder.interval = (input) => dbInterval(input);\n builder.not = (condition) => {\n if (typeof condition === \"boolean\") {\n return !condition;\n }\n\n return {\n type: \"not\",\n item: condition,\n };\n };\n\n builder.or = (...conditions) => {\n const out = {\n type: \"or\",\n items: [] as Condition[],\n } as const;\n\n for (const item of conditions) {\n if (item === true) {\n return true;\n }\n if (item === false) {\n continue;\n }\n\n out.items.push(item);\n }\n\n if (out.items.length === 0) {\n return false;\n }\n return out;\n };\n\n builder.and = (...conditions) => {\n const out = {\n type: \"and\",\n items: [] as Condition[],\n } as const;\n\n for (const item of conditions) {\n if (item === true) {\n continue;\n }\n if (item === false) {\n return false;\n }\n\n out.items.push(item);\n }\n\n if (out.items.length === 0) {\n return true;\n }\n return out;\n };\n\n return builder;\n}\n\nexport function buildCondition<T, Columns extends Record<string, AnyColumn>>(\n columns: Columns,\n input: (builder: ConditionBuilder<Columns>) => T,\n): T {\n return input(createBuilder(columns));\n}\n\n/**\n * Create a ConditionBuilder that only allows comparisons on indexed columns.\n * Used in Unit of Work to ensure queries can leverage indexes for optimal performance.\n *\n * @param columns - The full set of columns from the table\n * @param indexedColumnNames - Set of column names that are part of indexes\n * @returns A ConditionBuilder restricted to indexed columns only\n *\n * @example\n * ```ts\n * const builder = createIndexedBuilder(\n * table.columns,\n * new Set([\"id\", \"userId\", \"createdAt\"])\n * );\n * const condition = builder(\"userId\", \"=\", \"123\");\n * ```\n */\nexport function createIndexedBuilder<Columns extends Record<string, AnyColumn>>(\n columns: Columns,\n indexedColumnNames: Set<string>,\n): ConditionBuilder<Columns> {\n function col(name: keyof Columns) {\n const columnName = String(name);\n\n if (!indexedColumnNames.has(columnName)) {\n throw new Error(\n `Column \"${columnName}\" is not indexed. Only indexed columns can be used in Unit of Work queries. ` +\n `Available indexed columns: ${Array.from(indexedColumnNames).join(\", \")}`,\n );\n }\n\n const out = columns[name];\n if (!out) {\n throw new Error(`Invalid column name ${columnName}`);\n }\n\n return out;\n }\n\n const builder: ConditionBuilder<Columns> = (...args: [string, Operator, unknown] | [string]) => {\n if (args.length === 3) {\n const [a, operator, b] = args;\n\n if (!operators.includes(operator)) {\n throw new Error(`Unsupported operator: ${operator}`);\n }\n\n return {\n type: \"compare\",\n a: col(a),\n b,\n operator,\n };\n }\n\n return {\n type: \"compare\",\n a: col(args[0]),\n operator: \"=\",\n b: true,\n };\n };\n\n builder.isNull = (a) => builder(a, \"is\", null);\n builder.isNotNull = (a) => builder(a, \"is not\", null);\n builder.now = () => dbNow();\n builder.interval = (input) => dbInterval(input);\n builder.not = (condition) => {\n if (typeof condition === \"boolean\") {\n return !condition;\n }\n\n return {\n type: \"not\",\n item: condition,\n };\n };\n\n builder.or = (...conditions) => {\n const out = {\n type: \"or\",\n items: [] as Condition[],\n } as const;\n\n for (const item of conditions) {\n if (item === true) {\n return true;\n }\n if (item === false) {\n continue;\n }\n\n out.items.push(item);\n }\n\n if (out.items.length === 0) {\n return false;\n }\n return out;\n };\n\n builder.and = (...conditions) => {\n const out = {\n type: \"and\",\n items: [] as Condition[],\n } as const;\n\n for (const item of conditions) {\n if (item === true) {\n continue;\n }\n if (item === false) {\n return false;\n }\n\n out.items.push(item);\n }\n\n if (out.items.length === 0) {\n return true;\n }\n return out;\n };\n\n return builder;\n}\n"],"mappings":";;;AA8DA,MAAM,kBAAkB;CACtB;CACA;CACA;CAEA;CACA;CACA;CAED;AAED,MAAM,iBAAiB,CAAC,MAAM,SAAS;AAEvC,MAAM,iBAAiB;CAAC;CAAK;CAAM;CAAK;CAAM;CAAK;CAAM;CAAM;CAAS;AAKxE,MAAa,YAAY;CAAC,GAAG;CAAgB,GAAG;CAAgB,GAAG;CAAgB;AAInF,SAAgB,cACd,SAC2B;CAC3B,SAAS,IAAI,MAAqB;EAChC,MAAM,MAAM,QAAQ;AACpB,MAAI,CAAC,IACH,OAAM,IAAI,MAAM,uBAAuB,OAAO,KAAK,GAAG;AAGxD,SAAO;;CAGT,MAAMA,WAAsC,GAAG,SAAiD;AAC9F,MAAI,KAAK,WAAW,GAAG;GACrB,MAAM,CAAC,GAAG,UAAU,KAAK;AAEzB,OAAI,CAAC,UAAU,SAAS,SAAS,CAC/B,OAAM,IAAI,MAAM,yBAAyB,WAAW;AAGtD,UAAO;IACL,MAAM;IACN,GAAG,IAAI,EAAE;IACT;IACA;IACD;;AAGH,SAAO;GACL,MAAM;GACN,GAAG,IAAI,KAAK,GAAG;GACf,UAAU;GACV,GAAG;GACJ;;AAGH,SAAQ,UAAU,MAAM,QAAQ,GAAG,MAAM,KAAK;AAC9C,SAAQ,aAAa,MAAM,QAAQ,GAAG,UAAU,KAAK;AACrD,SAAQ,YAAY,OAAO;AAC3B,SAAQ,YAAY,UAAU,WAAW,MAAM;AAC/C,SAAQ,OAAO,cAAc;AAC3B,MAAI,OAAO,cAAc,UACvB,QAAO,CAAC;AAGV,SAAO;GACL,MAAM;GACN,MAAM;GACP;;AAGH,SAAQ,MAAM,GAAG,eAAe;EAC9B,MAAM,MAAM;GACV,MAAM;GACN,OAAO,EAAE;GACV;AAED,OAAK,MAAM,QAAQ,YAAY;AAC7B,OAAI,SAAS,KACX,QAAO;AAET,OAAI,SAAS,MACX;AAGF,OAAI,MAAM,KAAK,KAAK;;AAGtB,MAAI,IAAI,MAAM,WAAW,EACvB,QAAO;AAET,SAAO;;AAGT,SAAQ,OAAO,GAAG,eAAe;EAC/B,MAAM,MAAM;GACV,MAAM;GACN,OAAO,EAAE;GACV;AAED,OAAK,MAAM,QAAQ,YAAY;AAC7B,OAAI,SAAS,KACX;AAEF,OAAI,SAAS,MACX,QAAO;AAGT,OAAI,MAAM,KAAK,KAAK;;AAGtB,MAAI,IAAI,MAAM,WAAW,EACvB,QAAO;AAET,SAAO;;AAGT,QAAO;;AAGT,SAAgB,eACd,SACA,OACG;AACH,QAAO,MAAM,cAAc,QAAQ,CAAC"}