@fragno-dev/db 0.3.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (516) hide show
  1. package/.turbo/turbo-build.log +327 -160
  2. package/CHANGELOG.md +74 -0
  3. package/README.md +24 -0
  4. package/dist/adapters/adapters.d.ts +1 -1
  5. package/dist/adapters/adapters.d.ts.map +1 -1
  6. package/dist/adapters/adapters.js.map +1 -1
  7. package/dist/adapters/generic-sql/generic-sql-adapter.d.ts +0 -3
  8. package/dist/adapters/generic-sql/generic-sql-adapter.d.ts.map +1 -1
  9. package/dist/adapters/generic-sql/generic-sql-adapter.js +11 -12
  10. package/dist/adapters/generic-sql/generic-sql-adapter.js.map +1 -1
  11. package/dist/adapters/generic-sql/generic-sql-uow-executor.js +46 -6
  12. package/dist/adapters/generic-sql/generic-sql-uow-executor.js.map +1 -1
  13. package/dist/adapters/generic-sql/migration/cold-kysely.js.map +1 -1
  14. package/dist/adapters/generic-sql/migration/dialect/mysql.js +1 -1
  15. package/dist/adapters/generic-sql/migration/dialect/mysql.js.map +1 -1
  16. package/dist/adapters/generic-sql/migration/dialect/postgres.js +1 -1
  17. package/dist/adapters/generic-sql/migration/dialect/postgres.js.map +1 -1
  18. package/dist/adapters/generic-sql/migration/dialect/sqlite.js +185 -19
  19. package/dist/adapters/generic-sql/migration/dialect/sqlite.js.map +1 -1
  20. package/dist/adapters/generic-sql/migration/executor.d.ts.map +1 -1
  21. package/dist/adapters/generic-sql/migration/executor.js +30 -3
  22. package/dist/adapters/generic-sql/migration/executor.js.map +1 -1
  23. package/dist/adapters/generic-sql/migration/prepared-migrations.d.ts.map +1 -1
  24. package/dist/adapters/generic-sql/migration/prepared-migrations.js +3 -3
  25. package/dist/adapters/generic-sql/migration/prepared-migrations.js.map +1 -1
  26. package/dist/adapters/generic-sql/migration/sql-generator.js +1 -1
  27. package/dist/adapters/generic-sql/migration/sql-generator.js.map +1 -1
  28. package/dist/adapters/generic-sql/query/create-sql-query-compiler.js +1 -1
  29. package/dist/adapters/generic-sql/query/create-sql-query-compiler.js.map +1 -1
  30. package/dist/adapters/generic-sql/query/cursor-utils.js.map +1 -1
  31. package/dist/adapters/generic-sql/query/db-now-sql.js +27 -0
  32. package/dist/adapters/generic-sql/query/db-now-sql.js.map +1 -0
  33. package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js +9 -6
  34. package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js.map +1 -1
  35. package/dist/adapters/generic-sql/query/select-builder.js.map +1 -1
  36. package/dist/adapters/generic-sql/query/sql-query-compiler.js +37 -9
  37. package/dist/adapters/generic-sql/query/sql-query-compiler.js.map +1 -1
  38. package/dist/adapters/generic-sql/query/where-builder.js +24 -20
  39. package/dist/adapters/generic-sql/query/where-builder.js.map +1 -1
  40. package/dist/adapters/generic-sql/uow-decoder.js +1 -1
  41. package/dist/adapters/generic-sql/uow-decoder.js.map +1 -1
  42. package/dist/adapters/generic-sql/uow-encoder.js +8 -9
  43. package/dist/adapters/generic-sql/uow-encoder.js.map +1 -1
  44. package/dist/adapters/in-memory/condition-evaluator.js +10 -6
  45. package/dist/adapters/in-memory/condition-evaluator.js.map +1 -1
  46. package/dist/adapters/in-memory/in-memory-adapter.d.ts.map +1 -1
  47. package/dist/adapters/in-memory/in-memory-adapter.js +45 -25
  48. package/dist/adapters/in-memory/in-memory-adapter.js.map +1 -1
  49. package/dist/adapters/in-memory/in-memory-uow.js +236 -13
  50. package/dist/adapters/in-memory/in-memory-uow.js.map +1 -1
  51. package/dist/adapters/in-memory/options.d.ts +2 -0
  52. package/dist/adapters/in-memory/options.d.ts.map +1 -1
  53. package/dist/adapters/in-memory/options.js +3 -2
  54. package/dist/adapters/in-memory/options.js.map +1 -1
  55. package/dist/adapters/in-memory/reference-resolution.js.map +1 -1
  56. package/dist/adapters/in-memory/store.js +1 -1
  57. package/dist/adapters/in-memory/store.js.map +1 -1
  58. package/dist/adapters/shared/from-unit-of-work-compiler.js +51 -24
  59. package/dist/adapters/shared/from-unit-of-work-compiler.js.map +1 -1
  60. package/dist/adapters/shared/uow-operation-compiler.js.map +1 -1
  61. package/dist/browser/adapters/adapters.d.ts +61 -0
  62. package/dist/browser/adapters/adapters.d.ts.map +1 -0
  63. package/dist/browser/adapters/generic-sql/migration/executor.d.ts +15 -0
  64. package/dist/browser/adapters/generic-sql/migration/executor.d.ts.map +1 -0
  65. package/dist/browser/adapters/generic-sql/migration/prepared-migrations.d.ts +66 -0
  66. package/dist/browser/adapters/generic-sql/migration/prepared-migrations.d.ts.map +1 -0
  67. package/dist/browser/adapters/generic-sql/sqlite-storage.d.ts +11 -0
  68. package/dist/browser/adapters/generic-sql/sqlite-storage.d.ts.map +1 -0
  69. package/dist/browser/adapters/in-memory/in-memory-adapter.d.ts +5 -0
  70. package/dist/browser/adapters/in-memory/index.d.ts +2 -0
  71. package/dist/browser/adapters/in-memory/options.d.ts +1 -0
  72. package/dist/browser/db-fragment-definition-builder.d.ts +237 -0
  73. package/dist/browser/db-fragment-definition-builder.d.ts.map +1 -0
  74. package/dist/browser/durable-hooks.d.ts +3 -0
  75. package/dist/browser/fragments/internal-fragment.d.ts +317 -0
  76. package/dist/browser/fragments/internal-fragment.d.ts.map +1 -0
  77. package/dist/browser/fragments/internal-fragment.schema.d.ts +1 -0
  78. package/dist/browser/hooks/durable-hooks-logger.d.ts +10 -0
  79. package/dist/browser/hooks/durable-hooks-logger.d.ts.map +1 -0
  80. package/dist/browser/hooks/hooks.d.ts +146 -0
  81. package/dist/browser/hooks/hooks.d.ts.map +1 -0
  82. package/dist/browser/id.js +1 -0
  83. package/dist/browser/internal/adapter-registry.d.ts +4 -0
  84. package/dist/browser/internal/outbox-state.d.ts +2 -0
  85. package/dist/browser/mod.d.ts +15 -0
  86. package/dist/browser/mod.d.ts.map +1 -0
  87. package/dist/browser/mod.js +17 -0
  88. package/dist/browser/mod.js.map +1 -0
  89. package/dist/browser/mod2.d.ts +48 -0
  90. package/dist/browser/mod2.d.ts.map +1 -0
  91. package/dist/browser/naming/sql-naming.d.ts +19 -0
  92. package/dist/browser/naming/sql-naming.d.ts.map +1 -0
  93. package/dist/browser/outbox/outbox.d.ts +21 -0
  94. package/dist/browser/outbox/outbox.d.ts.map +1 -0
  95. package/dist/browser/query/column-defaults.js +1 -0
  96. package/dist/browser/query/condition-builder.d.ts +44 -0
  97. package/dist/browser/query/condition-builder.d.ts.map +1 -0
  98. package/dist/browser/query/condition-builder.js +97 -0
  99. package/dist/browser/query/condition-builder.js.map +1 -0
  100. package/dist/browser/query/cursor.d.ts +105 -0
  101. package/dist/browser/query/cursor.d.ts.map +1 -0
  102. package/dist/browser/query/cursor.js +150 -0
  103. package/dist/browser/query/cursor.js.map +1 -0
  104. package/dist/browser/query/db-now.d.ts +22 -0
  105. package/dist/browser/query/db-now.d.ts.map +1 -0
  106. package/dist/browser/query/db-now.js +33 -0
  107. package/dist/browser/query/db-now.js.map +1 -0
  108. package/dist/browser/query/orm/orm.d.ts +18 -0
  109. package/dist/browser/query/orm/orm.d.ts.map +1 -0
  110. package/dist/browser/query/simple-query-interface.d.ts +108 -0
  111. package/dist/browser/query/simple-query-interface.d.ts.map +1 -0
  112. package/dist/browser/query/unit-of-work/execute-unit-of-work.d.ts +423 -0
  113. package/dist/browser/query/unit-of-work/execute-unit-of-work.d.ts.map +1 -0
  114. package/dist/browser/query/unit-of-work/execute-unit-of-work.js +507 -0
  115. package/dist/browser/query/unit-of-work/execute-unit-of-work.js.map +1 -0
  116. package/dist/browser/query/unit-of-work/retry-policy.d.ts +23 -0
  117. package/dist/browser/query/unit-of-work/retry-policy.d.ts.map +1 -0
  118. package/dist/browser/query/unit-of-work/retry-policy.js +40 -0
  119. package/dist/browser/query/unit-of-work/retry-policy.js.map +1 -0
  120. package/dist/browser/query/unit-of-work/unit-of-work.d.ts +703 -0
  121. package/dist/browser/query/unit-of-work/unit-of-work.d.ts.map +1 -0
  122. package/dist/browser/query/unit-of-work/unit-of-work.js +1206 -0
  123. package/dist/browser/query/unit-of-work/unit-of-work.js.map +1 -0
  124. package/dist/browser/query/value-encoding.js +38 -0
  125. package/dist/browser/query/value-encoding.js.map +1 -0
  126. package/dist/browser/schema/create.d.ts +326 -0
  127. package/dist/browser/schema/create.d.ts.map +1 -0
  128. package/dist/browser/schema/create.js +89 -0
  129. package/dist/browser/schema/create.js.map +1 -0
  130. package/dist/browser/schema/generate-id.js +28 -0
  131. package/dist/browser/schema/generate-id.js.map +1 -0
  132. package/dist/browser/shared/providers.d.ts +6 -0
  133. package/dist/browser/shared/providers.d.ts.map +1 -0
  134. package/dist/browser/sql-driver/connection/connection-provider.d.ts +13 -0
  135. package/dist/browser/sql-driver/connection/connection-provider.d.ts.map +1 -0
  136. package/dist/browser/sql-driver/dialect-adapter/dialect-adapter.d.ts +7 -0
  137. package/dist/browser/sql-driver/dialect-adapter/dialect-adapter.d.ts.map +1 -0
  138. package/dist/browser/sql-driver/driver/runtime-driver.d.ts +23 -0
  139. package/dist/browser/sql-driver/driver/runtime-driver.d.ts.map +1 -0
  140. package/dist/browser/sql-driver/query-executor/plugin.d.ts +17 -0
  141. package/dist/browser/sql-driver/query-executor/plugin.d.ts.map +1 -0
  142. package/dist/browser/sql-driver/query-executor/query-executor.d.ts +36 -0
  143. package/dist/browser/sql-driver/query-executor/query-executor.d.ts.map +1 -0
  144. package/dist/browser/sql-driver/sql-driver-adapter.d.ts +29 -0
  145. package/dist/browser/sql-driver/sql-driver-adapter.d.ts.map +1 -0
  146. package/dist/browser/sql-driver/sql-driver.d.ts +38 -0
  147. package/dist/browser/sql-driver/sql-driver.d.ts.map +1 -0
  148. package/dist/browser/sync/commands.d.ts +15 -0
  149. package/dist/browser/sync/commands.d.ts.map +1 -0
  150. package/dist/browser/sync/commands.js +27 -0
  151. package/dist/browser/sync/commands.js.map +1 -0
  152. package/dist/browser/sync/types.d.ts +63 -0
  153. package/dist/browser/sync/types.d.ts.map +1 -0
  154. package/dist/browser/util/types.d.ts +8 -0
  155. package/dist/browser/util/types.d.ts.map +1 -0
  156. package/dist/browser/with-database.d.ts +29 -0
  157. package/dist/browser/with-database.d.ts.map +1 -0
  158. package/dist/client.d.ts +4 -0
  159. package/dist/client.js +5 -0
  160. package/dist/db-fragment-definition-builder.d.ts +85 -28
  161. package/dist/db-fragment-definition-builder.d.ts.map +1 -1
  162. package/dist/db-fragment-definition-builder.js +374 -46
  163. package/dist/db-fragment-definition-builder.js.map +1 -1
  164. package/dist/dispatchers/cloudflare-do/dispatcher.d.ts +20 -0
  165. package/dist/dispatchers/cloudflare-do/dispatcher.d.ts.map +1 -0
  166. package/dist/dispatchers/cloudflare-do/dispatcher.js +147 -0
  167. package/dist/dispatchers/cloudflare-do/dispatcher.js.map +1 -0
  168. package/dist/dispatchers/cloudflare-do/index.d.ts +5 -20
  169. package/dist/dispatchers/cloudflare-do/index.d.ts.map +1 -1
  170. package/dist/dispatchers/cloudflare-do/index.js +23 -55
  171. package/dist/dispatchers/cloudflare-do/index.js.map +1 -1
  172. package/dist/dispatchers/node/dispatcher.d.ts +14 -0
  173. package/dist/dispatchers/node/dispatcher.d.ts.map +1 -0
  174. package/dist/dispatchers/node/dispatcher.js +80 -0
  175. package/dist/dispatchers/node/dispatcher.js.map +1 -0
  176. package/dist/dispatchers/node/index.d.ts +5 -10
  177. package/dist/dispatchers/node/index.d.ts.map +1 -1
  178. package/dist/dispatchers/node/index.js +21 -53
  179. package/dist/dispatchers/node/index.js.map +1 -1
  180. package/dist/durable-hooks.d.ts +31 -0
  181. package/dist/durable-hooks.d.ts.map +1 -0
  182. package/dist/durable-hooks.js +23 -0
  183. package/dist/durable-hooks.js.map +1 -0
  184. package/dist/fragments/internal-fragment.d.ts +128 -27
  185. package/dist/fragments/internal-fragment.d.ts.map +1 -1
  186. package/dist/fragments/internal-fragment.js +125 -78
  187. package/dist/fragments/internal-fragment.js.map +1 -1
  188. package/dist/fragments/internal-fragment.routes.js +138 -3
  189. package/dist/fragments/internal-fragment.routes.js.map +1 -1
  190. package/dist/fragments/internal-fragment.schema.d.ts +7 -1
  191. package/dist/fragments/internal-fragment.schema.d.ts.map +1 -1
  192. package/dist/fragments/internal-fragment.schema.js +18 -1
  193. package/dist/fragments/internal-fragment.schema.js.map +1 -1
  194. package/dist/hooks/durable-hooks-logger.d.ts +10 -0
  195. package/dist/hooks/durable-hooks-logger.d.ts.map +1 -0
  196. package/dist/hooks/durable-hooks-logger.js +75 -0
  197. package/dist/hooks/durable-hooks-logger.js.map +1 -0
  198. package/dist/hooks/durable-hooks-processor.d.ts +1 -14
  199. package/dist/hooks/durable-hooks-processor.js +58 -10
  200. package/dist/hooks/durable-hooks-processor.js.map +1 -1
  201. package/dist/hooks/durable-hooks-runtime.js +44 -0
  202. package/dist/hooks/durable-hooks-runtime.js.map +1 -0
  203. package/dist/hooks/hooks.d.ts +60 -2
  204. package/dist/hooks/hooks.d.ts.map +1 -1
  205. package/dist/hooks/hooks.js +214 -53
  206. package/dist/hooks/hooks.js.map +1 -1
  207. package/dist/id.d.ts +2 -2
  208. package/dist/id.js +2 -2
  209. package/dist/internal/adapter-registry.d.ts +11 -0
  210. package/dist/internal/adapter-registry.d.ts.map +1 -0
  211. package/dist/internal/adapter-registry.js +135 -0
  212. package/dist/internal/adapter-registry.js.map +1 -0
  213. package/dist/internal/outbox-state.d.ts +2 -0
  214. package/dist/internal/outbox-state.js +26 -0
  215. package/dist/internal/outbox-state.js.map +1 -0
  216. package/dist/migration-engine/auto-from-schema.d.ts +33 -0
  217. package/dist/migration-engine/auto-from-schema.d.ts.map +1 -0
  218. package/dist/migration-engine/auto-from-schema.js +210 -27
  219. package/dist/migration-engine/auto-from-schema.js.map +1 -1
  220. package/dist/migration-engine/generation-engine.d.ts.map +1 -1
  221. package/dist/migration-engine/generation-engine.js +17 -5
  222. package/dist/migration-engine/generation-engine.js.map +1 -1
  223. package/dist/migration-engine/shared.d.ts +113 -0
  224. package/dist/migration-engine/shared.d.ts.map +1 -0
  225. package/dist/migration-engine/shared.js.map +1 -1
  226. package/dist/mod.d.ts +12 -11
  227. package/dist/mod.d.ts.map +1 -1
  228. package/dist/mod.js +10 -10
  229. package/dist/mod.js.map +1 -1
  230. package/dist/naming/sql-naming.d.ts.map +1 -1
  231. package/dist/naming/sql-naming.js.map +1 -1
  232. package/dist/outbox/outbox-builder.js.map +1 -1
  233. package/dist/outbox/outbox.d.ts +3 -1
  234. package/dist/outbox/outbox.d.ts.map +1 -1
  235. package/dist/outbox/outbox.js.map +1 -1
  236. package/dist/query/column-defaults.js.map +1 -1
  237. package/dist/query/condition-builder.d.ts +7 -1
  238. package/dist/query/condition-builder.d.ts.map +1 -1
  239. package/dist/query/condition-builder.js +5 -1
  240. package/dist/query/condition-builder.js.map +1 -1
  241. package/dist/query/cursor-client.d.ts +105 -0
  242. package/dist/query/cursor-client.d.ts.map +1 -0
  243. package/dist/query/cursor-client.js +165 -0
  244. package/dist/query/cursor-client.js.map +1 -0
  245. package/dist/query/cursor.d.ts.map +1 -1
  246. package/dist/query/cursor.js +7 -1
  247. package/dist/query/cursor.js.map +1 -1
  248. package/dist/query/db-now.d.ts +15 -1
  249. package/dist/query/db-now.d.ts.map +1 -1
  250. package/dist/query/db-now.js +30 -2
  251. package/dist/query/db-now.js.map +1 -1
  252. package/dist/query/orm/orm.js.map +1 -1
  253. package/dist/query/serialize/create-sql-serializer.js +2 -2
  254. package/dist/query/serialize/create-sql-serializer.js.map +1 -1
  255. package/dist/query/serialize/dialect/mysql-serializer.js.map +1 -1
  256. package/dist/query/serialize/dialect/postgres-serializer.js.map +1 -1
  257. package/dist/query/serialize/dialect/sqlite-serializer.js +6 -2
  258. package/dist/query/serialize/dialect/sqlite-serializer.js.map +1 -1
  259. package/dist/query/simple-query-interface.d.ts +7 -3
  260. package/dist/query/simple-query-interface.d.ts.map +1 -1
  261. package/dist/query/unit-of-work/execute-unit-of-work.d.ts +37 -2
  262. package/dist/query/unit-of-work/execute-unit-of-work.d.ts.map +1 -1
  263. package/dist/query/unit-of-work/execute-unit-of-work.js +39 -18
  264. package/dist/query/unit-of-work/execute-unit-of-work.js.map +1 -1
  265. package/dist/query/unit-of-work/unit-of-work.d.ts +42 -16
  266. package/dist/query/unit-of-work/unit-of-work.d.ts.map +1 -1
  267. package/dist/query/unit-of-work/unit-of-work.js +50 -6
  268. package/dist/query/unit-of-work/unit-of-work.js.map +1 -1
  269. package/dist/query/value-decoding.js +8 -1
  270. package/dist/query/value-decoding.js.map +1 -1
  271. package/dist/query/value-encoding.js.map +1 -1
  272. package/dist/schema/create.d.ts +69 -25
  273. package/dist/schema/create.d.ts.map +1 -1
  274. package/dist/schema/create.js +91 -16
  275. package/dist/schema/create.js.map +1 -1
  276. package/dist/schema/type-conversion/create-sql-type-mapper.js +1 -1
  277. package/dist/schema/type-conversion/create-sql-type-mapper.js.map +1 -1
  278. package/dist/schema/type-conversion/dialect/sqlite.js.map +1 -1
  279. package/dist/schema/validator.d.ts.map +1 -1
  280. package/dist/schema/validator.js.map +1 -1
  281. package/dist/schema-output/drizzle.d.ts.map +1 -1
  282. package/dist/schema-output/drizzle.js +8 -6
  283. package/dist/schema-output/drizzle.js.map +1 -1
  284. package/dist/schema-output/prisma.d.ts.map +1 -1
  285. package/dist/schema-output/prisma.js +21 -10
  286. package/dist/schema-output/prisma.js.map +1 -1
  287. package/dist/sql-driver/dialects/durable-object-dialect.js +3 -9
  288. package/dist/sql-driver/dialects/durable-object-dialect.js.map +1 -1
  289. package/dist/sql-driver/query-executor/default-query-executor.js.map +1 -1
  290. package/dist/sql-driver/query-executor/query-executor-base.js.map +1 -1
  291. package/dist/sql-driver/sql-driver-adapter.js.map +1 -1
  292. package/dist/sql-driver/sql.js.map +1 -1
  293. package/dist/sync/commands.d.ts +15 -0
  294. package/dist/sync/commands.d.ts.map +1 -0
  295. package/dist/sync/commands.js +27 -0
  296. package/dist/sync/commands.js.map +1 -0
  297. package/dist/sync/index.d.ts +4 -0
  298. package/dist/sync/index.js +4 -0
  299. package/dist/sync/read-tracking.d.ts +25 -0
  300. package/dist/sync/read-tracking.d.ts.map +1 -0
  301. package/dist/sync/read-tracking.js +148 -0
  302. package/dist/sync/read-tracking.js.map +1 -0
  303. package/dist/sync/submit.js +213 -0
  304. package/dist/sync/submit.js.map +1 -0
  305. package/dist/sync/types.d.ts +63 -0
  306. package/dist/sync/types.d.ts.map +1 -0
  307. package/dist/util/default-database-adapter.js +6 -1
  308. package/dist/util/default-database-adapter.js.map +1 -1
  309. package/dist/with-database.d.ts +3 -6
  310. package/dist/with-database.d.ts.map +1 -1
  311. package/dist/with-database.js +7 -15
  312. package/dist/with-database.js.map +1 -1
  313. package/package.json +33 -41
  314. package/src/adapters/adapters.ts +5 -4
  315. package/src/adapters/drizzle/migrate-drizzle.test.ts +46 -9
  316. package/src/adapters/drizzle/migration-parity-drizzle-kit.test.ts +5 -3
  317. package/src/adapters/drizzle/test-utils.ts +2 -1
  318. package/src/adapters/generic-sql/generic-sql-adapter.test.ts +5 -3
  319. package/src/adapters/generic-sql/generic-sql-adapter.ts +21 -24
  320. package/src/adapters/generic-sql/generic-sql-uow-executor.test.ts +1 -0
  321. package/src/adapters/generic-sql/generic-sql-uow-executor.ts +81 -15
  322. package/src/adapters/generic-sql/migration/adapter-migration-parity.test.ts +4 -2
  323. package/src/adapters/generic-sql/migration/cold-kysely.ts +1 -0
  324. package/src/adapters/generic-sql/migration/dialect/mysql.test.ts +3 -2
  325. package/src/adapters/generic-sql/migration/dialect/mysql.ts +1 -0
  326. package/src/adapters/generic-sql/migration/dialect/postgres.test.ts +5 -4
  327. package/src/adapters/generic-sql/migration/dialect/postgres.ts +2 -1
  328. package/src/adapters/generic-sql/migration/dialect/sqlite.test.ts +795 -3
  329. package/src/adapters/generic-sql/migration/dialect/sqlite.ts +385 -57
  330. package/src/adapters/generic-sql/migration/executor.test.ts +52 -0
  331. package/src/adapters/generic-sql/migration/executor.ts +47 -4
  332. package/src/adapters/generic-sql/migration/prepared-migrations.test.ts +117 -14
  333. package/src/adapters/generic-sql/migration/prepared-migrations.ts +9 -8
  334. package/src/adapters/generic-sql/migration/sql-generator.ts +5 -3
  335. package/src/adapters/generic-sql/query/create-sql-query-compiler.ts +3 -3
  336. package/src/adapters/generic-sql/query/cursor-utils.test.ts +3 -2
  337. package/src/adapters/generic-sql/query/cursor-utils.ts +1 -1
  338. package/src/adapters/generic-sql/query/db-now-sql.ts +49 -0
  339. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.test.ts +144 -8
  340. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.ts +16 -17
  341. package/src/adapters/generic-sql/query/select-builder.test.ts +1 -0
  342. package/src/adapters/generic-sql/query/select-builder.ts +2 -2
  343. package/src/adapters/generic-sql/query/sql-query-compiler.test.ts +24 -5
  344. package/src/adapters/generic-sql/query/sql-query-compiler.ts +83 -13
  345. package/src/adapters/generic-sql/query/where-builder.test.ts +7 -5
  346. package/src/adapters/generic-sql/query/where-builder.ts +48 -29
  347. package/src/adapters/generic-sql/sql-adapter-pglite-migrations.test.ts +6 -15
  348. package/src/adapters/generic-sql/sql-adapter-pglite-pagination.test.ts +52 -7
  349. package/src/adapters/generic-sql/sql-adapter-pglite-queries.test.ts +9 -6
  350. package/src/adapters/generic-sql/sql-adapter-sqlite3-driver.test.ts +273 -5
  351. package/src/adapters/generic-sql/sql-adapter-sqlite3-uow.test.ts +123 -6
  352. package/src/adapters/generic-sql/sql-adapter-sqlocal.test.ts +4 -2
  353. package/src/adapters/generic-sql/uow-decoder.test.ts +4 -3
  354. package/src/adapters/generic-sql/uow-decoder.ts +3 -3
  355. package/src/adapters/generic-sql/uow-encoder.test.ts +4 -2
  356. package/src/adapters/generic-sql/uow-encoder.ts +14 -18
  357. package/src/adapters/in-memory/condition-evaluator.test.ts +2 -1
  358. package/src/adapters/in-memory/condition-evaluator.ts +9 -4
  359. package/src/adapters/in-memory/in-memory-adapter.ts +155 -44
  360. package/src/adapters/in-memory/in-memory-uow.mutations.test.ts +50 -2
  361. package/src/adapters/in-memory/in-memory-uow.retrieval.test.ts +158 -3
  362. package/src/adapters/in-memory/in-memory-uow.ts +402 -26
  363. package/src/adapters/in-memory/options.test.ts +1 -0
  364. package/src/adapters/in-memory/options.ts +5 -1
  365. package/src/adapters/in-memory/outbox.test.ts +361 -0
  366. package/src/adapters/in-memory/reference-resolution.test.ts +3 -2
  367. package/src/adapters/in-memory/reference-resolution.ts +2 -2
  368. package/src/adapters/in-memory/sorted-array-index.test.ts +1 -0
  369. package/src/adapters/in-memory/store.test.ts +1 -0
  370. package/src/adapters/in-memory/store.ts +3 -3
  371. package/src/adapters/in-memory/value-normalization.test.ts +1 -0
  372. package/src/adapters/prisma/prisma-adapter-sqlite3.test.ts +51 -7
  373. package/src/adapters/shared/from-unit-of-work-compiler.ts +156 -46
  374. package/src/adapters/shared/uow-operation-compiler.ts +3 -3
  375. package/src/browser/mod.ts +64 -0
  376. package/src/client.ts +19 -0
  377. package/src/db-fragment-definition-builder.test.ts +821 -47
  378. package/src/db-fragment-definition-builder.ts +857 -110
  379. package/src/db-fragment-instantiator.test.ts +114 -90
  380. package/src/db-fragment-integration.test.ts +9 -6
  381. package/src/dispatchers/cloudflare-do/dispatcher.ts +204 -0
  382. package/src/dispatchers/cloudflare-do/index.test.ts +145 -12
  383. package/src/dispatchers/cloudflare-do/index.ts +49 -90
  384. package/src/dispatchers/node/dispatcher.ts +112 -0
  385. package/src/dispatchers/node/index.test.ts +43 -14
  386. package/src/dispatchers/node/index.ts +38 -75
  387. package/src/durable-hooks.test.ts +80 -0
  388. package/src/durable-hooks.ts +67 -0
  389. package/src/fragments/internal-fragment.routes.test.ts +570 -0
  390. package/src/fragments/internal-fragment.routes.ts +297 -5
  391. package/src/fragments/internal-fragment.schema.ts +45 -1
  392. package/src/fragments/internal-fragment.test.ts +223 -251
  393. package/src/fragments/internal-fragment.ts +278 -154
  394. package/src/hooks/durable-hooks-logger.ts +126 -0
  395. package/src/hooks/durable-hooks-processor.pglite.test.ts +87 -0
  396. package/src/hooks/durable-hooks-processor.test.ts +179 -14
  397. package/src/hooks/durable-hooks-processor.ts +120 -14
  398. package/src/hooks/durable-hooks-runtime.test.ts +65 -0
  399. package/src/hooks/durable-hooks-runtime.ts +81 -0
  400. package/src/hooks/hooks.test.ts +314 -53
  401. package/src/hooks/hooks.ts +360 -81
  402. package/src/id.test.ts +34 -0
  403. package/src/id.ts +1 -3
  404. package/src/internal/adapter-registry.test.ts +93 -0
  405. package/src/internal/adapter-registry.ts +239 -0
  406. package/src/internal/outbox-state.ts +43 -0
  407. package/src/migration-engine/auto-from-schema.test.ts +93 -0
  408. package/src/migration-engine/auto-from-schema.ts +360 -42
  409. package/src/migration-engine/create.test.ts +2 -1
  410. package/src/migration-engine/create.ts +1 -1
  411. package/src/migration-engine/generation-engine.test.ts +66 -9
  412. package/src/migration-engine/generation-engine.ts +31 -10
  413. package/src/migration-engine/shared.ts +13 -0
  414. package/src/mod.ts +45 -27
  415. package/src/naming/sql-naming.ts +1 -0
  416. package/src/outbox/outbox-builder.ts +2 -2
  417. package/src/outbox/outbox.test.ts +216 -45
  418. package/src/outbox/outbox.ts +3 -1
  419. package/src/query/column-defaults.ts +1 -1
  420. package/src/query/condition-builder.test.ts +15 -0
  421. package/src/query/condition-builder.ts +7 -0
  422. package/src/query/cursor-client.test.ts +70 -0
  423. package/src/query/cursor-client.ts +263 -0
  424. package/src/query/cursor.test.ts +3 -2
  425. package/src/query/cursor.ts +15 -3
  426. package/src/query/db-now.ts +69 -2
  427. package/src/query/orm/orm.ts +2 -2
  428. package/src/query/query-type.test.ts +2 -1
  429. package/src/query/serialize/create-sql-serializer.ts +3 -3
  430. package/src/query/serialize/dialect/mysql-serializer.ts +1 -1
  431. package/src/query/serialize/dialect/postgres-serializer.ts +1 -1
  432. package/src/query/serialize/dialect/sqlite-serializer.test.ts +39 -2
  433. package/src/query/serialize/dialect/sqlite-serializer.ts +18 -5
  434. package/src/query/simple-query-interface.ts +10 -4
  435. package/src/query/unit-of-work/execute-unit-of-work.test.ts +347 -9
  436. package/src/query/unit-of-work/execute-unit-of-work.ts +63 -20
  437. package/src/query/unit-of-work/retry-policy.test.ts +1 -0
  438. package/src/query/unit-of-work/tx-builder.test.ts +73 -1
  439. package/src/query/unit-of-work/unit-of-work-coordinator.test.ts +5 -4
  440. package/src/query/unit-of-work/unit-of-work-types.test.ts +41 -11
  441. package/src/query/unit-of-work/unit-of-work.test.ts +28 -2
  442. package/src/query/unit-of-work/unit-of-work.ts +105 -19
  443. package/src/query/value-decoding.test.ts +50 -2
  444. package/src/query/value-decoding.ts +17 -4
  445. package/src/query/value-encoding.test.ts +1 -0
  446. package/src/query/value-encoding.ts +1 -1
  447. package/src/schema/create.test.ts +164 -5
  448. package/src/schema/create.ts +222 -24
  449. package/src/schema/generate-id.test.ts +1 -0
  450. package/src/schema/serialize.test.ts +4 -3
  451. package/src/schema/type-conversion/create-sql-type-mapper.ts +1 -1
  452. package/src/schema/type-conversion/dialect/sqlite.ts +2 -2
  453. package/src/schema/type-conversion/type-mapping.test.ts +2 -1
  454. package/src/schema/validator.test.ts +4 -2
  455. package/src/schema/validator.ts +1 -0
  456. package/src/schema-output/drizzle.test.ts +72 -19
  457. package/src/schema-output/drizzle.ts +24 -18
  458. package/src/schema-output/prisma.test.ts +172 -14
  459. package/src/schema-output/prisma.ts +34 -14
  460. package/src/sql-driver/better-sqlite3.test.ts +5 -3
  461. package/src/sql-driver/dialects/durable-object-dialect.ts +3 -8
  462. package/src/sql-driver/query-executor/default-query-executor.ts +1 -1
  463. package/src/sql-driver/query-executor/query-executor-base.ts +1 -1
  464. package/src/sql-driver/query-executor/query-executor.ts +1 -1
  465. package/src/sql-driver/sql-driver-adapter.ts +2 -2
  466. package/src/sql-driver/sql.ts +2 -1
  467. package/src/sql-driver/sqlocal.test.ts +4 -2
  468. package/src/sync/commands.test.ts +39 -0
  469. package/src/sync/commands.ts +51 -0
  470. package/src/sync/conflict-checker.test.ts +450 -0
  471. package/src/sync/conflict-checker.ts +248 -0
  472. package/src/sync/index.ts +14 -0
  473. package/src/sync/plan.ts +9 -0
  474. package/src/sync/read-tracking.test.ts +177 -0
  475. package/src/sync/read-tracking.ts +287 -0
  476. package/src/sync/submit.test.ts +205 -0
  477. package/src/sync/submit.ts +328 -0
  478. package/src/sync/types.ts +80 -0
  479. package/src/util/default-database-adapter.ts +15 -2
  480. package/src/with-database.ts +20 -50
  481. package/tsconfig.json +1 -1
  482. package/tsdown.config.ts +38 -26
  483. package/vitest.config.ts +1 -0
  484. package/dist/hooks/durable-hooks-processor.d.ts.map +0 -1
  485. package/dist/node_modules/.pnpm/rou3@0.7.12/node_modules/rou3/dist/index.js +0 -168
  486. package/dist/node_modules/.pnpm/rou3@0.7.12/node_modules/rou3/dist/index.js.map +0 -1
  487. package/dist/packages/fragno/dist/api/bind-services.js +0 -20
  488. package/dist/packages/fragno/dist/api/bind-services.js.map +0 -1
  489. package/dist/packages/fragno/dist/api/error.js +0 -48
  490. package/dist/packages/fragno/dist/api/error.js.map +0 -1
  491. package/dist/packages/fragno/dist/api/fragment-definition-builder.js +0 -321
  492. package/dist/packages/fragno/dist/api/fragment-definition-builder.js.map +0 -1
  493. package/dist/packages/fragno/dist/api/fragment-instantiator.js +0 -669
  494. package/dist/packages/fragno/dist/api/fragment-instantiator.js.map +0 -1
  495. package/dist/packages/fragno/dist/api/fragno-response.js +0 -73
  496. package/dist/packages/fragno/dist/api/fragno-response.js.map +0 -1
  497. package/dist/packages/fragno/dist/api/internal/response-stream.js +0 -81
  498. package/dist/packages/fragno/dist/api/internal/response-stream.js.map +0 -1
  499. package/dist/packages/fragno/dist/api/internal/route.js +0 -10
  500. package/dist/packages/fragno/dist/api/internal/route.js.map +0 -1
  501. package/dist/packages/fragno/dist/api/mutable-request-state.js +0 -97
  502. package/dist/packages/fragno/dist/api/mutable-request-state.js.map +0 -1
  503. package/dist/packages/fragno/dist/api/request-context-storage.js +0 -43
  504. package/dist/packages/fragno/dist/api/request-context-storage.js.map +0 -1
  505. package/dist/packages/fragno/dist/api/request-input-context.js +0 -185
  506. package/dist/packages/fragno/dist/api/request-input-context.js.map +0 -1
  507. package/dist/packages/fragno/dist/api/request-middleware.js +0 -83
  508. package/dist/packages/fragno/dist/api/request-middleware.js.map +0 -1
  509. package/dist/packages/fragno/dist/api/request-output-context.js +0 -119
  510. package/dist/packages/fragno/dist/api/request-output-context.js.map +0 -1
  511. package/dist/packages/fragno/dist/api/route.js +0 -30
  512. package/dist/packages/fragno/dist/api/route.js.map +0 -1
  513. package/dist/packages/fragno/dist/internal/symbols.js +0 -10
  514. package/dist/packages/fragno/dist/internal/symbols.js.map +0 -1
  515. package/dist/packages/fragno/dist/internal/trace-context.js +0 -12
  516. package/dist/packages/fragno/dist/internal/trace-context.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"uow-decoder.js","names":["#driverConfig","#sqliteStorageMode","#resolver","cursor: Cursor | undefined"],"sources":["../../../src/adapters/generic-sql/uow-decoder.ts"],"sourcesContent":["import type { UOWDecoder } from \"../../query/unit-of-work/unit-of-work\";\nimport type { RetrievalOperation } from \"../../query/unit-of-work/unit-of-work\";\nimport type { AnySchema, AnyTable } from \"../../schema/create\";\nimport { decodeResult } from \"../../query/value-decoding\";\nimport { createCursorFromRecord, type Cursor, type CursorResult } from \"../../query/cursor\";\nimport type { DriverConfig } from \"./driver-config\";\nimport type { SQLiteStorageMode } from \"./sqlite-storage\";\nimport type { NamingResolver } from \"../../naming/sql-naming\";\n\n/**\n * Decoder class for Unit of Work retrieval results.\n *\n * Transforms raw database results into application format (e.g., converting raw columns\n * into FragnoId objects with external ID, internal ID, and version).\n */\nexport class UnitOfWorkDecoder implements UOWDecoder<unknown> {\n readonly #driverConfig: DriverConfig;\n readonly #sqliteStorageMode?: SQLiteStorageMode;\n readonly #resolver?: NamingResolver;\n\n constructor(\n driverConfig: DriverConfig,\n sqliteStorageMode?: SQLiteStorageMode,\n resolver?: NamingResolver,\n ) {\n this.#driverConfig = driverConfig;\n this.#sqliteStorageMode = sqliteStorageMode;\n this.#resolver = resolver;\n }\n\n /**\n * Decode raw database results from the retrieval phase\n *\n * @param rawResults - Array of raw result sets from database queries\n * @param operations - Array of retrieval operations that produced these results\n * @returns Decoded results in application format\n */\n decode(rawResults: unknown[], operations: RetrievalOperation<AnySchema>[]): unknown[] {\n if (rawResults.length !== operations.length) {\n throw new Error(\"rawResults and ops must have the same length\");\n }\n\n return rawResults.map((rows, index) => {\n const op = operations[index];\n if (!op) {\n throw new Error(\"op must be defined\");\n }\n\n const rowArray = rows as Record<string, unknown>[];\n return this.decodeResultSet(rowArray, op);\n });\n }\n\n /**\n * Decodes a result set based on the operation type.\n *\n * This is the main entry point for decoding query results, routing to the\n * appropriate decoder based on whether it's a count, cursor, or regular query.\n *\n * @param rows - The raw database rows\n * @param operation - The retrieval operation defining how to decode the result\n * @returns The decoded result (number for count, CursorResult for cursor, array otherwise)\n */\n private decodeResultSet(\n rows: Record<string, unknown>[],\n operation: RetrievalOperation<AnySchema>,\n ): number | Record<string, unknown>[] | CursorResult<unknown> {\n // Handle count operations\n if (operation.type === \"count\") {\n return this.decodeCountResult(rows);\n }\n\n const decodedRows = rows.map((row) =>\n decodeResult(\n row,\n operation.table,\n this.#driverConfig,\n this.#sqliteStorageMode,\n this.#resolver,\n ),\n );\n\n if (operation.withCursor) {\n return this.decodeCursorResult(decodedRows, operation.table, operation);\n }\n\n return decodedRows;\n }\n\n /**\n * Decodes a count query result to a number.\n *\n * @param rows - The raw database rows (should contain a single row with a count column)\n * @returns The count as a number\n * @throws If the count value is invalid or missing\n */\n private decodeCountResult(rows: Record<string, unknown>[]): number {\n const firstRow = rows[0];\n if (!firstRow) {\n return 0;\n }\n const count = Number(firstRow[\"count\"]);\n if (Number.isNaN(count)) {\n throw new Error(`Unexpected result for count, received: ${count}`);\n }\n return count;\n }\n\n /**\n * Handles cursor generation and hasNextPage detection for cursor-paginated queries.\n *\n * Checks if we received more rows than the requested pageSize (we fetch pageSize + 1).\n *\n * @param decodedRows - The already-decoded database rows (pageSize + 1 rows)\n * @param table - The table schema definition (needed for cursor generation)\n * @param operation - The find operation containing pagination options\n * @returns A CursorResult with items, cursor, and hasNextPage\n */\n private decodeCursorResult(\n decodedRows: Record<string, unknown>[],\n table: AnyTable,\n operation: Extract<RetrievalOperation<AnySchema>, { type: \"find\" }>,\n ): CursorResult<unknown> {\n let cursor: Cursor | undefined;\n let hasNextPage = false;\n let items = decodedRows;\n\n // Check if there are more results (we fetched pageSize + 1)\n if (\n operation.options.pageSize &&\n operation.options.pageSize > 0 &&\n decodedRows.length > operation.options.pageSize\n ) {\n hasNextPage = true;\n // Trim to requested pageSize\n items = decodedRows.slice(0, operation.options.pageSize);\n\n // Generate cursor from the last item we're returning\n if (operation.options.orderByIndex) {\n const lastItem = items[items.length - 1];\n const indexName = operation.options.orderByIndex.indexName;\n\n // Get index columns\n let indexColumns;\n if (indexName === \"_primary\") {\n indexColumns = [table.getIdColumn()];\n } else {\n const index = table.indexes[indexName];\n if (index) {\n indexColumns = index.columns;\n }\n }\n\n if (indexColumns && lastItem) {\n cursor = createCursorFromRecord(lastItem, indexColumns, {\n indexName: operation.options.orderByIndex.indexName,\n orderDirection: operation.options.orderByIndex.direction,\n pageSize: operation.options.pageSize,\n });\n }\n }\n }\n\n return {\n items,\n cursor,\n hasNextPage,\n };\n }\n}\n"],"mappings":";;;;;;;;;;AAeA,IAAa,oBAAb,MAA8D;CAC5D,CAASA;CACT,CAASC;CACT,CAASC;CAET,YACE,cACA,mBACA,UACA;AACA,QAAKF,eAAgB;AACrB,QAAKC,oBAAqB;AAC1B,QAAKC,WAAY;;;;;;;;;CAUnB,OAAO,YAAuB,YAAwD;AACpF,MAAI,WAAW,WAAW,WAAW,OACnC,OAAM,IAAI,MAAM,+CAA+C;AAGjE,SAAO,WAAW,KAAK,MAAM,UAAU;GACrC,MAAM,KAAK,WAAW;AACtB,OAAI,CAAC,GACH,OAAM,IAAI,MAAM,qBAAqB;GAGvC,MAAM,WAAW;AACjB,UAAO,KAAK,gBAAgB,UAAU,GAAG;IACzC;;;;;;;;;;;;CAaJ,AAAQ,gBACN,MACA,WAC4D;AAE5D,MAAI,UAAU,SAAS,QACrB,QAAO,KAAK,kBAAkB,KAAK;EAGrC,MAAM,cAAc,KAAK,KAAK,QAC5B,aACE,KACA,UAAU,OACV,MAAKF,cACL,MAAKC,mBACL,MAAKC,SACN,CACF;AAED,MAAI,UAAU,WACZ,QAAO,KAAK,mBAAmB,aAAa,UAAU,OAAO,UAAU;AAGzE,SAAO;;;;;;;;;CAUT,AAAQ,kBAAkB,MAAyC;EACjE,MAAM,WAAW,KAAK;AACtB,MAAI,CAAC,SACH,QAAO;EAET,MAAM,QAAQ,OAAO,SAAS,SAAS;AACvC,MAAI,OAAO,MAAM,MAAM,CACrB,OAAM,IAAI,MAAM,0CAA0C,QAAQ;AAEpE,SAAO;;;;;;;;;;;;CAaT,AAAQ,mBACN,aACA,OACA,WACuB;EACvB,IAAIC;EACJ,IAAI,cAAc;EAClB,IAAI,QAAQ;AAGZ,MACE,UAAU,QAAQ,YAClB,UAAU,QAAQ,WAAW,KAC7B,YAAY,SAAS,UAAU,QAAQ,UACvC;AACA,iBAAc;AAEd,WAAQ,YAAY,MAAM,GAAG,UAAU,QAAQ,SAAS;AAGxD,OAAI,UAAU,QAAQ,cAAc;IAClC,MAAM,WAAW,MAAM,MAAM,SAAS;IACtC,MAAM,YAAY,UAAU,QAAQ,aAAa;IAGjD,IAAI;AACJ,QAAI,cAAc,WAChB,gBAAe,CAAC,MAAM,aAAa,CAAC;SAC/B;KACL,MAAM,QAAQ,MAAM,QAAQ;AAC5B,SAAI,MACF,gBAAe,MAAM;;AAIzB,QAAI,gBAAgB,SAClB,UAAS,uBAAuB,UAAU,cAAc;KACtD,WAAW,UAAU,QAAQ,aAAa;KAC1C,gBAAgB,UAAU,QAAQ,aAAa;KAC/C,UAAU,UAAU,QAAQ;KAC7B,CAAC;;;AAKR,SAAO;GACL;GACA;GACA;GACD"}
