@fragno-dev/db 0.2.2 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (587) hide show
  1. package/.turbo/turbo-build.log +404 -175
  2. package/CHANGELOG.md +109 -0
  3. package/README.md +54 -9
  4. package/dist/adapters/adapters.d.ts +23 -21
  5. package/dist/adapters/adapters.d.ts.map +1 -1
  6. package/dist/adapters/adapters.js.map +1 -1
  7. package/dist/adapters/generic-sql/driver-config.d.ts +16 -1
  8. package/dist/adapters/generic-sql/driver-config.d.ts.map +1 -1
  9. package/dist/adapters/generic-sql/driver-config.js +23 -1
  10. package/dist/adapters/generic-sql/driver-config.js.map +1 -1
  11. package/dist/adapters/generic-sql/generic-sql-adapter.d.ts +24 -9
  12. package/dist/adapters/generic-sql/generic-sql-adapter.d.ts.map +1 -1
  13. package/dist/adapters/generic-sql/generic-sql-adapter.js +60 -22
  14. package/dist/adapters/generic-sql/generic-sql-adapter.js.map +1 -1
  15. package/dist/adapters/generic-sql/generic-sql-uow-executor.js +169 -3
  16. package/dist/adapters/generic-sql/generic-sql-uow-executor.js.map +1 -1
  17. package/dist/adapters/generic-sql/migration/cold-kysely.js.map +1 -1
  18. package/dist/adapters/generic-sql/migration/dialect/mysql.js +25 -6
  19. package/dist/adapters/generic-sql/migration/dialect/mysql.js.map +1 -1
  20. package/dist/adapters/generic-sql/migration/dialect/postgres.js +7 -6
  21. package/dist/adapters/generic-sql/migration/dialect/postgres.js.map +1 -1
  22. package/dist/adapters/generic-sql/migration/dialect/sqlite.js +193 -16
  23. package/dist/adapters/generic-sql/migration/dialect/sqlite.js.map +1 -1
  24. package/dist/adapters/generic-sql/migration/executor.d.ts.map +1 -1
  25. package/dist/adapters/generic-sql/migration/executor.js +30 -3
  26. package/dist/adapters/generic-sql/migration/executor.js.map +1 -1
  27. package/dist/adapters/generic-sql/migration/prepared-migrations.d.ts.map +1 -1
  28. package/dist/adapters/generic-sql/migration/prepared-migrations.js +9 -9
  29. package/dist/adapters/generic-sql/migration/prepared-migrations.js.map +1 -1
  30. package/dist/adapters/generic-sql/migration/sql-generator.js +75 -52
  31. package/dist/adapters/generic-sql/migration/sql-generator.js.map +1 -1
  32. package/dist/adapters/generic-sql/query/create-sql-query-compiler.js +7 -6
  33. package/dist/adapters/generic-sql/query/create-sql-query-compiler.js.map +1 -1
  34. package/dist/adapters/generic-sql/query/cursor-utils.js +42 -4
  35. package/dist/adapters/generic-sql/query/cursor-utils.js.map +1 -1
  36. package/dist/adapters/generic-sql/query/db-now-sql.js +27 -0
  37. package/dist/adapters/generic-sql/query/db-now-sql.js.map +1 -0
  38. package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js +32 -21
  39. package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js.map +1 -1
  40. package/dist/adapters/generic-sql/query/select-builder.js +5 -3
  41. package/dist/adapters/generic-sql/query/select-builder.js.map +1 -1
  42. package/dist/adapters/generic-sql/query/sql-query-compiler.js +49 -18
  43. package/dist/adapters/generic-sql/query/sql-query-compiler.js.map +1 -1
  44. package/dist/adapters/generic-sql/query/where-builder.js +43 -29
  45. package/dist/adapters/generic-sql/query/where-builder.js.map +1 -1
  46. package/dist/adapters/generic-sql/sqlite-storage.d.ts +13 -0
  47. package/dist/adapters/generic-sql/sqlite-storage.d.ts.map +1 -0
  48. package/dist/adapters/generic-sql/sqlite-storage.js +15 -0
  49. package/dist/adapters/generic-sql/sqlite-storage.js.map +1 -0
  50. package/dist/adapters/generic-sql/uow-decoder.js +6 -2
  51. package/dist/adapters/generic-sql/uow-decoder.js.map +1 -1
  52. package/dist/adapters/generic-sql/uow-encoder.js +27 -8
  53. package/dist/adapters/generic-sql/uow-encoder.js.map +1 -1
  54. package/dist/adapters/in-memory/condition-evaluator.js +135 -0
  55. package/dist/adapters/in-memory/condition-evaluator.js.map +1 -0
  56. package/dist/adapters/in-memory/errors.d.ts +13 -0
  57. package/dist/adapters/in-memory/errors.d.ts.map +1 -0
  58. package/dist/adapters/in-memory/errors.js +23 -0
  59. package/dist/adapters/in-memory/errors.js.map +1 -0
  60. package/dist/adapters/in-memory/in-memory-adapter.d.ts +27 -0
  61. package/dist/adapters/in-memory/in-memory-adapter.d.ts.map +1 -0
  62. package/dist/adapters/in-memory/in-memory-adapter.js +196 -0
  63. package/dist/adapters/in-memory/in-memory-adapter.js.map +1 -0
  64. package/dist/adapters/in-memory/in-memory-uow.js +871 -0
  65. package/dist/adapters/in-memory/in-memory-uow.js.map +1 -0
  66. package/dist/adapters/in-memory/index.d.ts +4 -0
  67. package/dist/adapters/in-memory/index.js +4 -0
  68. package/dist/adapters/in-memory/options.d.ts +30 -0
  69. package/dist/adapters/in-memory/options.d.ts.map +1 -0
  70. package/dist/adapters/in-memory/options.js +62 -0
  71. package/dist/adapters/in-memory/options.js.map +1 -0
  72. package/dist/adapters/in-memory/reference-resolution.js +26 -0
  73. package/dist/adapters/in-memory/reference-resolution.js.map +1 -0
  74. package/dist/adapters/in-memory/sorted-array-index.js +129 -0
  75. package/dist/adapters/in-memory/sorted-array-index.js.map +1 -0
  76. package/dist/adapters/in-memory/store.js +71 -0
  77. package/dist/adapters/in-memory/store.js.map +1 -0
  78. package/dist/adapters/in-memory/value-comparison.js +28 -0
  79. package/dist/adapters/in-memory/value-comparison.js.map +1 -0
  80. package/dist/adapters/shared/from-unit-of-work-compiler.js +51 -24
  81. package/dist/adapters/shared/from-unit-of-work-compiler.js.map +1 -1
  82. package/dist/adapters/shared/uow-operation-compiler.js +11 -11
  83. package/dist/adapters/shared/uow-operation-compiler.js.map +1 -1
  84. package/dist/adapters/sql/index.d.ts +5 -0
  85. package/dist/adapters/sql/index.js +4 -0
  86. package/dist/browser/adapters/adapters.d.ts +61 -0
  87. package/dist/browser/adapters/adapters.d.ts.map +1 -0
  88. package/dist/browser/adapters/generic-sql/migration/executor.d.ts +15 -0
  89. package/dist/browser/adapters/generic-sql/migration/executor.d.ts.map +1 -0
  90. package/dist/browser/adapters/generic-sql/migration/prepared-migrations.d.ts +66 -0
  91. package/dist/browser/adapters/generic-sql/migration/prepared-migrations.d.ts.map +1 -0
  92. package/dist/browser/adapters/generic-sql/sqlite-storage.d.ts +11 -0
  93. package/dist/browser/adapters/generic-sql/sqlite-storage.d.ts.map +1 -0
  94. package/dist/browser/adapters/in-memory/in-memory-adapter.d.ts +5 -0
  95. package/dist/browser/adapters/in-memory/index.d.ts +2 -0
  96. package/dist/browser/adapters/in-memory/options.d.ts +1 -0
  97. package/dist/browser/db-fragment-definition-builder.d.ts +237 -0
  98. package/dist/browser/db-fragment-definition-builder.d.ts.map +1 -0
  99. package/dist/browser/durable-hooks.d.ts +3 -0
  100. package/dist/browser/fragments/internal-fragment.d.ts +317 -0
  101. package/dist/browser/fragments/internal-fragment.d.ts.map +1 -0
  102. package/dist/browser/fragments/internal-fragment.schema.d.ts +1 -0
  103. package/dist/browser/hooks/durable-hooks-logger.d.ts +10 -0
  104. package/dist/browser/hooks/durable-hooks-logger.d.ts.map +1 -0
  105. package/dist/browser/hooks/hooks.d.ts +146 -0
  106. package/dist/browser/hooks/hooks.d.ts.map +1 -0
  107. package/dist/browser/id.js +1 -0
  108. package/dist/browser/internal/adapter-registry.d.ts +4 -0
  109. package/dist/browser/internal/outbox-state.d.ts +2 -0
  110. package/dist/browser/mod.d.ts +15 -0
  111. package/dist/browser/mod.d.ts.map +1 -0
  112. package/dist/browser/mod.js +17 -0
  113. package/dist/browser/mod.js.map +1 -0
  114. package/dist/browser/mod2.d.ts +48 -0
  115. package/dist/browser/mod2.d.ts.map +1 -0
  116. package/dist/browser/naming/sql-naming.d.ts +19 -0
  117. package/dist/browser/naming/sql-naming.d.ts.map +1 -0
  118. package/dist/browser/outbox/outbox.d.ts +21 -0
  119. package/dist/browser/outbox/outbox.d.ts.map +1 -0
  120. package/dist/browser/query/column-defaults.js +1 -0
  121. package/dist/browser/query/condition-builder.d.ts +44 -0
  122. package/dist/browser/query/condition-builder.d.ts.map +1 -0
  123. package/dist/browser/query/condition-builder.js +97 -0
  124. package/dist/browser/query/condition-builder.js.map +1 -0
  125. package/dist/browser/query/cursor.d.ts +105 -0
  126. package/dist/browser/query/cursor.d.ts.map +1 -0
  127. package/dist/browser/query/cursor.js +150 -0
  128. package/dist/browser/query/cursor.js.map +1 -0
  129. package/dist/browser/query/db-now.d.ts +22 -0
  130. package/dist/browser/query/db-now.d.ts.map +1 -0
  131. package/dist/browser/query/db-now.js +33 -0
  132. package/dist/browser/query/db-now.js.map +1 -0
  133. package/dist/browser/query/orm/orm.d.ts +18 -0
  134. package/dist/browser/query/orm/orm.d.ts.map +1 -0
  135. package/dist/browser/query/simple-query-interface.d.ts +108 -0
  136. package/dist/browser/query/simple-query-interface.d.ts.map +1 -0
  137. package/dist/browser/query/unit-of-work/execute-unit-of-work.d.ts +423 -0
  138. package/dist/browser/query/unit-of-work/execute-unit-of-work.d.ts.map +1 -0
  139. package/dist/browser/query/unit-of-work/execute-unit-of-work.js +507 -0
  140. package/dist/browser/query/unit-of-work/execute-unit-of-work.js.map +1 -0
  141. package/dist/browser/query/unit-of-work/retry-policy.d.ts +23 -0
  142. package/dist/browser/query/unit-of-work/retry-policy.d.ts.map +1 -0
  143. package/dist/browser/query/unit-of-work/retry-policy.js +40 -0
  144. package/dist/browser/query/unit-of-work/retry-policy.js.map +1 -0
  145. package/dist/browser/query/unit-of-work/unit-of-work.d.ts +703 -0
  146. package/dist/browser/query/unit-of-work/unit-of-work.d.ts.map +1 -0
  147. package/dist/browser/query/unit-of-work/unit-of-work.js +1206 -0
  148. package/dist/browser/query/unit-of-work/unit-of-work.js.map +1 -0
  149. package/dist/browser/query/value-encoding.js +38 -0
  150. package/dist/browser/query/value-encoding.js.map +1 -0
  151. package/dist/browser/schema/create.d.ts +326 -0
  152. package/dist/browser/schema/create.d.ts.map +1 -0
  153. package/dist/browser/schema/create.js +89 -0
  154. package/dist/browser/schema/create.js.map +1 -0
  155. package/dist/browser/schema/generate-id.js +28 -0
  156. package/dist/browser/schema/generate-id.js.map +1 -0
  157. package/dist/browser/shared/providers.d.ts +6 -0
  158. package/dist/browser/shared/providers.d.ts.map +1 -0
  159. package/dist/browser/sql-driver/connection/connection-provider.d.ts +13 -0
  160. package/dist/browser/sql-driver/connection/connection-provider.d.ts.map +1 -0
  161. package/dist/browser/sql-driver/dialect-adapter/dialect-adapter.d.ts +7 -0
  162. package/dist/browser/sql-driver/dialect-adapter/dialect-adapter.d.ts.map +1 -0
  163. package/dist/browser/sql-driver/driver/runtime-driver.d.ts +23 -0
  164. package/dist/browser/sql-driver/driver/runtime-driver.d.ts.map +1 -0
  165. package/dist/browser/sql-driver/query-executor/plugin.d.ts +17 -0
  166. package/dist/browser/sql-driver/query-executor/plugin.d.ts.map +1 -0
  167. package/dist/browser/sql-driver/query-executor/query-executor.d.ts +36 -0
  168. package/dist/browser/sql-driver/query-executor/query-executor.d.ts.map +1 -0
  169. package/dist/browser/sql-driver/sql-driver-adapter.d.ts +29 -0
  170. package/dist/browser/sql-driver/sql-driver-adapter.d.ts.map +1 -0
  171. package/dist/browser/sql-driver/sql-driver.d.ts +38 -0
  172. package/dist/browser/sql-driver/sql-driver.d.ts.map +1 -0
  173. package/dist/browser/sync/commands.d.ts +15 -0
  174. package/dist/browser/sync/commands.d.ts.map +1 -0
  175. package/dist/browser/sync/commands.js +27 -0
  176. package/dist/browser/sync/commands.js.map +1 -0
  177. package/dist/browser/sync/types.d.ts +63 -0
  178. package/dist/browser/sync/types.d.ts.map +1 -0
  179. package/dist/browser/util/types.d.ts +8 -0
  180. package/dist/browser/util/types.d.ts.map +1 -0
  181. package/dist/browser/with-database.d.ts +29 -0
  182. package/dist/browser/with-database.d.ts.map +1 -0
  183. package/dist/client.d.ts +4 -0
  184. package/dist/client.js +5 -0
  185. package/dist/db-fragment-definition-builder.d.ts +101 -33
  186. package/dist/db-fragment-definition-builder.d.ts.map +1 -1
  187. package/dist/db-fragment-definition-builder.js +450 -60
  188. package/dist/db-fragment-definition-builder.js.map +1 -1
  189. package/dist/dispatchers/cloudflare-do/dispatcher.d.ts +20 -0
  190. package/dist/dispatchers/cloudflare-do/dispatcher.d.ts.map +1 -0
  191. package/dist/dispatchers/cloudflare-do/dispatcher.js +147 -0
  192. package/dist/dispatchers/cloudflare-do/dispatcher.js.map +1 -0
  193. package/dist/dispatchers/cloudflare-do/index.d.ts +11 -0
  194. package/dist/dispatchers/cloudflare-do/index.d.ts.map +1 -0
  195. package/dist/dispatchers/cloudflare-do/index.js +31 -0
  196. package/dist/dispatchers/cloudflare-do/index.js.map +1 -0
  197. package/dist/dispatchers/node/dispatcher.d.ts +14 -0
  198. package/dist/dispatchers/node/dispatcher.d.ts.map +1 -0
  199. package/dist/dispatchers/node/dispatcher.js +80 -0
  200. package/dist/dispatchers/node/dispatcher.js.map +1 -0
  201. package/dist/dispatchers/node/index.d.ts +12 -0
  202. package/dist/dispatchers/node/index.d.ts.map +1 -0
  203. package/dist/dispatchers/node/index.js +27 -0
  204. package/dist/dispatchers/node/index.js.map +1 -0
  205. package/dist/durable-hooks.d.ts +31 -0
  206. package/dist/durable-hooks.d.ts.map +1 -0
  207. package/dist/durable-hooks.js +23 -0
  208. package/dist/durable-hooks.js.map +1 -0
  209. package/dist/fragments/internal-fragment.d.ts +186 -8
  210. package/dist/fragments/internal-fragment.d.ts.map +1 -1
  211. package/dist/fragments/internal-fragment.js +203 -38
  212. package/dist/fragments/internal-fragment.js.map +1 -1
  213. package/dist/fragments/internal-fragment.routes.js +164 -0
  214. package/dist/fragments/internal-fragment.routes.js.map +1 -0
  215. package/dist/fragments/internal-fragment.schema.d.ts +15 -0
  216. package/dist/fragments/internal-fragment.schema.d.ts.map +1 -0
  217. package/dist/fragments/internal-fragment.schema.js +39 -0
  218. package/dist/fragments/internal-fragment.schema.js.map +1 -0
  219. package/dist/hooks/durable-hooks-logger.d.ts +10 -0
  220. package/dist/hooks/durable-hooks-logger.d.ts.map +1 -0
  221. package/dist/hooks/durable-hooks-logger.js +75 -0
  222. package/dist/hooks/durable-hooks-logger.js.map +1 -0
  223. package/dist/hooks/durable-hooks-processor.d.ts +1 -0
  224. package/dist/hooks/durable-hooks-processor.js +80 -0
  225. package/dist/hooks/durable-hooks-processor.js.map +1 -0
  226. package/dist/hooks/durable-hooks-runtime.js +44 -0
  227. package/dist/hooks/durable-hooks-runtime.js.map +1 -0
  228. package/dist/hooks/hooks.d.ts +100 -1
  229. package/dist/hooks/hooks.d.ts.map +1 -1
  230. package/dist/hooks/hooks.js +254 -27
  231. package/dist/hooks/hooks.js.map +1 -1
  232. package/dist/id.d.ts +2 -2
  233. package/dist/id.js +2 -2
  234. package/dist/internal/adapter-registry.d.ts +11 -0
  235. package/dist/internal/adapter-registry.d.ts.map +1 -0
  236. package/dist/internal/adapter-registry.js +135 -0
  237. package/dist/internal/adapter-registry.js.map +1 -0
  238. package/dist/internal/outbox-state.d.ts +2 -0
  239. package/dist/internal/outbox-state.js +26 -0
  240. package/dist/internal/outbox-state.js.map +1 -0
  241. package/dist/migration-engine/auto-from-schema.d.ts +33 -0
  242. package/dist/migration-engine/auto-from-schema.d.ts.map +1 -0
  243. package/dist/migration-engine/auto-from-schema.js +223 -37
  244. package/dist/migration-engine/auto-from-schema.js.map +1 -1
  245. package/dist/migration-engine/generation-engine.d.ts +16 -10
  246. package/dist/migration-engine/generation-engine.d.ts.map +1 -1
  247. package/dist/migration-engine/generation-engine.js +86 -35
  248. package/dist/migration-engine/generation-engine.js.map +1 -1
  249. package/dist/migration-engine/shared.d.ts +113 -0
  250. package/dist/migration-engine/shared.d.ts.map +1 -0
  251. package/dist/migration-engine/shared.js.map +1 -1
  252. package/dist/mod.d.ts +20 -12
  253. package/dist/mod.d.ts.map +1 -1
  254. package/dist/mod.js +18 -12
  255. package/dist/mod.js.map +1 -1
  256. package/dist/naming/sql-naming.d.ts +19 -0
  257. package/dist/naming/sql-naming.d.ts.map +1 -0
  258. package/dist/naming/sql-naming.js +116 -0
  259. package/dist/naming/sql-naming.js.map +1 -0
  260. package/dist/outbox/outbox-builder.js +156 -0
  261. package/dist/outbox/outbox-builder.js.map +1 -0
  262. package/dist/outbox/outbox.d.ts +54 -0
  263. package/dist/outbox/outbox.d.ts.map +1 -0
  264. package/dist/outbox/outbox.js +37 -0
  265. package/dist/outbox/outbox.js.map +1 -0
  266. package/dist/query/column-defaults.js +20 -4
  267. package/dist/query/column-defaults.js.map +1 -1
  268. package/dist/query/condition-builder.d.ts +7 -1
  269. package/dist/query/condition-builder.d.ts.map +1 -1
  270. package/dist/query/condition-builder.js +5 -1
  271. package/dist/query/condition-builder.js.map +1 -1
  272. package/dist/query/cursor-client.d.ts +105 -0
  273. package/dist/query/cursor-client.d.ts.map +1 -0
  274. package/dist/query/cursor-client.js +165 -0
  275. package/dist/query/cursor-client.js.map +1 -0
  276. package/dist/query/cursor.d.ts +3 -1
  277. package/dist/query/cursor.d.ts.map +1 -1
  278. package/dist/query/cursor.js +51 -14
  279. package/dist/query/cursor.js.map +1 -1
  280. package/dist/query/db-now.d.ts +22 -0
  281. package/dist/query/db-now.d.ts.map +1 -0
  282. package/dist/query/db-now.js +35 -0
  283. package/dist/query/db-now.js.map +1 -0
  284. package/dist/query/orm/orm.js.map +1 -1
  285. package/dist/query/serialize/create-sql-serializer.js +5 -4
  286. package/dist/query/serialize/create-sql-serializer.js.map +1 -1
  287. package/dist/query/serialize/dialect/mysql-serializer.js +12 -6
  288. package/dist/query/serialize/dialect/mysql-serializer.js.map +1 -1
  289. package/dist/query/serialize/dialect/postgres-serializer.js +25 -7
  290. package/dist/query/serialize/dialect/postgres-serializer.js.map +1 -1
  291. package/dist/query/serialize/dialect/sqlite-serializer.js +60 -12
  292. package/dist/query/serialize/dialect/sqlite-serializer.js.map +1 -1
  293. package/dist/query/serialize/sql-serializer.js +2 -2
  294. package/dist/query/serialize/sql-serializer.js.map +1 -1
  295. package/dist/query/simple-query-interface.d.ts +13 -4
  296. package/dist/query/simple-query-interface.d.ts.map +1 -1
  297. package/dist/query/unit-of-work/execute-unit-of-work.d.ts +37 -2
  298. package/dist/query/unit-of-work/execute-unit-of-work.d.ts.map +1 -1
  299. package/dist/query/unit-of-work/execute-unit-of-work.js +50 -24
  300. package/dist/query/unit-of-work/execute-unit-of-work.js.map +1 -1
  301. package/dist/query/unit-of-work/unit-of-work.d.ts +92 -30
  302. package/dist/query/unit-of-work/unit-of-work.d.ts.map +1 -1
  303. package/dist/query/unit-of-work/unit-of-work.js +136 -11
  304. package/dist/query/unit-of-work/unit-of-work.js.map +1 -1
  305. package/dist/query/value-decoding.js +16 -6
  306. package/dist/query/value-decoding.js.map +1 -1
  307. package/dist/query/value-encoding.js +29 -9
  308. package/dist/query/value-encoding.js.map +1 -1
  309. package/dist/schema/create.d.ts +103 -35
  310. package/dist/schema/create.d.ts.map +1 -1
  311. package/dist/schema/create.js +172 -58
  312. package/dist/schema/create.js.map +1 -1
  313. package/dist/schema/generate-id.js +2 -2
  314. package/dist/schema/generate-id.js.map +1 -1
  315. package/dist/schema/type-conversion/create-sql-type-mapper.js +4 -3
  316. package/dist/schema/type-conversion/create-sql-type-mapper.js.map +1 -1
  317. package/dist/schema/type-conversion/dialect/sqlite.js +9 -0
  318. package/dist/schema/type-conversion/dialect/sqlite.js.map +1 -1
  319. package/dist/schema/validator.d.ts +10 -0
  320. package/dist/schema/validator.d.ts.map +1 -0
  321. package/dist/schema/validator.js +123 -0
  322. package/dist/schema/validator.js.map +1 -0
  323. package/dist/schema-output/drizzle.d.ts +30 -0
  324. package/dist/schema-output/drizzle.d.ts.map +1 -0
  325. package/dist/{adapters/drizzle/generate.js → schema-output/drizzle.js} +88 -60
  326. package/dist/schema-output/drizzle.js.map +1 -0
  327. package/dist/schema-output/prisma.d.ts +17 -0
  328. package/dist/schema-output/prisma.d.ts.map +1 -0
  329. package/dist/schema-output/prisma.js +307 -0
  330. package/dist/schema-output/prisma.js.map +1 -0
  331. package/dist/sql-driver/dialects/durable-object-dialect.js +3 -9
  332. package/dist/sql-driver/dialects/durable-object-dialect.js.map +1 -1
  333. package/dist/sql-driver/query-executor/default-query-executor.js.map +1 -1
  334. package/dist/sql-driver/query-executor/query-executor-base.js.map +1 -1
  335. package/dist/sql-driver/sql-driver-adapter.js.map +1 -1
  336. package/dist/sql-driver/sql.js.map +1 -1
  337. package/dist/sync/commands.d.ts +15 -0
  338. package/dist/sync/commands.d.ts.map +1 -0
  339. package/dist/sync/commands.js +27 -0
  340. package/dist/sync/commands.js.map +1 -0
  341. package/dist/sync/index.d.ts +4 -0
  342. package/dist/sync/index.js +4 -0
  343. package/dist/sync/read-tracking.d.ts +25 -0
  344. package/dist/sync/read-tracking.d.ts.map +1 -0
  345. package/dist/sync/read-tracking.js +148 -0
  346. package/dist/sync/read-tracking.js.map +1 -0
  347. package/dist/sync/submit.js +213 -0
  348. package/dist/sync/submit.js.map +1 -0
  349. package/dist/sync/types.d.ts +63 -0
  350. package/dist/sync/types.d.ts.map +1 -0
  351. package/dist/util/default-database-adapter.js +66 -0
  352. package/dist/util/default-database-adapter.js.map +1 -0
  353. package/dist/with-database.d.ts +3 -6
  354. package/dist/with-database.d.ts.map +1 -1
  355. package/dist/with-database.js +8 -7
  356. package/dist/with-database.js.map +1 -1
  357. package/package.json +62 -55
  358. package/src/adapters/adapters.ts +33 -26
  359. package/src/adapters/drizzle/migrate-drizzle.test.ts +99 -41
  360. package/src/adapters/drizzle/migration-parity-drizzle-kit.test.ts +601 -0
  361. package/src/adapters/drizzle/test-utils.ts +13 -8
  362. package/src/adapters/generic-sql/driver-config.ts +38 -0
  363. package/src/adapters/generic-sql/generic-sql-adapter.test.ts +10 -8
  364. package/src/adapters/generic-sql/generic-sql-adapter.ts +117 -34
  365. package/src/adapters/generic-sql/generic-sql-uow-executor.test.ts +55 -0
  366. package/src/adapters/generic-sql/generic-sql-uow-executor.ts +297 -3
  367. package/src/adapters/generic-sql/migration/adapter-migration-parity.test.ts +120 -0
  368. package/src/adapters/generic-sql/migration/cold-kysely.ts +1 -0
  369. package/src/adapters/generic-sql/migration/dialect/mysql.test.ts +27 -8
  370. package/src/adapters/generic-sql/migration/dialect/mysql.ts +47 -8
  371. package/src/adapters/generic-sql/migration/dialect/postgres.test.ts +28 -9
  372. package/src/adapters/generic-sql/migration/dialect/postgres.ts +9 -4
  373. package/src/adapters/generic-sql/migration/dialect/sqlite.test.ts +839 -8
  374. package/src/adapters/generic-sql/migration/dialect/sqlite.ts +396 -53
  375. package/src/adapters/generic-sql/migration/executor.test.ts +52 -0
  376. package/src/adapters/generic-sql/migration/executor.ts +47 -4
  377. package/src/adapters/generic-sql/migration/prepared-migrations.test.ts +238 -46
  378. package/src/adapters/generic-sql/migration/prepared-migrations.ts +21 -13
  379. package/src/adapters/generic-sql/migration/sql-generator.ts +145 -66
  380. package/src/adapters/generic-sql/query/create-sql-query-compiler.ts +11 -8
  381. package/src/adapters/generic-sql/query/cursor-utils.test.ts +272 -0
  382. package/src/adapters/generic-sql/query/cursor-utils.ts +42 -7
  383. package/src/adapters/generic-sql/query/db-now-sql.ts +49 -0
  384. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.test.ts +171 -35
  385. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.ts +53 -40
  386. package/src/adapters/generic-sql/query/select-builder.test.ts +16 -11
  387. package/src/adapters/generic-sql/query/select-builder.ts +7 -3
  388. package/src/adapters/generic-sql/query/sql-query-compiler.test.ts +75 -6
  389. package/src/adapters/generic-sql/query/sql-query-compiler.ts +129 -24
  390. package/src/adapters/generic-sql/query/where-builder.test.ts +96 -20
  391. package/src/adapters/generic-sql/query/where-builder.ts +112 -41
  392. package/src/adapters/{kysely/kysely-adapter-pglite.test.ts → generic-sql/sql-adapter-pglite-migrations.test.ts} +11 -20
  393. package/src/adapters/generic-sql/sql-adapter-pglite-pagination.test.ts +851 -0
  394. package/src/adapters/{drizzle/drizzle-adapter-pglite.test.ts → generic-sql/sql-adapter-pglite-queries.test.ts} +18 -15
  395. package/src/adapters/generic-sql/{test/generic-drizzle-adapter-sqlite3.test.ts → sql-adapter-sqlite3-driver.test.ts} +282 -14
  396. package/src/adapters/{drizzle/drizzle-adapter-sqlite3.test.ts → generic-sql/sql-adapter-sqlite3-uow.test.ts} +129 -12
  397. package/src/adapters/{kysely/kysely-adapter-sqlocal.test.ts → generic-sql/sql-adapter-sqlocal.test.ts} +9 -7
  398. package/src/adapters/generic-sql/sqlite-storage.ts +20 -0
  399. package/src/adapters/generic-sql/uow-decoder.test.ts +5 -4
  400. package/src/adapters/generic-sql/uow-decoder.ts +23 -5
  401. package/src/adapters/generic-sql/uow-encoder.test.ts +36 -3
  402. package/src/adapters/generic-sql/uow-encoder.ts +48 -13
  403. package/src/adapters/in-memory/condition-evaluator.test.ts +194 -0
  404. package/src/adapters/in-memory/condition-evaluator.ts +280 -0
  405. package/src/adapters/in-memory/errors.ts +20 -0
  406. package/src/adapters/in-memory/in-memory-adapter.ts +388 -0
  407. package/src/adapters/in-memory/in-memory-uow.mutations.test.ts +344 -0
  408. package/src/adapters/in-memory/in-memory-uow.retrieval.test.ts +255 -0
  409. package/src/adapters/in-memory/in-memory-uow.ts +1724 -0
  410. package/src/adapters/in-memory/index.ts +3 -0
  411. package/src/adapters/in-memory/options.test.ts +42 -0
  412. package/src/adapters/in-memory/options.ts +91 -0
  413. package/src/adapters/in-memory/outbox.test.ts +361 -0
  414. package/src/adapters/in-memory/reference-resolution.test.ts +51 -0
  415. package/src/adapters/in-memory/reference-resolution.ts +67 -0
  416. package/src/adapters/in-memory/sorted-array-index.test.ts +124 -0
  417. package/src/adapters/in-memory/sorted-array-index.ts +228 -0
  418. package/src/adapters/in-memory/store.test.ts +69 -0
  419. package/src/adapters/in-memory/store.ts +145 -0
  420. package/src/adapters/in-memory/value-comparison.ts +53 -0
  421. package/src/adapters/in-memory/value-normalization.test.ts +58 -0
  422. package/src/adapters/prisma/prisma-adapter-sqlite3.test.ts +1207 -0
  423. package/src/adapters/shared/from-unit-of-work-compiler.ts +159 -47
  424. package/src/adapters/shared/uow-operation-compiler.ts +28 -18
  425. package/src/adapters/sql/index.ts +12 -0
  426. package/src/browser/mod.ts +64 -0
  427. package/src/client.ts +19 -0
  428. package/src/db-fragment-definition-builder.test.ts +845 -53
  429. package/src/db-fragment-definition-builder.ts +911 -95
  430. package/src/db-fragment-instantiator.test.ts +210 -94
  431. package/src/db-fragment-integration.test.ts +17 -12
  432. package/src/dispatchers/cloudflare-do/dispatcher.ts +204 -0
  433. package/src/dispatchers/cloudflare-do/index.test.ts +206 -0
  434. package/src/dispatchers/cloudflare-do/index.ts +63 -0
  435. package/src/dispatchers/node/dispatcher.ts +112 -0
  436. package/src/dispatchers/node/index.test.ts +120 -0
  437. package/src/dispatchers/node/index.ts +50 -0
  438. package/src/durable-hooks.test.ts +80 -0
  439. package/src/durable-hooks.ts +67 -0
  440. package/src/fragments/internal-fragment.routes.test.ts +570 -0
  441. package/src/fragments/internal-fragment.routes.ts +334 -0
  442. package/src/fragments/internal-fragment.schema.ts +95 -0
  443. package/src/fragments/internal-fragment.test.ts +505 -83
  444. package/src/fragments/internal-fragment.ts +453 -70
  445. package/src/hooks/durable-hooks-logger.ts +126 -0
  446. package/src/hooks/durable-hooks-processor.pglite.test.ts +87 -0
  447. package/src/hooks/durable-hooks-processor.test.ts +282 -0
  448. package/src/hooks/durable-hooks-processor.ts +173 -0
  449. package/src/hooks/durable-hooks-runtime.test.ts +65 -0
  450. package/src/hooks/durable-hooks-runtime.ts +81 -0
  451. package/src/hooks/hooks.test.ts +455 -34
  452. package/src/hooks/hooks.ts +501 -34
  453. package/src/id.test.ts +34 -0
  454. package/src/id.ts +1 -3
  455. package/src/internal/adapter-registry.test.ts +93 -0
  456. package/src/internal/adapter-registry.ts +239 -0
  457. package/src/internal/outbox-state.ts +43 -0
  458. package/src/migration-engine/auto-from-schema.test.ts +107 -14
  459. package/src/migration-engine/auto-from-schema.ts +365 -44
  460. package/src/migration-engine/create.test.ts +4 -3
  461. package/src/migration-engine/create.ts +1 -1
  462. package/src/migration-engine/generation-engine.test.ts +292 -110
  463. package/src/migration-engine/generation-engine.ts +117 -66
  464. package/src/migration-engine/shared.ts +14 -0
  465. package/src/mod.ts +95 -39
  466. package/src/naming/sql-naming.ts +181 -0
  467. package/src/outbox/outbox-builder.ts +241 -0
  468. package/src/outbox/outbox.test.ts +424 -0
  469. package/src/outbox/outbox.ts +139 -0
  470. package/src/query/column-defaults.ts +42 -4
  471. package/src/query/condition-builder.test.ts +18 -3
  472. package/src/query/condition-builder.ts +7 -0
  473. package/src/query/cursor-client.test.ts +70 -0
  474. package/src/query/cursor-client.ts +263 -0
  475. package/src/query/cursor.test.ts +119 -20
  476. package/src/query/cursor.ts +88 -27
  477. package/src/query/db-now.ts +73 -0
  478. package/src/query/orm/orm.ts +2 -2
  479. package/src/query/query-type.test.ts +4 -3
  480. package/src/query/serialize/create-sql-serializer.ts +10 -5
  481. package/src/query/serialize/dialect/mysql-serializer.ts +13 -5
  482. package/src/query/serialize/dialect/postgres-serializer.ts +35 -5
  483. package/src/query/serialize/dialect/sqlite-serializer.test.ts +90 -3
  484. package/src/query/serialize/dialect/sqlite-serializer.ts +108 -12
  485. package/src/query/serialize/sql-serializer.ts +4 -4
  486. package/src/query/simple-query-interface.ts +15 -4
  487. package/src/query/unit-of-work/execute-unit-of-work.test.ts +372 -10
  488. package/src/query/unit-of-work/execute-unit-of-work.ts +87 -27
  489. package/src/query/unit-of-work/retry-policy.test.ts +1 -0
  490. package/src/query/unit-of-work/tx-builder.test.ts +73 -1
  491. package/src/query/unit-of-work/unit-of-work-coordinator.test.ts +17 -16
  492. package/src/query/unit-of-work/unit-of-work-types.test.ts +42 -12
  493. package/src/query/unit-of-work/unit-of-work.test.ts +196 -39
  494. package/src/query/unit-of-work/unit-of-work.ts +309 -38
  495. package/src/query/value-decoding.test.ts +63 -4
  496. package/src/query/value-decoding.ts +32 -6
  497. package/src/query/value-encoding.test.ts +86 -2
  498. package/src/query/value-encoding.ts +56 -6
  499. package/src/schema/create.test.ts +293 -47
  500. package/src/schema/create.ts +406 -70
  501. package/src/schema/generate-id.test.ts +3 -2
  502. package/src/schema/generate-id.ts +2 -2
  503. package/src/schema/serialize.test.ts +18 -5
  504. package/src/schema/type-conversion/create-sql-type-mapper.ts +8 -3
  505. package/src/schema/type-conversion/dialect/sqlite.ts +18 -0
  506. package/src/schema/type-conversion/type-mapping.test.ts +26 -1
  507. package/src/schema/validator.test.ts +199 -0
  508. package/src/schema/validator.ts +232 -0
  509. package/src/{adapters/drizzle/generate.test.ts → schema-output/drizzle.test.ts} +232 -129
  510. package/src/{adapters/drizzle/generate.ts → schema-output/drizzle.ts} +155 -99
  511. package/src/schema-output/prisma.test.ts +694 -0
  512. package/src/schema-output/prisma.ts +593 -0
  513. package/src/sql-driver/better-sqlite3.test.ts +5 -3
  514. package/src/sql-driver/dialects/durable-object-dialect.ts +3 -8
  515. package/src/sql-driver/query-executor/default-query-executor.ts +1 -1
  516. package/src/sql-driver/query-executor/query-executor-base.ts +1 -1
  517. package/src/sql-driver/query-executor/query-executor.ts +1 -1
  518. package/src/sql-driver/sql-driver-adapter.ts +2 -2
  519. package/src/sql-driver/sql.ts +2 -1
  520. package/src/sql-driver/sqlocal.test.ts +4 -2
  521. package/src/sync/commands.test.ts +39 -0
  522. package/src/sync/commands.ts +51 -0
  523. package/src/sync/conflict-checker.test.ts +450 -0
  524. package/src/sync/conflict-checker.ts +248 -0
  525. package/src/sync/index.ts +14 -0
  526. package/src/sync/plan.ts +9 -0
  527. package/src/sync/read-tracking.test.ts +177 -0
  528. package/src/sync/read-tracking.ts +287 -0
  529. package/src/sync/submit.test.ts +205 -0
  530. package/src/sync/submit.ts +328 -0
  531. package/src/sync/types.ts +80 -0
  532. package/src/util/default-database-adapter.ts +119 -0
  533. package/src/with-database.ts +20 -31
  534. package/tsconfig.json +1 -1
  535. package/tsdown.config.ts +38 -24
  536. package/vitest.config.ts +1 -0
  537. package/dist/adapters/drizzle/drizzle-adapter.d.ts +0 -20
  538. package/dist/adapters/drizzle/drizzle-adapter.d.ts.map +0 -1
  539. package/dist/adapters/drizzle/drizzle-adapter.js +0 -27
  540. package/dist/adapters/drizzle/drizzle-adapter.js.map +0 -1
  541. package/dist/adapters/drizzle/generate.d.ts +0 -30
  542. package/dist/adapters/drizzle/generate.d.ts.map +0 -1
  543. package/dist/adapters/drizzle/generate.js.map +0 -1
  544. package/dist/adapters/kysely/kysely-adapter.d.ts +0 -19
  545. package/dist/adapters/kysely/kysely-adapter.d.ts.map +0 -1
  546. package/dist/adapters/kysely/kysely-adapter.js +0 -17
  547. package/dist/adapters/kysely/kysely-adapter.js.map +0 -1
  548. package/dist/adapters/shared/table-name-mapper.d.ts +0 -12
  549. package/dist/adapters/shared/table-name-mapper.d.ts.map +0 -1
  550. package/dist/adapters/shared/table-name-mapper.js +0 -43
  551. package/dist/adapters/shared/table-name-mapper.js.map +0 -1
  552. package/dist/node_modules/.pnpm/rou3@0.7.10/node_modules/rou3/dist/index.js +0 -165
  553. package/dist/node_modules/.pnpm/rou3@0.7.10/node_modules/rou3/dist/index.js.map +0 -1
  554. package/dist/packages/fragno/dist/api/bind-services.js +0 -20
  555. package/dist/packages/fragno/dist/api/bind-services.js.map +0 -1
  556. package/dist/packages/fragno/dist/api/error.js +0 -48
  557. package/dist/packages/fragno/dist/api/error.js.map +0 -1
  558. package/dist/packages/fragno/dist/api/fragment-definition-builder.js +0 -320
  559. package/dist/packages/fragno/dist/api/fragment-definition-builder.js.map +0 -1
  560. package/dist/packages/fragno/dist/api/fragment-instantiator.js +0 -525
  561. package/dist/packages/fragno/dist/api/fragment-instantiator.js.map +0 -1
  562. package/dist/packages/fragno/dist/api/fragno-response.js +0 -73
  563. package/dist/packages/fragno/dist/api/fragno-response.js.map +0 -1
  564. package/dist/packages/fragno/dist/api/internal/response-stream.js +0 -81
  565. package/dist/packages/fragno/dist/api/internal/response-stream.js.map +0 -1
  566. package/dist/packages/fragno/dist/api/internal/route.js +0 -10
  567. package/dist/packages/fragno/dist/api/internal/route.js.map +0 -1
  568. package/dist/packages/fragno/dist/api/mutable-request-state.js +0 -97
  569. package/dist/packages/fragno/dist/api/mutable-request-state.js.map +0 -1
  570. package/dist/packages/fragno/dist/api/request-context-storage.js +0 -43
  571. package/dist/packages/fragno/dist/api/request-context-storage.js.map +0 -1
  572. package/dist/packages/fragno/dist/api/request-input-context.js +0 -118
  573. package/dist/packages/fragno/dist/api/request-input-context.js.map +0 -1
  574. package/dist/packages/fragno/dist/api/request-middleware.js +0 -83
  575. package/dist/packages/fragno/dist/api/request-middleware.js.map +0 -1
  576. package/dist/packages/fragno/dist/api/request-output-context.js +0 -119
  577. package/dist/packages/fragno/dist/api/request-output-context.js.map +0 -1
  578. package/dist/packages/fragno/dist/api/route.js +0 -17
  579. package/dist/packages/fragno/dist/api/route.js.map +0 -1
  580. package/dist/packages/fragno/dist/internal/symbols.js +0 -10
  581. package/dist/packages/fragno/dist/internal/symbols.js.map +0 -1
  582. package/dist/schema-generator/schema-generator.d.ts +0 -15
  583. package/dist/schema-generator/schema-generator.d.ts.map +0 -1
  584. package/src/adapters/drizzle/drizzle-adapter.ts +0 -39
  585. package/src/adapters/kysely/kysely-adapter.ts +0 -27
  586. package/src/adapters/shared/table-name-mapper.ts +0 -50
  587. package/src/schema-generator/schema-generator.ts +0 -12
