@fragno-dev/db 0.2.2 → 0.3.0

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 (355) hide show
  1. package/.turbo/turbo-build.log +202 -140
  2. package/CHANGELOG.md +35 -0
  3. package/README.md +30 -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 +27 -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 +55 -16
  14. package/dist/adapters/generic-sql/generic-sql-adapter.js.map +1 -1
  15. package/dist/adapters/generic-sql/generic-sql-uow-executor.js +129 -3
  16. package/dist/adapters/generic-sql/generic-sql-uow-executor.js.map +1 -1
  17. package/dist/adapters/generic-sql/migration/dialect/mysql.js +24 -5
  18. package/dist/adapters/generic-sql/migration/dialect/mysql.js.map +1 -1
  19. package/dist/adapters/generic-sql/migration/dialect/postgres.js +6 -5
  20. package/dist/adapters/generic-sql/migration/dialect/postgres.js.map +1 -1
  21. package/dist/adapters/generic-sql/migration/dialect/sqlite.js +21 -10
  22. package/dist/adapters/generic-sql/migration/dialect/sqlite.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 +8 -8
  25. package/dist/adapters/generic-sql/migration/prepared-migrations.js.map +1 -1
  26. package/dist/adapters/generic-sql/migration/sql-generator.js +74 -51
  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 +6 -5
  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 +42 -4
  31. package/dist/adapters/generic-sql/query/cursor-utils.js.map +1 -1
  32. package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js +25 -17
  33. package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js.map +1 -1
  34. package/dist/adapters/generic-sql/query/select-builder.js +5 -3
  35. package/dist/adapters/generic-sql/query/select-builder.js.map +1 -1
  36. package/dist/adapters/generic-sql/query/sql-query-compiler.js +15 -12
  37. package/dist/adapters/generic-sql/query/sql-query-compiler.js.map +1 -1
  38. package/dist/adapters/generic-sql/query/where-builder.js +39 -29
  39. package/dist/adapters/generic-sql/query/where-builder.js.map +1 -1
  40. package/dist/adapters/generic-sql/sqlite-storage.d.ts +13 -0
  41. package/dist/adapters/generic-sql/sqlite-storage.d.ts.map +1 -0
  42. package/dist/adapters/generic-sql/sqlite-storage.js +15 -0
  43. package/dist/adapters/generic-sql/sqlite-storage.js.map +1 -0
  44. package/dist/adapters/generic-sql/uow-decoder.js +7 -3
  45. package/dist/adapters/generic-sql/uow-decoder.js.map +1 -1
  46. package/dist/adapters/generic-sql/uow-encoder.js +28 -8
  47. package/dist/adapters/generic-sql/uow-encoder.js.map +1 -1
  48. package/dist/adapters/in-memory/condition-evaluator.js +131 -0
  49. package/dist/adapters/in-memory/condition-evaluator.js.map +1 -0
  50. package/dist/adapters/in-memory/errors.d.ts +13 -0
  51. package/dist/adapters/in-memory/errors.d.ts.map +1 -0
  52. package/dist/adapters/in-memory/errors.js +23 -0
  53. package/dist/adapters/in-memory/errors.js.map +1 -0
  54. package/dist/adapters/in-memory/in-memory-adapter.d.ts +27 -0
  55. package/dist/adapters/in-memory/in-memory-adapter.d.ts.map +1 -0
  56. package/dist/adapters/in-memory/in-memory-adapter.js +176 -0
  57. package/dist/adapters/in-memory/in-memory-adapter.js.map +1 -0
  58. package/dist/adapters/in-memory/in-memory-uow.js +648 -0
  59. package/dist/adapters/in-memory/in-memory-uow.js.map +1 -0
  60. package/dist/adapters/in-memory/index.d.ts +4 -0
  61. package/dist/adapters/in-memory/index.js +4 -0
  62. package/dist/adapters/in-memory/options.d.ts +28 -0
  63. package/dist/adapters/in-memory/options.d.ts.map +1 -0
  64. package/dist/adapters/in-memory/options.js +61 -0
  65. package/dist/adapters/in-memory/options.js.map +1 -0
  66. package/dist/adapters/in-memory/reference-resolution.js +26 -0
  67. package/dist/adapters/in-memory/reference-resolution.js.map +1 -0
  68. package/dist/adapters/in-memory/sorted-array-index.js +129 -0
  69. package/dist/adapters/in-memory/sorted-array-index.js.map +1 -0
  70. package/dist/adapters/in-memory/store.js +71 -0
  71. package/dist/adapters/in-memory/store.js.map +1 -0
  72. package/dist/adapters/in-memory/value-comparison.js +28 -0
  73. package/dist/adapters/in-memory/value-comparison.js.map +1 -0
  74. package/dist/adapters/shared/from-unit-of-work-compiler.js.map +1 -1
  75. package/dist/adapters/shared/uow-operation-compiler.js +11 -11
  76. package/dist/adapters/shared/uow-operation-compiler.js.map +1 -1
  77. package/dist/adapters/sql/index.d.ts +5 -0
  78. package/dist/adapters/sql/index.js +4 -0
  79. package/dist/db-fragment-definition-builder.d.ts +18 -7
  80. package/dist/db-fragment-definition-builder.d.ts.map +1 -1
  81. package/dist/db-fragment-definition-builder.js +116 -54
  82. package/dist/db-fragment-definition-builder.js.map +1 -1
  83. package/dist/dispatchers/cloudflare-do/index.d.ts +26 -0
  84. package/dist/dispatchers/cloudflare-do/index.d.ts.map +1 -0
  85. package/dist/dispatchers/cloudflare-do/index.js +63 -0
  86. package/dist/dispatchers/cloudflare-do/index.js.map +1 -0
  87. package/dist/dispatchers/node/index.d.ts +17 -0
  88. package/dist/dispatchers/node/index.d.ts.map +1 -0
  89. package/dist/dispatchers/node/index.js +59 -0
  90. package/dist/dispatchers/node/index.js.map +1 -0
  91. package/dist/fragments/internal-fragment.d.ts +79 -2
  92. package/dist/fragments/internal-fragment.d.ts.map +1 -1
  93. package/dist/fragments/internal-fragment.js +150 -32
  94. package/dist/fragments/internal-fragment.js.map +1 -1
  95. package/dist/fragments/internal-fragment.routes.js +29 -0
  96. package/dist/fragments/internal-fragment.routes.js.map +1 -0
  97. package/dist/fragments/internal-fragment.schema.d.ts +9 -0
  98. package/dist/fragments/internal-fragment.schema.d.ts.map +1 -0
  99. package/dist/fragments/internal-fragment.schema.js +22 -0
  100. package/dist/fragments/internal-fragment.schema.js.map +1 -0
  101. package/dist/hooks/durable-hooks-processor.d.ts +14 -0
  102. package/dist/hooks/durable-hooks-processor.d.ts.map +1 -0
  103. package/dist/hooks/durable-hooks-processor.js +32 -0
  104. package/dist/hooks/durable-hooks-processor.js.map +1 -0
  105. package/dist/hooks/hooks.d.ts +42 -1
  106. package/dist/hooks/hooks.d.ts.map +1 -1
  107. package/dist/hooks/hooks.js +72 -6
  108. package/dist/hooks/hooks.js.map +1 -1
  109. package/dist/migration-engine/auto-from-schema.js +14 -11
  110. package/dist/migration-engine/auto-from-schema.js.map +1 -1
  111. package/dist/migration-engine/generation-engine.d.ts +16 -10
  112. package/dist/migration-engine/generation-engine.d.ts.map +1 -1
  113. package/dist/migration-engine/generation-engine.js +72 -33
  114. package/dist/migration-engine/generation-engine.js.map +1 -1
  115. package/dist/migration-engine/shared.js.map +1 -1
  116. package/dist/mod.d.ts +15 -8
  117. package/dist/mod.d.ts.map +1 -1
  118. package/dist/mod.js +14 -8
  119. package/dist/mod.js.map +1 -1
  120. package/dist/naming/sql-naming.d.ts +19 -0
  121. package/dist/naming/sql-naming.d.ts.map +1 -0
  122. package/dist/naming/sql-naming.js +116 -0
  123. package/dist/naming/sql-naming.js.map +1 -0
  124. package/dist/node_modules/.pnpm/{rou3@0.7.10 → rou3@0.7.12}/node_modules/rou3/dist/index.js +8 -5
  125. package/dist/node_modules/.pnpm/rou3@0.7.12/node_modules/rou3/dist/index.js.map +1 -0
  126. package/dist/outbox/outbox-builder.js +156 -0
  127. package/dist/outbox/outbox-builder.js.map +1 -0
  128. package/dist/outbox/outbox.d.ts +52 -0
  129. package/dist/outbox/outbox.d.ts.map +1 -0
  130. package/dist/outbox/outbox.js +37 -0
  131. package/dist/outbox/outbox.js.map +1 -0
  132. package/dist/packages/fragno/dist/api/fragment-definition-builder.js +3 -2
  133. package/dist/packages/fragno/dist/api/fragment-definition-builder.js.map +1 -1
  134. package/dist/packages/fragno/dist/api/fragment-instantiator.js +164 -20
  135. package/dist/packages/fragno/dist/api/fragment-instantiator.js.map +1 -1
  136. package/dist/packages/fragno/dist/api/request-input-context.js +67 -0
  137. package/dist/packages/fragno/dist/api/request-input-context.js.map +1 -1
  138. package/dist/packages/fragno/dist/api/route.js +14 -1
  139. package/dist/packages/fragno/dist/api/route.js.map +1 -1
  140. package/dist/packages/fragno/dist/internal/trace-context.js +12 -0
  141. package/dist/packages/fragno/dist/internal/trace-context.js.map +1 -0
  142. package/dist/query/column-defaults.js +20 -4
  143. package/dist/query/column-defaults.js.map +1 -1
  144. package/dist/query/cursor.d.ts +3 -1
  145. package/dist/query/cursor.d.ts.map +1 -1
  146. package/dist/query/cursor.js +45 -14
  147. package/dist/query/cursor.js.map +1 -1
  148. package/dist/query/db-now.d.ts +8 -0
  149. package/dist/query/db-now.d.ts.map +1 -0
  150. package/dist/query/db-now.js +7 -0
  151. package/dist/query/db-now.js.map +1 -0
  152. package/dist/query/serialize/create-sql-serializer.js +3 -2
  153. package/dist/query/serialize/create-sql-serializer.js.map +1 -1
  154. package/dist/query/serialize/dialect/mysql-serializer.js +12 -6
  155. package/dist/query/serialize/dialect/mysql-serializer.js.map +1 -1
  156. package/dist/query/serialize/dialect/postgres-serializer.js +25 -7
  157. package/dist/query/serialize/dialect/postgres-serializer.js.map +1 -1
  158. package/dist/query/serialize/dialect/sqlite-serializer.js +55 -11
  159. package/dist/query/serialize/dialect/sqlite-serializer.js.map +1 -1
  160. package/dist/query/serialize/sql-serializer.js +2 -2
  161. package/dist/query/serialize/sql-serializer.js.map +1 -1
  162. package/dist/query/simple-query-interface.d.ts +6 -1
  163. package/dist/query/simple-query-interface.d.ts.map +1 -1
  164. package/dist/query/unit-of-work/execute-unit-of-work.d.ts.map +1 -1
  165. package/dist/query/unit-of-work/execute-unit-of-work.js +11 -6
  166. package/dist/query/unit-of-work/execute-unit-of-work.js.map +1 -1
  167. package/dist/query/unit-of-work/unit-of-work.d.ts +50 -14
  168. package/dist/query/unit-of-work/unit-of-work.d.ts.map +1 -1
  169. package/dist/query/unit-of-work/unit-of-work.js +86 -5
  170. package/dist/query/unit-of-work/unit-of-work.js.map +1 -1
  171. package/dist/query/value-decoding.js +9 -6
  172. package/dist/query/value-decoding.js.map +1 -1
  173. package/dist/query/value-encoding.js +29 -9
  174. package/dist/query/value-encoding.js.map +1 -1
  175. package/dist/schema/create.d.ts +38 -14
  176. package/dist/schema/create.d.ts.map +1 -1
  177. package/dist/schema/create.js +81 -42
  178. package/dist/schema/create.js.map +1 -1
  179. package/dist/schema/generate-id.js +2 -2
  180. package/dist/schema/generate-id.js.map +1 -1
  181. package/dist/schema/type-conversion/create-sql-type-mapper.js +3 -2
  182. package/dist/schema/type-conversion/create-sql-type-mapper.js.map +1 -1
  183. package/dist/schema/type-conversion/dialect/sqlite.js +9 -0
  184. package/dist/schema/type-conversion/dialect/sqlite.js.map +1 -1
  185. package/dist/schema/validator.d.ts +10 -0
  186. package/dist/schema/validator.d.ts.map +1 -0
  187. package/dist/schema/validator.js +123 -0
  188. package/dist/schema/validator.js.map +1 -0
  189. package/dist/schema-output/drizzle.d.ts +30 -0
  190. package/dist/schema-output/drizzle.d.ts.map +1 -0
  191. package/dist/{adapters/drizzle/generate.js → schema-output/drizzle.js} +82 -56
  192. package/dist/schema-output/drizzle.js.map +1 -0
  193. package/dist/schema-output/prisma.d.ts +17 -0
  194. package/dist/schema-output/prisma.d.ts.map +1 -0
  195. package/dist/schema-output/prisma.js +296 -0
  196. package/dist/schema-output/prisma.js.map +1 -0
  197. package/dist/util/default-database-adapter.js +61 -0
  198. package/dist/util/default-database-adapter.js.map +1 -0
  199. package/dist/with-database.d.ts +1 -1
  200. package/dist/with-database.d.ts.map +1 -1
  201. package/dist/with-database.js +12 -3
  202. package/dist/with-database.js.map +1 -1
  203. package/package.json +43 -28
  204. package/src/adapters/adapters.ts +30 -24
  205. package/src/adapters/drizzle/migrate-drizzle.test.ts +54 -33
  206. package/src/adapters/drizzle/migration-parity-drizzle-kit.test.ts +599 -0
  207. package/src/adapters/drizzle/test-utils.ts +12 -8
  208. package/src/adapters/generic-sql/driver-config.ts +38 -0
  209. package/src/adapters/generic-sql/generic-sql-adapter.test.ts +5 -5
  210. package/src/adapters/generic-sql/generic-sql-adapter.ts +110 -24
  211. package/src/adapters/generic-sql/generic-sql-uow-executor.test.ts +54 -0
  212. package/src/adapters/generic-sql/generic-sql-uow-executor.ts +231 -3
  213. package/src/adapters/generic-sql/migration/adapter-migration-parity.test.ts +118 -0
  214. package/src/adapters/generic-sql/migration/dialect/mysql.test.ts +26 -8
  215. package/src/adapters/generic-sql/migration/dialect/mysql.ts +46 -8
  216. package/src/adapters/generic-sql/migration/dialect/postgres.test.ts +25 -7
  217. package/src/adapters/generic-sql/migration/dialect/postgres.ts +8 -4
  218. package/src/adapters/generic-sql/migration/dialect/sqlite.test.ts +47 -8
  219. package/src/adapters/generic-sql/migration/dialect/sqlite.ts +27 -12
  220. package/src/adapters/generic-sql/migration/prepared-migrations.test.ts +128 -39
  221. package/src/adapters/generic-sql/migration/prepared-migrations.ts +15 -8
  222. package/src/adapters/generic-sql/migration/sql-generator.ts +142 -65
  223. package/src/adapters/generic-sql/query/create-sql-query-compiler.ts +9 -6
  224. package/src/adapters/generic-sql/query/cursor-utils.test.ts +271 -0
  225. package/src/adapters/generic-sql/query/cursor-utils.ts +41 -6
  226. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.test.ts +27 -27
  227. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.ts +38 -24
  228. package/src/adapters/generic-sql/query/select-builder.test.ts +15 -11
  229. package/src/adapters/generic-sql/query/select-builder.ts +6 -2
  230. package/src/adapters/generic-sql/query/sql-query-compiler.test.ts +52 -2
  231. package/src/adapters/generic-sql/query/sql-query-compiler.ts +50 -15
  232. package/src/adapters/generic-sql/query/where-builder.test.ts +91 -17
  233. package/src/adapters/generic-sql/query/where-builder.ts +90 -38
  234. package/src/adapters/{kysely/kysely-adapter-pglite.test.ts → generic-sql/sql-adapter-pglite-migrations.test.ts} +6 -6
  235. package/src/adapters/generic-sql/sql-adapter-pglite-pagination.test.ts +806 -0
  236. package/src/adapters/{drizzle/drizzle-adapter-pglite.test.ts → generic-sql/sql-adapter-pglite-queries.test.ts} +11 -11
  237. package/src/adapters/generic-sql/{test/generic-drizzle-adapter-sqlite3.test.ts → sql-adapter-sqlite3-driver.test.ts} +10 -10
  238. package/src/adapters/{drizzle/drizzle-adapter-sqlite3.test.ts → generic-sql/sql-adapter-sqlite3-uow.test.ts} +7 -7
  239. package/src/adapters/{kysely/kysely-adapter-sqlocal.test.ts → generic-sql/sql-adapter-sqlocal.test.ts} +6 -6
  240. package/src/adapters/generic-sql/sqlite-storage.ts +20 -0
  241. package/src/adapters/generic-sql/uow-decoder.test.ts +1 -1
  242. package/src/adapters/generic-sql/uow-decoder.ts +21 -3
  243. package/src/adapters/generic-sql/uow-encoder.test.ts +33 -2
  244. package/src/adapters/generic-sql/uow-encoder.ts +50 -11
  245. package/src/adapters/in-memory/condition-evaluator.test.ts +193 -0
  246. package/src/adapters/in-memory/condition-evaluator.ts +275 -0
  247. package/src/adapters/in-memory/errors.ts +20 -0
  248. package/src/adapters/in-memory/in-memory-adapter.ts +277 -0
  249. package/src/adapters/in-memory/in-memory-uow.mutations.test.ts +296 -0
  250. package/src/adapters/in-memory/in-memory-uow.retrieval.test.ts +100 -0
  251. package/src/adapters/in-memory/in-memory-uow.ts +1348 -0
  252. package/src/adapters/in-memory/index.ts +3 -0
  253. package/src/adapters/in-memory/options.test.ts +41 -0
  254. package/src/adapters/in-memory/options.ts +87 -0
  255. package/src/adapters/in-memory/reference-resolution.test.ts +50 -0
  256. package/src/adapters/in-memory/reference-resolution.ts +67 -0
  257. package/src/adapters/in-memory/sorted-array-index.test.ts +123 -0
  258. package/src/adapters/in-memory/sorted-array-index.ts +228 -0
  259. package/src/adapters/in-memory/store.test.ts +68 -0
  260. package/src/adapters/in-memory/store.ts +145 -0
  261. package/src/adapters/in-memory/value-comparison.ts +53 -0
  262. package/src/adapters/in-memory/value-normalization.test.ts +57 -0
  263. package/src/adapters/prisma/prisma-adapter-sqlite3.test.ts +1163 -0
  264. package/src/adapters/shared/from-unit-of-work-compiler.ts +3 -1
  265. package/src/adapters/shared/uow-operation-compiler.ts +26 -16
  266. package/src/adapters/sql/index.ts +12 -0
  267. package/src/db-fragment-definition-builder.test.ts +30 -12
  268. package/src/db-fragment-definition-builder.ts +142 -73
  269. package/src/db-fragment-instantiator.test.ts +105 -13
  270. package/src/db-fragment-integration.test.ts +9 -7
  271. package/src/dispatchers/cloudflare-do/index.test.ts +73 -0
  272. package/src/dispatchers/cloudflare-do/index.ts +104 -0
  273. package/src/dispatchers/node/index.test.ts +91 -0
  274. package/src/dispatchers/node/index.ts +87 -0
  275. package/src/fragments/internal-fragment.routes.ts +42 -0
  276. package/src/fragments/internal-fragment.schema.ts +51 -0
  277. package/src/fragments/internal-fragment.test.ts +458 -8
  278. package/src/fragments/internal-fragment.ts +322 -63
  279. package/src/hooks/durable-hooks-processor.test.ts +117 -0
  280. package/src/hooks/durable-hooks-processor.ts +67 -0
  281. package/src/hooks/hooks.test.ts +165 -5
  282. package/src/hooks/hooks.ts +197 -9
  283. package/src/migration-engine/auto-from-schema.test.ts +14 -14
  284. package/src/migration-engine/auto-from-schema.ts +5 -2
  285. package/src/migration-engine/create.test.ts +2 -2
  286. package/src/migration-engine/generation-engine.test.ts +229 -104
  287. package/src/migration-engine/generation-engine.ts +94 -64
  288. package/src/migration-engine/shared.ts +1 -0
  289. package/src/mod.ts +64 -26
  290. package/src/naming/sql-naming.ts +180 -0
  291. package/src/outbox/outbox-builder.ts +241 -0
  292. package/src/outbox/outbox.test.ts +253 -0
  293. package/src/outbox/outbox.ts +137 -0
  294. package/src/query/column-defaults.ts +41 -3
  295. package/src/query/condition-builder.test.ts +3 -3
  296. package/src/query/cursor.test.ts +116 -18
  297. package/src/query/cursor.ts +75 -26
  298. package/src/query/db-now.ts +6 -0
  299. package/src/query/query-type.test.ts +2 -2
  300. package/src/query/serialize/create-sql-serializer.ts +7 -2
  301. package/src/query/serialize/dialect/mysql-serializer.ts +12 -4
  302. package/src/query/serialize/dialect/postgres-serializer.ts +34 -4
  303. package/src/query/serialize/dialect/sqlite-serializer.test.ts +51 -1
  304. package/src/query/serialize/dialect/sqlite-serializer.ts +92 -9
  305. package/src/query/serialize/sql-serializer.ts +4 -4
  306. package/src/query/simple-query-interface.ts +5 -0
  307. package/src/query/unit-of-work/execute-unit-of-work.test.ts +25 -1
  308. package/src/query/unit-of-work/execute-unit-of-work.ts +25 -8
  309. package/src/query/unit-of-work/unit-of-work-coordinator.test.ts +12 -12
  310. package/src/query/unit-of-work/unit-of-work-types.test.ts +1 -1
  311. package/src/query/unit-of-work/unit-of-work.test.ts +168 -37
  312. package/src/query/unit-of-work/unit-of-work.ts +203 -18
  313. package/src/query/value-decoding.test.ts +13 -2
  314. package/src/query/value-decoding.ts +17 -4
  315. package/src/query/value-encoding.test.ts +85 -2
  316. package/src/query/value-encoding.ts +56 -6
  317. package/src/schema/create.test.ts +129 -42
  318. package/src/schema/create.ts +185 -47
  319. package/src/schema/generate-id.test.ts +2 -2
  320. package/src/schema/generate-id.ts +2 -2
  321. package/src/schema/serialize.test.ts +14 -2
  322. package/src/schema/type-conversion/create-sql-type-mapper.ts +7 -2
  323. package/src/schema/type-conversion/dialect/sqlite.ts +18 -0
  324. package/src/schema/type-conversion/type-mapping.test.ts +25 -1
  325. package/src/schema/validator.test.ts +197 -0
  326. package/src/schema/validator.ts +231 -0
  327. package/src/{adapters/drizzle/generate.test.ts → schema-output/drizzle.test.ts} +179 -129
  328. package/src/{adapters/drizzle/generate.ts → schema-output/drizzle.ts} +143 -93
  329. package/src/schema-output/prisma.test.ts +536 -0
  330. package/src/schema-output/prisma.ts +573 -0
  331. package/src/util/default-database-adapter.ts +106 -0
  332. package/src/with-database.ts +22 -3
  333. package/tsdown.config.ts +6 -4
  334. package/dist/adapters/drizzle/drizzle-adapter.d.ts +0 -20
  335. package/dist/adapters/drizzle/drizzle-adapter.d.ts.map +0 -1
  336. package/dist/adapters/drizzle/drizzle-adapter.js +0 -27
  337. package/dist/adapters/drizzle/drizzle-adapter.js.map +0 -1
  338. package/dist/adapters/drizzle/generate.d.ts +0 -30
  339. package/dist/adapters/drizzle/generate.d.ts.map +0 -1
  340. package/dist/adapters/drizzle/generate.js.map +0 -1
  341. package/dist/adapters/kysely/kysely-adapter.d.ts +0 -19
  342. package/dist/adapters/kysely/kysely-adapter.d.ts.map +0 -1
  343. package/dist/adapters/kysely/kysely-adapter.js +0 -17
  344. package/dist/adapters/kysely/kysely-adapter.js.map +0 -1
  345. package/dist/adapters/shared/table-name-mapper.d.ts +0 -12
  346. package/dist/adapters/shared/table-name-mapper.d.ts.map +0 -1
  347. package/dist/adapters/shared/table-name-mapper.js +0 -43
  348. package/dist/adapters/shared/table-name-mapper.js.map +0 -1
  349. package/dist/node_modules/.pnpm/rou3@0.7.10/node_modules/rou3/dist/index.js.map +0 -1
  350. package/dist/schema-generator/schema-generator.d.ts +0 -15
  351. package/dist/schema-generator/schema-generator.d.ts.map +0 -1
  352. package/src/adapters/drizzle/drizzle-adapter.ts +0 -39
  353. package/src/adapters/kysely/kysely-adapter.ts +0 -27
  354. package/src/adapters/shared/table-name-mapper.ts +0 -50
  355. package/src/schema-generator/schema-generator.ts +0 -12