1
+ {"version":3,"file":"uow-decoder.js","names":["#driverConfig","#sqliteStorageMode","#resolver","cursor: Cursor | undefined"],"sources":["../../../src/adapters/generic-sql/uow-decoder.ts"],"sourcesContent":["import type { NamingResolver } from \"../../naming/sql-naming\";\nimport { createCursorFromRecord, type Cursor, type CursorResult } from \"../../query/cursor\";\nimport type { UOWDecoder } from \"../../query/unit-of-work/unit-of-work\";\nimport type { RetrievalOperation } from \"../../query/unit-of-work/unit-of-work\";\nimport { decodeResult } from \"../../query/value-decoding\";\nimport type { AnySchema, AnyTable } from \"../../schema/create\";\nimport type { DriverConfig } from \"./driver-config\";\nimport type { SQLiteStorageMode } from \"./sqlite-storage\";\n\n/**\n * Decoder class for Unit of Work retrieval results.\n *\n * Transforms raw database results into application format (e.g., converting raw columns\n * into FragnoId objects with external ID, internal ID, and version).\n */\nexport class UnitOfWorkDecoder implements UOWDecoder<unknown> {\n readonly #driverConfig: DriverConfig;\n readonly #sqliteStorageMode?: SQLiteStorageMode;\n readonly #resolver?: NamingResolver;\n\n constructor(\n driverConfig: DriverConfig,\n sqliteStorageMode?: SQLiteStorageMode,\n resolver?: NamingResolver,\n ) {\n this.#driverConfig = driverConfig;\n this.#sqliteStorageMode = sqliteStorageMode;\n this.#resolver = resolver;\n }\n\n /**\n * Decode raw database results from the retrieval phase\n *\n * @param rawResults - Array of raw result sets from database queries\n * @param operations - Array of retrieval operations that produced these results\n * @returns Decoded results in application format\n */\n decode(rawResults: unknown[], operations: RetrievalOperation<AnySchema>[]): unknown[] {\n if (rawResults.length !== operations.length) {\n throw new Error(\"rawResults and ops must have the same length\");\n }\n\n return rawResults.map((rows, index) => {\n const op = operations[index];\n if (!op) {\n throw new Error(\"op must be defined\");\n }\n\n const rowArray = rows as Record<string, unknown>[];\n return this.decodeResultSet(rowArray, op);\n });\n }\n\n /**\n * Decodes a result set based on the operation type.\n *\n * This is the main entry point for decoding query results, routing to the\n * appropriate decoder based on whether it's a count, cursor, or regular query.\n *\n * @param rows - The raw database rows\n * @param operation - The retrieval operation defining how to decode the result\n * @returns The decoded result (number for count, CursorResult for cursor, array otherwise)\n */\n private decodeResultSet(\n rows: Record<string, unknown>[],\n operation: RetrievalOperation<AnySchema>,\n ): number | Record<string, unknown>[] | CursorResult<unknown> {\n // Handle count operations\n if (operation.type === \"count\") {\n return this.decodeCountResult(rows);\n }\n\n const decodedRows = rows.map((row) =>\n decodeResult(\n row,\n operation.table,\n this.#driverConfig,\n this.#sqliteStorageMode,\n this.#resolver,\n ),\n );\n\n if (operation.withCursor) {\n return this.decodeCursorResult(decodedRows, operation.table, operation);\n }\n\n return decodedRows;\n }\n\n /**\n * Decodes a count query result to a number.\n *\n * @param rows - The raw database rows (should contain a single row with a count column)\n * @returns The count as a number\n * @throws If the count value is invalid or missing\n */\n private decodeCountResult(rows: Record<string, unknown>[]): number {\n const firstRow = rows[0];\n if (!firstRow) {\n return 0;\n }\n const count = Number(firstRow[\"count\"]);\n if (Number.isNaN(count)) {\n throw new Error(`Unexpected result for count, received: ${count}`);\n }\n return count;\n }\n\n /**\n * Handles cursor generation and hasNextPage detection for cursor-paginated queries.\n *\n * Checks if we received more rows than the requested pageSize (we fetch pageSize + 1).\n *\n * @param decodedRows - The already-decoded database rows (pageSize + 1 rows)\n * @param table - The table schema definition (needed for cursor generation)\n * @param operation - The find operation containing pagination options\n * @returns A CursorResult with items, cursor, and hasNextPage\n */\n private decodeCursorResult(\n decodedRows: Record<string, unknown>[],\n table: AnyTable,\n operation: Extract<RetrievalOperation<AnySchema>, { type: \"find\" }>,\n ): CursorResult<unknown> {\n let cursor: Cursor | undefined;\n let hasNextPage = false;\n let items = decodedRows;\n\n // Check if there are more results (we fetched pageSize + 1)\n if (\n operation.options.pageSize &&\n operation.options.pageSize > 0 &&\n decodedRows.length > operation.options.pageSize\n ) {\n hasNextPage = true;\n // Trim to requested pageSize\n items = decodedRows.slice(0, operation.options.pageSize);\n\n // Generate cursor from the last item we're returning\n if (operation.options.orderByIndex) {\n const lastItem = items[items.length - 1];\n const indexName = operation.options.orderByIndex.indexName;\n\n // Get index columns\n let indexColumns;\n if (indexName === \"_primary\") {\n indexColumns = [table.getIdColumn()];\n } else {\n const index = table.indexes[indexName];\n if (index) {\n indexColumns = index.columns;\n }\n }\n\n if (indexColumns && lastItem) {\n cursor = createCursorFromRecord(lastItem, indexColumns, {\n indexName: operation.options.orderByIndex.indexName,\n orderDirection: operation.options.orderByIndex.direction,\n pageSize: operation.options.pageSize,\n });\n }\n }\n }\n\n return {\n items,\n cursor,\n hasNextPage,\n };\n }\n}\n"],"mappings":";;;;;;;;;;AAeA,IAAa,oBAAb,MAA8D;CAC5D,CAASA;CACT,CAASC;CACT,CAASC;CAET,YACE,cACA,mBACA,UACA;AACA,QAAKF,eAAgB;AACrB,QAAKC,oBAAqB;AAC1B,QAAKC,WAAY;;;;;;;;;CAUnB,OAAO,YAAuB,YAAwD;AACpF,MAAI,WAAW,WAAW,WAAW,OACnC,OAAM,IAAI,MAAM,+CAA+C;AAGjE,SAAO,WAAW,KAAK,MAAM,UAAU;GACrC,MAAM,KAAK,WAAW;AACtB,OAAI,CAAC,GACH,OAAM,IAAI,MAAM,qBAAqB;GAGvC,MAAM,WAAW;AACjB,UAAO,KAAK,gBAAgB,UAAU,GAAG;IACzC;;;;;;;;;;;;CAaJ,AAAQ,gBACN,MACA,WAC4D;AAE5D,MAAI,UAAU,SAAS,QACrB,QAAO,KAAK,kBAAkB,KAAK;EAGrC,MAAM,cAAc,KAAK,KAAK,QAC5B,aACE,KACA,UAAU,OACV,MAAKF,cACL,MAAKC,mBACL,MAAKC,SACN,CACF;AAED,MAAI,UAAU,WACZ,QAAO,KAAK,mBAAmB,aAAa,UAAU,OAAO,UAAU;AAGzE,SAAO;;;;;;;;;CAUT,AAAQ,kBAAkB,MAAyC;EACjE,MAAM,WAAW,KAAK;AACtB,MAAI,CAAC,SACH,QAAO;EAET,MAAM,QAAQ,OAAO,SAAS,SAAS;AACvC,MAAI,OAAO,MAAM,MAAM,CACrB,OAAM,IAAI,MAAM,0CAA0C,QAAQ;AAEpE,SAAO;;;;;;;;;;;;CAaT,AAAQ,mBACN,aACA,OACA,WACuB;EACvB,IAAIC;EACJ,IAAI,cAAc;EAClB,IAAI,QAAQ;AAGZ,MACE,UAAU,QAAQ,YAClB,UAAU,QAAQ,WAAW,KAC7B,YAAY,SAAS,UAAU,QAAQ,UACvC;AACA,iBAAc;AAEd,WAAQ,YAAY,MAAM,GAAG,UAAU,QAAQ,SAAS;AAGxD,OAAI,UAAU,QAAQ,cAAc;IAClC,MAAM,WAAW,MAAM,MAAM,SAAS;IACtC,MAAM,YAAY,UAAU,QAAQ,aAAa;IAGjD,IAAI;AACJ,QAAI,cAAc,WAChB,gBAAe,CAAC,MAAM,aAAa,CAAC;SAC/B;KACL,MAAM,QAAQ,MAAM,QAAQ;AAC5B,SAAI,MACF,gBAAe,MAAM;;AAIzB,QAAI,gBAAgB,SAClB,UAAS,uBAAuB,UAAU,cAAc;KACtD,WAAW,UAAU,QAAQ,aAAa;KAC1C,gBAAgB,UAAU,QAAQ,aAAa;KAC/C,UAAU,UAAU,QAAQ;KAC7B,CAAC;;;AAKR,SAAO;GACL;GACA;GACA;GACD"}
@@ -1,9 +1,8 @@
1
- import { sqliteStorageDefault } from "./sqlite-storage.js";
1
+ import { getDbNowOffsetMs, isDbNow } from "../../query/db-now.js";
2
2
  import { createSQLSerializer } from "../../query/serialize/create-sql-serializer.js";