@@ -0,0 +1,328 @@
1
+ import type { OutboxEntry } from "../outbox/outbox";
2
+ import { ConcurrencyConflictError } from "../query/unit-of-work/execute-unit-of-work";
3
+ import type { SubmitResponse, SubmitConflictReason, SyncCommandDefinition } from "./types";
4
+
5
+ export const DEFAULT_MAX_COMMANDS_PER_SUBMIT = 100;
6
+ export const DEFAULT_MAX_UNSEEN_MUTATIONS = 10_000;
7
+
8
+ export type SyncRequestRecord = {
9
+ requestId: string;
10
+ status: "applied" | "conflict";
11
+ confirmedCommandIds: string[];
12
+ conflictCommandId?: string;
13
+ baseVersionstamp?: string;
14
+ lastVersionstamp?: string;
15
+ };
16
+
17
+ export type SyncCommandResolution = {
18
+ command: SyncCommandDefinition;
19
+ namespace: string | null;
20
+ };
21
+
22
+ export type SyncSubmitRuntime = {
23
+ getAdapterIdentity: () => Promise<string>;
24
+ listOutboxEntries: (afterVersionstamp?: string) => Promise<OutboxEntry[]>;
25
+ countOutboxMutations: (afterVersionstamp?: string) => Promise<number>;
26
+ getSyncRequest: (requestId: string) => Promise<SyncRequestRecord | undefined>;
27
+ storeSyncRequest: (record: SyncRequestRecord) => Promise<void>;
28
+ resolveCommand: (
29
+ fragment: string,
30
+ schema: string,
31
+ name: string,
32
+ ) => SyncCommandResolution | undefined;
33
+ createCommandContext: (command: SyncCommandDefinition) => unknown;
34
+ executeCommand: (command: SyncCommandDefinition, input: unknown, ctx: unknown) => Promise<void>;
35
+ maxCommandsPerSubmit?: number;
36
+ maxUnseenMutations?: number;
37
+ };
38
+
39
+ export type SyncSubmitError = {
40
+ status: "error";
41
+ statusCode: number;
42
+ body: {
43
+ error: {
44
+ code: string;
45
+ message: string;
46
+ detail?: string;
47
+ };
48
+ };
49
+ };
50
+
51
+ export type SyncSubmitResult =
52
+ | {
53
+ status: "ok";
54
+ response: SubmitResponse;
55
+ }
56
+ | SyncSubmitError;
57
+
58
+ const VALID_CONFLICT_RESOLUTION = new Set(["server", "disabled"] as const);
59
+ const VERSIONSTAMP_REGEX = /^[0-9a-f]{24}$/i;
60
+
61
+ const isObject = (value: unknown): value is Record<string, unknown> =>
62
+ value !== null && typeof value === "object";
63
+
64
+ const isNonEmptyString = (value: unknown): value is string =>
65
+ typeof value === "string" && value.trim().length > 0;
66
+
67
+ const normalizeVersionstamp = (value: string | undefined): string | undefined =>
68
+ value ? value.toLowerCase() : undefined;
69
+
70
+ const isValidVersionstamp = (value: string): boolean => VERSIONSTAMP_REGEX.test(value);
71
+
72
+ const buildError = (code: string, message: string, statusCode = 400): SyncSubmitError => ({
73
+ status: "error",
74
+ statusCode,
75
+ body: {
76
+ error: {
77
+ code,
78
+ message,
79
+ },
80
+ },
81
+ });
82
+
83
+ const withEntries = async (
84
+ runtime: SyncSubmitRuntime,
85
+ baseVersionstamp: string | undefined,
86
+ ): Promise<{ entries: OutboxEntry[]; lastVersionstamp?: string }> => {
87
+ const entries = await runtime.listOutboxEntries(baseVersionstamp);
88
+ const lastVersionstamp =
89
+ entries.length > 0 ? entries[entries.length - 1]?.versionstamp : undefined;
90
+ return { entries, lastVersionstamp };
91
+ };
92
+
93
+ export const submitSyncRequest = async (
94
+ raw: unknown,
95
+ runtime: SyncSubmitRuntime,
96
+ ): Promise<SyncSubmitResult> => {
97
+ if (!isObject(raw)) {
98
+ return buildError("INVALID_REQUEST", "Request body must be an object.");
99
+ }
100
+
101
+ const requestId = raw["requestId"];
102
+ if (!isNonEmptyString(requestId)) {
103
+ return buildError("INVALID_REQUEST", "requestId is required.");
104
+ }
105
+
106
+ const adapterIdentity = raw["adapterIdentity"];
107
+ if (!isNonEmptyString(adapterIdentity)) {
108
+ return buildError("INVALID_REQUEST", "adapterIdentity is required.");
109
+ }
110
+
111
+ const conflictResolutionStrategy = raw["conflictResolutionStrategy"];
112
+ if (
113
+ !isNonEmptyString(conflictResolutionStrategy) ||
114
+ !VALID_CONFLICT_RESOLUTION.has(conflictResolutionStrategy as "server" | "disabled")
115
+ ) {
116
+ return buildError(
117
+ "INVALID_REQUEST",
118
+ 'conflictResolutionStrategy must be "server" or "disabled".',
119
+ );
120
+ }
121
+
122
+ const baseVersionstamp = raw["baseVersionstamp"];
123
+ if (baseVersionstamp !== undefined && !isNonEmptyString(baseVersionstamp)) {
124
+ return buildError("INVALID_REQUEST", "baseVersionstamp must be a non-empty string.");
125
+ }
126
+
127
+ const normalizedBaseVersionstamp =
128
+ baseVersionstamp !== undefined ? normalizeVersionstamp(baseVersionstamp) : undefined;
129
+ if (normalizedBaseVersionstamp && !isValidVersionstamp(normalizedBaseVersionstamp)) {
130
+ return buildError("INVALID_VERSIONSTAMP", "baseVersionstamp must be 24 hex characters.");
131
+ }
132
+
133
+ const commands = raw["commands"];
134
+ if (!Array.isArray(commands)) {
135
+ return buildError("INVALID_REQUEST", "commands must be an array.");
136
+ }
137
+
138
+ const expectedAdapterIdentity = await runtime.getAdapterIdentity();
139
+ if (expectedAdapterIdentity !== adapterIdentity) {
140
+ return buildError(
141
+ "ADAPTER_IDENTITY_MISMATCH",
142
+ "adapterIdentity does not match this adapter.",
143
+ 409,
144
+ );
145
+ }
146
+
147
+ const existing = await runtime.getSyncRequest(requestId);
148
+ if (existing) {
149
+ const { entries, lastVersionstamp } = await withEntries(runtime, normalizedBaseVersionstamp);
150
+ const response: SubmitResponse = {
151
+ status: "conflict",
152
+ requestId,
153
+ confirmedCommandIds: existing.confirmedCommandIds ?? [],
154
+ conflictCommandId: existing.conflictCommandId ?? undefined,
155
+ lastVersionstamp: lastVersionstamp ?? existing.lastVersionstamp ?? undefined,
156
+ entries,
157
+ reason: "already_handled",
158
+ };
159
+ return { status: "ok", response };
160
+ }
161
+
162
+ const maxCommands = runtime.maxCommandsPerSubmit ?? DEFAULT_MAX_COMMANDS_PER_SUBMIT;
163
+ const maxUnseen = runtime.maxUnseenMutations ?? DEFAULT_MAX_UNSEEN_MUTATIONS;
164
+
165
+ if (commands.length === 0) {
166
+ const { entries, lastVersionstamp } = await withEntries(runtime, normalizedBaseVersionstamp);
167
+ const response: SubmitResponse = {
168
+ status: "conflict",
169
+ requestId,
170
+ confirmedCommandIds: [],
171
+ entries,
172
+ lastVersionstamp,
173
+ reason: "no_commands",
174
+ };
175
+ await runtime.storeSyncRequest({
176
+ requestId,
177
+ status: "conflict",
178
+ confirmedCommandIds: [],
179
+ baseVersionstamp: normalizedBaseVersionstamp,
180
+ lastVersionstamp,
181
+ });
182
+ return { status: "ok", response };
183
+ }
184
+
185
+ if (commands.length > maxCommands) {
186
+ const { entries, lastVersionstamp } = await withEntries(runtime, normalizedBaseVersionstamp);
187
+ const response: SubmitResponse = {
188
+ status: "conflict",
189
+ requestId,
190
+ confirmedCommandIds: [],
191
+ entries,
192
+ lastVersionstamp,
193
+ reason: "limit_exceeded",
194
+ };
195
+ await runtime.storeSyncRequest({
196
+ requestId,
197
+ status: "conflict",
198
+ confirmedCommandIds: [],
199
+ baseVersionstamp: normalizedBaseVersionstamp,
200
+ lastVersionstamp,
201
+ });
202
+ return { status: "ok", response };
203
+ }
204
+
205
+ const unseenCount = await runtime.countOutboxMutations(normalizedBaseVersionstamp);
206
+ if (unseenCount > maxUnseen) {
207
+ const { entries, lastVersionstamp } = await withEntries(runtime, normalizedBaseVersionstamp);
208
+ const response: SubmitResponse = {
209
+ status: "conflict",
210
+ requestId,
211
+ confirmedCommandIds: [],
212
+ entries,
213
+ lastVersionstamp,
214
+ reason: "client_far_behind",
215
+ };
216
+ await runtime.storeSyncRequest({
217
+ requestId,
218
+ status: "conflict",
219
+ confirmedCommandIds: [],
220
+ baseVersionstamp: normalizedBaseVersionstamp,
221
+ lastVersionstamp,
222
+ });
223
+ return { status: "ok", response };
224
+ }
225
+
226
+ const confirmedCommandIds: string[] = [];
227
+ let conflictCommandId: string | undefined;
228
+ let conflictReason: SubmitConflictReason | undefined;
229
+
230
+ for (const command of commands) {
231
+ if (!isObject(command)) {
232
+ return buildError("INVALID_COMMAND", "Command entries must be objects.");
233
+ }
234
+
235
+ const commandId = command["id"];
236
+ const commandName = command["name"];
237
+ const target = command["target"];
238
+
239
+ if (!isNonEmptyString(commandId) || !isNonEmptyString(commandName) || !isObject(target)) {
240
+ return buildError("INVALID_COMMAND", "Command entries must include id, name, and target.");
241
+ }
242
+
243
+ const fragmentName = target["fragment"];
244
+ const schemaName = target["schema"];
245
+
246
+ if (!isNonEmptyString(fragmentName) || !isNonEmptyString(schemaName)) {
247
+ return buildError("INVALID_COMMAND", "Command target must include fragment and schema.");
248
+ }
249
+
250
+ const resolved = runtime.resolveCommand(fragmentName, schemaName, commandName);
251
+ if (!resolved) {
252
+ return buildError("UNKNOWN_COMMAND", "Command target or name was not recognized.");
253
+ }
254
+
255
+ const ctx = runtime.createCommandContext(resolved.command);
256
+
257
+ try {
258
+ await runtime.executeCommand(resolved.command, command["input"], ctx);
259
+ confirmedCommandIds.push(commandId);
260
+ } catch (error) {
261
+ if (error instanceof ConcurrencyConflictError) {
262
+ conflictCommandId = commandId;
263
+ conflictReason = "write_congestion";
264
+ break;
265
+ }
266
+ await runtime.storeSyncRequest({
267
+ requestId,
268
+ status: "conflict",
269
+ confirmedCommandIds,
270
+ conflictCommandId: commandId,
271
+ baseVersionstamp: normalizedBaseVersionstamp,
272
+ });
273
+ return {
274
+ status: "error",
275
+ statusCode: 500,
276
+ body: {
277
+ error: {
278
+ code: "SYNC_COMMAND_FAILED",
279
+ message: error instanceof Error ? error.message : "Sync command failed.",
280
+ },
281
+ },
282
+ };
283
+ }
284
+ }
285
+
286
+ const { entries, lastVersionstamp } = await withEntries(runtime, normalizedBaseVersionstamp);
287
+
288
+ if (conflictReason) {
289
+ const response: SubmitResponse = {
290
+ status: "conflict",
291
+ requestId,
292
+ confirmedCommandIds,
293
+ conflictCommandId,
294
+ entries,
295
+ lastVersionstamp,
296
+ reason: conflictReason,
297
+ };
298
+
299
+ await runtime.storeSyncRequest({
300
+ requestId,
301
+ status: "conflict",
302
+ confirmedCommandIds,
303
+ conflictCommandId,
304
+ baseVersionstamp: normalizedBaseVersionstamp,
305
+ lastVersionstamp,
306
+ });
307
+
308
+ return { status: "ok", response };
309
+ }
310
+
311
+ const response: SubmitResponse = {
312
+ status: "applied",
313
+ requestId,
314
+ confirmedCommandIds,
315
+ entries,
316
+ lastVersionstamp,
317
+ };
318
+
319
+ await runtime.storeSyncRequest({
320
+ requestId,
321
+ status: "applied",
322
+ confirmedCommandIds,
323
+ baseVersionstamp: normalizedBaseVersionstamp,
324
+ lastVersionstamp,
325
+ });
326
+
327
+ return { status: "ok", response };
328
+ };
@@ -0,0 +1,80 @@
1
+ import type { RequestThisContext } from "@fragno-dev/core";
2
+
3
+ import type { OutboxEntry } from "../outbox/outbox";
4
+ import type {
5
+ ExecuteTxOptions,
6
+ HandlerTxBuilder,
7
+ } from "../query/unit-of-work/execute-unit-of-work";
8
+
9
+ export type SubmitRequest = {
10
+ baseVersionstamp?: string;
11
+ requestId: string;
12
+ conflictResolutionStrategy: "server" | "disabled";
13
+ adapterIdentity: string;
14
+ commands: Array<{
15
+ id: string;
16
+ name: string;
17
+ target: {
18
+ fragment: string;
19
+ schema: string;
20
+ };
21
+ input: unknown;
22
+ }>;
23
+ };
24
+
25
+ export type SubmitConflictReason =
26
+ | "conflict"
27
+ | "write_congestion"
28
+ | "client_far_behind"
29
+ | "no_commands"
30
+ | "already_handled"
31
+ | "limit_exceeded";
32
+
33
+ export type SubmitAppliedResponse = {
34
+ status: "applied";
35
+ requestId: string;
36
+ confirmedCommandIds: string[];
37
+ lastVersionstamp?: string;
38
+ entries: OutboxEntry[];
39
+ };
40
+
41
+ export type SubmitConflictResponse = {
42
+ status: "conflict";
43
+ requestId: string;
44
+ confirmedCommandIds: string[];
45
+ conflictCommandId?: string;
46
+ lastVersionstamp?: string;
47
+ entries: OutboxEntry[];
48
+ reason: SubmitConflictReason;
49
+ };
50
+
51
+ export type SubmitResponse = SubmitAppliedResponse | SubmitConflictResponse;
52
+
53
+ export type SyncCommandTxFactory = (
54
+ options?: Omit<ExecuteTxOptions, "createUnitOfWork">,
55
+ ) => HandlerTxBuilder<readonly [], [], [], unknown, unknown, false, false, false, false, {}>;
56
+
57
+ export type SyncCommandHandler<TInput = unknown, TContext = unknown> = (args: {
58
+ input: TInput;
59
+ tx: SyncCommandTxFactory;
60
+ ctx: TContext;
61
+ }) => Promise<unknown>;
62
+
63
+ export type SyncCommandDefinition<TInput = unknown, TContext = unknown> = {
64
+ name: string;
65
+ handler: SyncCommandHandler<TInput, TContext>;
66
+ createServerContext?: (requestContext: RequestThisContext) => TContext;
67
+ };
68
+
69
+ export type SyncCommandRegistry = {
70
+ schemaName: string;
71
+ commands: Map<string, SyncCommandDefinition>;
72
+ getCommand: (name: string) => SyncCommandDefinition | undefined;
73
+ };
74
+
75
+ export type SyncCommandTargetRegistration = {
76
+ fragmentName: string;
77
+ schemaName: string;
78
+ namespace: string | null;
79
+ commands: Map<string, SyncCommandDefinition>;
80
+ };
@@ -0,0 +1,119 @@
1
+ import fs from "node:fs";
2
+ import { createRequire } from "node:module";
3
+ import path from "node:path";
4
+
5
+ import { SqliteDialect } from "kysely";
6
+
7
+ import type { DatabaseAdapter } from "../adapters/adapters";
8
+ import { BetterSQLite3DriverConfig } from "../adapters/generic-sql/driver-config";
9
+ import { SqlAdapter } from "../adapters/generic-sql/generic-sql-adapter";
10
+ import type { AnySchema } from "../schema/create";
11
+ type DatabaseAdapterConfig = {
12
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
13
+ databaseAdapter?: DatabaseAdapter<any>;
14
+ databaseNamespace?: string | null;
15
+ };
16
+
17
+ type BetterSqlite3Constructor = typeof import("better-sqlite3");
18
+
19
+ const isCloudflareWorkers = (): boolean => {
20
+ if (typeof globalThis === "undefined") {
21
+ return false;
22
+ }
23
+ const navigatorRef = (globalThis as { navigator?: { userAgent?: string } }).navigator;
24
+ return navigatorRef?.userAgent === "Cloudflare-Workers";
25
+ };
26
+
27
+ const createNodeRequire = (): NodeRequire | null => {
28
+ try {
29
+ const metaUrl = typeof import.meta !== "undefined" ? import.meta.url : undefined;
30
+ if (!metaUrl || typeof metaUrl !== "string") {
31
+ return null;
32
+ }
33
+ return createRequire(metaUrl);
34
+ } catch {
35
+ return null;
36
+ }
37
+ };
38
+
39
+ const loadBetterSqlite3 = (): BetterSqlite3Constructor | null => {
40
+ if (isCloudflareWorkers()) {
41
+ return null;
42
+ }
43
+ const requireFn = createNodeRequire();
44
+ if (!requireFn) {
45
+ return null;
46
+ }
47
+ try {
48
+ const module = requireFn("better-sqlite3");
49
+ return (module.default ?? module) as BetterSqlite3Constructor;
50
+ } catch {
51
+ return null;
52
+ }
53
+ };
54
+
55
+ const betterSqlite3Constructor = loadBetterSqlite3();
56
+
57
+ const defaultDataDir = (): string => {
58
+ const configured = process.env["FRAGNO_DATA_DIR"];
59
+ if (configured && configured.trim().length > 0) {
60
+ return configured;
61
+ }
62
+ return path.join(process.env["HOME"] ?? process.cwd(), ".fragno");
63
+ };
64
+
65
+ const sanitizeFileSegment = (name: string): string => {
66
+ const sanitized = name.replace(/[^a-z0-9-]/gi, "_");
67
+ return sanitized.length > 0 ? sanitized : "fragno";
68
+ };
69
+
70
+ const resolveSqliteDatabasePath = <TSchema extends AnySchema>(
71
+ options: DatabaseAdapterConfig,
72
+ schema: TSchema,
73
+ ): string => {
74
+ const baseName =
75
+ typeof options.databaseNamespace === "string" && options.databaseNamespace.length > 0
76
+ ? options.databaseNamespace
77
+ : schema.name;
78
+ const fileName = `${sanitizeFileSegment(baseName)}.sqlite`;
79
+ return path.join(defaultDataDir(), fileName);
80
+ };
81
+
82
+ const createDefaultSqliteAdapter = <TSchema extends AnySchema>(
83
+ options: DatabaseAdapterConfig,
84
+ schema: TSchema,
85
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
86
+ ): DatabaseAdapter<any> | null => {
87
+ if (!betterSqlite3Constructor) {
88
+ return null;
89
+ }
90
+
91
+ const dbPath = resolveSqliteDatabasePath(options, schema);
92
+ fs.mkdirSync(path.dirname(dbPath), { recursive: true });
93
+
94
+ const dialect = new SqliteDialect({
95
+ database: new betterSqlite3Constructor(dbPath),
96
+ });
97
+ const driverConfig = new BetterSQLite3DriverConfig();
98
+ return new SqlAdapter({ dialect, driverConfig });
99
+ };
100
+
101
+ export const resolveDatabaseAdapter = <TSchema extends AnySchema>(
102
+ options: DatabaseAdapterConfig,
103
+ schema: TSchema,
104
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
105
+ ): DatabaseAdapter<any> => {
106
+ if (options.databaseAdapter) {
107
+ return options.databaseAdapter;
108
+ }
109
+
110
+ const defaultAdapter = createDefaultSqliteAdapter(options, schema);
111
+ if (!defaultAdapter) {
112
+ throw new Error(
113
+ "Database fragment requires options.databaseAdapter, or install better-sqlite3 to use the default SQLite adapter.",
114
+ );
115
+ }
116
+
117
+ options.databaseAdapter = defaultAdapter;
118
+ return defaultAdapter;
119
+ };
@@ -1,10 +1,6 @@
1
- import type { AnySchema } from "./schema/create";
2
- import type {
3
- RequestThisContext,
4
- FragnoPublicConfig,
5
- AnyFragnoInstantiatedFragment,
6
- } from "@fragno-dev/core";
7
- import { FragmentDefinitionBuilder, instantiate } from "@fragno-dev/core";
1
+ import type { RequestThisContext, FragnoPublicConfig, AnyRouteOrFactory } from "@fragno-dev/core";
2
+ import { FragmentDefinitionBuilder } from "@fragno-dev/core";
3
+
8
4
  import {
9
5
  DatabaseFragmentDefinitionBuilder,
10
6
  type DatabaseServiceContext,
@@ -13,12 +9,13 @@ import {
13
9
  type FragnoPublicConfigWithDatabase,
14
10
  type DatabaseRequestStorage,
15
11
  } from "./db-fragment-definition-builder";
16
- import { internalFragmentDef, type InternalFragmentInstance } from "./fragments/internal-fragment";
17
12
  import type { HooksMap } from "./hooks/hooks";
13
+ import { getInternalFragment, getRegistryForAdapterSync } from "./internal/adapter-registry";
14
+ import type { AnySchema } from "./schema/create";
18
15
 
19
16
  /**
20
17
  * Helper to add database support to a fragment builder.
21
- * Automatically links the internal fragment and adds ImplicitDatabaseDependencies to the TDeps type.
18
+ * Registers the schema with the adapter registry and adds ImplicitDatabaseDependencies to the TDeps type.
22
19
  *
23
20
  * @example
24
21
  * ```typescript
@@ -36,7 +33,6 @@ import type { HooksMap } from "./hooks/hooks";
36
33
  */
37
34
  export function withDatabase<TSchema extends AnySchema>(
38
35
  schema: TSchema,
39
- namespace?: string,
40
36
  ): <
41
37
  TConfig,
42
38
  TDeps,
@@ -47,7 +43,7 @@ export function withDatabase<TSchema extends AnySchema>(
47
43
  TServiceThisContext extends RequestThisContext,
48
44
  THandlerThisContext extends RequestThisContext,
49
45
  TRequestStorage,
50
- TLinkedFragments extends Record<string, AnyFragnoInstantiatedFragment>,
46
+ TInternalRoutes extends readonly AnyRouteOrFactory[],
51
47
  >(
52
48
  builder: FragmentDefinitionBuilder<
53
49
  TConfig,
@@ -60,7 +56,7 @@ export function withDatabase<TSchema extends AnySchema>(
60
56
  TServiceThisContext,
61
57
  THandlerThisContext,
62
58
  TRequestStorage,
63
- TLinkedFragments
59
+ TInternalRoutes
64
60
  >,
65
61
  ) => DatabaseFragmentDefinitionBuilder<
66
62
  TSchema,
@@ -73,7 +69,7 @@ export function withDatabase<TSchema extends AnySchema>(
73
69
  HooksMap,
74
70
  DatabaseServiceContext<HooksMap>,
75
71
  DatabaseHandlerContext,
76
- TLinkedFragments & { _fragno_internal: InternalFragmentInstance }
72
+ TInternalRoutes
77
73
  > {
78
74
  return <
79
75
  TConfig,
@@ -85,7 +81,7 @@ export function withDatabase<TSchema extends AnySchema>(
85
81
  TServiceThisContext extends RequestThisContext,
86
82
  THandlerThisContext extends RequestThisContext,
87
83
  TRequestStorage,
88
- TLinkedFragments extends Record<string, AnyFragnoInstantiatedFragment>,
84
+ TInternalRoutes extends readonly AnyRouteOrFactory[],
89
85
  >(
90
86
  builder: FragmentDefinitionBuilder<
91
87
  TConfig,
@@ -98,21 +94,9 @@ export function withDatabase<TSchema extends AnySchema>(
98
94
  TServiceThisContext,
99
95
  THandlerThisContext,
100
96
  TRequestStorage,
101
- TLinkedFragments
97
+ TInternalRoutes
102
98
  >,
103
99
  ) => {
104
- const builderWithInternal = builder.withLinkedFragment(
105
- "_fragno_internal",
106
- ({ config, options }) => {
107
- // Cast is safe: by the time this callback is invoked during fragment instantiation,
108
- // the options will be FragnoPublicConfigWithDatabase (enforced by DatabaseFragmentDefinitionBuilder)
109
- return instantiate(internalFragmentDef)
110
- .withConfig(config as {})
111
- .withOptions(options as FragnoPublicConfigWithDatabase)
112
- .build();
113
- },
114
- );
115
-
116
100
  // Cast is safe: we're creating a DatabaseFragmentDefinitionBuilder which internally uses
117
101
  // FragnoPublicConfigWithDatabase, but the input builder uses FragnoPublicConfig.
118
102
  // The database builder's build() method will enforce FragnoPublicConfigWithDatabase at the end.
@@ -130,9 +114,9 @@ export function withDatabase<TSchema extends AnySchema>(
130
114
  {}, // Start with empty hooks, provideHooks() will update this
131
115
  DatabaseServiceContext<{}>,
132
116
  DatabaseHandlerContext,
133
- TLinkedFragments & { _fragno_internal: InternalFragmentInstance }
117
+ TInternalRoutes
134
118
  >(
135
- builderWithInternal as unknown as FragmentDefinitionBuilder<
119
+ builder as unknown as FragmentDefinitionBuilder<
136
120
  TConfig,
137
121
  FragnoPublicConfigWithDatabase,
138
122
  TDeps & ImplicitDatabaseDependencies<TSchema>,
@@ -143,10 +127,15 @@ export function withDatabase<TSchema extends AnySchema>(
143
127
  DatabaseServiceContext<{}>,
144
128
  DatabaseHandlerContext,
145
129
  DatabaseRequestStorage,
146
- TLinkedFragments & { _fragno_internal: InternalFragmentInstance }
130
+ TInternalRoutes
147
131
  >,
148
132
  schema,
149
- namespace,
133
+ undefined,
134
+ undefined,
135
+ {
136
+ getRegistryForAdapterSync,
137
+ getInternalFragment,
138
+ },
150
139
  );
151
140
  };
152
141
  }
package/tsconfig.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "extends": "@fragno-private/typescript-config/tsconfig.base.json",
2
+ "extends": "@fragno-private/typescript-config/tsconfig.node.json",
3
3
  "compilerOptions": {
4
4
  "outDir": "./dist",
5
5
  "rootDir": ".",