@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,6 +1,6 @@
1
- import type { AnyTable } from "../../../schema/create";
2
- import type { AnySelectClause } from "../../../query/simple-query-interface";
3
1
  import type { NamingResolver } from "../../../naming/sql-naming";
2
+ import type { AnySelectClause } from "../../../query/simple-query-interface";
3
+ import type { AnyTable } from "../../../schema/create";
4
4
 
5
5
  /**
6
6
  * Maps a select clause to SQL column names with optional aliases.
@@ -1,16 +1,18 @@
1
1
  import { describe, test, expect } from "vitest";
2
- import { Kysely, SqliteDialect } from "kysely";
2
+
3
3
  import Database from "better-sqlite3";
4
- import { schema, column, idColumn, referenceColumn } from "../../../schema/create";
4
+ import { Kysely, SqliteDialect } from "kysely";
5
+
5
6
  import { createNamingResolver, type SqlNamingStrategy } from "../../../naming/sql-naming";
6
- import { PostgreSQLQueryCompiler } from "./dialect/postgres";
7
- import { MySQLQueryCompiler } from "./dialect/mysql";
8
- import { SQLiteQueryCompiler } from "./dialect/sqlite";
7
+ import { schema, column, idColumn, referenceColumn } from "../../../schema/create";
9
8
  import {
10
9
  BetterSQLite3DriverConfig,
11
10
  NodePostgresDriverConfig,
12
11
  MySQL2DriverConfig,
13
12
  } from "../driver-config";
13
+ import { MySQLQueryCompiler } from "./dialect/mysql";
14
+ import { PostgreSQLQueryCompiler } from "./dialect/postgres";
15
+ import { SQLiteQueryCompiler } from "./dialect/sqlite";
14
16
 
15
17
  // Test schema
16
18
  const testSchema = schema("test", (s) => {
@@ -80,6 +82,23 @@ describe("SQLQueryCompiler", () => {
80
82
  );
81
83
  });
82
84
 
85
+ test("compileFindMany includes id when read tracking is enabled", () => {
86
+ const db = new Kysely({
87
+ dialect: new SqliteDialect({ database: new Database(":memory:") }),
88
+ });
89
+ const compiler = new PostgreSQLQueryCompiler(db, new NodePostgresDriverConfig());
90
+
91
+ const query = compiler.compileFindMany(testSchema.tables.users, {
92
+ select: ["email"],
93
+ limit: 10,
94
+ readTracking: true,
95
+ });
96
+
97
+ expect(query.sql).toMatchInlineSnapshot(
98
+ `"select "users"."email" as "email", "users"."id" as "id", "users"."_internalId" as "_internalId", "users"."_version" as "_version" from "users" limit ?"`,
99
+ );
100
+ });
101
+
83
102
  test("compileFindMany with orderBy", () => {
84
103
  const db = new Kysely({
85
104
  dialect: new SqliteDialect({ database: new Database(":memory:") }),
@@ -8,15 +8,16 @@ import type {
8
8
  } from "kysely";
9
9
  import { sql } from "kysely";
10
10
  import type { SqlBool } from "kysely";
11
- import type { AnyColumn, AnyTable } from "../../../schema/create";
11
+
12
+ import type { NamingResolver } from "../../../naming/sql-naming";
12
13
  import type { Condition } from "../../../query/condition-builder";
14
+ import type { CompiledJoin } from "../../../query/orm/orm";
15
+ import type { AnyColumn, AnyTable } from "../../../schema/create";
13
16
  import type { DriverConfig, SupportedDatabase } from "../driver-config";
14
17
  import type { SQLiteStorageMode } from "../sqlite-storage";
15
- import type { NamingResolver } from "../../../naming/sql-naming";
16
- import { buildWhere, fullSQLName } from "./where-builder";
17
- import { mapSelect, extendSelect } from "./select-builder";
18
- import type { CompiledJoin } from "../../../query/orm/orm";
19
18
  import { UnitOfWorkEncoder } from "../uow-encoder";
19
+ import { mapSelect, extendSelect } from "./select-builder";
20
+ import { buildWhere, fullSQLName } from "./where-builder";
20
21
 
21
22
  /**
22
23
  * Type helpers for Kysely query builders.
@@ -45,12 +46,13 @@ export type AnyInsertQueryBuilder<O = any> = InsertQueryBuilder<any, any, O>;
45
46
  * Options for compiling a find operation
46
47
  */