3
3
  import { encodeValues } from "../../query/value-encoding.js";
4
- import { isDbNow } from "../../query/db-now.js";
4
+ import { buildDbNowSql } from "./query/db-now-sql.js";
5
5
  import { processReferenceSubqueries } from "./query/where-builder.js";
6
- import { sql } from "kysely";
7
6
 
8
7
  //#region src/adapters/generic-sql/uow-encoder.ts
9
8
  /**
@@ -81,12 +80,12 @@ var UnitOfWorkEncoder = class {
81
80
  continue;
82
81
  }
83
82
  if (isDbNow(value)) {
84
- if (this.#driverConfig.databaseType === "sqlite") {
85
- const storageMode = this.#sqliteStorageMode ?? sqliteStorageDefault;
86
- const storage = col.type === "date" ? storageMode.dateStorage : storageMode.timestampStorage;
87
- if ((col.type === "timestamp" || col.type === "date") && storage === "epoch-ms") result[dbColumnName] = sql`(cast((julianday('now') - 2440587.5)*86400000 as integer))`;
88
- else result[dbColumnName] = sql`CURRENT_TIMESTAMP`;
89
- } else result[dbColumnName] = sql`CURRENT_TIMESTAMP`;
83
+ result[dbColumnName] = buildDbNowSql({
84
+ driverConfig: this.#driverConfig,
85
+ columnType: col.type,
86
+ offsetMs: getDbNowOffsetMs(value),
87
+ sqliteStorageMode: this.#sqliteStorageMode
88
+ });
90
89
  continue;
91
90
  }
92
91
  result[dbColumnName] = this.#serializer.serialize(value, col);
@@ -1 +1 @@
1
- {"version":3,"file":"uow-encoder.js","names":["#driverConfig","#serializer","#db","#sqliteStorageMode","#resolver","result: Record<string, unknown>"],"sources":["../../../src/adapters/generic-sql/uow-encoder.ts"],"sourcesContent":["import type { AnyTable, AnyColumn } from \"../../schema/create\";\nimport type { DriverConfig } from \"./driver-config\";\nimport {\n createSQLSerializer,\n type SQLSerializer,\n} from \"../../query/serialize/create-sql-serializer\";\nimport { encodeValues } from \"../../query/value-encoding\";\nimport { processReferenceSubqueries } from \"./query/where-builder\";\nimport type { NamingResolver } from \"../../naming/sql-naming\";\nimport { sql, type Kysely } from \"kysely\";\nimport { isDbNow } from \"../../query/db-now\";\nimport { sqliteStorageDefault, type SQLiteStorageMode } from \"./sqlite-storage\";\n\n/**\n * Encoder class for Unit of Work mutation operations.\n *\n * Handles the complete transformation from application values to database-ready values\n * in three clear steps:\n * 1. Resolution - Resolve FragnoId/FragnoReference objects and generate defaults\n * 2. Reference Processing - Create subqueries for external ID lookups\n * 3. Serialization - Apply database-specific type conversions\n *\n * This class mirrors the UnitOfWorkDecoder pattern for symmetry.\n */\nexport class UnitOfWorkEncoder {\n readonly #driverConfig: DriverConfig;\n readonly #serializer: SQLSerializer;\n readonly #db: Kysely<any>; // eslint-disable-line @typescript-eslint/no-explicit-any\n readonly #sqliteStorageMode?: SQLiteStorageMode;\n readonly #resolver?: NamingResolver;\n\n constructor(\n driverConfig: DriverConfig,\n db: Kysely<any>, // eslint-disable-line @typescript-eslint/no-explicit-any\n sqliteStorageMode?: SQLiteStorageMode,\n resolver?: NamingResolver,\n ) {\n this.#driverConfig = driverConfig;\n this.#serializer = createSQLSerializer(driverConfig, sqliteStorageMode);\n this.#db = db;\n this.#sqliteStorageMode = sqliteStorageMode;\n this.#resolver = resolver;\n }\n\n /**\n * Encode application values to database-ready format.\n *\n * This is the main entry point that handles all encoding steps:\n * 1. **Resolution**: Transform ORM names to DB columns, resolve FragnoId/FragnoReference,\n * generate defaults (CUIDs for IDs, etc.)\n * 2. **Reference Processing**: Convert external ID strings to subqueries for internal ID lookup\n * 3. **Serialization**: Apply database-specific conversions (Date → number for SQLite, etc.)\n *\n * @param options - Encoding options\n * @param options.values - Application values to encode\n * @param options.table - Table schema definition\n * @param options.generateDefaults - Whether to generate default values for undefined columns\n * @returns Database-ready values\n *\n * @example\n * ```ts\n * const encoded = encoder.encodeForDatabase({\n * values: { userId: FragnoId(...), createdAt: new Date(), isActive: true },\n * table: usersTable,\n * generateDefaults: true\n * });\n * // For SQLite: { user_id: 456, created_at: 1705316400000, is_active: 1 }\n * ```\n */\n encodeForDatabase(options: {\n values: Record<string, unknown>;\n table: AnyTable;\n generateDefaults: boolean;\n }): Record<string, unknown> {\n // Step 1: Resolution - Resolve FragnoId/FragnoReference and generate defaults\n const resolved = encodeValues(\n options.values,\n options.table,\n options.generateDefaults,\n {},\n this.#resolver,\n );\n\n // Step 2: Reference Processing - Convert external IDs to subqueries\n const processed = processReferenceSubqueries(resolved, this.#db, this.#resolver);\n\n // Step 3: Serialization - Apply database-specific type conversions\n const serialized = this.serializeValues(processed, options.table);\n\n return serialized;\n }\n\n /**\n * Serialize resolved values to database format.\n *\n * Applies database-specific type conversions:\n * - SQLite: Date → number, boolean → 0/1, bigint → Buffer (or Number for reference columns)\n * - PostgreSQL: Mostly pass-through (database handles types natively)\n * - MySQL: Mostly pass-through\n *\n * @param values - Resolved values (after resolution and reference processing)\n * @param table - The table schema definition\n * @returns Serialized values ready for database driver\n */\n private serializeValues(\n values: Record<string, unknown>,\n table: AnyTable,\n ): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n const columnMap = this.#resolver ? this.#resolver.getColumnNameMap(table) : undefined;\n\n for (const [dbColumnName, value] of Object.entries(values)) {\n // Find the column definition by database column name\n const col = this.findColumnByDbName(table, dbColumnName, columnMap);\n\n if (!col) {\n // Not a regular column (might be a special value like sql.raw())\n // Pass through as-is\n result[dbColumnName] = value;\n continue;\n }\n\n if (isDbNow(value)) {\n if (this.#driverConfig.databaseType === \"sqlite\") {\n const storageMode = this.#sqliteStorageMode ?? sqliteStorageDefault;\n const storage =\n col.type === \"date\" ? storageMode.dateStorage : storageMode.timestampStorage;\n if ((col.type === \"timestamp\" || col.type === \"date\") && storage === \"epoch-ms\") {\n result[dbColumnName] = sql`(cast((julianday('now') - 2440587.5)*86400000 as integer))`;\n } else {\n result[dbColumnName] = sql`CURRENT_TIMESTAMP`;\n }\n } else {\n result[dbColumnName] = sql`CURRENT_TIMESTAMP`;\n }\n continue;\n }\n\n // Serialize the value using the column definition and database type\n result[dbColumnName] = this.#serializer.serialize(value, col);\n }\n\n return result;\n }\n\n /**\n * Find a column definition by its database column name.\n *\n * @param table - The table to search\n * @param dbColumnName - The database column name (e.g., \"user_id\")\n * @returns The column definition or undefined if not found\n */\n private findColumnByDbName(\n table: AnyTable,\n dbColumnName: string,\n columnMap?: Record<string, string>,\n ): AnyColumn | undefined {\n const logicalName = columnMap?.[dbColumnName] ?? dbColumnName;\n const direct = table.columns[logicalName];\n if (direct) {\n return direct;\n }\n for (const col of Object.values(table.columns)) {\n if (col.name === logicalName) {\n return col;\n }\n }\n return undefined;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAwBA,IAAa,oBAAb,MAA+B;CAC7B,CAASA;CACT,CAASC;CACT,CAASC;CACT,CAASC;CACT,CAASC;CAET,YACE,cACA,IACA,mBACA,UACA;AACA,QAAKJ,eAAgB;AACrB,QAAKC,aAAc,oBAAoB,cAAc,kBAAkB;AACvE,QAAKC,KAAM;AACX,QAAKC,oBAAqB;AAC1B,QAAKC,WAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BnB,kBAAkB,SAIU;EAW1B,MAAM,YAAY,2BATD,aACf,QAAQ,QACR,QAAQ,OACR,QAAQ,kBACR,EAAE,EACF,MAAKA,SACN,EAGsD,MAAKF,IAAK,MAAKE,SAAU;AAKhF,SAFmB,KAAK,gBAAgB,WAAW,QAAQ,MAAM;;;;;;;;;;;;;;CAiBnE,AAAQ,gBACN,QACA,OACyB;EACzB,MAAMC,SAAkC,EAAE;EAC1C,MAAM,YAAY,MAAKD,WAAY,MAAKA,SAAU,iBAAiB,MAAM,GAAG;AAE5E,OAAK,MAAM,CAAC,cAAc,UAAU,OAAO,QAAQ,OAAO,EAAE;GAE1D,MAAM,MAAM,KAAK,mBAAmB,OAAO,cAAc,UAAU;AAEnE,OAAI,CAAC,KAAK;AAGR,WAAO,gBAAgB;AACvB;;AAGF,OAAI,QAAQ,MAAM,EAAE;AAClB,QAAI,MAAKJ,aAAc,iBAAiB,UAAU;KAChD,MAAM,cAAc,MAAKG,qBAAsB;KAC/C,MAAM,UACJ,IAAI,SAAS,SAAS,YAAY,cAAc,YAAY;AAC9D,UAAK,IAAI,SAAS,eAAe,IAAI,SAAS,WAAW,YAAY,WACnE,QAAO,gBAAgB,GAAG;SAE1B,QAAO,gBAAgB,GAAG;UAG5B,QAAO,gBAAgB,GAAG;AAE5B;;AAIF,UAAO,gBAAgB,MAAKF,WAAY,UAAU,OAAO,IAAI;;AAG/D,SAAO;;;;;;;;;CAUT,AAAQ,mBACN,OACA,cACA,WACuB;EACvB,MAAM,cAAc,YAAY,iBAAiB;EACjD,MAAM,SAAS,MAAM,QAAQ;AAC7B,MAAI,OACF,QAAO;AAET,OAAK,MAAM,OAAO,OAAO,OAAO,MAAM,QAAQ,CAC5C,KAAI,IAAI,SAAS,YACf,QAAO"}
1
+ {"version":3,"file":"uow-encoder.js","names":["#driverConfig","#serializer","#db","#sqliteStorageMode","#resolver","result: Record<string, unknown>"],"sources":["../../../src/adapters/generic-sql/uow-encoder.ts"],"sourcesContent":["import type { Kysely } from \"kysely\";\n\nimport type { NamingResolver } from \"../../naming/sql-naming\";\nimport { getDbNowOffsetMs, isDbNow } from \"../../query/db-now\";\nimport {\n createSQLSerializer,\n type SQLSerializer,\n} from \"../../query/serialize/create-sql-serializer\";\nimport { encodeValues } from \"../../query/value-encoding\";\nimport type { AnyTable, AnyColumn } from \"../../schema/create\";\nimport type { DriverConfig } from \"./driver-config\";\nimport { buildDbNowSql } from \"./query/db-now-sql\";\nimport { processReferenceSubqueries } from \"./query/where-builder\";\nimport type { SQLiteStorageMode } from \"./sqlite-storage\";\n\n/**\n * Encoder class for Unit of Work mutation operations.\n *\n * Handles the complete transformation from application values to database-ready values\n * in three clear steps:\n * 1. Resolution - Resolve FragnoId/FragnoReference objects and generate defaults\n * 2. Reference Processing - Create subqueries for external ID lookups\n * 3. Serialization - Apply database-specific type conversions\n *\n * This class mirrors the UnitOfWorkDecoder pattern for symmetry.\n */\nexport class UnitOfWorkEncoder {\n readonly #driverConfig: DriverConfig;\n readonly #serializer: SQLSerializer;\n readonly #db: Kysely<any>; // eslint-disable-line @typescript-eslint/no-explicit-any\n readonly #sqliteStorageMode?: SQLiteStorageMode;\n readonly #resolver?: NamingResolver;\n\n constructor(\n driverConfig: DriverConfig,\n db: Kysely<any>, // eslint-disable-line @typescript-eslint/no-explicit-any\n sqliteStorageMode?: SQLiteStorageMode,\n resolver?: NamingResolver,\n ) {\n this.#driverConfig = driverConfig;\n this.#serializer = createSQLSerializer(driverConfig, sqliteStorageMode);\n this.#db = db;\n this.#sqliteStorageMode = sqliteStorageMode;\n this.#resolver = resolver;\n }\n\n /**\n * Encode application values to database-ready format.\n *\n * This is the main entry point that handles all encoding steps:\n * 1. **Resolution**: Transform ORM names to DB columns, resolve FragnoId/FragnoReference,\n * generate defaults (CUIDs for IDs, etc.)\n * 2. **Reference Processing**: Convert external ID strings to subqueries for internal ID lookup\n * 3. **Serialization**: Apply database-specific conversions (Date → number for SQLite, etc.)\n *\n * @param options - Encoding options\n * @param options.values - Application values to encode\n * @param options.table - Table schema definition\n * @param options.generateDefaults - Whether to generate default values for undefined columns\n * @returns Database-ready values\n *\n * @example\n * ```ts\n * const encoded = encoder.encodeForDatabase({\n * values: { userId: FragnoId(...), createdAt: new Date(), isActive: true },\n * table: usersTable,\n * generateDefaults: true\n * });\n * // For SQLite: { user_id: 456, created_at: 1705316400000, is_active: 1 }\n * ```\n */\n encodeForDatabase(options: {\n values: Record<string, unknown>;\n table: AnyTable;\n generateDefaults: boolean;\n }): Record<string, unknown> {\n // Step 1: Resolution - Resolve FragnoId/FragnoReference and generate defaults\n const resolved = encodeValues(\n options.values,\n options.table,\n options.generateDefaults,\n {},\n this.#resolver,\n );\n\n // Step 2: Reference Processing - Convert external IDs to subqueries\n const processed = processReferenceSubqueries(resolved, this.#db, this.#resolver);\n\n // Step 3: Serialization - Apply database-specific type conversions\n const serialized = this.serializeValues(processed, options.table);\n\n return serialized;\n }\n\n /**\n * Serialize resolved values to database format.\n *\n * Applies database-specific type conversions:\n * - SQLite: Date → number, boolean → 0/1, bigint → Buffer (or Number for reference columns)\n * - PostgreSQL: Mostly pass-through (database handles types natively)\n * - MySQL: Mostly pass-through\n *\n * @param values - Resolved values (after resolution and reference processing)\n * @param table - The table schema definition\n * @returns Serialized values ready for database driver\n */\n private serializeValues(\n values: Record<string, unknown>,\n table: AnyTable,\n ): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n const columnMap = this.#resolver ? this.#resolver.getColumnNameMap(table) : undefined;\n\n for (const [dbColumnName, value] of Object.entries(values)) {\n // Find the column definition by database column name\n const col = this.findColumnByDbName(table, dbColumnName, columnMap);\n\n if (!col) {\n // Not a regular column (might be a special value like sql.raw())\n // Pass through as-is\n result[dbColumnName] = value;\n continue;\n }\n\n if (isDbNow(value)) {\n result[dbColumnName] = buildDbNowSql({\n driverConfig: this.#driverConfig,\n columnType: col.type,\n offsetMs: getDbNowOffsetMs(value),\n sqliteStorageMode: this.#sqliteStorageMode,\n });\n continue;\n }\n\n // Serialize the value using the column definition and database type\n result[dbColumnName] = this.#serializer.serialize(value, col);\n }\n\n return result;\n }\n\n /**\n * Find a column definition by its database column name.\n *\n * @param table - The table to search\n * @param dbColumnName - The database column name (e.g., \"user_id\")\n * @returns The column definition or undefined if not found\n */\n private findColumnByDbName(\n table: AnyTable,\n dbColumnName: string,\n columnMap?: Record<string, string>,\n ): AnyColumn | undefined {\n const logicalName = columnMap?.[dbColumnName] ?? dbColumnName;\n const direct = table.columns[logicalName];\n if (direct) {\n return direct;\n }\n for (const col of Object.values(table.columns)) {\n if (col.name === logicalName) {\n return col;\n }\n }\n return undefined;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AA0BA,IAAa,oBAAb,MAA+B;CAC7B,CAASA;CACT,CAASC;CACT,CAASC;CACT,CAASC;CACT,CAASC;CAET,YACE,cACA,IACA,mBACA,UACA;AACA,QAAKJ,eAAgB;AACrB,QAAKC,aAAc,oBAAoB,cAAc,kBAAkB;AACvE,QAAKC,KAAM;AACX,QAAKC,oBAAqB;AAC1B,QAAKC,WAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BnB,kBAAkB,SAIU;EAW1B,MAAM,YAAY,2BATD,aACf,QAAQ,QACR,QAAQ,OACR,QAAQ,kBACR,EAAE,EACF,MAAKA,SACN,EAGsD,MAAKF,IAAK,MAAKE,SAAU;AAKhF,SAFmB,KAAK,gBAAgB,WAAW,QAAQ,MAAM;;;;;;;;;;;;;;CAiBnE,AAAQ,gBACN,QACA,OACyB;EACzB,MAAMC,SAAkC,EAAE;EAC1C,MAAM,YAAY,MAAKD,WAAY,MAAKA,SAAU,iBAAiB,MAAM,GAAG;AAE5E,OAAK,MAAM,CAAC,cAAc,UAAU,OAAO,QAAQ,OAAO,EAAE;GAE1D,MAAM,MAAM,KAAK,mBAAmB,OAAO,cAAc,UAAU;AAEnE,OAAI,CAAC,KAAK;AAGR,WAAO,gBAAgB;AACvB;;AAGF,OAAI,QAAQ,MAAM,EAAE;AAClB,WAAO,gBAAgB,cAAc;KACnC,cAAc,MAAKJ;KACnB,YAAY,IAAI;KAChB,UAAU,iBAAiB,MAAM;KACjC,mBAAmB,MAAKG;KACzB,CAAC;AACF;;AAIF,UAAO,gBAAgB,MAAKF,WAAY,UAAU,OAAO,IAAI;;AAG/D,SAAO;;;;;;;;;CAUT,AAAQ,mBACN,OACA,cACA,WACuB;EACvB,MAAM,cAAc,YAAY,iBAAiB;EACjD,MAAM,SAAS,MAAM,QAAQ;AAC7B,MAAI,OACF,QAAO;AAET,OAAK,MAAM,OAAO,OAAO,OAAO,MAAM,QAAQ,CAC5C,KAAI,IAAI,SAAS,YACf,QAAO"}
@@ -1,9 +1,9 @@
1
+ import { getDbNowOffsetMs, isDbNow } from "../../query/db-now.js";
1
2
  import { Column, FragnoId, FragnoReference } from "../../schema/create.js";
2
3
  import { ReferenceSubquery, resolveFragnoIdValue } from "../../query/value-encoding.js";
3
- import { isDbNow } from "../../query/db-now.js";
4
+ import { resolveReferenceSubquery } from "./reference-resolution.js";
4
5
  import { compareNormalizedValues } from "./value-comparison.js";
5
6
  import { normalizeIndexValue } from "./store.js";
6
- import { resolveReferenceSubquery } from "./reference-resolution.js";
7
7
 
8
8
  //#region src/adapters/in-memory/condition-evaluator.ts
9
9
  const isNullish = (value) => value === null || value === void 0;
@@ -30,10 +30,14 @@ const resolveComparisonValue = (value, column, table, row, namespaceStore, resol
30
30
  value: row[resolver ? resolver.getColumnName(table.name, value.name) : value.name],
31
31
  column: value
32
32
  };
33
- if (isDbNow(value)) return {
34
- value: now(),
35
- column
36
- };
33
+ if (isDbNow(value)) {
34
+ const base = now();
35
+ const offsetMs = getDbNowOffsetMs(value);
36
+ return {
37
+ value: offsetMs === 0 ? base : new Date(base.getTime() + offsetMs),
38
+ column
39
+ };
40
+ }
37
41
  if (column.role === "reference") return {
38
42
  value: resolveReferenceValue(value, column, table, namespaceStore, resolver),
39
43
  column
@@ -1 +1 @@
1
- {"version":3,"file":"condition-evaluator.js","names":["exhaustiveCheck: never","matches"],"sources":["../../../src/adapters/in-memory/condition-evaluator.ts"],"sourcesContent":["import type { Condition } from \"../../query/condition-builder\";\nimport { ReferenceSubquery, resolveFragnoIdValue } from \"../../query/value-encoding\";\nimport { isDbNow } from \"../../query/db-now\";\nimport type { AnyColumn, AnyTable } from \"../../schema/create\";\nimport { Column, FragnoId, FragnoReference } from \"../../schema/create\";\nimport type { InMemoryNamespaceStore, InMemoryRow } from \"./store\";\nimport { normalizeIndexValue } from \"./store\";\nimport { resolveReferenceSubquery } from \"./reference-resolution\";\nimport { compareNormalizedValues } from \"./value-comparison\";\nimport type { NamingResolver } from \"../../naming/sql-naming\";\n\nconst isNullish = (value: unknown): value is null | undefined =>\n value === null || value === undefined;\n\nconst resolveReferenceValue = (\n value: unknown,\n column: AnyColumn,\n table: AnyTable,\n namespaceStore?: InMemoryNamespaceStore,\n resolver?: NamingResolver,\n): unknown => {\n if (value instanceof FragnoReference) {\n return value.internalId;\n }\n\n if (value instanceof FragnoId) {\n if (value.internalId !== undefined) {\n return value.internalId;\n }\n return resolveReferenceValue(value.externalId, column, table, namespaceStore, resolver);\n }\n\n if (value instanceof ReferenceSubquery) {\n if (!namespaceStore) {\n throw new Error(\"In-memory condition evaluation requires a namespace store.\");\n }\n return resolveReferenceSubquery(namespaceStore, value, resolver);\n }\n\n if (typeof value === \"string\") {\n if (!namespaceStore) {\n throw new Error(\"In-memory condition evaluation requires a namespace store.\");\n }\n\n const relation = Object.values(table.relations).find((rel) =>\n rel.on.some(([localCol]) => localCol === column.name),\n );\n if (!relation) {\n throw new Error(`Missing relation for reference column \"${column.name}\".`);\n }\n\n return resolveReferenceSubquery(\n namespaceStore,\n new ReferenceSubquery(relation.table, value),\n resolver,\n );\n }\n\n return resolveFragnoIdValue(value, column);\n};\n\nconst resolveComparisonValue = (\n value: unknown,\n column: AnyColumn,\n table: AnyTable,\n row: InMemoryRow,\n namespaceStore?: InMemoryNamespaceStore,\n resolver?: NamingResolver,\n now: () => Date = () => new Date(),\n): { value: unknown; column: AnyColumn } => {\n if (value instanceof Column) {\n const columnName = resolver ? resolver.getColumnName(table.name, value.name) : value.name;\n return { value: row[columnName], column: value };\n }\n\n if (isDbNow(value)) {\n return { value: now(), column };\n }\n\n if (column.role === \"reference\") {\n return {\n value: resolveReferenceValue(value, column, table, namespaceStore, resolver),\n column,\n };\n }\n\n return { value: resolveFragnoIdValue(value, column), column };\n};\n\nconst normalizeLikeValue = (value: unknown, column: AnyColumn): string | null => {\n const normalized = normalizeIndexValue(value, column);\n if (normalized === null || normalized === undefined) {\n return null;\n }\n if (normalized instanceof Buffer) {\n return normalized.toString(\"hex\");\n }\n return String(normalized);\n};\n\nconst compareNormalized = (left: unknown, right: unknown): number =>\n compareNormalizedValues(left, right);\n\nexport const evaluateCondition = (\n condition: Condition | boolean,\n table: AnyTable,\n row: InMemoryRow,\n namespaceStore?: InMemoryNamespaceStore,\n resolver?: NamingResolver,\n now: () => Date = () => new Date(),\n): boolean => {\n if (typeof condition === \"boolean\") {\n return condition;\n }\n\n switch (condition.type) {\n case \"and\": {\n for (const item of condition.items) {\n if (!evaluateCondition(item, table, row, namespaceStore, resolver, now)) {\n return false;\n }\n }\n return true;\n }\n case \"or\": {\n for (const item of condition.items) {\n if (evaluateCondition(item, table, row, namespaceStore, resolver, now)) {\n return true;\n }\n }\n return false;\n }\n case \"not\":\n return !evaluateCondition(condition.item, table, row, namespaceStore, resolver, now);\n case \"compare\":\n break;\n default: {\n const exhaustiveCheck: never = condition;\n throw new Error(`Unsupported condition type: ${JSON.stringify(exhaustiveCheck)}`);\n }\n }\n\n const leftColumn = condition.a;\n const leftColumnName = resolver\n ? resolver.getColumnName(table.name, leftColumn.name)\n : leftColumn.name;\n const leftValue = row[leftColumnName];\n const right = resolveComparisonValue(\n condition.b,\n leftColumn,\n table,\n row,\n namespaceStore,\n resolver,\n now,\n );\n\n const op = condition.operator;\n const rightValue = right.value;\n\n if (op === \"is\" || op === \"is not\") {\n if (isNullish(rightValue)) {\n const matches = isNullish(leftValue);\n return op === \"is\" ? matches : !matches;\n }\n\n if (isNullish(leftValue)) {\n return op === \"is not\";\n }\n\n const leftNormalized = normalizeIndexValue(leftValue, leftColumn);\n const rightNormalized = normalizeIndexValue(rightValue, right.column);\n const matches = compareNormalized(leftNormalized, rightNormalized) === 0;\n return op === \"is\" ? matches : !matches;\n }\n\n if (isNullish(leftValue) || isNullish(rightValue)) {\n return false;\n }\n\n if (op === \"in\" || op === \"not in\") {\n if (!Array.isArray(rightValue)) {\n throw new Error(`Operator \"${op}\" expects an array value.`);\n }\n\n const leftNormalized = normalizeIndexValue(leftValue, leftColumn);\n let hasNull = false;\n let hasMatch = false;\n\n for (const item of rightValue) {\n const resolved = resolveComparisonValue(\n item,\n leftColumn,\n table,\n row,\n namespaceStore,\n resolver,\n now,\n );\n if (isNullish(resolved.value)) {\n hasNull = true;\n continue;\n }\n const normalized = normalizeIndexValue(resolved.value, leftColumn);\n if (compareNormalized(leftNormalized, normalized) === 0) {\n hasMatch = true;\n break;\n }\n }\n\n if (hasMatch) {\n return op === \"in\";\n }\n\n if (hasNull) {\n return false;\n }\n\n return op === \"not in\";\n }\n\n if (\n op === \"contains\" ||\n op === \"starts with\" ||\n op === \"ends with\" ||\n op === \"not contains\" ||\n op === \"not starts with\" ||\n op === \"not ends with\"\n ) {\n const leftLike = normalizeLikeValue(leftValue, leftColumn);\n const rightLike = normalizeLikeValue(rightValue, right.column);\n\n if (leftLike === null || rightLike === null) {\n return false;\n }\n\n const leftText = leftLike.toLowerCase();\n const rightText = rightLike.toLowerCase();\n let matches = false;\n\n if (op.includes(\"contains\")) {\n matches = leftText.includes(rightText);\n } else if (op.includes(\"starts with\")) {\n matches = leftText.startsWith(rightText);\n } else {\n matches = leftText.endsWith(rightText);\n }\n\n if (op.startsWith(\"not \")) {\n return !matches;\n }\n return matches;\n }\n\n const leftNormalized = normalizeIndexValue(leftValue, leftColumn);\n const rightNormalized = normalizeIndexValue(rightValue, right.column);\n const comparison = compareNormalized(leftNormalized, rightNormalized);\n\n switch (op) {\n case \"=\":\n return comparison === 0;\n case \"!=\":\n return comparison !== 0;\n case \">\":\n return comparison > 0;\n case \">=\":\n return comparison >= 0;\n case \"<\":\n return comparison < 0;\n case \"<=\":\n return comparison <= 0;\n default:\n throw new Error(`Unsupported operator \"${op}\".`);\n }\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"condition-evaluator.js","names":["exhaustiveCheck: never","matches"],"sources":["../../../src/adapters/in-memory/condition-evaluator.ts"],"sourcesContent":["import type { NamingResolver } from \"../../naming/sql-naming\";\nimport type { Condition } from \"../../query/condition-builder\";\nimport { getDbNowOffsetMs, isDbNow } from \"../../query/db-now\";\nimport { ReferenceSubquery, resolveFragnoIdValue } from \"../../query/value-encoding\";\nimport type { AnyColumn, AnyTable } from \"../../schema/create\";\nimport { Column, FragnoId, FragnoReference } from \"../../schema/create\";\nimport { resolveReferenceSubquery } from \"./reference-resolution\";\nimport type { InMemoryNamespaceStore, InMemoryRow } from \"./store\";\nimport { normalizeIndexValue } from \"./store\";\nimport { compareNormalizedValues } from \"./value-comparison\";\n\nconst isNullish = (value: unknown): value is null | undefined =>\n value === null || value === undefined;\n\nconst resolveReferenceValue = (\n value: unknown,\n column: AnyColumn,\n table: AnyTable,\n namespaceStore?: InMemoryNamespaceStore,\n resolver?: NamingResolver,\n): unknown => {\n if (value instanceof FragnoReference) {\n return value.internalId;\n }\n\n if (value instanceof FragnoId) {\n if (value.internalId !== undefined) {\n return value.internalId;\n }\n return resolveReferenceValue(value.externalId, column, table, namespaceStore, resolver);\n }\n\n if (value instanceof ReferenceSubquery) {\n if (!namespaceStore) {\n throw new Error(\"In-memory condition evaluation requires a namespace store.\");\n }\n return resolveReferenceSubquery(namespaceStore, value, resolver);\n }\n\n if (typeof value === \"string\") {\n if (!namespaceStore) {\n throw new Error(\"In-memory condition evaluation requires a namespace store.\");\n }\n\n const relation = Object.values(table.relations).find((rel) =>\n rel.on.some(([localCol]) => localCol === column.name),\n );\n if (!relation) {\n throw new Error(`Missing relation for reference column \"${column.name}\".`);\n }\n\n return resolveReferenceSubquery(\n namespaceStore,\n new ReferenceSubquery(relation.table, value),\n resolver,\n );\n }\n\n return resolveFragnoIdValue(value, column);\n};\n\nconst resolveComparisonValue = (\n value: unknown,\n column: AnyColumn,\n table: AnyTable,\n row: InMemoryRow,\n namespaceStore?: InMemoryNamespaceStore,\n resolver?: NamingResolver,\n now: () => Date = () => new Date(),\n): { value: unknown; column: AnyColumn } => {\n if (value instanceof Column) {\n const columnName = resolver ? resolver.getColumnName(table.name, value.name) : value.name;\n return { value: row[columnName], column: value };\n }\n\n if (isDbNow(value)) {\n const base = now();\n const offsetMs = getDbNowOffsetMs(value);\n return {\n value: offsetMs === 0 ? base : new Date(base.getTime() + offsetMs),\n column,\n };\n }\n\n if (column.role === \"reference\") {\n return {\n value: resolveReferenceValue(value, column, table, namespaceStore, resolver),\n column,\n };\n }\n\n return { value: resolveFragnoIdValue(value, column), column };\n};\n\nconst normalizeLikeValue = (value: unknown, column: AnyColumn): string | null => {\n const normalized = normalizeIndexValue(value, column);\n if (normalized === null || normalized === undefined) {\n return null;\n }\n if (normalized instanceof Buffer) {\n return normalized.toString(\"hex\");\n }\n return String(normalized);\n};\n\nconst compareNormalized = (left: unknown, right: unknown): number =>\n compareNormalizedValues(left, right);\n\nexport const evaluateCondition = (\n condition: Condition | boolean,\n table: AnyTable,\n row: InMemoryRow,\n namespaceStore?: InMemoryNamespaceStore,\n resolver?: NamingResolver,\n now: () => Date = () => new Date(),\n): boolean => {\n if (typeof condition === \"boolean\") {\n return condition;\n }\n\n switch (condition.type) {\n case \"and\": {\n for (const item of condition.items) {\n if (!evaluateCondition(item, table, row, namespaceStore, resolver, now)) {\n return false;\n }\n }\n return true;\n }\n case \"or\": {\n for (const item of condition.items) {\n if (evaluateCondition(item, table, row, namespaceStore, resolver, now)) {\n return true;\n }\n }\n return false;\n }\n case \"not\":\n return !evaluateCondition(condition.item, table, row, namespaceStore, resolver, now);\n case \"compare\":\n break;\n default: {\n const exhaustiveCheck: never = condition;\n throw new Error(`Unsupported condition type: ${JSON.stringify(exhaustiveCheck)}`);\n }\n }\n\n const leftColumn = condition.a;\n const leftColumnName = resolver\n ? resolver.getColumnName(table.name, leftColumn.name)\n : leftColumn.name;\n const leftValue = row[leftColumnName];\n const right = resolveComparisonValue(\n condition.b,\n leftColumn,\n table,\n row,\n namespaceStore,\n resolver,\n now,\n );\n\n const op = condition.operator;\n const rightValue = right.value;\n\n if (op === \"is\" || op === \"is not\") {\n if (isNullish(rightValue)) {\n const matches = isNullish(leftValue);\n return op === \"is\" ? matches : !matches;\n }\n\n if (isNullish(leftValue)) {\n return op === \"is not\";\n }\n\n const leftNormalized = normalizeIndexValue(leftValue, leftColumn);\n const rightNormalized = normalizeIndexValue(rightValue, right.column);\n const matches = compareNormalized(leftNormalized, rightNormalized) === 0;\n return op === \"is\" ? matches : !matches;\n }\n\n if (isNullish(leftValue) || isNullish(rightValue)) {\n return false;\n }\n\n if (op === \"in\" || op === \"not in\") {\n if (!Array.isArray(rightValue)) {\n throw new Error(`Operator \"${op}\" expects an array value.`);\n }\n\n const leftNormalized = normalizeIndexValue(leftValue, leftColumn);\n let hasNull = false;\n let hasMatch = false;\n\n for (const item of rightValue) {\n const resolved = resolveComparisonValue(\n item,\n leftColumn,\n table,\n row,\n namespaceStore,\n resolver,\n now,\n );\n if (isNullish(resolved.value)) {\n hasNull = true;\n continue;\n }\n const normalized = normalizeIndexValue(resolved.value, leftColumn);\n if (compareNormalized(leftNormalized, normalized) === 0) {\n hasMatch = true;\n break;\n }\n }\n\n if (hasMatch) {\n return op === \"in\";\n }\n\n if (hasNull) {\n return false;\n }\n\n return op === \"not in\";\n }\n\n if (\n op === \"contains\" ||\n op === \"starts with\" ||\n op === \"ends with\" ||\n op === \"not contains\" ||\n op === \"not starts with\" ||\n op === \"not ends with\"\n ) {\n const leftLike = normalizeLikeValue(leftValue, leftColumn);\n const rightLike = normalizeLikeValue(rightValue, right.column);\n\n if (leftLike === null || rightLike === null) {\n return false;\n }\n\n const leftText = leftLike.toLowerCase();\n const rightText = rightLike.toLowerCase();\n let matches = false;\n\n if (op.includes(\"contains\")) {\n matches = leftText.includes(rightText);\n } else if (op.includes(\"starts with\")) {\n matches = leftText.startsWith(rightText);\n } else {\n matches = leftText.endsWith(rightText);\n }\n\n if (op.startsWith(\"not \")) {\n return !matches;\n }\n return matches;\n }\n\n const leftNormalized = normalizeIndexValue(leftValue, leftColumn);\n const rightNormalized = normalizeIndexValue(rightValue, right.column);\n const comparison = compareNormalized(leftNormalized, rightNormalized);\n\n switch (op) {\n case \"=\":\n return comparison === 0;\n case \"!=\":\n return comparison !== 0;\n case \">\":\n return comparison > 0;\n case \">=\":\n return comparison >= 0;\n case \"<\":\n return comparison < 0;\n case \"<=\":\n return comparison <= 0;\n default:\n throw new Error(`Unsupported operator \"${op}\".`);\n }\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"in-memory-adapter.d.ts","names":[],"sources":["../../../src/adapters/in-memory/in-memory-adapter.ts"],"sourcesContent":[],"mappings":";;;;;;;;;KAwDY,iBAAA,GAAoB;cAEnB,eAAA,YAA2B,gBAAgB;EAF5C,CAAA,OAAA;EAEC,SAAA,OAAA,EACO,8BADS;EAA2B,SAAA,cAAA,EAE7B,iBAF6B;EACpC,WAAA,CAAA,OAAA,CAAA,EAQG,sBARH;EACO,KAapB,mCAAA,GAboB,EAAA,MAAA;EAOJ,KAUhB,sCAAA,GAVgB,EAAA,MAAA;EAMhB,IAAA,cAAA,CAAA,CAAA,EAQiB,qBARjB,CAQuC,sBARvC,CAAA;EAIA,gBAAA,CAAA,UAAA,EAAA,MAAA,CAAA,EAQuC,OARvC,CAAA,MAAA,GAAA,SAAA,CAAA;EAIuC,mBAAA,CAAA,CAAA,EAQf,OARe,CAAA,OAAA,CAAA;EAAtB,KAAA,CAAA,CAAA,EAYP,OAZO,CAAA,IAAA,CAAA;EAIsB,KAAA,CAAA,CAAA,EAY7B,OAZ6B,CAAA,IAAA,CAAA;EAIf,iBAAA,CAAA,UAgBD,SAhBC,CAAA,CAAA,MAAA,EAiBnB,CAjBmB,EAAA,SAAA,EAAA,MAAA,GAAA,IAAA,CAAA,EAmB1B,oBAnB0B,CAmBL,CAnBK,EAmBF,iBAnBE,CAAA"}
1
+ {"version":3,"file":"in-memory-adapter.d.ts","names":[],"sources":["../../../src/adapters/in-memory/in-memory-adapter.ts"],"sourcesContent":[],"mappings":";;;;;;;;;KA8EY,iBAAA,GAAoB;cAEnB,eAAA,YAA2B,gBAAgB;EAF5C,CAAA,OAAA;EAEC,SAAA,OAAA,EACO,8BADS;EAA2B,SAAA,cAAA,EAE7B,iBAF6B;EACpC,WAAA,CAAA,OAAA,CAAA,EAQG,sBARH;EACO,KAcpB,mCAAA,GAdoB,EAAA,MAAA;EAOJ,KAWhB,sCAAA,GAXgB,EAAA,MAAA;EAOhB,IAAA,cAAA,CAAA,CAAA,EAQiB,qBARjB,CAQuC,sBARvC,CAAA;EAIA,gBAAA,CAAA,UAAA,EAAA,MAAA,CAAA,EAQuC,OARvC,CAAA,MAAA,GAAA,SAAA,CAAA;EAIuC,mBAAA,CAAA,CAAA,EAQf,OARe,CAAA,OAAA,CAAA;EAAtB,KAAA,CAAA,CAAA,EAYP,OAZO,CAAA,IAAA,CAAA;EAIsB,KAAA,CAAA,CAAA,EAY7B,OAZ6B,CAAA,IAAA,CAAA;EAIf,iBAAA,CAAA,UAgBD,SAhBC,CAAA,CAAA,MAAA,EAiBnB,CAjBmB,EAAA,SAAA,EAAA,MAAA,GAAA,IAAA,CAAA,EAmB1B,oBAnB0B,CAmBL,CAnBK,EAmBF,iBAnBE,CAAA"}
@@ -1,10 +1,12 @@
1
- import { RequestContextStorage } from "../../packages/fragno/dist/api/request-context-storage.js";
2
- import { fragnoDatabaseAdapterNameFakeSymbol, fragnoDatabaseAdapterVersionFakeSymbol } from "../adapters.js";
1
+ import { dbInterval, dbNow } from "../../query/db-now.js";
3
2
  import { createNamingResolver, suffixNamingStrategy } from "../../naming/sql-naming.js";
3
+ import { getOutboxConfigForAdapter } from "../../internal/outbox-state.js";
4
+ import { fragnoDatabaseAdapterNameFakeSymbol, fragnoDatabaseAdapterVersionFakeSymbol } from "../adapters.js";
4
5
  import { UnitOfWork } from "../../query/unit-of-work/unit-of-work.js";
5
- import { resolveInMemoryAdapterOptions } from "./options.js";
6
6
  import { createInMemoryStore, ensureNamespaceStore } from "./store.js";
7
7
  import { InMemoryUowDecoder, createInMemoryUowCompiler, createInMemoryUowExecutor } from "./in-memory-uow.js";
8
+ import { resolveInMemoryAdapterOptions } from "./options.js";
9
+ import { RequestContextStorage } from "@fragno-dev/core/internal/request-context-storage";
8
10
 
9
11
  //#region src/adapters/in-memory/in-memory-adapter.ts
10
12
  var UpdateManySpecialBuilder = class {
@@ -20,6 +22,12 @@ var UpdateManySpecialBuilder = class {
20
22
  this.#setValues = values;
21
23
  return this;
22
24
  }
25
+ now() {
26
+ return dbNow();
27
+ }
28
+ interval(input) {
29
+ return dbInterval(input);
30
+ }
23
31
  getConfig() {
24
32
  return {
25
33
  indexName: this.#indexName,
@@ -40,6 +48,7 @@ var InMemoryAdapter = class {
40
48
  this.options = resolveInMemoryAdapterOptions(options);
41
49
  this.namingStrategy = options.namingStrategy ?? suffixNamingStrategy;
42
50
  this.#contextStorage = new RequestContextStorage();
51
+ this.options.outbox = getOutboxConfigForAdapter(this);
43
52
  }
44
53
  get [fragnoDatabaseAdapterNameFakeSymbol]() {
45
54
  return "in-memory";
@@ -73,31 +82,36 @@ var InMemoryAdapter = class {
73
82
  const resolver = resolverFactory(schema, namespace);
74
83
  ensureNamespaceStore(this.#store, namespaceKey, schema, resolver);
75
84
  const compiler = createInMemoryUowCompiler();
76
- const executor = createInMemoryUowExecutor(this.#store, this.options, resolverFactory);
85
+ const executor = createInMemoryUowExecutor(this.#store, this.options, resolverFactory, this.#schemaByNamespace);
77
86
  const decoder = new InMemoryUowDecoder(resolverFactory);
78
- const createUow = (opts) => new UnitOfWork(compiler, executor, decoder, opts?.name, opts?.config, this.#schemaNamespaceMap).forSchema(schema);
87
+ const createBaseUow = (opts) => new UnitOfWork(compiler, executor, decoder, opts?.name, opts?.config, this.#schemaNamespaceMap);
88
+ const createUow = (opts) => createBaseUow(opts).forSchema(schema);
89
+ async function find(tableName, builderFn) {
90
+ const uow = createUow();
91
+ if (builderFn) uow.find(tableName, builderFn);
92
+ else uow.find(tableName);
93
+ const [result] = await uow.executeRetrieve();
94
+ return result ?? [];
95
+ }
96
+ async function findWithCursor(tableName, builderFn) {
97
+ const [result] = await createUow().findWithCursor(tableName, builderFn).executeRetrieve();
98
+ return result;
99
+ }
100
+ async function findFirst(tableName, builderFn) {
101
+ const uow = createUow();
102
+ if (builderFn) uow.find(tableName, (b) => {
103
+ builderFn(b);
104
+ return b.pageSize(1);
105
+ });
106
+ else uow.find(tableName, (b) => b.whereIndex("primary").pageSize(1));
107
+ const [result] = await uow.executeRetrieve();
108
+ return result?.[0] ?? null;
109
+ }
79
110
  return {
80
111
  now: async () => this.options.clock.now(),
81
- async find(tableName, builderFn) {
82
- const uow = createUow();
83
- uow.find(tableName, builderFn);
84
- const [result] = await uow.executeRetrieve();
85
- return result ?? [];
86
- },
87
- async findWithCursor(tableName, builderFn) {
88
- const [result] = await createUow().findWithCursor(tableName, builderFn).executeRetrieve();
89
- return result;
90
- },
91
- async findFirst(tableName, builderFn) {
92
- const uow = createUow();
93
- if (builderFn) uow.find(tableName, (b) => {
94
- builderFn(b);
95
- return b.pageSize(1);
96
- });
97
- else uow.find(tableName, (b) => b.whereIndex("primary").pageSize(1));
98
- const [result] = await uow.executeRetrieve();
99
- return result?.[0] ?? null;
100
- },
112
+ find,
113
+ findWithCursor,
114
+ findFirst,
101
115
  async create(tableName, values) {
102
116
  const uow = createUow();
103
117
  uow.create(tableName, values);
@@ -166,6 +180,12 @@ var InMemoryAdapter = class {
166
180
  name,
167
181
  config
168
182
  });
183
+ },
184
+ createBaseUnitOfWork(name, config) {
185
+ return createBaseUow({
186
+ name,
187
+ config
188
+ });
169
189
  }
170
190
  };
171
191
  }
@@ -1 +1 @@
1
- {"version":3,"file":"in-memory-adapter.js","names":["#indexName","#condition","#setValues","#contextStorage","#store","#schemaByNamespace","#schemaNamespaceMap"],"sources":["../../../src/adapters/in-memory/in-memory-adapter.ts"],"sourcesContent":["import { RequestContextStorage } from \"@fragno-dev/core/internal/request-context-storage\";\nimport {\n fragnoDatabaseAdapterNameFakeSymbol,\n fragnoDatabaseAdapterVersionFakeSymbol,\n type DatabaseAdapter,\n type DatabaseContextStorage,\n} from \"../adapters\";\nimport type { AnySchema, AnyTable, FragnoId } from \"../../schema/create\";\nimport type { SimpleQueryInterface, TableToUpdateValues } from \"../../query/simple-query-interface\";\nimport {\n resolveInMemoryAdapterOptions,\n type InMemoryAdapterOptions,\n type ResolvedInMemoryAdapterOptions,\n} from \"./options\";\nimport { createInMemoryStore, ensureNamespaceStore } from \"./store\";\nimport {\n createInMemoryUowCompiler,\n createInMemoryUowExecutor,\n InMemoryUowDecoder,\n} from \"./in-memory-uow\";\nimport { UnitOfWork, type UnitOfWorkConfig } from \"../../query/unit-of-work/unit-of-work\";\nimport type { CursorResult } from \"../../query/cursor\";\nimport {\n createNamingResolver,\n suffixNamingStrategy,\n type SqlNamingStrategy,\n} from \"../../naming/sql-naming\";\n\nclass UpdateManySpecialBuilder<TTable extends AnyTable> {\n #indexName?: string;\n #condition?: unknown;\n #setValues?: TableToUpdateValues<TTable>;\n\n whereIndex(indexName: string, condition?: unknown): this {\n this.#indexName = indexName;\n this.#condition = condition;\n return this;\n }\n\n set(values: TableToUpdateValues<TTable>): this {\n this.#setValues = values;\n return this;\n }\n\n getConfig() {\n return {\n indexName: this.#indexName,\n condition: this.#condition,\n setValues: this.#setValues,\n };\n }\n}\n\nconst hasIdField = (record: unknown): record is { id: string | FragnoId } =>\n record !== null && typeof record === \"object\" && \"id\" in record;\n\nexport type InMemoryUowConfig = UnitOfWorkConfig;\n\nexport class InMemoryAdapter implements DatabaseAdapter<InMemoryUowConfig> {\n readonly options: ResolvedInMemoryAdapterOptions;\n readonly namingStrategy: SqlNamingStrategy;\n\n #contextStorage: RequestContextStorage<DatabaseContextStorage>;\n #store = createInMemoryStore();\n #schemaNamespaceMap = new WeakMap<AnySchema, string | null>();\n #schemaByNamespace = new Map<string, { schema: AnySchema; namespace: string | null }>();\n\n constructor(options: InMemoryAdapterOptions = {}) {\n this.options = resolveInMemoryAdapterOptions(options);\n this.namingStrategy = options.namingStrategy ?? suffixNamingStrategy;\n this.#contextStorage = new RequestContextStorage();\n }\n\n get [fragnoDatabaseAdapterNameFakeSymbol](): string {\n return \"in-memory\";\n }\n\n get [fragnoDatabaseAdapterVersionFakeSymbol](): number {\n return 0;\n }\n\n get contextStorage(): RequestContextStorage<DatabaseContextStorage> {\n return this.#contextStorage;\n }\n\n async getSchemaVersion(_namespace: string): Promise<string | undefined> {\n return undefined;\n }\n\n async isConnectionHealthy(): Promise<boolean> {\n return true;\n }\n\n async close(): Promise<void> {\n return;\n }\n\n async reset(): Promise<void> {\n this.#store.namespaces.clear();\n for (const [namespaceKey, { schema, namespace }] of this.#schemaByNamespace) {\n const resolver = createNamingResolver(schema, namespace, this.namingStrategy);\n ensureNamespaceStore(this.#store, namespaceKey, schema, resolver);\n }\n }\n\n createQueryEngine<T extends AnySchema>(\n schema: T,\n namespace: string | null,\n ): SimpleQueryInterface<T, InMemoryUowConfig> {\n this.#schemaNamespaceMap.set(schema, namespace);\n const namespaceKey = namespace ?? schema.name;\n this.#schemaByNamespace.set(namespaceKey, { schema, namespace });\n const resolverFactory = (schemaForResolver: AnySchema, namespaceForResolver: string | null) =>\n createNamingResolver(schemaForResolver, namespaceForResolver, this.namingStrategy);\n const resolver = resolverFactory(schema, namespace);\n ensureNamespaceStore(this.#store, namespaceKey, schema, resolver);\n\n const compiler = createInMemoryUowCompiler();\n const executor = createInMemoryUowExecutor(this.#store, this.options, resolverFactory);\n const decoder = new InMemoryUowDecoder(resolverFactory);\n\n const createUow = (opts?: { name?: string; config?: UnitOfWorkConfig }) =>\n new UnitOfWork(\n compiler,\n executor,\n decoder,\n opts?.name,\n opts?.config,\n this.#schemaNamespaceMap,\n ).forSchema(schema);\n\n const queryEngine = {\n now: async () => this.options.clock.now(),\n async find(tableName, builderFn) {\n const uow = createUow();\n uow.find(tableName, builderFn);\n const [result]: unknown[][] = await uow.executeRetrieve();\n return result ?? [];\n },\n\n async findWithCursor(tableName, builderFn) {\n const uow = createUow().findWithCursor(tableName, builderFn);\n const [result] = await uow.executeRetrieve();\n return result as CursorResult<unknown>;\n },\n\n async findFirst(tableName, builderFn) {\n const uow = createUow();\n if (builderFn) {\n uow.find(tableName, (b) => {\n builderFn(b);\n return b.pageSize(1);\n });\n } else {\n uow.find(tableName, (b) => b.whereIndex(\"primary\").pageSize(1));\n }\n const [result]: unknown[][] = await uow.executeRetrieve();\n return result?.[0] ?? null;\n },\n\n async create(tableName, values) {\n const uow = createUow();\n uow.create(tableName, values);\n const { success } = await uow.executeMutations();\n if (!success) {\n throw new Error(\"Failed to create record\");\n }\n\n const createdId = uow.getCreatedIds()[0];\n if (!createdId) {\n throw new Error(\"Failed to get created ID\");\n }\n return createdId;\n },\n\n async createMany(tableName, valuesArray) {\n const uow = createUow();\n for (const values of valuesArray) {\n uow.create(tableName, values);\n }\n const { success } = await uow.executeMutations();\n if (!success) {\n throw new Error(\"Failed to create records\");\n }\n return uow.getCreatedIds();\n },\n\n async update(tableName, id, builderFn) {\n const uow = createUow();\n uow.update(tableName, id, builderFn);\n const { success } = await uow.executeMutations();\n if (!success) {\n throw new Error(\"Failed to update record (version conflict or record not found)\");\n }\n },\n\n async updateMany(tableName, builderFn) {\n const table = schema.tables[tableName];\n if (!table) {\n throw new Error(`Table ${tableName} not found in schema`);\n }\n\n const specialBuilder = new UpdateManySpecialBuilder<typeof table>();\n builderFn(specialBuilder);\n const { indexName, condition, setValues } = specialBuilder.getConfig();\n\n if (!indexName) {\n throw new Error(\"whereIndex() must be called in updateMany\");\n }\n if (!setValues) {\n throw new Error(\"set() must be called in updateMany\");\n }\n\n const findUow = createUow();\n findUow.find(tableName, (b) => {\n if (condition !== undefined && condition !== null) {\n return b.whereIndex(indexName as never, condition as never);\n }\n return b.whereIndex(indexName as never);\n });\n const [records]: unknown[][] = await findUow.executeRetrieve();\n\n if (!records || records.length === 0) {\n return;\n }\n\n const updateUow = createUow();\n for (const record of records) {\n if (!hasIdField(record)) {\n throw new Error(\"Record missing id field\");\n }\n updateUow.update(tableName, record.id, (b) => b.set(setValues).check());\n }\n const { success } = await updateUow.executeMutations();\n if (!success) {\n throw new Error(\"Failed to update records (version conflict)\");\n }\n },\n\n async delete(tableName, id, builderFn) {\n const uow = createUow();\n uow.delete(tableName, id, builderFn);\n const { success } = await uow.executeMutations();\n if (!success) {\n throw new Error(\"Failed to delete record (version conflict or record not found)\");\n }\n },\n\n async deleteMany(tableName, builderFn) {\n const findUow = createUow();\n findUow.find(tableName, builderFn);\n const [records]: unknown[][] = await findUow.executeRetrieve();\n\n if (!records || records.length === 0) {\n return;\n }\n\n const deleteUow = createUow();\n for (const record of records) {\n if (!hasIdField(record)) {\n throw new Error(\"Record missing id field\");\n }\n deleteUow.delete(tableName, record.id);\n }\n const { success } = await deleteUow.executeMutations();\n if (!success) {\n throw new Error(\"Failed to delete records (version conflict)\");\n }\n },\n\n createUnitOfWork(name, config) {\n return createUow({ name, config });\n },\n } as SimpleQueryInterface<T, InMemoryUowConfig>;\n return queryEngine;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"in-memory-adapter.js","names":["#indexName","#condition","#setValues","#contextStorage","#store","#schemaByNamespace","#schemaNamespaceMap"],"sources":["../../../src/adapters/in-memory/in-memory-adapter.ts"],"sourcesContent":["import { RequestContextStorage } from \"@fragno-dev/core/internal/request-context-storage\";\n\nimport { getOutboxConfigForAdapter } from \"../../internal/outbox-state\";\nimport {\n createNamingResolver,\n suffixNamingStrategy,\n type SqlNamingStrategy,\n} from \"../../naming/sql-naming\";\nimport type { CursorResult } from \"../../query/cursor\";\nimport { dbInterval, dbNow, type DbIntervalInput, type DbInterval } from \"../../query/db-now\";\nimport type {\n SimpleQueryInterface,\n TableToUpdateValues,\n SelectResult,\n ExtractJoinOut,\n ExtractSelect,\n SelectClause,\n} from \"../../query/simple-query-interface\";\nimport {\n UnitOfWork,\n type UnitOfWorkConfig,\n type FindBuilder,\n} from \"../../query/unit-of-work/unit-of-work\";\nimport type { AnySchema, AnyTable, FragnoId } from \"../../schema/create\";\nimport {\n fragnoDatabaseAdapterNameFakeSymbol,\n fragnoDatabaseAdapterVersionFakeSymbol,\n type DatabaseAdapter,\n type DatabaseContextStorage,\n} from \"../adapters\";\nimport {\n createInMemoryUowCompiler,\n createInMemoryUowExecutor,\n InMemoryUowDecoder,\n} from \"./in-memory-uow\";\nimport {\n resolveInMemoryAdapterOptions,\n type InMemoryAdapterOptions,\n type ResolvedInMemoryAdapterOptions,\n} from \"./options\";\nimport { createInMemoryStore, ensureNamespaceStore } from \"./store\";\n\nclass UpdateManySpecialBuilder<TTable extends AnyTable> {\n #indexName?: string;\n #condition?: unknown;\n #setValues?: TableToUpdateValues<TTable>;\n\n whereIndex(indexName: string, condition?: unknown): this {\n this.#indexName = indexName;\n this.#condition = condition;\n return this;\n }\n\n set(values: TableToUpdateValues<TTable>): this {\n this.#setValues = values;\n return this;\n }\n\n now() {\n return dbNow();\n }\n\n interval(input: DbIntervalInput): DbInterval {\n return dbInterval(input);\n }\n\n getConfig() {\n return {\n indexName: this.#indexName,\n condition: this.#condition,\n setValues: this.#setValues,\n };\n }\n}\n\nconst hasIdField = (record: unknown): record is { id: string | FragnoId } =>\n record !== null && typeof record === \"object\" && \"id\" in record;\n\nexport type InMemoryUowConfig = UnitOfWorkConfig;\n\nexport class InMemoryAdapter implements DatabaseAdapter<InMemoryUowConfig> {\n readonly options: ResolvedInMemoryAdapterOptions;\n readonly namingStrategy: SqlNamingStrategy;\n\n #contextStorage: RequestContextStorage<DatabaseContextStorage>;\n #store = createInMemoryStore();\n #schemaNamespaceMap = new WeakMap<AnySchema, string | null>();\n #schemaByNamespace = new Map<string, { schema: AnySchema; namespace: string | null }>();\n\n constructor(options: InMemoryAdapterOptions = {}) {\n this.options = resolveInMemoryAdapterOptions(options);\n this.namingStrategy = options.namingStrategy ?? suffixNamingStrategy;\n this.#contextStorage = new RequestContextStorage();\n this.options.outbox = getOutboxConfigForAdapter(this);\n }\n\n get [fragnoDatabaseAdapterNameFakeSymbol](): string {\n return \"in-memory\";\n }\n\n get [fragnoDatabaseAdapterVersionFakeSymbol](): number {\n return 0;\n }\n\n get contextStorage(): RequestContextStorage<DatabaseContextStorage> {\n return this.#contextStorage;\n }\n\n async getSchemaVersion(_namespace: string): Promise<string | undefined> {\n return undefined;\n }\n\n async isConnectionHealthy(): Promise<boolean> {\n return true;\n }\n\n async close(): Promise<void> {\n return;\n }\n\n async reset(): Promise<void> {\n this.#store.namespaces.clear();\n for (const [namespaceKey, { schema, namespace }] of this.#schemaByNamespace) {\n const resolver = createNamingResolver(schema, namespace, this.namingStrategy);\n ensureNamespaceStore(this.#store, namespaceKey, schema, resolver);\n }\n }\n\n createQueryEngine<T extends AnySchema>(\n schema: T,\n namespace: string | null,\n ): SimpleQueryInterface<T, InMemoryUowConfig> {\n this.#schemaNamespaceMap.set(schema, namespace);\n const namespaceKey = namespace ?? schema.name;\n this.#schemaByNamespace.set(namespaceKey, { schema, namespace });\n const resolverFactory = (schemaForResolver: AnySchema, namespaceForResolver: string | null) =>\n createNamingResolver(schemaForResolver, namespaceForResolver, this.namingStrategy);\n const resolver = resolverFactory(schema, namespace);\n ensureNamespaceStore(this.#store, namespaceKey, schema, resolver);\n\n const compiler = createInMemoryUowCompiler();\n const executor = createInMemoryUowExecutor(\n this.#store,\n this.options,\n resolverFactory,\n this.#schemaByNamespace,\n );\n const decoder = new InMemoryUowDecoder(resolverFactory);\n\n const createBaseUow = (opts?: { name?: string; config?: UnitOfWorkConfig }) =>\n new UnitOfWork(\n compiler,\n executor,\n decoder,\n opts?.name,\n opts?.config,\n this.#schemaNamespaceMap,\n );\n\n const createUow = (opts?: { name?: string; config?: UnitOfWorkConfig }) =>\n createBaseUow(opts).forSchema(schema);\n\n async function find<TableName extends keyof T[\"tables\"] & string, const TBuilderResult>(\n tableName: TableName,\n builderFn: (builder: Omit<FindBuilder<T[\"tables\"][TableName]>, \"build\">) => TBuilderResult,\n ): Promise<\n SelectResult<\n T[\"tables\"][TableName],\n ExtractJoinOut<TBuilderResult>,\n Extract<ExtractSelect<TBuilderResult>, SelectClause<T[\"tables\"][TableName]>>\n >[]\n >;\n async function find<TableName extends keyof T[\"tables\"] & string>(\n tableName: TableName,\n ): Promise<SelectResult<T[\"tables\"][TableName], {}, true>[]>;\n async function find<TableName extends keyof T[\"tables\"] & string, const TBuilderResult>(\n tableName: TableName,\n builderFn?: (builder: Omit<FindBuilder<T[\"tables\"][TableName]>, \"build\">) => TBuilderResult,\n ): Promise<\n SelectResult<\n T[\"tables\"][TableName],\n ExtractJoinOut<TBuilderResult>,\n Extract<ExtractSelect<TBuilderResult>, SelectClause<T[\"tables\"][TableName]>>\n >[]\n > {\n const uow = createUow();\n if (builderFn) {\n uow.find(tableName, builderFn);\n } else {\n uow.find(tableName);\n }\n const [result]: unknown[][] = await uow.executeRetrieve();\n return (result ?? []) as SelectResult<\n T[\"tables\"][TableName],\n ExtractJoinOut<TBuilderResult>,\n Extract<ExtractSelect<TBuilderResult>, SelectClause<T[\"tables\"][TableName]>>\n >[];\n }\n\n async function findWithCursor<\n TableName extends keyof T[\"tables\"] & string,\n const TBuilderResult,\n >(\n tableName: TableName,\n builderFn: (builder: Omit<FindBuilder<T[\"tables\"][TableName]>, \"build\">) => TBuilderResult,\n ): Promise<\n CursorResult<\n SelectResult<\n T[\"tables\"][TableName],\n ExtractJoinOut<TBuilderResult>,\n Extract<ExtractSelect<TBuilderResult>, SelectClause<T[\"tables\"][TableName]>>\n >\n >\n > {\n const uow = createUow().findWithCursor(tableName, builderFn);\n const [result] = await uow.executeRetrieve();\n return result as CursorResult<\n SelectResult<\n T[\"tables\"][TableName],\n ExtractJoinOut<TBuilderResult>,\n Extract<ExtractSelect<TBuilderResult>, SelectClause<T[\"tables\"][TableName]>>\n >\n >;\n }\n\n async function findFirst<TableName extends keyof T[\"tables\"] & string, const TBuilderResult>(\n tableName: TableName,\n builderFn: (builder: Omit<FindBuilder<T[\"tables\"][TableName]>, \"build\">) => TBuilderResult,\n ): Promise<SelectResult<\n T[\"tables\"][TableName],\n ExtractJoinOut<TBuilderResult>,\n Extract<ExtractSelect<TBuilderResult>, SelectClause<T[\"tables\"][TableName]>>\n > | null>;\n async function findFirst<TableName extends keyof T[\"tables\"] & string>(\n tableName: TableName,\n ): Promise<SelectResult<T[\"tables\"][TableName], {}, true> | null>;\n async function findFirst<TableName extends keyof T[\"tables\"] & string, const TBuilderResult>(\n tableName: TableName,\n builderFn?: (builder: Omit<FindBuilder<T[\"tables\"][TableName]>, \"build\">) => TBuilderResult,\n ): Promise<SelectResult<\n T[\"tables\"][TableName],\n ExtractJoinOut<TBuilderResult>,\n Extract<ExtractSelect<TBuilderResult>, SelectClause<T[\"tables\"][TableName]>>\n > | null> {\n const uow = createUow();\n if (builderFn) {\n uow.find(tableName, (b) => {\n builderFn(b);\n return b.pageSize(1);\n });\n } else {\n uow.find(tableName, (b) => b.whereIndex(\"primary\").pageSize(1));\n }\n const [result]: unknown[][] = await uow.executeRetrieve();\n return (result?.[0] ?? null) as SelectResult<\n T[\"tables\"][TableName],\n ExtractJoinOut<TBuilderResult>,\n Extract<ExtractSelect<TBuilderResult>, SelectClause<T[\"tables\"][TableName]>>\n > | null;\n }\n\n const queryEngine: SimpleQueryInterface<T, InMemoryUowConfig> = {\n now: async () => this.options.clock.now(),\n find,\n findWithCursor,\n findFirst,\n\n async create(tableName, values) {\n const uow = createUow();\n uow.create(tableName, values);\n const { success } = await uow.executeMutations();\n if (!success) {\n throw new Error(\"Failed to create record\");\n }\n\n const createdId = uow.getCreatedIds()[0];\n if (!createdId) {\n throw new Error(\"Failed to get created ID\");\n }\n return createdId;\n },\n\n async createMany(tableName, valuesArray) {\n const uow = createUow();\n for (const values of valuesArray) {\n uow.create(tableName, values);\n }\n const { success } = await uow.executeMutations();\n if (!success) {\n throw new Error(\"Failed to create records\");\n }\n return uow.getCreatedIds();\n },\n\n async update(tableName, id, builderFn) {\n const uow = createUow();\n uow.update(tableName, id, builderFn);\n const { success } = await uow.executeMutations();\n if (!success) {\n throw new Error(\"Failed to update record (version conflict or record not found)\");\n }\n },\n\n async updateMany(tableName, builderFn) {\n const table = schema.tables[tableName];\n if (!table) {\n throw new Error(`Table ${tableName} not found in schema`);\n }\n\n const specialBuilder = new UpdateManySpecialBuilder<typeof table>();\n builderFn(specialBuilder);\n const { indexName, condition, setValues } = specialBuilder.getConfig();\n\n if (!indexName) {\n throw new Error(\"whereIndex() must be called in updateMany\");\n }\n if (!setValues) {\n throw new Error(\"set() must be called in updateMany\");\n }\n\n const findUow = createUow();\n findUow.find(tableName, (b) => {\n if (condition !== undefined && condition !== null) {\n return b.whereIndex(indexName as never, condition as never);\n }\n return b.whereIndex(indexName as never);\n });\n const [records]: unknown[][] = await findUow.executeRetrieve();\n\n if (!records || records.length === 0) {\n return;\n }\n\n const updateUow = createUow();\n for (const record of records) {\n if (!hasIdField(record)) {\n throw new Error(\"Record missing id field\");\n }\n updateUow.update(tableName, record.id, (b) => b.set(setValues).check());\n }\n const { success } = await updateUow.executeMutations();\n if (!success) {\n throw new Error(\"Failed to update records (version conflict)\");\n }\n },\n\n async delete(tableName, id, builderFn?) {\n const uow = createUow();\n uow.delete(tableName, id, builderFn);\n const { success } = await uow.executeMutations();\n if (!success) {\n throw new Error(\"Failed to delete record (version conflict or record not found)\");\n }\n },\n\n async deleteMany(tableName, builderFn) {\n const findUow = createUow();\n findUow.find(tableName, builderFn);\n const [records]: unknown[][] = await findUow.executeRetrieve();\n\n if (!records || records.length === 0) {\n return;\n }\n\n const deleteUow = createUow();\n for (const record of records) {\n if (!hasIdField(record)) {\n throw new Error(\"Record missing id field\");\n }\n deleteUow.delete(tableName, record.id);\n }\n const { success } = await deleteUow.executeMutations();\n if (!success) {\n throw new Error(\"Failed to delete records (version conflict)\");\n }\n },\n\n createUnitOfWork(name, config) {\n return createUow({ name, config });\n },\n\n createBaseUnitOfWork(name, config) {\n return createBaseUow({ name, config });\n },\n };\n return queryEngine;\n }\n}\n"],"mappings":"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"}