@@ -0,0 +1 @@
1
+ {"version":3,"file":"in-memory-uow.js","names":["selected: InMemoryRow","prefixed: InMemoryRow","matches: InMemoryRow[]","outputs: InMemoryRow[]","nextOutputs: InMemoryRow[]","results: InMemoryRow[]","row: InMemoryRow","resolvedUpdateValues: InMemoryRow","updatedRow: InMemoryRow","applied: typeof indexUpdates","removedEntries: typeof indexEntries","results: InMemoryRawResult[]","createdInternalIds: (bigint | null)[]","rollbackActions: Array<() => void>","#resolverFactory","output: Record<string, unknown>","columnValues: Record<string, unknown>","relationData: Record<string, Record<string, unknown>>","cursor: Cursor | undefined"],"sources":["../../../src/adapters/in-memory/in-memory-uow.ts"],"sourcesContent":["import type { AnySchema, AnyTable } from \"../../schema/create\";\nimport { FragnoId, FragnoReference } from \"../../schema/create\";\nimport { SQLocalDriverConfig } from \"../generic-sql/driver-config\";\nimport type {\n CompiledMutation,\n MutationOperation,\n MutationResult,\n RetrievalOperation,\n UOWCompiler,\n UOWDecoder,\n UOWExecutor,\n} from \"../../query/unit-of-work/unit-of-work\";\nimport { buildCondition } from \"../../query/condition-builder\";\nimport {\n encodeValues,\n encodeValuesWithDbDefaults,\n ReferenceSubquery,\n} from \"../../query/value-encoding\";\nimport { isDbNow } from \"../../query/db-now\";\nimport { createSQLSerializer } from \"../../query/serialize/create-sql-serializer\";\nimport type { CompiledJoin } from \"../../query/orm/orm\";\nimport {\n createCursorFromRecord,\n decodeCursor,\n type Cursor,\n type CursorResult,\n} from \"../../query/cursor\";\nimport type {\n InMemoryNamespaceStore,\n InMemoryRow,\n InMemoryStore,\n InMemoryTableStore,\n} from \"./store\";\nimport { buildIndexKey, ensureNamespaceStore, normalizeIndexValue } from \"./store\";\nimport { evaluateCondition } from \"./condition-evaluator\";\nimport { resolveReferenceSubqueries } from \"./reference-resolution\";\nimport type { ResolvedInMemoryAdapterOptions } from \"./options\";\nimport { compareNormalizedValues } from \"./value-comparison\";\nimport type { NamingResolver } from \"../../naming/sql-naming\";\n\ntype InMemoryCompiledQuery = RetrievalOperation<AnySchema> | MutationOperation<AnySchema>;\ntype InMemoryRawResult = InMemoryRow[] | { count: number }[];\ntype CursorInput = string | Cursor | undefined;\ntype ResolverFactory = (schema: AnySchema, namespace: string | null) => NamingResolver;\n\nconst getResolver = (\n schema: AnySchema,\n namespace: string | null | undefined,\n resolverFactory?: ResolverFactory,\n) => (resolverFactory ? resolverFactory(schema, namespace ?? null) : undefined);\n\nconst getPhysicalTableName = (table: AnyTable, resolver?: NamingResolver) =>\n resolver ? resolver.getTableName(table.name) : table.name;\n\nconst getPhysicalColumnName = (table: AnyTable, columnName: string, resolver?: NamingResolver) =>\n resolver ? resolver.getColumnName(table.name, columnName) : columnName;\n\nconst cursorSerializer = createSQLSerializer(new SQLocalDriverConfig());\n\nclass VersionConflictError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"VersionConflictError\";\n }\n}\n\nconst getNamespaceStore = (\n store: InMemoryStore,\n schema: AnySchema,\n namespace: string | null | undefined,\n resolver?: NamingResolver,\n): InMemoryNamespaceStore => {\n const namespaceKey = namespace ?? schema.name;\n return ensureNamespaceStore(store, namespaceKey, schema, resolver);\n};\n\nconst getTableStore = (\n namespaceStore: InMemoryNamespaceStore,\n table: AnyTable,\n resolver?: NamingResolver,\n): InMemoryTableStore => {\n const physicalTableName = getPhysicalTableName(table, resolver);\n const tableStore = namespaceStore.tables.get(physicalTableName);\n if (!tableStore) {\n throw new Error(`Missing in-memory table store for \"${physicalTableName}\".`);\n }\n return tableStore;\n};\n\nconst buildSelection = (\n table: AnyTable,\n select: undefined | true | readonly string[],\n _resolver?: NamingResolver,\n): Set<string> => {\n const selection = new Set<string>();\n\n if (!select || select === true) {\n for (const columnName of Object.keys(table.columns)) {\n selection.add(columnName);\n }\n } else {\n for (const columnName of select) {\n selection.add(columnName);\n }\n }\n\n selection.add(\"_internalId\");\n selection.add(\"_version\");\n\n return selection;\n};\n\nconst selectRow = (\n row: InMemoryRow,\n table: AnyTable,\n select: undefined | true | readonly string[],\n resolver?: NamingResolver,\n): InMemoryRow => {\n const selection = buildSelection(table, select, resolver);\n const selected: InMemoryRow = {};\n for (const columnName of selection) {\n const physicalColumnName = getPhysicalColumnName(table, columnName, resolver);\n if (Object.prototype.hasOwnProperty.call(row, physicalColumnName)) {\n selected[columnName] = row[physicalColumnName];\n }\n }\n return selected;\n};\n\nconst isNullish = (value: unknown): value is null | undefined =>\n value === null || value === undefined;\n\nconst prefixSelection = (\n row: InMemoryRow,\n table: AnyTable,\n select: undefined | true | readonly string[],\n prefix: string,\n resolver?: NamingResolver,\n): InMemoryRow => {\n const selected = selectRow(row, table, select, resolver);\n const prefixed: InMemoryRow = {};\n\n for (const key in selected) {\n prefixed[`${prefix}:${key}`] = selected[key];\n }\n\n return prefixed;\n};\n\nconst orderRows = (\n rows: InMemoryRow[],\n orderBy: [AnyTable[\"columns\"][string], \"asc\" | \"desc\"][] | undefined,\n resolver?: NamingResolver,\n): InMemoryRow[] => {\n if (!orderBy || orderBy.length === 0) {\n return rows;\n }\n\n return rows.slice().sort((left, right) => {\n for (const [column, direction] of orderBy) {\n const columnName = resolver\n ? resolver.getColumnName(column.tableName, column.name)\n : column.name;\n const leftValue = normalizeIndexValue(left[columnName], column);\n const rightValue = normalizeIndexValue(right[columnName], column);\n const comparison = compareNormalizedValues(leftValue, rightValue);\n if (comparison !== 0) {\n return direction === \"asc\" ? comparison : -comparison;\n }\n }\n return 0;\n });\n};\n\nconst assertOrderByIndexOnly = (\n table: AnyTable,\n orderBy: [AnyTable[\"columns\"][string], \"asc\" | \"desc\"][] | undefined,\n resolver?: NamingResolver,\n): void => {\n if (!orderBy || orderBy.length === 0) {\n return;\n }\n\n const direction = orderBy[0][1];\n if (!orderBy.every(([, dir]) => dir === direction)) {\n throw new Error(\n `In-memory adapter only supports orderByIndex; mixed orderBy directions found on table \"${table.name}\".`,\n );\n }\n\n const orderColumnNames = orderBy.map(([column]) =>\n resolver ? resolver.getColumnName(table.name, column.name) : column.name,\n );\n const idColumnName = resolver\n ? resolver.getColumnName(table.name, table.getIdColumn().name)\n : table.getIdColumn().name;\n if (orderColumnNames.length === 1 && orderColumnNames[0] === idColumnName) {\n return;\n }\n\n for (const index of Object.values(table.indexes)) {\n const indexColumnNames = (index.columnNames as readonly string[]).map((columnName) =>\n resolver ? resolver.getColumnName(table.name, columnName) : columnName,\n );\n if (indexColumnNames.length !== orderColumnNames.length) {\n continue;\n }\n let matches = true;\n for (let i = 0; i < indexColumnNames.length; i += 1) {\n if (indexColumnNames[i] !== orderColumnNames[i]) {\n matches = false;\n break;\n }\n }\n if (matches) {\n return;\n }\n }\n\n throw new Error(\n `In-memory adapter only supports orderByIndex; received orderBy on table \"${table.name}\".`,\n );\n};\n\nconst findJoinMatches = (\n parentRow: InMemoryRow,\n parentTable: AnyTable,\n join: CompiledJoin,\n namespaceStore: InMemoryNamespaceStore,\n resolver?: NamingResolver,\n now: () => Date = () => new Date(),\n): InMemoryRow[] => {\n const { relation, options } = join;\n if (options === false) {\n return [];\n }\n\n const targetTable = relation.table;\n const targetStore = getTableStore(namespaceStore, targetTable, resolver);\n const matches: InMemoryRow[] = [];\n\n assertOrderByIndexOnly(targetTable, options.orderBy, resolver);\n\n for (const row of targetStore.rows.values()) {\n let matchesJoin = true;\n\n for (const [left, right] of relation.on) {\n const leftColumn = parentTable.columns[left];\n if (!leftColumn) {\n throw new Error(`Column \"${left}\" not found on table \"${parentTable.name}\".`);\n }\n\n const rightColumn = targetTable.columns[right];\n if (!rightColumn) {\n throw new Error(`Column \"${right}\" not found on table \"${targetTable.name}\".`);\n }\n\n const actualRight = rightColumn.role === \"external-id\" ? \"_internalId\" : right;\n const actualRightColumn = targetTable.columns[actualRight];\n if (!actualRightColumn) {\n throw new Error(`Column \"${actualRight}\" not found on table \"${targetTable.name}\".`);\n }\n\n const leftValue = parentRow[getPhysicalColumnName(parentTable, left, resolver)];\n const rightValue = row[getPhysicalColumnName(targetTable, actualRight, resolver)];\n if (isNullish(leftValue) || isNullish(rightValue)) {\n matchesJoin = false;\n break;\n }\n\n const leftNormalized = normalizeIndexValue(leftValue, leftColumn);\n const rightNormalized = normalizeIndexValue(rightValue, actualRightColumn);\n if (compareNormalizedValues(leftNormalized, rightNormalized) !== 0) {\n matchesJoin = false;\n break;\n }\n }\n\n if (!matchesJoin) {\n continue;\n }\n\n if (\n options.where &&\n !evaluateCondition(options.where, targetTable, row, namespaceStore, resolver, now)\n ) {\n continue;\n }\n\n matches.push(row);\n }\n\n const ordered = orderRows(matches, options.orderBy, resolver);\n if (options.limit !== undefined) {\n return ordered.slice(0, Math.max(0, options.limit));\n }\n\n return ordered;\n};\n\nconst applyJoins = (\n baseOutput: InMemoryRow,\n parentRow: InMemoryRow,\n parentTable: AnyTable,\n joins: CompiledJoin[] | undefined,\n namespaceStore: InMemoryNamespaceStore,\n resolver?: NamingResolver,\n now: () => Date = () => new Date(),\n parentPath = \"\",\n): InMemoryRow[] => {\n if (!joins || joins.length === 0) {\n return [baseOutput];\n }\n\n let outputs: InMemoryRow[] = [baseOutput];\n\n for (const join of joins) {\n if (join.options === false) {\n continue;\n }\n\n const relationPath = parentPath ? `${parentPath}:${join.relation.name}` : join.relation.name;\n const nextOutputs: InMemoryRow[] = [];\n\n for (const currentOutput of outputs) {\n const matches = findJoinMatches(parentRow, parentTable, join, namespaceStore, resolver, now);\n\n if (matches.length === 0) {\n nextOutputs.push(currentOutput);\n continue;\n }\n\n for (const matchRow of matches) {\n const prefixed = prefixSelection(\n matchRow,\n join.relation.table,\n join.options.select,\n relationPath,\n resolver,\n );\n const merged = { ...currentOutput, ...prefixed };\n\n if (join.options.join && join.options.join.length > 0) {\n nextOutputs.push(\n ...applyJoins(\n merged,\n matchRow,\n join.relation.table,\n join.options.join,\n namespaceStore,\n resolver,\n now,\n relationPath,\n ),\n );\n } else {\n nextOutputs.push(merged);\n }\n }\n }\n\n outputs = nextOutputs;\n }\n\n return outputs;\n};\n\nconst getExternalId = (id: FragnoId | string): string =>\n typeof id === \"string\" ? id : id.externalId;\n\nconst getVersionToCheck = (id: FragnoId | string, checkVersion: boolean): number | undefined => {\n if (!checkVersion) {\n return undefined;\n }\n\n if (typeof id === \"string\") {\n throw new Error(\n \"Cannot use checkVersion with a string ID. Version checking requires a FragnoId.\",\n );\n }\n\n return id.version;\n};\n\nconst resolveReferenceSubqueriesOrThrow = (\n namespaceStore: InMemoryNamespaceStore,\n table: AnyTable,\n encodedValues: Record<string, unknown>,\n resolver?: NamingResolver,\n): Record<string, unknown> => {\n const resolved = resolveReferenceSubqueries(namespaceStore, encodedValues, resolver);\n for (const [key, value] of Object.entries(encodedValues)) {\n if (!(value instanceof ReferenceSubquery)) {\n continue;\n }\n\n if (resolved[key] === null || resolved[key] === undefined) {\n throw new Error(\n `Foreign key constraint violation on table \"${table.name}\" for column \"${key}\".`,\n );\n }\n }\n return resolved;\n};\n\nconst getReferencedColumn = (\n table: AnyTable,\n columnName: string,\n resolver?: NamingResolver,\n): { name: string; column: AnyTable[\"columns\"][string] } => {\n const column = table.columns[columnName];\n if (!column) {\n throw new Error(`Column \"${columnName}\" not found on table \"${table.name}\".`);\n }\n\n const actualName = column.role === \"external-id\" ? \"_internalId\" : columnName;\n const actualColumn = table.columns[actualName];\n if (!actualColumn) {\n throw new Error(`Column \"${actualName}\" not found on table \"${table.name}\".`);\n }\n\n return {\n name: getPhysicalColumnName(table, actualName, resolver),\n column: actualColumn,\n };\n};\n\nconst enforceOutgoingForeignKeys = (\n namespaceStore: InMemoryNamespaceStore,\n table: AnyTable,\n row: InMemoryRow,\n columnsToCheck?: Set<string>,\n resolver?: NamingResolver,\n): void => {\n for (const relation of Object.values(table.relations)) {\n if (relation.type !== \"one\") {\n continue;\n }\n\n const localColumnNames = relation.on.map(([local]) => local);\n if (columnsToCheck && !localColumnNames.some((name) => columnsToCheck.has(name))) {\n continue;\n }\n\n const localValues = localColumnNames.map(\n (name) => row[getPhysicalColumnName(table, name, resolver)],\n );\n if (localValues.some((value) => value === null || value === undefined)) {\n continue;\n }\n\n const referencedTable = relation.table;\n const referencedStore = getTableStore(namespaceStore, referencedTable, resolver);\n let foundMatch = false;\n\n for (const targetRow of referencedStore.rows.values()) {\n let matches = true;\n for (const [localName, foreignName] of relation.on) {\n if (!table.columns[localName]) {\n throw new Error(`Column \"${localName}\" not found on table \"${table.name}\".`);\n }\n\n const { name: actualForeignName, column: foreignColumn } = getReferencedColumn(\n referencedTable,\n foreignName,\n resolver,\n );\n const localValue = row[getPhysicalColumnName(table, localName, resolver)];\n const targetValue = targetRow[actualForeignName];\n\n const normalizedLocal = normalizeIndexValue(localValue, foreignColumn);\n const normalizedTarget = normalizeIndexValue(targetValue, foreignColumn);\n\n if (compareNormalizedValues(normalizedLocal, normalizedTarget) !== 0) {\n matches = false;\n break;\n }\n }\n\n if (matches) {\n foundMatch = true;\n break;\n }\n }\n\n if (!foundMatch) {\n throw new Error(\n `Foreign key constraint violation on table \"${table.name}\" for relation \"${relation.name}\".`,\n );\n }\n }\n};\n\nconst enforceNoIncomingForeignKeys = (\n namespaceStore: InMemoryNamespaceStore,\n schema: AnySchema,\n table: AnyTable,\n row: InMemoryRow,\n resolver?: NamingResolver,\n): void => {\n for (const sourceTable of Object.values(schema.tables)) {\n for (const relation of Object.values(sourceTable.relations)) {\n if (relation.type !== \"one\") {\n continue;\n }\n\n if (relation.table.name !== table.name) {\n continue;\n }\n\n const sourceStore = getTableStore(namespaceStore, sourceTable, resolver);\n const targetColumnInfo = relation.on.map(([, foreignName]) =>\n getReferencedColumn(table, foreignName, resolver),\n );\n const targetValues = targetColumnInfo.map(({ name }) => row[name]);\n if (targetValues.some((value) => value === null || value === undefined)) {\n continue;\n }\n\n for (const sourceRow of sourceStore.rows.values()) {\n let matches = true;\n for (let i = 0; i < relation.on.length; i += 1) {\n const [localName] = relation.on[i]!;\n const { column } = targetColumnInfo[i]!;\n const localValue = sourceRow[getPhysicalColumnName(sourceTable, localName, resolver)];\n if (localValue === null || localValue === undefined) {\n matches = false;\n break;\n }\n\n const normalizedLocal = normalizeIndexValue(localValue, column);\n const normalizedTarget = normalizeIndexValue(targetValues[i], column);\n if (compareNormalizedValues(normalizedLocal, normalizedTarget) !== 0) {\n matches = false;\n break;\n }\n }\n\n if (matches) {\n throw new Error(\n `Foreign key constraint violation on table \"${table.name}\" for relation \"${relation.name}\".`,\n );\n }\n }\n }\n }\n};\n\nconst findRowByExternalId = (\n tableStore: InMemoryTableStore,\n table: AnyTable,\n externalId: string,\n resolver?: NamingResolver,\n): { internalId: bigint; row: InMemoryRow } | undefined => {\n const idColumn = table.getIdColumn();\n const idColumnName = getPhysicalColumnName(table, idColumn.name, resolver);\n for (const [internalId, row] of tableStore.rows) {\n if (row[idColumnName] === externalId) {\n return { internalId, row };\n }\n }\n return undefined;\n};\n\nconst resolveCursorValue = (value: unknown, column: AnyTable[\"columns\"][string]): unknown => {\n if (value && typeof value === \"object\") {\n const maybeExternalId = (value as { externalId?: unknown }).externalId;\n const maybeInternalId = (value as { internalId?: unknown }).internalId;\n\n if (typeof maybeExternalId === \"string\") {\n if (column.role === \"external-id\") {\n return maybeExternalId;\n }\n if ((column.role === \"internal-id\" || column.role === \"reference\") && maybeInternalId) {\n return typeof maybeInternalId === \"string\" ? BigInt(maybeInternalId) : maybeInternalId;\n }\n }\n }\n\n return value;\n};\n\nconst buildCursorKey = (\n cursor: CursorInput,\n table: AnyTable,\n columnNames: readonly string[],\n resolver?: NamingResolver,\n): readonly unknown[] | undefined => {\n if (!cursor) {\n return undefined;\n }\n\n const cursorObj = typeof cursor === \"string\" ? decodeCursor(cursor) : cursor;\n\n const columnMap = resolver ? resolver.getColumnNameMap(table) : undefined;\n\n return columnNames.map((columnName) => {\n const logicalName = columnMap?.[columnName] ?? columnName;\n const column = table.columns[logicalName];\n if (!column) {\n throw new Error(`Column \"${logicalName}\" not found on table \"${table.name}\".`);\n }\n\n const rawValue = resolveCursorValue(cursorObj.indexValues[column.name], column);\n if (rawValue === undefined) {\n return undefined;\n }\n\n const deserialized = cursorSerializer.deserialize(rawValue, column);\n return normalizeIndexValue(deserialized, column);\n });\n};\n\nconst findRows = (\n op: Extract<RetrievalOperation<AnySchema>, { type: \"find\" }>,\n namespaceStore: InMemoryNamespaceStore,\n tableStore: InMemoryTableStore,\n resolver?: NamingResolver,\n now: () => Date = () => new Date(),\n): InMemoryRow[] => {\n const table = op.table;\n const orderByIndex = op.options.orderByIndex;\n const orderIndexName = orderByIndex?.indexName ?? op.indexName;\n const orderIndex = tableStore.indexes.get(orderIndexName);\n if (!orderIndex) {\n throw new Error(`Missing in-memory index \"${orderIndexName}\" on table \"${table.name}\".`);\n }\n const direction = orderByIndex?.direction ?? \"asc\";\n const afterKey = buildCursorKey(\n op.options.after,\n table,\n orderIndex.definition.columnNames,\n resolver,\n );\n const beforeKey = buildCursorKey(\n op.options.before,\n table,\n orderIndex.definition.columnNames,\n resolver,\n );\n const limit =\n op.withCursor && op.options.pageSize !== undefined\n ? op.options.pageSize + 1\n : op.options.pageSize;\n\n const scanOptions = {\n direction,\n limit,\n start: undefined as readonly unknown[] | undefined,\n startInclusive: true,\n end: undefined as readonly unknown[] | undefined,\n endInclusive: true,\n };\n\n if (afterKey) {\n if (direction === \"asc\") {\n scanOptions.start = afterKey;\n scanOptions.startInclusive = false;\n } else {\n scanOptions.end = afterKey;\n scanOptions.endInclusive = false;\n }\n }\n\n if (beforeKey) {\n if (direction === \"asc\") {\n scanOptions.end = beforeKey;\n scanOptions.endInclusive = false;\n } else {\n scanOptions.start = beforeKey;\n scanOptions.startInclusive = false;\n }\n }\n\n const entries = orderIndex.index.scan(scanOptions);\n\n const whereResult = op.options.where\n ? buildCondition(table.columns, op.options.where)\n : undefined;\n\n if (whereResult === false) {\n return [];\n }\n\n const condition = whereResult === true ? undefined : whereResult;\n const results: InMemoryRow[] = [];\n\n for (const entry of entries) {\n const row = tableStore.rows.get(entry.value);\n if (!row) {\n continue;\n }\n if (condition && !evaluateCondition(condition, table, row, namespaceStore, resolver, now)) {\n continue;\n }\n\n const baseOutput = selectRow(\n row,\n table,\n op.options.select as readonly string[] | true | undefined,\n resolver,\n );\n\n if (op.options.joins && op.options.joins.length > 0) {\n const joined = applyJoins(\n baseOutput,\n row,\n table,\n op.options.joins,\n namespaceStore,\n resolver,\n now,\n );\n for (const joinedRow of joined) {\n results.push(joinedRow);\n if (limit !== undefined && results.length >= limit) {\n break;\n }\n }\n } else {\n results.push(baseOutput);\n }\n\n if (limit !== undefined && results.length >= limit) {\n break;\n }\n }\n\n return results;\n};\n\nconst countRows = (\n op: Extract<RetrievalOperation<AnySchema>, { type: \"count\" }>,\n namespaceStore: InMemoryNamespaceStore,\n tableStore: InMemoryTableStore,\n resolver?: NamingResolver,\n now: () => Date = () => new Date(),\n): number => {\n const table = op.table;\n const whereResult = op.options.where\n ? buildCondition(table.columns, op.options.where)\n : undefined;\n\n if (whereResult === false) {\n return 0;\n }\n\n const condition = whereResult === true ? undefined : whereResult;\n let count = 0;\n\n for (const row of tableStore.rows.values()) {\n if (condition && !evaluateCondition(condition, table, row, namespaceStore, resolver, now)) {\n continue;\n }\n count += 1;\n }\n\n return count;\n};\n\nconst resolveDbNowValue = (value: unknown, options: ResolvedInMemoryAdapterOptions): unknown =>\n isDbNow(value) ? options.clock.now() : value;\n\nconst createRow = (\n op: Extract<MutationOperation<AnySchema>, { type: \"create\" }>,\n namespaceStore: InMemoryNamespaceStore,\n tableStore: InMemoryTableStore,\n options: ResolvedInMemoryAdapterOptions,\n resolver?: NamingResolver,\n): bigint => {\n const table = op.schema.tables[op.table];\n if (!table) {\n throw new Error(`Invalid table name ${op.table}.`);\n }\n\n const encoded = encodeValuesWithDbDefaults(\n op.values,\n table,\n {\n now: options.clock.now,\n createId: options.idGenerator,\n },\n resolver,\n );\n const resolvedValues = options.enforceConstraints\n ? resolveReferenceSubqueriesOrThrow(namespaceStore, table, encoded, resolver)\n : resolveReferenceSubqueries(namespaceStore, encoded, resolver);\n\n const row: InMemoryRow = {};\n for (const columnName of Object.keys(table.columns)) {\n const column = table.columns[columnName];\n if (!column || column.role === \"internal-id\") {\n continue;\n }\n\n const physicalColumnName = getPhysicalColumnName(table, column.name, resolver);\n const value = resolvedValues[physicalColumnName];\n if (value === undefined) {\n if (column.isNullable) {\n row[physicalColumnName] = null;\n continue;\n }\n\n if (column.role === \"version\") {\n row[physicalColumnName] = 0;\n continue;\n }\n\n throw new Error(`Missing required value for column \"${column.name}\".`);\n }\n\n row[physicalColumnName] = resolveDbNowValue(value, options);\n }\n\n const internalId = options.internalIdGeneratorProvided\n ? options.internalIdGenerator()\n : tableStore.nextInternalId;\n if (!options.internalIdGeneratorProvided) {\n tableStore.nextInternalId += 1n;\n }\n\n const internalIdColumnName = getPhysicalColumnName(table, \"_internalId\", resolver);\n const versionColumnName = getPhysicalColumnName(table, \"_version\", resolver);\n row[internalIdColumnName] = internalId;\n row[versionColumnName] = row[versionColumnName] ?? 0;\n\n if (options.enforceConstraints) {\n enforceOutgoingForeignKeys(namespaceStore, table, row, undefined, resolver);\n }\n\n tableStore.rows.set(internalId, row);\n\n for (const indexStore of tableStore.indexes.values()) {\n const key = buildIndexKey(table, indexStore.definition, row, resolver);\n indexStore.index.insert(key, internalId, { enforceUnique: options.enforceConstraints });\n }\n\n return internalId;\n};\n\nconst updateRow = (\n op: Extract<MutationOperation<AnySchema>, { type: \"update\" }>,\n namespaceStore: InMemoryNamespaceStore,\n tableStore: InMemoryTableStore,\n options: ResolvedInMemoryAdapterOptions,\n resolver?: NamingResolver,\n): (() => void) | null => {\n const table = op.schema.tables[op.table];\n if (!table) {\n throw new Error(`Invalid table name ${op.table}.`);\n }\n\n const externalId = getExternalId(op.id);\n const versionToCheck = getVersionToCheck(op.id, op.checkVersion);\n const existing = findRowByExternalId(tableStore, table, externalId, resolver);\n if (!existing) {\n if (versionToCheck !== undefined) {\n throw new VersionConflictError(`Version conflict: row \"${externalId}\" not found.`);\n }\n return null;\n }\n\n const versionColumnName = getPhysicalColumnName(table, \"_version\", resolver);\n const currentVersion = Number(existing.row[versionColumnName] ?? 0);\n if (versionToCheck !== undefined && currentVersion !== versionToCheck) {\n throw new VersionConflictError(`Version conflict: row \"${externalId}\" has changed.`);\n }\n\n const encoded = encodeValues(op.set as Record<string, unknown>, table, false, {}, resolver);\n const resolvedValues = options.enforceConstraints\n ? resolveReferenceSubqueriesOrThrow(namespaceStore, table, encoded, resolver)\n : resolveReferenceSubqueries(namespaceStore, encoded, resolver);\n\n const resolvedUpdateValues: InMemoryRow = {};\n for (const [columnName, value] of Object.entries(resolvedValues)) {\n resolvedUpdateValues[columnName] = resolveDbNowValue(value, options);\n }\n\n const updatedRow: InMemoryRow = { ...existing.row, ...resolvedUpdateValues };\n updatedRow[versionColumnName] = currentVersion + 1;\n\n if (options.enforceConstraints) {\n enforceOutgoingForeignKeys(\n namespaceStore,\n table,\n updatedRow,\n new Set(Object.keys(resolvedValues)),\n resolver,\n );\n }\n\n const indexUpdates = Array.from(tableStore.indexes.values()).map((indexStore) => ({\n indexStore,\n oldKey: buildIndexKey(table, indexStore.definition, existing.row, resolver),\n newKey: buildIndexKey(table, indexStore.definition, updatedRow, resolver),\n }));\n\n const applied: typeof indexUpdates = [];\n try {\n for (const update of indexUpdates) {\n update.indexStore.index.update(update.oldKey, update.newKey, existing.internalId, {\n enforceUnique: options.enforceConstraints,\n });\n applied.push(update);\n }\n } catch (error) {\n for (const update of applied.reverse()) {\n update.indexStore.index.update(update.newKey, update.oldKey, existing.internalId, {\n enforceUnique: options.enforceConstraints,\n });\n }\n throw error;\n }\n\n tableStore.rows.set(existing.internalId, updatedRow);\n\n return () => {\n for (const update of indexUpdates.slice().reverse()) {\n update.indexStore.index.update(update.newKey, update.oldKey, existing.internalId, {\n enforceUnique: options.enforceConstraints,\n });\n }\n tableStore.rows.set(existing.internalId, existing.row);\n };\n};\n\nconst deleteRow = (\n op: Extract<MutationOperation<AnySchema>, { type: \"delete\" }>,\n namespaceStore: InMemoryNamespaceStore,\n tableStore: InMemoryTableStore,\n table: AnyTable,\n options: ResolvedInMemoryAdapterOptions,\n resolver?: NamingResolver,\n): (() => void) | null => {\n const externalId = getExternalId(op.id);\n const versionToCheck = getVersionToCheck(op.id, op.checkVersion);\n const existing = findRowByExternalId(tableStore, table, externalId, resolver);\n if (!existing) {\n if (versionToCheck !== undefined) {\n throw new VersionConflictError(`Version conflict: row \"${externalId}\" not found.`);\n }\n return null;\n }\n\n const versionColumnName = getPhysicalColumnName(table, \"_version\", resolver);\n const currentVersion = Number(existing.row[versionColumnName] ?? 0);\n if (versionToCheck !== undefined && currentVersion !== versionToCheck) {\n throw new VersionConflictError(`Version conflict: row \"${externalId}\" has changed.`);\n }\n\n if (options.enforceConstraints) {\n enforceNoIncomingForeignKeys(namespaceStore, op.schema, table, existing.row, resolver);\n }\n\n const indexEntries = Array.from(tableStore.indexes.values()).map((indexStore) => ({\n indexStore,\n key: buildIndexKey(table, indexStore.definition, existing.row, resolver),\n }));\n\n const removedEntries: typeof indexEntries = [];\n for (const entry of indexEntries) {\n const removed = entry.indexStore.index.remove(entry.key, existing.internalId);\n if (!removed) {\n for (const removedEntry of removedEntries) {\n removedEntry.indexStore.index.insert(removedEntry.key, existing.internalId, {\n enforceUnique: options.enforceConstraints,\n });\n }\n throw new Error(\"Failed to remove index entry during delete.\");\n }\n removedEntries.push(entry);\n }\n\n tableStore.rows.delete(existing.internalId);\n\n return () => {\n tableStore.rows.set(existing.internalId, existing.row);\n for (const entry of indexEntries) {\n entry.indexStore.index.insert(entry.key, existing.internalId, {\n enforceUnique: options.enforceConstraints,\n });\n }\n };\n};\n\nconst checkRow = (\n op: Extract<MutationOperation<AnySchema>, { type: \"check\" }>,\n tableStore: InMemoryTableStore,\n table: AnyTable,\n resolver?: NamingResolver,\n): void => {\n const existing = findRowByExternalId(tableStore, table, op.id.externalId, resolver);\n if (!existing) {\n throw new VersionConflictError(`Version conflict: row \"${op.id.externalId}\" not found.`);\n }\n\n const versionColumnName = getPhysicalColumnName(table, \"_version\", resolver);\n const currentVersion = Number(existing.row[versionColumnName] ?? 0);\n if (currentVersion !== op.id.version) {\n throw new VersionConflictError(`Version conflict: row \"${op.id.externalId}\" has changed.`);\n }\n};\n\nexport const createInMemoryUowCompiler = (): UOWCompiler<InMemoryCompiledQuery> => ({\n compileRetrievalOperation(op: RetrievalOperation<AnySchema>): InMemoryCompiledQuery | null {\n return op;\n },\n compileMutationOperation(\n op: MutationOperation<AnySchema>,\n ): CompiledMutation<InMemoryCompiledQuery> | null {\n return {\n query: op,\n operation: op,\n op: op.type,\n expectedAffectedRows: null,\n expectedReturnedRows: null,\n };\n },\n});\n\nexport const createInMemoryUowExecutor = (\n store: InMemoryStore,\n options: ResolvedInMemoryAdapterOptions,\n resolverFactory?: ResolverFactory,\n): UOWExecutor<InMemoryCompiledQuery, InMemoryRawResult> => ({\n async executeRetrievalPhase(\n retrievalBatch: InMemoryCompiledQuery[],\n ): Promise<InMemoryRawResult[]> {\n const results: InMemoryRawResult[] = [];\n\n for (const compiled of retrievalBatch) {\n if (compiled.type === \"count\" || compiled.type === \"find\") {\n const resolver = getResolver(compiled.schema, compiled.namespace, resolverFactory);\n const namespaceStore = getNamespaceStore(\n store,\n compiled.schema,\n compiled.namespace,\n resolver,\n );\n const tableStore = getTableStore(namespaceStore, compiled.table, resolver);\n\n if (compiled.type === \"find\") {\n results.push(findRows(compiled, namespaceStore, tableStore, resolver, options.clock.now));\n } else {\n results.push([\n { count: countRows(compiled, namespaceStore, tableStore, resolver, options.clock.now) },\n ]);\n }\n continue;\n }\n\n throw new Error(`Unsupported in-memory retrieval operation: ${compiled.type}`);\n }\n\n return results;\n },\n\n async executeMutationPhase(\n mutationBatch: CompiledMutation<InMemoryCompiledQuery>[],\n ): Promise<MutationResult> {\n const createdInternalIds: (bigint | null)[] = [];\n const rollbackActions: Array<() => void> = [];\n\n try {\n for (const compiled of mutationBatch) {\n const operation = compiled.query;\n\n if (operation.type === \"create\") {\n const resolver = getResolver(operation.schema, operation.namespace, resolverFactory);\n const namespaceStore = getNamespaceStore(\n store,\n operation.schema,\n operation.namespace,\n resolver,\n );\n const table = operation.schema.tables[operation.table];\n if (!table) {\n throw new Error(`Invalid table name ${operation.table}.`);\n }\n const tableStore = getTableStore(namespaceStore, table, resolver);\n const previousInternalId = tableStore.nextInternalId;\n const internalId = createRow(operation, namespaceStore, tableStore, options, resolver);\n createdInternalIds.push(internalId);\n rollbackActions.push(() => {\n const row = tableStore.rows.get(internalId);\n if (row) {\n for (const indexStore of tableStore.indexes.values()) {\n const key = buildIndexKey(table, indexStore.definition, row, resolver);\n indexStore.index.remove(key, internalId);\n }\n tableStore.rows.delete(internalId);\n }\n tableStore.nextInternalId = previousInternalId;\n });\n continue;\n }\n\n if (operation.type === \"update\") {\n const resolver = getResolver(operation.schema, operation.namespace, resolverFactory);\n const namespaceStore = getNamespaceStore(\n store,\n operation.schema,\n operation.namespace,\n resolver,\n );\n const table = operation.schema.tables[operation.table];\n if (!table) {\n throw new Error(`Invalid table name ${operation.table}.`);\n }\n const tableStore = getTableStore(namespaceStore, table, resolver);\n const rollback = updateRow(operation, namespaceStore, tableStore, options, resolver);\n if (rollback) {\n rollbackActions.push(rollback);\n }\n continue;\n }\n\n if (operation.type === \"delete\") {\n const resolver = getResolver(operation.schema, operation.namespace, resolverFactory);\n const namespaceStore = getNamespaceStore(\n store,\n operation.schema,\n operation.namespace,\n resolver,\n );\n const table = operation.schema.tables[operation.table];\n if (!table) {\n throw new Error(`Invalid table name ${operation.table}.`);\n }\n const tableStore = getTableStore(namespaceStore, table, resolver);\n const rollback = deleteRow(\n operation,\n namespaceStore,\n tableStore,\n table,\n options,\n resolver,\n );\n if (rollback) {\n rollbackActions.push(rollback);\n }\n continue;\n }\n\n if (operation.type === \"check\") {\n const resolver = getResolver(operation.schema, operation.namespace, resolverFactory);\n const namespaceStore = getNamespaceStore(\n store,\n operation.schema,\n operation.namespace,\n resolver,\n );\n const table = operation.schema.tables[operation.table];\n if (!table) {\n throw new Error(`Invalid table name ${operation.table}.`);\n }\n const tableStore = getTableStore(namespaceStore, table, resolver);\n checkRow(operation, tableStore, table, resolver);\n continue;\n }\n\n throw new Error(`Unsupported in-memory mutation \"${operation.type}\".`);\n }\n } catch (error) {\n for (const rollback of rollbackActions.reverse()) {\n rollback();\n }\n if (error instanceof VersionConflictError) {\n return { success: false };\n }\n throw error;\n }\n\n return { success: true, createdInternalIds };\n },\n});\n\nexport class InMemoryUowDecoder implements UOWDecoder<InMemoryRawResult> {\n readonly #resolverFactory?: ResolverFactory;\n\n constructor(resolverFactory?: ResolverFactory) {\n this.#resolverFactory = resolverFactory;\n }\n\n decode(rawResults: InMemoryRawResult[], operations: RetrievalOperation<AnySchema>[]): unknown[] {\n if (rawResults.length !== operations.length) {\n throw new Error(\"rawResults and ops must have the same length\");\n }\n\n return rawResults.map((result, index) => {\n const op = operations[index];\n if (!op) {\n throw new Error(\"op must be defined\");\n }\n\n if (op.type === \"count\") {\n return this.decodeCount(result);\n }\n\n const resolver = getResolver(op.schema, op.namespace, this.#resolverFactory);\n const rows = result as InMemoryRow[];\n const decodedRows = rows.map((row) => this.decodeRow(row, op.table, resolver));\n\n if (op.withCursor) {\n return this.decodeCursorResult(decodedRows, op.table, op);\n }\n\n return decodedRows;\n });\n }\n\n private decodeCount(result: InMemoryRawResult): number {\n if (typeof result === \"number\") {\n return result;\n }\n\n const rows = result as { count: number }[];\n const first = rows[0];\n if (!first) {\n return 0;\n }\n const count = Number(first.count);\n if (Number.isNaN(count)) {\n throw new Error(`Unexpected result for count, received: ${first.count}`);\n }\n return count;\n }\n\n private decodeRow(\n row: InMemoryRow,\n table: AnyTable,\n resolver?: NamingResolver,\n ): Record<string, unknown> {\n const output: Record<string, unknown> = {};\n const columnValues: Record<string, unknown> = {};\n const relationData: Record<string, Record<string, unknown>> = {};\n const columnMap = resolver ? resolver.getColumnNameMap(table) : undefined;\n\n for (const key in row) {\n const colonIndex = key.indexOf(\":\");\n if (colonIndex === -1) {\n const logicalName = columnMap?.[key] ?? key;\n if (table.columns[logicalName]) {\n columnValues[logicalName] = row[key];\n }\n continue;\n }\n\n const relationName = key.slice(0, colonIndex);\n const remainder = key.slice(colonIndex + 1);\n const relation = table.relations[relationName];\n if (!relation) {\n continue;\n }\n\n relationData[relationName] ??= {};\n relationData[relationName][remainder] = row[key];\n }\n\n for (const relationName in relationData) {\n const relation = table.relations[relationName];\n if (!relation) {\n continue;\n }\n output[relationName] = this.decodeRow(relationData[relationName], relation.table, resolver);\n }\n\n for (const key in columnValues) {\n const column = table.columns[key];\n if (!column) {\n continue;\n }\n if (column.isHidden) {\n continue;\n }\n\n if (column.role === \"external-id\" && columnValues[\"_internalId\"] !== undefined) {\n output[key] = new FragnoId({\n externalId: columnValues[key] as string,\n internalId: columnValues[\"_internalId\"] as bigint,\n version: columnValues[\"_version\"] as number,\n });\n continue;\n }\n\n if (column.role === \"reference\") {\n const value = columnValues[key];\n output[key] =\n value === null || value === undefined\n ? null\n : FragnoReference.fromInternal(value as bigint);\n continue;\n }\n\n output[key] = columnValues[key];\n }\n\n return output;\n }\n\n private decodeCursorResult(\n decodedRows: Record<string, unknown>[],\n table: AnyTable,\n operation: Extract<RetrievalOperation<AnySchema>, { type: \"find\" }>,\n ): CursorResult<unknown> {\n let cursor: Cursor | undefined;\n let hasNextPage = false;\n let items = decodedRows;\n\n if (\n operation.options.pageSize &&\n operation.options.pageSize > 0 &&\n decodedRows.length > operation.options.pageSize\n ) {\n hasNextPage = true;\n items = decodedRows.slice(0, operation.options.pageSize);\n\n if (operation.options.orderByIndex) {\n const lastItem = items[items.length - 1];\n const indexName = operation.options.orderByIndex.indexName;\n\n let indexColumns;\n if (indexName === \"_primary\") {\n indexColumns = [table.getIdColumn()];\n } else {\n const index = table.indexes[indexName];\n if (index) {\n indexColumns = index.columns;\n }\n }\n\n if (indexColumns && lastItem) {\n cursor = createCursorFromRecord(lastItem, indexColumns, {\n indexName: operation.options.orderByIndex.indexName,\n orderDirection: operation.options.orderByIndex.direction,\n pageSize: operation.options.pageSize,\n });\n }\n }\n }\n\n return {\n items,\n cursor,\n hasNextPage,\n };\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { InMemoryAdapterOptions, ResolvedInMemoryAdapterOptions } from "./options.js";
2
+ import { InMemoryAdapter, InMemoryUowConfig } from "./in-memory-adapter.js";
3
+ import { ForeignKeyConstraintError, NotFoundError, UniqueConstraintError } from "./errors.js";
4
+ export { ForeignKeyConstraintError, InMemoryAdapter, type InMemoryAdapterOptions, type InMemoryUowConfig, NotFoundError, type ResolvedInMemoryAdapterOptions, UniqueConstraintError };
@@ -0,0 +1,4 @@
1
+ import { ForeignKeyConstraintError, NotFoundError, UniqueConstraintError } from "./errors.js";
2
+ import { InMemoryAdapter } from "./in-memory-adapter.js";
3
+
4
+ export { ForeignKeyConstraintError, InMemoryAdapter, NotFoundError, UniqueConstraintError };
@@ -0,0 +1,28 @@
1
+ import { SqlNamingStrategy } from "../../naming/sql-naming.js";
2
+
3
+ //#region src/adapters/in-memory/options.d.ts
4
+ type InMemoryAdapterOptions = {
5
+ clock?: {
6
+ now: () => Date;
7
+ };
8
+ idGenerator?: () => string;
9
+ idSeed?: string;
10
+ internalIdGenerator?: () => bigint;
11
+ enforceConstraints?: boolean;
12
+ btreeOrder?: number;
13
+ namingStrategy?: SqlNamingStrategy;
14
+ };
15
+ type ResolvedInMemoryAdapterOptions = {
16
+ clock: {
17
+ now: () => Date;
18
+ };
19
+ idGenerator: () => string;
20
+ idSeed: string;
21
+ internalIdGenerator: () => bigint;
22
+ internalIdGeneratorProvided: boolean;
23
+ enforceConstraints: boolean;
24
+ btreeOrder: number;
25
+ };
26
+ //#endregion
27
+ export { InMemoryAdapterOptions, ResolvedInMemoryAdapterOptions };
28
+ //# sourceMappingURL=options.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"options.d.ts","names":[],"sources":["../../../src/adapters/in-memory/options.ts"],"sourcesContent":[],"mappings":";;;KAGY,sBAAA;;IAAA,GAAA,EAAA,GAAA,GACW,IADX;EAUA,CAAA;;;;;;mBAHO;;KAGP,8BAAA;;eACU"}
@@ -0,0 +1,61 @@
1
+ import { createId, init } from "@paralleldrive/cuid2";
2
+
3
+ //#region src/adapters/in-memory/options.ts
4
+ const defaultClock = { now: () => /* @__PURE__ */ new Date() };
5
+ const defaultBtreeOrder = 32;
6
+ const defaultEnforceConstraints = true;
7
+ const initialCountMax = 476782367;
8
+ const seededRandomStep = 1831565813;
9
+ const createCounter = (start) => {
10
+ let value = start;
11
+ return () => value++;
12
+ };
13
+ const hashSeed = (seed) => {
14
+ let hash = 2166136261;
15
+ for (let i = 0; i < seed.length; i += 1) {
16
+ hash ^= seed.charCodeAt(i);
17
+ hash = Math.imul(hash, 16777619);
18
+ }
19
+ return hash >>> 0;
20
+ };
21
+ const createSeededRandom = (seed) => {
22
+ let state = hashSeed(seed);
23
+ return () => {
24
+ state |= 0;
25
+ state = state + seededRandomStep | 0;
26
+ let t = Math.imul(state ^ state >>> 15, 1 | state);
27
+ t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
28
+ return ((t ^ t >>> 14) >>> 0) / 4294967296;
29
+ };
30
+ };
31
+ const createSeededIdGenerator = (seed) => {
32
+ const random = createSeededRandom(seed);
33
+ return init({
34
+ random,
35
+ counter: createCounter(Math.floor(random() * initialCountMax))
36
+ });
37
+ };
38
+ const createInternalIdGenerator = () => {
39
+ let current = 0n;
40
+ return () => {
41
+ current += 1n;
42
+ return current;
43
+ };
44
+ };
45
+ const resolveInMemoryAdapterOptions = (options = {}) => {
46
+ const idSeed = options.idSeed ?? createId();
47
+ const internalIdGeneratorProvided = options.internalIdGenerator !== void 0;
48
+ return {
49
+ clock: options.clock ?? defaultClock,
50
+ idGenerator: options.idGenerator ?? createSeededIdGenerator(idSeed),
51
+ idSeed,
52
+ internalIdGenerator: options.internalIdGenerator ?? createInternalIdGenerator(),
53
+ internalIdGeneratorProvided,
54
+ enforceConstraints: options.enforceConstraints ?? defaultEnforceConstraints,
55
+ btreeOrder: options.btreeOrder ?? defaultBtreeOrder
56
+ };
57
+ };
58
+
59
+ //#endregion
60
+ export { resolveInMemoryAdapterOptions };
61
+ //# sourceMappingURL=options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"options.js","names":[],"sources":["../../../src/adapters/in-memory/options.ts"],"sourcesContent":["import { createId, init } from \"@paralleldrive/cuid2\";\nimport type { SqlNamingStrategy } from \"../../naming/sql-naming\";\n\nexport type InMemoryAdapterOptions = {\n clock?: { now: () => Date };\n idGenerator?: () => string;\n idSeed?: string;\n internalIdGenerator?: () => bigint;\n enforceConstraints?: boolean;\n btreeOrder?: number;\n namingStrategy?: SqlNamingStrategy;\n};\n\nexport type ResolvedInMemoryAdapterOptions = {\n clock: { now: () => Date };\n idGenerator: () => string;\n idSeed: string;\n internalIdGenerator: () => bigint;\n internalIdGeneratorProvided: boolean;\n enforceConstraints: boolean;\n btreeOrder: number;\n};\n\nconst defaultClock = {\n now: () => new Date(),\n};\n\nconst defaultBtreeOrder = 32;\nconst defaultEnforceConstraints = true;\nconst initialCountMax = 476782367;\nconst seededRandomStep = 1831565813;\n\nconst createCounter = (start: number) => {\n let value = start;\n return () => value++;\n};\n\nconst hashSeed = (seed: string): number => {\n let hash = 2166136261;\n for (let i = 0; i < seed.length; i += 1) {\n hash ^= seed.charCodeAt(i);\n hash = Math.imul(hash, 16777619);\n }\n return hash >>> 0;\n};\n\nconst createSeededRandom = (seed: string) => {\n let state = hashSeed(seed);\n return () => {\n state |= 0;\n state = (state + seededRandomStep) | 0;\n let t = Math.imul(state ^ (state >>> 15), 1 | state);\n t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296;\n };\n};\n\nconst createSeededIdGenerator = (seed: string): (() => string) => {\n const random = createSeededRandom(seed);\n const counter = createCounter(Math.floor(random() * initialCountMax));\n return init({ random, counter });\n};\n\nconst createInternalIdGenerator = (): (() => bigint) => {\n let current = 0n;\n return () => {\n current += 1n;\n return current;\n };\n};\n\nexport const resolveInMemoryAdapterOptions = (\n options: InMemoryAdapterOptions = {},\n): ResolvedInMemoryAdapterOptions => {\n const idSeed = options.idSeed ?? createId();\n const internalIdGeneratorProvided = options.internalIdGenerator !== undefined;\n\n return {\n clock: options.clock ?? defaultClock,\n idGenerator: options.idGenerator ?? createSeededIdGenerator(idSeed),\n idSeed,\n internalIdGenerator: options.internalIdGenerator ?? createInternalIdGenerator(),\n internalIdGeneratorProvided,\n enforceConstraints: options.enforceConstraints ?? defaultEnforceConstraints,\n btreeOrder: options.btreeOrder ?? defaultBtreeOrder,\n };\n};\n"],"mappings":";;;AAuBA,MAAM,eAAe,EACnB,2BAAW,IAAI,MAAM,EACtB;AAED,MAAM,oBAAoB;AAC1B,MAAM,4BAA4B;AAClC,MAAM,kBAAkB;AACxB,MAAM,mBAAmB;AAEzB,MAAM,iBAAiB,UAAkB;CACvC,IAAI,QAAQ;AACZ,cAAa;;AAGf,MAAM,YAAY,SAAyB;CACzC,IAAI,OAAO;AACX,MAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK,GAAG;AACvC,UAAQ,KAAK,WAAW,EAAE;AAC1B,SAAO,KAAK,KAAK,MAAM,SAAS;;AAElC,QAAO,SAAS;;AAGlB,MAAM,sBAAsB,SAAiB;CAC3C,IAAI,QAAQ,SAAS,KAAK;AAC1B,cAAa;AACX,WAAS;AACT,UAAS,QAAQ,mBAAoB;EACrC,IAAI,IAAI,KAAK,KAAK,QAAS,UAAU,IAAK,IAAI,MAAM;AACpD,MAAK,IAAI,KAAK,KAAK,IAAK,MAAM,GAAI,KAAK,EAAE,GAAI;AAC7C,WAAS,IAAK,MAAM,QAAS,KAAK;;;AAItC,MAAM,2BAA2B,SAAiC;CAChE,MAAM,SAAS,mBAAmB,KAAK;AAEvC,QAAO,KAAK;EAAE;EAAQ,SADN,cAAc,KAAK,MAAM,QAAQ,GAAG,gBAAgB,CAAC;EACtC,CAAC;;AAGlC,MAAM,kCAAkD;CACtD,IAAI,UAAU;AACd,cAAa;AACX,aAAW;AACX,SAAO;;;AAIX,MAAa,iCACX,UAAkC,EAAE,KACD;CACnC,MAAM,SAAS,QAAQ,UAAU,UAAU;CAC3C,MAAM,8BAA8B,QAAQ,wBAAwB;AAEpE,QAAO;EACL,OAAO,QAAQ,SAAS;EACxB,aAAa,QAAQ,eAAe,wBAAwB,OAAO;EACnE;EACA,qBAAqB,QAAQ,uBAAuB,2BAA2B;EAC/E;EACA,oBAAoB,QAAQ,sBAAsB;EAClD,YAAY,QAAQ,cAAc;EACnC"}
@@ -0,0 +1,26 @@
1
+ import { ReferenceSubquery } from "../../query/value-encoding.js";
2
+
3
+ //#region src/adapters/in-memory/reference-resolution.ts
4
+ const getTableStore = (namespaceStore, table, resolver) => {
5
+ const tableName = resolver ? resolver.getTableName(table.name) : table.name;
6
+ const store = namespaceStore.tables.get(tableName);
7
+ if (!store) throw new Error(`Missing in-memory table store for "${tableName}".`);
8
+ return store;
9
+ };
10
+ const resolveExternalIdToInternalId = (tableStore, table, externalId, resolver) => {
11
+ const idColumnName = table.getIdColumn().name;
12
+ const physicalIdColumnName = resolver ? resolver.getColumnName(table.name, idColumnName) : idColumnName;
13
+ for (const [internalId, row] of tableStore.rows) if (row[physicalIdColumnName] === externalId) return internalId;
14
+ };
15
+ const resolveReferenceSubquery = (namespaceStore, reference, resolver) => {
16
+ return resolveExternalIdToInternalId(getTableStore(namespaceStore, reference.referencedTable, resolver), reference.referencedTable, reference.externalIdValue, resolver) ?? null;
17
+ };
18
+ const resolveReferenceSubqueries = (namespaceStore, values, resolver) => {
19
+ const resolved = {};
20
+ for (const [key, value] of Object.entries(values)) resolved[key] = value instanceof ReferenceSubquery ? resolveReferenceSubquery(namespaceStore, value, resolver) : value;
21
+ return resolved;
22
+ };
23
+
24
+ //#endregion
25
+ export { resolveReferenceSubqueries, resolveReferenceSubquery };
26
+ //# sourceMappingURL=reference-resolution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reference-resolution.js","names":["resolved: Record<string, unknown>"],"sources":["../../../src/adapters/in-memory/reference-resolution.ts"],"sourcesContent":["import type { AnyTable } from \"../../schema/create\";\nimport { ReferenceSubquery } from \"../../query/value-encoding\";\nimport type { InMemoryNamespaceStore, InMemoryTableStore } from \"./store\";\nimport type { NamingResolver } from \"../../naming/sql-naming\";\n\nconst getTableStore = (\n namespaceStore: InMemoryNamespaceStore,\n table: AnyTable,\n resolver?: NamingResolver,\n): InMemoryTableStore => {\n const tableName = resolver ? resolver.getTableName(table.name) : table.name;\n const store = namespaceStore.tables.get(tableName);\n if (!store) {\n throw new Error(`Missing in-memory table store for \"${tableName}\".`);\n }\n return store;\n};\n\nconst resolveExternalIdToInternalId = (\n tableStore: InMemoryTableStore,\n table: AnyTable,\n externalId: string,\n resolver?: NamingResolver,\n): bigint | undefined => {\n const idColumnName = table.getIdColumn().name;\n const physicalIdColumnName = resolver\n ? resolver.getColumnName(table.name, idColumnName)\n : idColumnName;\n for (const [internalId, row] of tableStore.rows) {\n if (row[physicalIdColumnName] === externalId) {\n return internalId;\n }\n }\n return undefined;\n};\n\nexport const resolveReferenceSubquery = (\n namespaceStore: InMemoryNamespaceStore,\n reference: ReferenceSubquery,\n resolver?: NamingResolver,\n): bigint | null => {\n const tableStore = getTableStore(namespaceStore, reference.referencedTable, resolver);\n const resolved = resolveExternalIdToInternalId(\n tableStore,\n reference.referencedTable,\n reference.externalIdValue,\n resolver,\n );\n return resolved ?? null;\n};\n\nexport const resolveReferenceSubqueries = (\n namespaceStore: InMemoryNamespaceStore,\n values: Record<string, unknown>,\n resolver?: NamingResolver,\n): Record<string, unknown> => {\n const resolved: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(values)) {\n resolved[key] =\n value instanceof ReferenceSubquery\n ? resolveReferenceSubquery(namespaceStore, value, resolver)\n : value;\n }\n\n return resolved;\n};\n"],"mappings":";;;AAKA,MAAM,iBACJ,gBACA,OACA,aACuB;CACvB,MAAM,YAAY,WAAW,SAAS,aAAa,MAAM,KAAK,GAAG,MAAM;CACvE,MAAM,QAAQ,eAAe,OAAO,IAAI,UAAU;AAClD,KAAI,CAAC,MACH,OAAM,IAAI,MAAM,sCAAsC,UAAU,IAAI;AAEtE,QAAO;;AAGT,MAAM,iCACJ,YACA,OACA,YACA,aACuB;CACvB,MAAM,eAAe,MAAM,aAAa,CAAC;CACzC,MAAM,uBAAuB,WACzB,SAAS,cAAc,MAAM,MAAM,aAAa,GAChD;AACJ,MAAK,MAAM,CAAC,YAAY,QAAQ,WAAW,KACzC,KAAI,IAAI,0BAA0B,WAChC,QAAO;;AAMb,MAAa,4BACX,gBACA,WACA,aACkB;AAQlB,QANiB,8BADE,cAAc,gBAAgB,UAAU,iBAAiB,SAAS,EAGnF,UAAU,iBACV,UAAU,iBACV,SACD,IACkB;;AAGrB,MAAa,8BACX,gBACA,QACA,aAC4B;CAC5B,MAAMA,WAAoC,EAAE;AAE5C,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,OAAO,CAC/C,UAAS,OACP,iBAAiB,oBACb,yBAAyB,gBAAgB,OAAO,SAAS,GACzD;AAGR,QAAO"}
@@ -0,0 +1,129 @@
1
+ import { UniqueConstraintError } from "./errors.js";
2
+
3
+ //#region src/adapters/in-memory/sorted-array-index.ts
4
+ const compareKeys = (left, right, compareValue) => {
5
+ const length = Math.min(left.length, right.length);
6
+ for (let i = 0; i < length; i += 1) {
7
+ const result = compareValue(left[i], right[i]);
8
+ if (result !== 0) return result;
9
+ }
10
+ return left.length - right.length;
11
+ };
12
+ var SortedArrayIndex = class {
13
+ #entries = [];
14
+ #compareValue;
15
+ #unique;
16
+ constructor(compareValue, options = {}) {
17
+ this.#compareValue = compareValue;
18
+ this.#unique = options.unique ?? false;
19
+ }
20
+ get size() {
21
+ return this.#entries.length;
22
+ }
23
+ entries() {
24
+ return this.#entries.slice();
25
+ }
26
+ insert(key, value, options = {}) {
27
+ const enforceUnique = options.enforceUnique ?? true;
28
+ if (this.#unique && enforceUnique) this.#assertUnique(key);
29
+ const entry = {
30
+ key,
31
+ value
32
+ };
33
+ const index = this.#upperBound(key);
34
+ this.#entries.splice(index, 0, entry);
35
+ }
36
+ remove(key, value) {
37
+ const start = this.#lowerBound(key);
38
+ const end = this.#upperBound(key);
39
+ if (start === end) return false;
40
+ if (value === void 0) {
41
+ this.#entries.splice(start, 1);
42
+ return true;
43
+ }
44
+ for (let i = start; i < end; i += 1) if (this.#entries[i]?.value === value) {
45
+ this.#entries.splice(i, 1);
46
+ return true;
47
+ }
48
+ return false;
49
+ }
50
+ update(oldKey, newKey, value, options = {}) {
51
+ const enforceUnique = options.enforceUnique ?? true;
52
+ if (this.#unique && enforceUnique) {
53
+ const range = this.#rangeForKey(newKey);
54
+ if (range.start !== range.end) {
55
+ const sameKey = compareKeys(oldKey, newKey, this.#compareValue) === 0;
56
+ const singleEntry = range.end - range.start === 1;
57
+ const entry = this.#entries[range.start];
58
+ if (!(sameKey && singleEntry && entry?.value === value)) throw new UniqueConstraintError(this.#uniqueErrorMessage(newKey));
59
+ if (sameKey) return;
60
+ }
61
+ }
62
+ if (!this.remove(oldKey, value)) throw new Error("SortedArrayIndex update failed to locate existing entry.");
63
+ this.insert(newKey, value, { enforceUnique });
64
+ }
65
+ scan(options = {}) {
66
+ const direction = options.direction ?? "asc";
67
+ const limit = options.limit ?? Number.POSITIVE_INFINITY;
68
+ const start = options.start ? options.startInclusive === false ? this.#upperBound(options.start) : this.#lowerBound(options.start) : 0;
69
+ const end = options.end ? options.endInclusive === true ? this.#upperBound(options.end) : this.#lowerBound(options.end) : this.#entries.length;
70
+ if (start >= end || limit <= 0) return [];
71
+ const results = [];
72
+ if (direction === "desc") {
73
+ for (let i = end - 1; i >= start && results.length < limit; i -= 1) results.push(this.#entries[i]);
74
+ return results;
75
+ }
76
+ for (let i = start; i < end && results.length < limit; i += 1) results.push(this.#entries[i]);
77
+ return results;
78
+ }
79
+ #compareEntryWithKey(entry, key) {
80
+ return compareKeys(entry.key, key, this.#compareValue);
81
+ }
82
+ #rangeForKey(key) {
83
+ return {
84
+ start: this.#lowerBound(key),
85
+ end: this.#upperBound(key)
86
+ };
87
+ }
88
+ #assertUnique(key) {
89
+ const range = this.#rangeForKey(key);
90
+ if (range.start !== range.end) throw new UniqueConstraintError(this.#uniqueErrorMessage(key));
91
+ }
92
+ #uniqueErrorMessage(key) {
93
+ return `Unique constraint violation for key ${this.#formatKey(key)}.`;
94
+ }
95
+ #formatKey(key) {
96
+ return `[${key.map((value) => this.#formatKeyValue(value)).join(", ")}]`;
97
+ }
98
+ #formatKeyValue(value) {
99
+ if (value instanceof Date) return value.toISOString();
100
+ if (typeof value === "bigint") return `${value}n`;
101
+ return String(value);
102
+ }
103
+ #lowerBound(key) {
104
+ let low = 0;
105
+ let high = this.#entries.length;
106
+ while (low < high) {
107
+ const mid = low + high >>> 1;
108
+ const entry = this.#entries[mid];
109
+ if ((entry ? this.#compareEntryWithKey(entry, key) : 0) < 0) low = mid + 1;
110
+ else high = mid;
111
+ }
112
+ return low;
113
+ }
114
+ #upperBound(key) {
115
+ let low = 0;
116
+ let high = this.#entries.length;
117
+ while (low < high) {
118
+ const mid = low + high >>> 1;
119
+ const entry = this.#entries[mid];
120
+ if ((entry ? this.#compareEntryWithKey(entry, key) : 0) <= 0) low = mid + 1;
121
+ else high = mid;
122
+ }
123
+ return low;
124
+ }
125
+ };
126
+
127
+ //#endregion
128
+ export { SortedArrayIndex };
129
+ //# sourceMappingURL=sorted-array-index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sorted-array-index.js","names":["#compareValue","#unique","#entries","#assertUnique","#upperBound","#lowerBound","#rangeForKey","#uniqueErrorMessage","results: SortedArrayIndexEntry<T>[]","#formatKey","#formatKeyValue","#compareEntryWithKey"],"sources":["../../../src/adapters/in-memory/sorted-array-index.ts"],"sourcesContent":["export type IndexKey = readonly unknown[];\n\nexport type SortedArrayIndexEntry<T> = {\n key: IndexKey;\n value: T;\n};\n\nimport { UniqueConstraintError } from \"./errors\";\n\nexport type CompareValue = (left: unknown, right: unknown) => number;\n\nexport type SortedArrayIndexOptions = {\n unique?: boolean;\n};\n\nexport type UniqueEnforcementOptions = {\n enforceUnique?: boolean;\n};\n\nexport type IndexScanOptions = {\n start?: IndexKey;\n startInclusive?: boolean;\n end?: IndexKey;\n endInclusive?: boolean;\n direction?: \"asc\" | \"desc\";\n limit?: number;\n};\n\nconst compareKeys = (left: IndexKey, right: IndexKey, compareValue: CompareValue): number => {\n const length = Math.min(left.length, right.length);\n for (let i = 0; i < length; i += 1) {\n const result = compareValue(left[i], right[i]);\n if (result !== 0) {\n return result;\n }\n }\n\n return left.length - right.length;\n};\n\nexport class SortedArrayIndex<T> {\n #entries: SortedArrayIndexEntry<T>[] = [];\n #compareValue: CompareValue;\n #unique: boolean;\n\n constructor(compareValue: CompareValue, options: SortedArrayIndexOptions = {}) {\n this.#compareValue = compareValue;\n this.#unique = options.unique ?? false;\n }\n\n get size(): number {\n return this.#entries.length;\n }\n\n entries(): SortedArrayIndexEntry<T>[] {\n return this.#entries.slice();\n }\n\n insert(key: IndexKey, value: T, options: UniqueEnforcementOptions = {}): void {\n const enforceUnique = options.enforceUnique ?? true;\n if (this.#unique && enforceUnique) {\n this.#assertUnique(key);\n }\n const entry = { key, value };\n const index = this.#upperBound(key);\n this.#entries.splice(index, 0, entry);\n }\n\n remove(key: IndexKey, value?: T): boolean {\n const start = this.#lowerBound(key);\n const end = this.#upperBound(key);\n if (start === end) {\n return false;\n }\n\n if (value === undefined) {\n this.#entries.splice(start, 1);\n return true;\n }\n\n for (let i = start; i < end; i += 1) {\n if (this.#entries[i]?.value === value) {\n this.#entries.splice(i, 1);\n return true;\n }\n }\n\n return false;\n }\n\n update(\n oldKey: IndexKey,\n newKey: IndexKey,\n value: T,\n options: UniqueEnforcementOptions = {},\n ): void {\n const enforceUnique = options.enforceUnique ?? true;\n if (this.#unique && enforceUnique) {\n const range = this.#rangeForKey(newKey);\n if (range.start !== range.end) {\n const sameKey = compareKeys(oldKey, newKey, this.#compareValue) === 0;\n const singleEntry = range.end - range.start === 1;\n const entry = this.#entries[range.start];\n const isSameEntry = sameKey && singleEntry && entry?.value === value;\n if (!isSameEntry) {\n throw new UniqueConstraintError(this.#uniqueErrorMessage(newKey));\n }\n if (sameKey) {\n return;\n }\n }\n }\n const removed = this.remove(oldKey, value);\n if (!removed) {\n throw new Error(\"SortedArrayIndex update failed to locate existing entry.\");\n }\n this.insert(newKey, value, { enforceUnique });\n }\n\n scan(options: IndexScanOptions = {}): SortedArrayIndexEntry<T>[] {\n const direction = options.direction ?? \"asc\";\n const limit = options.limit ?? Number.POSITIVE_INFINITY;\n\n const start = options.start\n ? options.startInclusive === false\n ? this.#upperBound(options.start)\n : this.#lowerBound(options.start)\n : 0;\n\n const end = options.end\n ? options.endInclusive === true\n ? this.#upperBound(options.end)\n : this.#lowerBound(options.end)\n : this.#entries.length;\n\n if (start >= end || limit <= 0) {\n return [];\n }\n\n const results: SortedArrayIndexEntry<T>[] = [];\n\n if (direction === \"desc\") {\n for (let i = end - 1; i >= start && results.length < limit; i -= 1) {\n results.push(this.#entries[i]);\n }\n return results;\n }\n\n for (let i = start; i < end && results.length < limit; i += 1) {\n results.push(this.#entries[i]);\n }\n\n return results;\n }\n\n #compareEntryWithKey(entry: SortedArrayIndexEntry<T>, key: IndexKey): number {\n return compareKeys(entry.key, key, this.#compareValue);\n }\n\n #rangeForKey(key: IndexKey): { start: number; end: number } {\n return {\n start: this.#lowerBound(key),\n end: this.#upperBound(key),\n };\n }\n\n #assertUnique(key: IndexKey): void {\n const range = this.#rangeForKey(key);\n if (range.start !== range.end) {\n throw new UniqueConstraintError(this.#uniqueErrorMessage(key));\n }\n }\n\n #uniqueErrorMessage(key: IndexKey): string {\n return `Unique constraint violation for key ${this.#formatKey(key)}.`;\n }\n\n #formatKey(key: IndexKey): string {\n const parts = key.map((value) => this.#formatKeyValue(value));\n return `[${parts.join(\", \")}]`;\n }\n\n #formatKeyValue(value: unknown): string {\n if (value instanceof Date) {\n return value.toISOString();\n }\n if (typeof value === \"bigint\") {\n return `${value}n`;\n }\n return String(value);\n }\n\n #lowerBound(key: IndexKey): number {\n let low = 0;\n let high = this.#entries.length;\n\n while (low < high) {\n const mid = (low + high) >>> 1;\n const entry = this.#entries[mid];\n const comparison = entry ? this.#compareEntryWithKey(entry, key) : 0;\n if (comparison < 0) {\n low = mid + 1;\n } else {\n high = mid;\n }\n }\n\n return low;\n }\n\n #upperBound(key: IndexKey): number {\n let low = 0;\n let high = this.#entries.length;\n\n while (low < high) {\n const mid = (low + high) >>> 1;\n const entry = this.#entries[mid];\n const comparison = entry ? this.#compareEntryWithKey(entry, key) : 0;\n if (comparison <= 0) {\n low = mid + 1;\n } else {\n high = mid;\n }\n }\n\n return low;\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,71 @@
1
+ import { createSQLSerializer } from "../../query/serialize/create-sql-serializer.js";
2
+ import { SQLocalDriverConfig } from "../generic-sql/driver-config.js";
3
+ import { SortedArrayIndex } from "./sorted-array-index.js";
4
+ import { compareNormalizedValues } from "./value-comparison.js";
5
+
6
+ //#region src/adapters/in-memory/store.ts
7
+ const sqliteSerializer = createSQLSerializer(new SQLocalDriverConfig());
8
+ const normalizeIndexValue = (value, column) => {
9
+ if (value === void 0) return;
10
+ return sqliteSerializer.serialize(value, column);
11
+ };
12
+ const buildIndexKey = (table, index, row, resolver) => {
13
+ const columnMap = resolver ? resolver.getColumnNameMap(table) : void 0;
14
+ return index.columnNames.map((columnName) => {
15
+ const logicalName = columnMap?.[columnName] ?? columnName;
16
+ const column = table.columns[logicalName];
17
+ if (!column) throw new Error(`Column "${columnName}" not found in table "${table.name}" for index "${index.name}".`);
18
+ return normalizeIndexValue(row[columnName], column);
19
+ });
20
+ };
21
+ const createTableIndexes = (table, resolver) => {
22
+ const indexes = /* @__PURE__ */ new Map();
23
+ const primaryIndex = table.indexes["_primary"];
24
+ const primaryDefinition = {
25
+ name: "_primary",
26
+ columnNames: primaryIndex ? primaryIndex.columnNames.map((columnName) => resolver ? resolver.getColumnName(table.name, columnName) : columnName) : [resolver ? resolver.getColumnName(table.name, table.getIdColumn().name) : table.getIdColumn().name],
27
+ unique: primaryIndex?.unique ?? true
28
+ };
29
+ indexes.set("_primary", {
30
+ definition: primaryDefinition,
31
+ index: new SortedArrayIndex(compareNormalizedValues, { unique: primaryDefinition.unique })
32
+ });
33
+ for (const [name, index] of Object.entries(table.indexes)) {
34
+ if (name === "_primary") continue;
35
+ indexes.set(name, {
36
+ definition: {
37
+ name,
38
+ columnNames: index.columnNames.map((columnName) => resolver ? resolver.getColumnName(table.name, columnName) : columnName),
39
+ unique: index.unique
40
+ },
41
+ index: new SortedArrayIndex(compareNormalizedValues, { unique: index.unique })
42
+ });
43
+ }
44
+ return indexes;
45
+ };
46
+ const createTableStore = (table, resolver) => ({
47
+ rows: /* @__PURE__ */ new Map(),
48
+ nextInternalId: 1n,
49
+ indexes: createTableIndexes(table, resolver)
50
+ });
51
+ const createNamespaceStore = (schema, resolver) => {
52
+ const tables = /* @__PURE__ */ new Map();
53
+ for (const tableName of Object.keys(schema.tables)) {
54
+ const table = schema.tables[tableName];
55
+ const storeKey = resolver ? resolver.getTableName(table.name) : table.name;
56
+ tables.set(storeKey, createTableStore(table, resolver));
57
+ }
58
+ return { tables };
59
+ };
60
+ const createInMemoryStore = () => ({ namespaces: /* @__PURE__ */ new Map() });
61
+ const ensureNamespaceStore = (store, namespace, schema, resolver) => {
62
+ const existing = store.namespaces.get(namespace);
63
+ if (existing) return existing;
64
+ const created = createNamespaceStore(schema, resolver);
65
+ store.namespaces.set(namespace, created);
66
+ return created;
67
+ };
68
+
69
+ //#endregion
70
+ export { buildIndexKey, createInMemoryStore, ensureNamespaceStore, normalizeIndexValue };
71
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","names":["primaryDefinition: InMemoryIndexDefinition"],"sources":["../../../src/adapters/in-memory/store.ts"],"sourcesContent":["import type { AnyColumn, AnySchema, AnyTable } from \"../../schema/create\";\nimport { SortedArrayIndex } from \"./sorted-array-index\";\nimport { SQLocalDriverConfig } from \"../generic-sql/driver-config\";\nimport { createSQLSerializer } from \"../../query/serialize/create-sql-serializer\";\nimport { compareNormalizedValues } from \"./value-comparison\";\nimport type { NamingResolver } from \"../../naming/sql-naming\";\n\nexport type InMemoryRow = Record<string, unknown>;\n\nexport type InMemoryIndexDefinition = {\n name: string;\n columnNames: string[];\n unique: boolean;\n};\n\nexport type InMemoryIndexStore = {\n definition: InMemoryIndexDefinition;\n index: SortedArrayIndex<bigint>;\n};\n\nexport type InMemoryTableStore = {\n rows: Map<bigint, InMemoryRow>;\n nextInternalId: bigint;\n indexes: Map<string, InMemoryIndexStore>;\n};\n\nexport type InMemoryNamespaceStore = {\n tables: Map<string, InMemoryTableStore>;\n};\n\nexport type InMemoryStore = {\n namespaces: Map<string, InMemoryNamespaceStore>;\n};\n\nconst sqliteSerializer = createSQLSerializer(new SQLocalDriverConfig());\n\nexport const normalizeIndexValue = (value: unknown, column: AnyColumn): unknown => {\n if (value === undefined) {\n return undefined;\n }\n return sqliteSerializer.serialize(value, column);\n};\n\nexport const buildIndexKey = (\n table: AnyTable,\n index: InMemoryIndexDefinition,\n row: InMemoryRow,\n resolver?: NamingResolver,\n): readonly unknown[] => {\n const columnMap = resolver ? resolver.getColumnNameMap(table) : undefined;\n return index.columnNames.map((columnName) => {\n const logicalName = columnMap?.[columnName] ?? columnName;\n const column = table.columns[logicalName];\n if (!column) {\n throw new Error(\n `Column \"${columnName}\" not found in table \"${table.name}\" for index \"${index.name}\".`,\n );\n }\n return normalizeIndexValue(row[columnName], column);\n });\n};\n\nconst createTableIndexes = (\n table: AnyTable,\n resolver?: NamingResolver,\n): Map<string, InMemoryIndexStore> => {\n const indexes = new Map<string, InMemoryIndexStore>();\n const primaryIndex = table.indexes[\"_primary\"];\n const primaryColumnNames = primaryIndex\n ? primaryIndex.columnNames.map((columnName) =>\n resolver ? resolver.getColumnName(table.name, columnName) : columnName,\n )\n : [\n resolver\n ? resolver.getColumnName(table.name, table.getIdColumn().name)\n : table.getIdColumn().name,\n ];\n const primaryDefinition: InMemoryIndexDefinition = {\n name: \"_primary\",\n columnNames: primaryColumnNames,\n unique: primaryIndex?.unique ?? true,\n };\n indexes.set(\"_primary\", {\n definition: primaryDefinition,\n index: new SortedArrayIndex(compareNormalizedValues, { unique: primaryDefinition.unique }),\n });\n\n for (const [name, index] of Object.entries(table.indexes)) {\n if (name === \"_primary\") {\n continue;\n }\n indexes.set(name, {\n definition: {\n name,\n columnNames: index.columnNames.map((columnName) =>\n resolver ? resolver.getColumnName(table.name, columnName) : columnName,\n ),\n unique: index.unique,\n },\n index: new SortedArrayIndex(compareNormalizedValues, { unique: index.unique }),\n });\n }\n\n return indexes;\n};\n\nconst createTableStore = (table: AnyTable, resolver?: NamingResolver): InMemoryTableStore => ({\n rows: new Map(),\n nextInternalId: 1n,\n indexes: createTableIndexes(table, resolver),\n});\n\nexport const createNamespaceStore = (\n schema: AnySchema,\n resolver?: NamingResolver,\n): InMemoryNamespaceStore => {\n const tables = new Map<string, InMemoryTableStore>();\n for (const tableName of Object.keys(schema.tables)) {\n const table = schema.tables[tableName];\n const storeKey = resolver ? resolver.getTableName(table.name) : table.name;\n tables.set(storeKey, createTableStore(table, resolver));\n }\n\n return { tables };\n};\n\nexport const createInMemoryStore = (): InMemoryStore => ({\n namespaces: new Map(),\n});\n\nexport const ensureNamespaceStore = (\n store: InMemoryStore,\n namespace: string,\n schema: AnySchema,\n resolver?: NamingResolver,\n): InMemoryNamespaceStore => {\n const existing = store.namespaces.get(namespace);\n if (existing) {\n return existing;\n }\n\n const created = createNamespaceStore(schema, resolver);\n store.namespaces.set(namespace, created);\n return created;\n};\n"],"mappings":";;;;;;AAkCA,MAAM,mBAAmB,oBAAoB,IAAI,qBAAqB,CAAC;AAEvE,MAAa,uBAAuB,OAAgB,WAA+B;AACjF,KAAI,UAAU,OACZ;AAEF,QAAO,iBAAiB,UAAU,OAAO,OAAO;;AAGlD,MAAa,iBACX,OACA,OACA,KACA,aACuB;CACvB,MAAM,YAAY,WAAW,SAAS,iBAAiB,MAAM,GAAG;AAChE,QAAO,MAAM,YAAY,KAAK,eAAe;EAC3C,MAAM,cAAc,YAAY,eAAe;EAC/C,MAAM,SAAS,MAAM,QAAQ;AAC7B,MAAI,CAAC,OACH,OAAM,IAAI,MACR,WAAW,WAAW,wBAAwB,MAAM,KAAK,eAAe,MAAM,KAAK,IACpF;AAEH,SAAO,oBAAoB,IAAI,aAAa,OAAO;GACnD;;AAGJ,MAAM,sBACJ,OACA,aACoC;CACpC,MAAM,0BAAU,IAAI,KAAiC;CACrD,MAAM,eAAe,MAAM,QAAQ;CAUnC,MAAMA,oBAA6C;EACjD,MAAM;EACN,aAXyB,eACvB,aAAa,YAAY,KAAK,eAC5B,WAAW,SAAS,cAAc,MAAM,MAAM,WAAW,GAAG,WAC7D,GACD,CACE,WACI,SAAS,cAAc,MAAM,MAAM,MAAM,aAAa,CAAC,KAAK,GAC5D,MAAM,aAAa,CAAC,KACzB;EAIH,QAAQ,cAAc,UAAU;EACjC;AACD,SAAQ,IAAI,YAAY;EACtB,YAAY;EACZ,OAAO,IAAI,iBAAiB,yBAAyB,EAAE,QAAQ,kBAAkB,QAAQ,CAAC;EAC3F,CAAC;AAEF,MAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,MAAM,QAAQ,EAAE;AACzD,MAAI,SAAS,WACX;AAEF,UAAQ,IAAI,MAAM;GAChB,YAAY;IACV;IACA,aAAa,MAAM,YAAY,KAAK,eAClC,WAAW,SAAS,cAAc,MAAM,MAAM,WAAW,GAAG,WAC7D;IACD,QAAQ,MAAM;IACf;GACD,OAAO,IAAI,iBAAiB,yBAAyB,EAAE,QAAQ,MAAM,QAAQ,CAAC;GAC/E,CAAC;;AAGJ,QAAO;;AAGT,MAAM,oBAAoB,OAAiB,cAAmD;CAC5F,sBAAM,IAAI,KAAK;CACf,gBAAgB;CAChB,SAAS,mBAAmB,OAAO,SAAS;CAC7C;AAED,MAAa,wBACX,QACA,aAC2B;CAC3B,MAAM,yBAAS,IAAI,KAAiC;AACpD,MAAK,MAAM,aAAa,OAAO,KAAK,OAAO,OAAO,EAAE;EAClD,MAAM,QAAQ,OAAO,OAAO;EAC5B,MAAM,WAAW,WAAW,SAAS,aAAa,MAAM,KAAK,GAAG,MAAM;AACtE,SAAO,IAAI,UAAU,iBAAiB,OAAO,SAAS,CAAC;;AAGzD,QAAO,EAAE,QAAQ;;AAGnB,MAAa,6BAA4C,EACvD,4BAAY,IAAI,KAAK,EACtB;AAED,MAAa,wBACX,OACA,WACA,QACA,aAC2B;CAC3B,MAAM,WAAW,MAAM,WAAW,IAAI,UAAU;AAChD,KAAI,SACF,QAAO;CAGT,MAAM,UAAU,qBAAqB,QAAQ,SAAS;AACtD,OAAM,WAAW,IAAI,WAAW,QAAQ;AACxC,QAAO"}
@@ -0,0 +1,28 @@
1
+ //#region src/adapters/in-memory/value-comparison.ts
2
+ const asBuffer = (value) => {
3
+ if (value instanceof Buffer) return value;
4
+ if (value instanceof Uint8Array) return Buffer.from(value);
5
+ if (value instanceof ArrayBuffer) return Buffer.from(value);
6
+ };
7
+ const compareNormalizedValues = (left, right) => {
8
+ if (left === right) return 0;
9
+ if (left === void 0) return -1;
10
+ if (right === void 0) return 1;
11
+ if (left === null) return -1;
12
+ if (right === null) return 1;
13
+ const leftBuffer = asBuffer(left);
14
+ const rightBuffer = asBuffer(right);
15
+ if (leftBuffer && rightBuffer) return Buffer.compare(leftBuffer, rightBuffer);
16
+ if (left instanceof Date && right instanceof Date) return left.getTime() - right.getTime();
17
+ if (typeof left === "number" && typeof right === "number") return left - right;
18
+ if (typeof left === "bigint" && typeof right === "bigint") return left < right ? -1 : 1;
19
+ if (typeof left === "string" && typeof right === "string") return left < right ? -1 : 1;
20
+ if (typeof left === "boolean" && typeof right === "boolean") return left === right ? 0 : left ? 1 : -1;
21
+ const leftString = String(left);
22
+ const rightString = String(right);
23
+ return leftString < rightString ? -1 : leftString > rightString ? 1 : 0;
24
+ };
25
+
26
+ //#endregion
27
+ export { compareNormalizedValues };
28
+ //# sourceMappingURL=value-comparison.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"value-comparison.js","names":[],"sources":["../../../src/adapters/in-memory/value-comparison.ts"],"sourcesContent":["const asBuffer = (value: unknown): Buffer | undefined => {\n if (value instanceof Buffer) {\n return value;\n }\n if (value instanceof Uint8Array) {\n return Buffer.from(value);\n }\n if (value instanceof ArrayBuffer) {\n return Buffer.from(value);\n }\n return undefined;\n};\n\nexport const compareNormalizedValues = (left: unknown, right: unknown): number => {\n if (left === right) {\n return 0;\n }\n if (left === undefined) {\n return -1;\n }\n if (right === undefined) {\n return 1;\n }\n if (left === null) {\n return -1;\n }\n if (right === null) {\n return 1;\n }\n const leftBuffer = asBuffer(left);\n const rightBuffer = asBuffer(right);\n if (leftBuffer && rightBuffer) {\n return Buffer.compare(leftBuffer, rightBuffer);\n }\n if (left instanceof Date && right instanceof Date) {\n return left.getTime() - right.getTime();\n }\n if (typeof left === \"number\" && typeof right === \"number\") {\n return left - right;\n }\n if (typeof left === \"bigint\" && typeof right === \"bigint\") {\n return left < right ? -1 : 1;\n }\n if (typeof left === \"string\" && typeof right === \"string\") {\n return left < right ? -1 : 1;\n }\n if (typeof left === \"boolean\" && typeof right === \"boolean\") {\n return left === right ? 0 : left ? 1 : -1;\n }\n const leftString = String(left);\n const rightString = String(right);\n return leftString < rightString ? -1 : leftString > rightString ? 1 : 0;\n};\n"],"mappings":";AAAA,MAAM,YAAY,UAAuC;AACvD,KAAI,iBAAiB,OACnB,QAAO;AAET,KAAI,iBAAiB,WACnB,QAAO,OAAO,KAAK,MAAM;AAE3B,KAAI,iBAAiB,YACnB,QAAO,OAAO,KAAK,MAAM;;AAK7B,MAAa,2BAA2B,MAAe,UAA2B;AAChF,KAAI,SAAS,MACX,QAAO;AAET,KAAI,SAAS,OACX,QAAO;AAET,KAAI,UAAU,OACZ,QAAO;AAET,KAAI,SAAS,KACX,QAAO;AAET,KAAI,UAAU,KACZ,QAAO;CAET,MAAM,aAAa,SAAS,KAAK;CACjC,MAAM,cAAc,SAAS,MAAM;AACnC,KAAI,cAAc,YAChB,QAAO,OAAO,QAAQ,YAAY,YAAY;AAEhD,KAAI,gBAAgB,QAAQ,iBAAiB,KAC3C,QAAO,KAAK,SAAS,GAAG,MAAM,SAAS;AAEzC,KAAI,OAAO,SAAS,YAAY,OAAO,UAAU,SAC/C,QAAO,OAAO;AAEhB,KAAI,OAAO,SAAS,YAAY,OAAO,UAAU,SAC/C,QAAO,OAAO,QAAQ,KAAK;AAE7B,KAAI,OAAO,SAAS,YAAY,OAAO,UAAU,SAC/C,QAAO,OAAO,QAAQ,KAAK;AAE7B,KAAI,OAAO,SAAS,aAAa,OAAO,UAAU,UAChD,QAAO,SAAS,QAAQ,IAAI,OAAO,IAAI;CAEzC,MAAM,aAAa,OAAO,KAAK;CAC/B,MAAM,cAAc,OAAO,MAAM;AACjC,QAAO,aAAa,cAAc,KAAK,aAAa,cAAc,IAAI"}