47
48
  export interface FindManyCompilerOptions {
48
- select: true | string[];
49
+ select: true | readonly string[];
49
50
  where?: Condition;
50
51
  orderBy?: [AnyColumn, "asc" | "desc"][];
51
52
  limit?: number;
52
53
  offset?: number;
53
54
  join?: CompiledJoin[];
55
+ readTracking?: boolean;
54
56
  }
55
57
 
56
58
  /**
@@ -85,6 +87,11 @@ export interface DeleteCompilerOptions {
85
87
  returning?: boolean;
86
88
  }
87
89
 
90
+ export type JoinAliasInfo = {
91
+ table: AnyTable;
92
+ alias: string;
93
+ };
94
+
88
95
  /**
89
96
  * Abstract base class for SQL query compilation.
90
97
  *
@@ -147,7 +154,12 @@ export abstract class SQLQueryCompiler {
147
154
  /**
148
155
  * Build WHERE clause from a condition tree.
149
156
  */
150
- protected buildWhereClause(condition: Condition, eb: AnyExpressionBuilder, table: AnyTable) {
157
+ protected buildWhereClause(
158
+ condition: Condition,
159
+ eb: AnyExpressionBuilder,
160
+ table: AnyTable,
161
+ tableAlias?: string,
162
+ ) {
151
163
  return buildWhere(
152
164
  condition,
153
165
  eb,
@@ -155,6 +167,7 @@ export abstract class SQLQueryCompiler {
155
167
  this.sqliteStorageMode,
156
168
  this.resolver,
157
169
  table,
170
+ tableAlias,
158
171
  );
159
172
  }
160
173
 
@@ -168,6 +181,8 @@ export abstract class SQLQueryCompiler {
168
181
  parentTableName: string,
169
182
  mappedSelect: string[],
170
183
  parentPath: string = "",
184
+ aliasCollector?: JoinAliasInfo[],
185
+ readTracking?: boolean,
171
186
  ): AnySelectQueryBuilder<O> {
172
187
  let result = query;
173
188
 
@@ -183,10 +198,17 @@ export abstract class SQLQueryCompiler {
183
198
  const fullPath = parentPath ? `${parentPath}:${relation.name}` : relation.name;
184
199
  // SQL table alias uses underscores (e.g., "author_inviter")
185
200
  const joinName = fullPath.replace(/:/g, "_");
201
+ if (aliasCollector) {
202
+ aliasCollector.push({ table: targetTable, alias: joinName });
203
+ }
186
204
 
187
- // Update select
205
+ const joinSelectBuilder = extendSelect(joinOptions.select);
206
+ if (readTracking) {
207
+ joinSelectBuilder.extend(targetTable.getIdColumn().name);
208
+ }
209
+ const compiledJoinSelect = joinSelectBuilder.compile();
188
210
  mappedSelect.push(
189
- ...mapSelect(joinOptions.select, targetTable, this.resolver, {
211
+ ...mapSelect(compiledJoinSelect.result, targetTable, this.resolver, {
190
212
  relation: fullPath, // Use full path with colons for column aliases
191
213
  tableName: joinName, // Use underscore version for table name
192
214
  }),
@@ -196,6 +218,10 @@ export abstract class SQLQueryCompiler {
196
218
  b.on((eb) => {
197
219
  const conditions = [];
198
220
  for (const [left, right] of relation.on) {
221
+ const leftCol = parentTable.columns[left];
222
+ const actualLeft =
223
+ leftCol?.role === "external-id" ? parentTable.getInternalIdColumn().name : left;
224
+ const actualLeftCol = parentTable.columns[actualLeft];
199
225
  // Foreign keys always use internal IDs
200
226
  // If the relation references an external ID column (any name), translate to "_internalId"
201
227
  const rightCol = targetTable.columns[right];
@@ -205,8 +231,11 @@ export abstract class SQLQueryCompiler {
205
231
  eb(
206
232
  `${parentTableName}.${
207
233
  this.resolver
208
- ? this.resolver.getColumnName(parentTable.name, parentTable.columns[left].name)
209
- : parentTable.columns[left].name
234
+ ? this.resolver.getColumnName(
235
+ parentTable.name,
236
+ actualLeftCol ? actualLeftCol.name : parentTable.columns[left].name,
237
+ )
238
+ : (actualLeftCol ?? parentTable.columns[left]).name
210
239
  }`,
211
240
  "=",
212
241
  eb.ref(
@@ -224,7 +253,7 @@ export abstract class SQLQueryCompiler {
224
253
  }
225
254
 
226
255
  if (joinOptions.where) {
227
- conditions.push(this.buildWhereClause(joinOptions.where, eb, targetTable));
256
+ conditions.push(this.buildWhereClause(joinOptions.where, eb, targetTable, joinName));
228
257
  }
229
258
 
230
259
  return eb.and(conditions);
@@ -240,6 +269,8 @@ export abstract class SQLQueryCompiler {
240
269
  joinName,
241
270
  mappedSelect,
242
271
  fullPath,
272
+ aliasCollector,
273
+ readTracking,
243
274
  );
244
275
  }
245
276
  }
@@ -247,6 +278,33 @@ export abstract class SQLQueryCompiler {
247
278
  return result;
248
279
  }
249
280
 
281
+ /**
282
+ * Build a select query with joins applied, returning a list of table aliases used.
283
+ * Intended for conflict checks that need to mirror the join tree from queries.
284
+ */
285
+ buildJoinQuery(
286
+ table: AnyTable,
287
+ options: { where?: Condition; join?: CompiledJoin[] },
288
+ ): {
289
+ query: AnySelectQueryBuilder;
290
+ aliases: JoinAliasInfo[];
291
+ } {
292
+ const tableName = this.getTableName(table);
293
+ let query = this.db.selectFrom(tableName);
294
+ const aliases: JoinAliasInfo[] = [{ table, alias: tableName }];
295
+
296
+ if (options.where) {
297
+ query = query.where((eb) => this.buildWhereClause(options.where!, eb, table));
298
+ }
299
+
300
+ if (options.join && options.join.length > 0) {
301
+ const mappedSelect: string[] = [];
302
+ query = this.processJoins(query, options.join, table, tableName, mappedSelect, "", aliases);
303
+ }
304
+
305
+ return { query, aliases };
306
+ }
307
+
250
308
  /**
251
309
  * Compile a COUNT query.
252
310
  */
@@ -293,11 +351,23 @@ export abstract class SQLQueryCompiler {
293
351
 
294
352
  // Build SELECT with joins
295
353
  const selectBuilder = extendSelect(options.select);
354
+ if (options.readTracking) {
355
+ selectBuilder.extend(table.getIdColumn().name);
356
+ }
296
357
  const mappedSelect: string[] = [];
297
358
 
298
359
  // Process joins if provided
299
360
  if (options.join && options.join.length > 0) {
300
- query = this.processJoins(query, options.join, table, this.getTableName(table), mappedSelect);
361
+ query = this.processJoins(
362
+ query,
363
+ options.join,
364
+ table,
365
+ this.getTableName(table),
366
+ mappedSelect,
367
+ "",
368
+ undefined,
369
+ options.readTracking,
370
+ );
301
371
  }
302
372
 
303
373
  const compiledSelect = selectBuilder.compile();
@@ -1,11 +1,13 @@
1
- import { Kysely, PostgresDialect } from "kysely";
2
1
  import { beforeAll, describe, expect, it } from "vitest";
3
- import { column, idColumn, referenceColumn, schema } from "../../../schema/create";
4
- import { fullSQLName, buildWhere, processReferenceSubqueries } from "./where-builder";
2
+
3
+ import { Kysely, PostgresDialect } from "kysely";
4
+
5
+ import { createNamingResolver, type SqlNamingStrategy } from "../../../naming/sql-naming";
6
+ import { dbNow } from "../../../query/db-now";
5
7
  import { ReferenceSubquery } from "../../../query/value-encoding";
8
+ import { column, idColumn, referenceColumn, schema } from "../../../schema/create";
6
9
  import { BetterSQLite3DriverConfig, NodePostgresDriverConfig } from "../driver-config";
7
- import { dbNow } from "../../../query/db-now";
8
- import { createNamingResolver, type SqlNamingStrategy } from "../../../naming/sql-naming";
10
+ import { fullSQLName, buildWhere, processReferenceSubqueries } from "./where-builder";
9
11
 
10
12
  describe("where-builder", () => {
11
13
  const testSchema = schema("test", (s) => {
@@ -1,4 +1,10 @@
1
1
  import { sql, type BinaryOperator } from "kysely";
2
+
3
+ import type { NamingResolver } from "../../../naming/sql-naming";
4
+ import type { Condition } from "../../../query/condition-builder";
5
+ import { getDbNowOffsetMs, isDbNow } from "../../../query/db-now";
6
+ import { createSQLSerializer } from "../../../query/serialize/create-sql-serializer";
7
+ import { ReferenceSubquery, resolveFragnoIdValue } from "../../../query/value-encoding";
2
8
  import {
3
9
  type AnyColumn,
4
10
  type AnyTable,
@@ -6,13 +12,9 @@ import {
6
12
  FragnoId,
7
13
  FragnoReference,
8
14
  } from "../../../schema/create";
9
- import type { Condition } from "../../../query/condition-builder";
10
- import { createSQLSerializer } from "../../../query/serialize/create-sql-serializer";
11
- import type { NamingResolver } from "../../../naming/sql-naming";
12
15
  import type { DriverConfig } from "../driver-config";
13
- import { sqliteStorageDefault, type SQLiteStorageMode } from "../sqlite-storage";
14
- import { ReferenceSubquery, resolveFragnoIdValue } from "../../../query/value-encoding";
15
- import { isDbNow } from "../../../query/db-now";
16
+ import type { SQLiteStorageMode } from "../sqlite-storage";
17
+ import { buildDbNowSql } from "./db-now-sql";
16
18
  import type { AnyKysely, AnyExpressionBuilder, AnyExpressionWrapper } from "./sql-query-compiler";
17
19
 
18
20
  /**
@@ -29,6 +31,21 @@ export function fullSQLName(column: AnyColumn, resolver?: NamingResolver): strin
29
31
  return `${tableName}.${columnName}`;
30
32
  }
31
33
 
34
+ function fullSQLNameWithAlias(
35
+ column: AnyColumn,
36
+ resolver?: NamingResolver,
37
+ table?: AnyTable,
38
+ tableAlias?: string,
39
+ ): string {
40
+ if (table && tableAlias && column.tableName === table.name) {
41
+ const columnName = resolver
42
+ ? resolver.getColumnName(column.tableName, column.name)
43
+ : column.name;
44
+ return `${tableAlias}.${columnName}`;
45
+ }
46
+ return fullSQLName(column, resolver);
47
+ }
48
+
32
49
  /**
33
50
  * Builds a WHERE clause expression from a Condition tree.
34
51
  *
@@ -51,6 +68,7 @@ export function buildWhere(
51
68
  sqliteStorageMode?: SQLiteStorageMode,
52
69
  resolver?: NamingResolver,
53
70
  table?: AnyTable,
71
+ tableAlias?: string,
54
72
  ): AnyExpressionWrapper {
55
73
  const serializer = createSQLSerializer(driverConfig, sqliteStorageMode);
56
74
 
@@ -61,18 +79,12 @@ export function buildWhere(
61
79
 
62
80
  if (!(val instanceof Column)) {
63
81
  if (isDbNow(val)) {
64
- if (driverConfig.databaseType === "sqlite") {
65
- const storageMode = sqliteStorageMode ?? sqliteStorageDefault;
66
- const storage =
67
- left.type === "date" ? storageMode.dateStorage : storageMode.timestampStorage;
68
- if ((left.type === "timestamp" || left.type === "date") && storage === "epoch-ms") {
69
- val = sql`(cast((julianday('now') - 2440587.5)*86400000 as integer))`;
70
- } else {
71
- val = sql`CURRENT_TIMESTAMP`;
72
- }
73
- } else {
74
- val = sql`CURRENT_TIMESTAMP`;
75
- }
82
+ val = buildDbNowSql({
83
+ driverConfig,
84
+ columnType: left.type,
85
+ offsetMs: getDbNowOffsetMs(val),
86
+ sqliteStorageMode,
87
+ });
76
88
  } else if (left.role === "reference" && table) {
77
89
  // Handle reference columns specially
78
90
  if (typeof val === "string") {
@@ -155,67 +167,74 @@ export function buildWhere(
155
167
  v = "like";
156
168
  rhs =
157
169
  val instanceof Column
158
- ? sql`concat('%', ${eb.ref(fullSQLName(val, resolver))}, '%')`
170
+ ? sql`concat('%', ${eb.ref(fullSQLNameWithAlias(val, resolver, table, tableAlias))}, '%')`
159
171
  : `%${val}%`;
160
172
  break;
161
173
  case "not contains":
162
174
  v = "not like";
163
175
  rhs =
164
176
  val instanceof Column
165
- ? sql`concat('%', ${eb.ref(fullSQLName(val, resolver))}, '%')`
177
+ ? sql`concat('%', ${eb.ref(fullSQLNameWithAlias(val, resolver, table, tableAlias))}, '%')`
166
178
  : `%${val}%`;
167
179
  break;
168
180
  case "starts with":
169
181
  v = "like";
170
182
  rhs =
171
183
  val instanceof Column
172
- ? sql`concat(${eb.ref(fullSQLName(val, resolver))}, '%')`
184
+ ? sql`concat(${eb.ref(fullSQLNameWithAlias(val, resolver, table, tableAlias))}, '%')`
173
185
  : `${val}%`;
174
186
  break;
175
187
  case "not starts with":
176
188
  v = "not like";
177
189
  rhs =
178
190
  val instanceof Column
179
- ? sql`concat(${eb.ref(fullSQLName(val, resolver))}, '%')`
191
+ ? sql`concat(${eb.ref(fullSQLNameWithAlias(val, resolver, table, tableAlias))}, '%')`
180
192
  : `${val}%`;
181
193
  break;
182
194
  case "ends with":
183
195
  v = "like";
184
196
  rhs =
185
197
  val instanceof Column
186
- ? sql`concat('%', ${eb.ref(fullSQLName(val, resolver))})`
198
+ ? sql`concat('%', ${eb.ref(fullSQLNameWithAlias(val, resolver, table, tableAlias))})`
187
199
  : `%${val}`;
188
200
  break;
189
201
  case "not ends with":
190
202
  v = "not like";
191
203
  rhs =
192
204
  val instanceof Column
193
- ? sql`concat('%', ${eb.ref(fullSQLName(val, resolver))})`
205
+ ? sql`concat('%', ${eb.ref(fullSQLNameWithAlias(val, resolver, table, tableAlias))})`
194
206
  : `%${val}`;
195
207
  break;
196
208
  default:
197
209
  v = op;
198
- rhs = val instanceof Column ? eb.ref(fullSQLName(val, resolver)) : val;
210
+ rhs =
211
+ val instanceof Column
212
+ ? eb.ref(fullSQLNameWithAlias(val, resolver, table, tableAlias))
213
+ : val;
199
214
  }
200
215
 
201
- return eb(fullSQLName(left, resolver), v, rhs);
216
+ return eb(fullSQLNameWithAlias(left, resolver, table, tableAlias), v, rhs);
202
217
  }
203
218
 
204
219
  // Nested conditions
205
220
  if (condition.type === "and") {
206
221
  return eb.and(
207
222
  condition.items.map((v) =>
208
- buildWhere(v, eb, driverConfig, sqliteStorageMode, resolver, table),
223
+ buildWhere(v, eb, driverConfig, sqliteStorageMode, resolver, table, tableAlias),
209
224
  ),
210
225
  );
211
226
  }
212
227
 
213
228
  if (condition.type === "not") {
214
- return eb.not(buildWhere(condition.item, eb, driverConfig, sqliteStorageMode, resolver, table));
229
+ return eb.not(
230
+ buildWhere(condition.item, eb, driverConfig, sqliteStorageMode, resolver, table, tableAlias),
231
+ );
215
232
  }
216
233
 
217
234
  return eb.or(
218
- condition.items.map((v) => buildWhere(v, eb, driverConfig, sqliteStorageMode, resolver, table)),
235
+ condition.items.map((v) =>
236
+ buildWhere(v, eb, driverConfig, sqliteStorageMode, resolver, table, tableAlias),
237
+ ),
219
238
  );
220
239
  }
221
240
 
@@ -1,17 +1,12 @@
1
- import { KyselyPGlite } from "kysely-pglite";
2
1
  import { beforeAll, describe, expect, expectTypeOf, it } from "vitest";
3
- import { SqlAdapter } from "./generic-sql-adapter";
4
- import {
5
- column,
6
- idColumn,
7
- referenceColumn,
8
- schema,
9
- type FragnoId,
10
- type FragnoReference,
11
- } from "../../schema/create";
2
+
3
+ import { KyselyPGlite } from "kysely-pglite";
4
+
5
+ import { internalSchema } from "../../fragments/internal-fragment";
12
6
  import { Cursor } from "../../query/cursor";
7
+ import { column, idColumn, referenceColumn, schema, type FragnoId } from "../../schema/create";
13
8
  import { PGLiteDriverConfig } from "./driver-config";
14
- import { internalSchema } from "../../fragments/internal-fragment";
9
+ import { SqlAdapter } from "./generic-sql-adapter";
15
10
 
16
11
  describe("SqlAdapter PGLite", () => {
17
12
  const testSchema = schema("test", (s) => {
@@ -478,7 +473,6 @@ describe("SqlAdapter PGLite", () => {
478
473
  type PostTag = Prettify<InferArrayElement<typeof postTags>>;
479
474
  type Tag = Prettify<RemoveIndex<PostTag["tag"]>>;
480
475
  expectTypeOf<Tag>().toEqualTypeOf<{
481
- id: FragnoId;
482
476
  name: string;
483
477
  } | null>();
484
478
 
@@ -487,10 +481,7 @@ describe("SqlAdapter PGLite", () => {
487
481
  expect(typeScriptPosts).toHaveLength(1);
488
482
  type Post = Prettify<(typeof typeScriptPosts)[number]["post"]>;
489
483
  expectTypeOf<Post>().toEqualTypeOf<{
490
- id: FragnoId;
491
- user_id: FragnoReference;
492
484
  title: string;
493
- content: string;
494
485
  } | null>();
495
486
  expect(typeScriptPosts[0]!.post!.title).toBe("TypeScript Tips");
496
487
 
@@ -1,12 +1,15 @@
1
- import { PGlite } from "@electric-sql/pglite";
2
- import { KyselyPGlite } from "kysely-pglite";
3
1
  import { beforeAll, describe, expect, expectTypeOf, it } from "vitest";
4
- import { SqlAdapter } from "./generic-sql-adapter";
5
- import { column, idColumn, referenceColumn, schema } from "../../schema/create";
6
- import { Cursor } from "../../query/cursor";
7
- import { PGLiteDriverConfig } from "./driver-config";
2
+
3
+ import { KyselyPGlite } from "kysely-pglite";
4
+
5
+ import { PGlite } from "@electric-sql/pglite";
6
+
8
7
  import { internalSchema } from "../../fragments/internal-fragment";
8
+ import { Cursor } from "../../query/cursor";
9
+ import { column, idColumn, referenceColumn, schema } from "../../schema/create";
9
10
  import type { CompiledQuery } from "../../sql-driver/sql-driver";
11
+ import { PGLiteDriverConfig } from "./driver-config";
12
+ import { SqlAdapter } from "./generic-sql-adapter";
10
13
 
11
14
  describe("SqlAdapter PGLite", () => {
12
15
  const testSchema = schema("test", (s) => {
@@ -16,7 +19,8 @@ describe("SqlAdapter PGLite", () => {
16
19
  .addColumn("id", idColumn())
17
20
  .addColumn("name", column("string"))
18
21
  .addColumn("age", column("integer").nullable())
19
- .createIndex("name_idx", ["name"]);
22
+ .createIndex("name_idx", ["name"])
23
+ .createIndex("name_id_idx", ["name", "id"]);
20
24
  })
21
25
  .addTable("emails", (t) => {
22
26
  return t
@@ -304,6 +308,47 @@ describe("SqlAdapter PGLite", () => {
304
308
  expect(emptyPage.cursor).toBeUndefined();
305
309
  });
306
310
 
311
+ it("should support composite cursor pagination with findWithCursor()", async () => {
312
+ const queryEngine = adapter.createQueryEngine(testSchema, "namespace");
313
+ const nameValue = "SqlAdapter PGLite Composite Cursor";
314
+
315
+ const createUow = queryEngine.createUnitOfWork("create-composite-cursor-users");
316
+ for (let i = 0; i < 5; i += 1) {
317
+ createUow.create("users", { name: nameValue, age: 50 + i });
318
+ }
319
+ await createUow.executeMutations();
320
+
321
+ const all = await queryEngine.find("users", (b) =>
322
+ b
323
+ .whereIndex("name_id_idx", (eb) => eb("name", "=", nameValue))
324
+ .orderByIndex("name_id_idx", "asc"),
325
+ );
326
+
327
+ const firstPage = await queryEngine.findWithCursor("users", (b) =>
328
+ b
329
+ .whereIndex("name_id_idx", (eb) => eb("name", "=", nameValue))
330
+ .orderByIndex("name_id_idx", "asc")
331
+ .pageSize(2),
332
+ );
333
+
334
+ const secondPage = await queryEngine.findWithCursor("users", (b) =>
335
+ b
336
+ .whereIndex("name_id_idx", (eb) => eb("name", "=", nameValue))
337
+ .after(firstPage.cursor!)
338
+ .orderByIndex("name_id_idx", "asc")
339
+ .pageSize(2),
340
+ );
341
+
342
+ const ids = (rows: { id: { externalId: string } }[]) => rows.map((row) => row.id.externalId);
343
+
344
+ expect(all.length).toBeGreaterThanOrEqual(5);
345
+ expect(firstPage.items).toHaveLength(2);
346
+ expect(firstPage.cursor).toBeInstanceOf(Cursor);
347
+ expect(firstPage.hasNextPage).toBe(true);
348
+ expect(ids(firstPage.items)).toEqual(ids(all).slice(0, 2));
349
+ expect(ids([...firstPage.items, ...secondPage.items])).toEqual(ids(all).slice(0, 4));
350
+ });
351
+
307
352
  it("should support findWithCursor() in Unit of Work", async () => {
308
353
  const queryEngine = adapter.createQueryEngine(testSchema, "namespace");
309
354
  const prefix = "SqlAdapter PGLite UOW Cursor";
@@ -1,12 +1,15 @@
1
- import { PGlite } from "@electric-sql/pglite";
2
- import { KyselyPGlite } from "kysely-pglite";
3
- import { SqlAdapter } from "./generic-sql-adapter";
4
1
  import { beforeAll, describe, expect, expectTypeOf, it } from "vitest";
5
- import { column, idColumn, referenceColumn, schema } from "../../schema/create";
2
+
3
+ import { KyselyPGlite } from "kysely-pglite";
4
+
5
+ import { PGlite } from "@electric-sql/pglite";
6
+
7
+ import { internalSchema } from "../../fragments/internal-fragment";
6
8
  import { Cursor } from "../../query/cursor";
7
- import { PGLiteDriverConfig } from "./driver-config";
9
+ import { column, idColumn, referenceColumn, schema } from "../../schema/create";
8
10
  import type { CompiledQuery } from "../../sql-driver/sql-driver";
9
- import { internalSchema } from "../../fragments/internal-fragment";
11
+ import { PGLiteDriverConfig } from "./driver-config";
12
+ import { SqlAdapter } from "./generic-sql-adapter";
10
13
 
11
14
  describe("SqlAdapter PGLite", () => {
12
15
  let pgliteDatabase: PGlite;