@effect-app/infra 4.0.0-beta.25 → 4.0.0-beta.251

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 (467) hide show
  1. package/CHANGELOG.md +1900 -0
  2. package/_check.sh +1 -1
  3. package/dist/CUPS.d.ts +30 -11
  4. package/dist/CUPS.d.ts.map +1 -1
  5. package/dist/CUPS.js +35 -14
  6. package/dist/ContextProvider.d.ts +34 -0
  7. package/dist/ContextProvider.d.ts.map +1 -0
  8. package/dist/ContextProvider.js +40 -0
  9. package/dist/Emailer/Sendgrid.d.ts +111 -147
  10. package/dist/Emailer/Sendgrid.d.ts.map +1 -1
  11. package/dist/Emailer/Sendgrid.js +24 -19
  12. package/dist/Emailer/fake.d.ts +2 -2
  13. package/dist/Emailer/fake.d.ts.map +1 -1
  14. package/dist/Emailer/fake.js +4 -4
  15. package/dist/MainFiberSet.d.ts +12 -9
  16. package/dist/MainFiberSet.d.ts.map +1 -1
  17. package/dist/MainFiberSet.js +10 -6
  18. package/dist/QueueMaker/SQLQueue.d.ts +8 -9
  19. package/dist/QueueMaker/SQLQueue.d.ts.map +1 -1
  20. package/dist/QueueMaker/SQLQueue.js +138 -120
  21. package/dist/QueueMaker/errors.d.ts +5 -3
  22. package/dist/QueueMaker/errors.d.ts.map +1 -1
  23. package/dist/QueueMaker/errors.js +4 -2
  24. package/dist/QueueMaker/memQueue.d.ts +10 -6
  25. package/dist/QueueMaker/memQueue.d.ts.map +1 -1
  26. package/dist/QueueMaker/memQueue.js +84 -68
  27. package/dist/QueueMaker/sbqueue.d.ts +9 -5
  28. package/dist/QueueMaker/sbqueue.d.ts.map +1 -1
  29. package/dist/QueueMaker/sbqueue.js +60 -58
  30. package/dist/RequestFiberSet.d.ts +10 -7
  31. package/dist/RequestFiberSet.d.ts.map +1 -1
  32. package/dist/RequestFiberSet.js +13 -8
  33. package/dist/SQL/Model.d.ts +468 -0
  34. package/dist/SQL/Model.d.ts.map +1 -0
  35. package/dist/SQL/Model.js +469 -0
  36. package/dist/SQL.d.ts +2 -0
  37. package/dist/SQL.d.ts.map +1 -0
  38. package/dist/{adapters/SQL.js → SQL.js} +1 -1
  39. package/dist/ServiceBus.d.ts +61 -0
  40. package/dist/ServiceBus.d.ts.map +1 -0
  41. package/dist/ServiceBus.js +108 -0
  42. package/dist/Store/Cosmos/query.d.ts +15 -4
  43. package/dist/Store/Cosmos/query.d.ts.map +1 -1
  44. package/dist/Store/Cosmos/query.js +179 -41
  45. package/dist/Store/Cosmos.d.ts +3 -3
  46. package/dist/Store/Cosmos.d.ts.map +1 -1
  47. package/dist/Store/Cosmos.js +344 -246
  48. package/dist/Store/Disk.d.ts +5 -5
  49. package/dist/Store/Disk.d.ts.map +1 -1
  50. package/dist/Store/Disk.js +78 -38
  51. package/dist/Store/Memory.d.ts +7 -10
  52. package/dist/Store/Memory.d.ts.map +1 -1
  53. package/dist/Store/Memory.js +326 -66
  54. package/dist/Store/SQL/Pg.d.ts +4 -0
  55. package/dist/Store/SQL/Pg.d.ts.map +1 -0
  56. package/dist/Store/SQL/Pg.js +232 -0
  57. package/dist/Store/SQL/query.d.ts +49 -0
  58. package/dist/Store/SQL/query.d.ts.map +1 -0
  59. package/dist/Store/SQL/query.js +527 -0
  60. package/dist/Store/SQL.d.ts +21 -0
  61. package/dist/Store/SQL.d.ts.map +1 -0
  62. package/dist/Store/SQL.js +449 -0
  63. package/dist/Store/codeFilter.d.ts +5 -5
  64. package/dist/Store/codeFilter.d.ts.map +1 -1
  65. package/dist/Store/codeFilter.js +6 -3
  66. package/dist/Store/index.d.ts +7 -5
  67. package/dist/Store/index.d.ts.map +1 -1
  68. package/dist/Store/index.js +18 -5
  69. package/dist/Store/utils.d.ts +4 -3
  70. package/dist/Store/utils.d.ts.map +1 -1
  71. package/dist/Store/utils.js +5 -5
  72. package/dist/arbs.d.ts +2 -2
  73. package/dist/arbs.d.ts.map +1 -1
  74. package/dist/arbs.js +5 -3
  75. package/dist/codec.d.ts +5 -0
  76. package/dist/codec.d.ts.map +1 -0
  77. package/dist/codec.js +5 -0
  78. package/dist/cosmos-client.d.ts +16 -0
  79. package/dist/cosmos-client.d.ts.map +1 -0
  80. package/dist/cosmos-client.js +11 -0
  81. package/dist/errorReporter.d.ts +7 -5
  82. package/dist/errorReporter.d.ts.map +1 -1
  83. package/dist/errorReporter.js +23 -27
  84. package/dist/errors.d.ts +1 -1
  85. package/dist/fileUtil.d.ts +2 -2
  86. package/dist/fileUtil.d.ts.map +1 -1
  87. package/dist/fileUtil.js +2 -2
  88. package/dist/index.d.ts +3 -2
  89. package/dist/index.d.ts.map +1 -1
  90. package/dist/index.js +3 -2
  91. package/dist/internal/RequestContextMiddleware.d.ts +5 -0
  92. package/dist/internal/RequestContextMiddleware.d.ts.map +1 -0
  93. package/dist/internal/RequestContextMiddleware.js +45 -0
  94. package/dist/internal/auth.d.ts +53 -0
  95. package/dist/internal/auth.d.ts.map +1 -0
  96. package/dist/internal/auth.js +180 -0
  97. package/dist/internal/events.d.ts +11 -0
  98. package/dist/internal/events.d.ts.map +1 -0
  99. package/dist/internal/events.js +49 -0
  100. package/dist/internal/health.d.ts +3 -0
  101. package/dist/internal/health.d.ts.map +1 -0
  102. package/dist/internal/health.js +5 -0
  103. package/dist/layerUtils.d.ts +32 -0
  104. package/dist/layerUtils.d.ts.map +1 -0
  105. package/dist/layerUtils.js +17 -0
  106. package/dist/logger/jsonLogger.d.ts +2 -2
  107. package/dist/logger/jsonLogger.d.ts.map +1 -1
  108. package/dist/logger/jsonLogger.js +5 -3
  109. package/dist/logger/logFmtLogger.d.ts +2 -2
  110. package/dist/logger/logFmtLogger.d.ts.map +1 -1
  111. package/dist/logger/logFmtLogger.js +3 -3
  112. package/dist/logger/shared.d.ts +3 -3
  113. package/dist/logger/shared.d.ts.map +1 -1
  114. package/dist/logger/shared.js +5 -5
  115. package/dist/logger.d.ts +1 -1
  116. package/dist/logger.d.ts.map +1 -1
  117. package/dist/memQueue.d.ts +15 -0
  118. package/dist/memQueue.d.ts.map +1 -0
  119. package/dist/memQueue.js +21 -0
  120. package/dist/middlewares.d.ts +10 -0
  121. package/dist/middlewares.d.ts.map +1 -0
  122. package/dist/{api/middlewares.js → middlewares.js} +1 -1
  123. package/dist/mongo-client.d.ts +11 -0
  124. package/dist/mongo-client.d.ts.map +1 -0
  125. package/dist/mongo-client.js +15 -0
  126. package/dist/otel.d.ts +75 -0
  127. package/dist/otel.d.ts.map +1 -0
  128. package/dist/otel.js +65 -0
  129. package/dist/rateLimit.d.ts +12 -4
  130. package/dist/rateLimit.d.ts.map +1 -1
  131. package/dist/rateLimit.js +7 -12
  132. package/dist/redis-client.d.ts +42 -0
  133. package/dist/redis-client.d.ts.map +1 -0
  134. package/dist/redis-client.js +98 -0
  135. package/dist/reportError.d.ts +4 -0
  136. package/dist/reportError.d.ts.map +1 -0
  137. package/dist/reportError.js +28 -0
  138. package/dist/routing/middleware/RouterMiddleware.d.ts +16 -0
  139. package/dist/routing/middleware/RouterMiddleware.d.ts.map +1 -0
  140. package/dist/{api/routing → routing}/middleware/RouterMiddleware.js +1 -1
  141. package/dist/routing/middleware/middleware.d.ts +48 -0
  142. package/dist/routing/middleware/middleware.d.ts.map +1 -0
  143. package/dist/routing/middleware/middleware.js +128 -0
  144. package/dist/routing/middleware.d.ts +3 -0
  145. package/dist/routing/middleware.d.ts.map +1 -0
  146. package/dist/{api/routing → routing}/middleware.js +1 -2
  147. package/dist/routing/schema/jwt.d.ts +4 -0
  148. package/dist/routing/schema/jwt.d.ts.map +1 -0
  149. package/dist/routing/schema/jwt.js +13 -0
  150. package/dist/routing/tsort.d.ts +8 -0
  151. package/dist/routing/tsort.d.ts.map +1 -0
  152. package/dist/routing/tsort.js +51 -0
  153. package/dist/routing/utils.d.ts +19 -0
  154. package/dist/routing/utils.d.ts.map +1 -0
  155. package/dist/routing/utils.js +45 -0
  156. package/dist/routing.d.ts +184 -0
  157. package/dist/routing.d.ts.map +1 -0
  158. package/dist/routing.js +236 -0
  159. package/dist/test.d.ts +3 -3
  160. package/dist/test.d.ts.map +1 -1
  161. package/dist/test.js +2 -2
  162. package/dist/util.d.ts +3 -0
  163. package/dist/util.d.ts.map +1 -0
  164. package/dist/util.js +14 -0
  165. package/dist/vitest.d.ts +1 -1
  166. package/examples/query.ts +47 -39
  167. package/package.json +119 -234
  168. package/src/CUPS.ts +52 -13
  169. package/src/{api/ContextProvider.ts → ContextProvider.ts} +19 -16
  170. package/src/Emailer/Sendgrid.ts +82 -59
  171. package/src/Emailer/fake.ts +3 -3
  172. package/src/MainFiberSet.ts +12 -10
  173. package/src/QueueMaker/SQLQueue.ts +153 -156
  174. package/src/QueueMaker/errors.ts +3 -1
  175. package/src/QueueMaker/memQueue.ts +113 -107
  176. package/src/QueueMaker/sbqueue.ts +78 -90
  177. package/src/RequestFiberSet.ts +13 -8
  178. package/src/{adapters/SQL → SQL}/Model.ts +42 -41
  179. package/src/ServiceBus.ts +219 -0
  180. package/src/Store/Cosmos/query.ts +216 -52
  181. package/src/Store/Cosmos.ts +493 -353
  182. package/src/Store/Disk.ts +109 -69
  183. package/src/Store/Memory.ts +365 -96
  184. package/src/Store/SQL/Pg.ts +363 -0
  185. package/src/Store/SQL/query.ts +603 -0
  186. package/src/Store/SQL.ts +735 -0
  187. package/src/Store/codeFilter.ts +8 -5
  188. package/src/Store/index.ts +21 -6
  189. package/src/Store/utils.ts +26 -24
  190. package/src/arbs.ts +5 -3
  191. package/src/{adapters/cosmos-client.ts → cosmos-client.ts} +5 -3
  192. package/src/errorReporter.ts +66 -76
  193. package/src/fileUtil.ts +1 -1
  194. package/src/index.ts +2 -1
  195. package/src/{api/internal → internal}/RequestContextMiddleware.ts +23 -6
  196. package/src/internal/auth.ts +272 -0
  197. package/src/{api/internal → internal}/events.ts +22 -13
  198. package/src/{api/layerUtils.ts → layerUtils.ts} +14 -10
  199. package/src/logger/jsonLogger.ts +4 -2
  200. package/src/logger/logFmtLogger.ts +2 -2
  201. package/src/logger/shared.ts +5 -4
  202. package/src/{adapters/memQueue.ts → memQueue.ts} +5 -4
  203. package/src/{adapters/mongo-client.ts → mongo-client.ts} +4 -2
  204. package/src/otel.ts +152 -0
  205. package/src/rateLimit.ts +34 -23
  206. package/src/{adapters/redis-client.ts → redis-client.ts} +7 -3
  207. package/src/{api/reportError.ts → reportError.ts} +3 -2
  208. package/src/{api/routing → routing}/middleware/RouterMiddleware.ts +5 -4
  209. package/src/{api/routing → routing}/middleware/middleware.ts +62 -17
  210. package/src/routing/middleware.ts +4 -0
  211. package/src/{api/routing → routing}/schema/jwt.ts +2 -1
  212. package/src/{api/routing → routing}/utils.ts +2 -1
  213. package/src/routing.ts +768 -0
  214. package/src/test.ts +2 -2
  215. package/test/auth.test.ts +101 -0
  216. package/test/contextProvider.test.ts +15 -12
  217. package/test/controller.test.ts +28 -32
  218. package/test/cosmos-query.test.ts +159 -0
  219. package/test/dist/auth.test.d.ts.map +1 -0
  220. package/test/dist/contextProvider.test.d.ts.map +1 -1
  221. package/test/dist/controller.test.d.ts.map +1 -1
  222. package/test/dist/cosmos-query.test.d.ts.map +1 -0
  223. package/test/dist/date-query.test.d.ts.map +1 -0
  224. package/test/dist/fixtures.d.ts +30 -12
  225. package/test/dist/fixtures.d.ts.map +1 -1
  226. package/test/dist/fixtures.js +17 -10
  227. package/test/dist/query.test.d.ts.map +1 -1
  228. package/test/dist/rawQuery.test.d.ts.map +1 -1
  229. package/test/dist/repository-ext.test.d.ts.map +1 -0
  230. package/test/dist/requires.test.d.ts.map +1 -1
  231. package/test/dist/router-generator.test.d.ts.map +1 -0
  232. package/test/dist/routing-interruptibility.test.d.ts.map +1 -0
  233. package/test/dist/rpc-context-map-streaming.test.d.ts.map +1 -0
  234. package/test/dist/rpc-e2e-invalidation.test.d.ts.map +1 -0
  235. package/test/dist/rpc-multi-middleware.test.d.ts.map +1 -1
  236. package/test/dist/rpc-stream-fullstack.test.d.ts.map +1 -0
  237. package/test/dist/sql-store.test.d.ts.map +1 -0
  238. package/test/fixtures.ts +16 -9
  239. package/test/layerUtils.test.ts +2 -2
  240. package/test/query.test.ts +903 -40
  241. package/test/rawQuery.test.ts +340 -22
  242. package/test/repository-ext.test.ts +62 -0
  243. package/test/requires.test.ts +10 -5
  244. package/test/router-generator.test.ts +187 -0
  245. package/test/routing-interruptibility.test.ts +66 -0
  246. package/test/rpc-context-map-streaming.test.ts +262 -0
  247. package/test/rpc-e2e-invalidation.test.ts +256 -0
  248. package/test/rpc-multi-middleware.test.ts +85 -10
  249. package/test/rpc-stream-fullstack.test.ts +304 -0
  250. package/test/sql-store.test.ts +1711 -0
  251. package/test/validateSample.test.ts +19 -14
  252. package/tsconfig.examples.json +1 -1
  253. package/tsconfig.json +2 -1
  254. package/tsconfig.json.bak +2 -2
  255. package/tsconfig.src.json +35 -35
  256. package/tsconfig.test.json +2 -2
  257. package/dist/Emailer/service.d.ts +0 -55
  258. package/dist/Emailer/service.d.ts.map +0 -1
  259. package/dist/Emailer/service.js +0 -6
  260. package/dist/Emailer.d.ts +0 -2
  261. package/dist/Emailer.d.ts.map +0 -1
  262. package/dist/Emailer.js +0 -2
  263. package/dist/Model/Repository/ext.d.ts +0 -41
  264. package/dist/Model/Repository/ext.d.ts.map +0 -1
  265. package/dist/Model/Repository/ext.js +0 -65
  266. package/dist/Model/Repository/internal/internal.d.ts +0 -59
  267. package/dist/Model/Repository/internal/internal.d.ts.map +0 -1
  268. package/dist/Model/Repository/internal/internal.js +0 -316
  269. package/dist/Model/Repository/legacy.d.ts +0 -19
  270. package/dist/Model/Repository/legacy.d.ts.map +0 -1
  271. package/dist/Model/Repository/legacy.js +0 -2
  272. package/dist/Model/Repository/makeRepo.d.ts +0 -49
  273. package/dist/Model/Repository/makeRepo.d.ts.map +0 -1
  274. package/dist/Model/Repository/makeRepo.js +0 -24
  275. package/dist/Model/Repository/service.d.ts +0 -89
  276. package/dist/Model/Repository/service.d.ts.map +0 -1
  277. package/dist/Model/Repository/service.js +0 -2
  278. package/dist/Model/Repository/validation.d.ts +0 -42
  279. package/dist/Model/Repository/validation.d.ts.map +0 -1
  280. package/dist/Model/Repository/validation.js +0 -32
  281. package/dist/Model/Repository.d.ts +0 -6
  282. package/dist/Model/Repository.d.ts.map +0 -1
  283. package/dist/Model/Repository.js +0 -6
  284. package/dist/Model/dsl.d.ts +0 -32
  285. package/dist/Model/dsl.d.ts.map +0 -1
  286. package/dist/Model/dsl.js +0 -44
  287. package/dist/Model/filter/filterApi.d.ts +0 -30
  288. package/dist/Model/filter/filterApi.d.ts.map +0 -1
  289. package/dist/Model/filter/filterApi.js +0 -2
  290. package/dist/Model/filter/types/errors.d.ts +0 -29
  291. package/dist/Model/filter/types/errors.d.ts.map +0 -1
  292. package/dist/Model/filter/types/errors.js +0 -2
  293. package/dist/Model/filter/types/fields.d.ts +0 -15
  294. package/dist/Model/filter/types/fields.d.ts.map +0 -1
  295. package/dist/Model/filter/types/fields.js +0 -2
  296. package/dist/Model/filter/types/path/common.d.ts +0 -316
  297. package/dist/Model/filter/types/path/common.d.ts.map +0 -1
  298. package/dist/Model/filter/types/path/common.js +0 -2
  299. package/dist/Model/filter/types/path/eager.d.ts +0 -95
  300. package/dist/Model/filter/types/path/eager.d.ts.map +0 -1
  301. package/dist/Model/filter/types/path/eager.js +0 -31
  302. package/dist/Model/filter/types/path/index.d.ts +0 -4
  303. package/dist/Model/filter/types/path/index.d.ts.map +0 -1
  304. package/dist/Model/filter/types/path/index.js +0 -3
  305. package/dist/Model/filter/types/utils.d.ts +0 -79
  306. package/dist/Model/filter/types/utils.d.ts.map +0 -1
  307. package/dist/Model/filter/types/utils.js +0 -2
  308. package/dist/Model/filter/types/validator.d.ts +0 -30
  309. package/dist/Model/filter/types/validator.d.ts.map +0 -1
  310. package/dist/Model/filter/types/validator.js +0 -2
  311. package/dist/Model/filter/types.d.ts +0 -5
  312. package/dist/Model/filter/types.d.ts.map +0 -1
  313. package/dist/Model/filter/types.js +0 -7
  314. package/dist/Model/query/dsl.d.ts +0 -248
  315. package/dist/Model/query/dsl.d.ts.map +0 -1
  316. package/dist/Model/query/dsl.js +0 -104
  317. package/dist/Model/query/new-kid-interpreter.d.ts +0 -28
  318. package/dist/Model/query/new-kid-interpreter.d.ts.map +0 -1
  319. package/dist/Model/query/new-kid-interpreter.js +0 -165
  320. package/dist/Model/query.d.ts +0 -15
  321. package/dist/Model/query.d.ts.map +0 -1
  322. package/dist/Model/query.js +0 -3
  323. package/dist/Model.d.ts +0 -4
  324. package/dist/Model.d.ts.map +0 -1
  325. package/dist/Model.js +0 -4
  326. package/dist/Operations.d.ts +0 -55
  327. package/dist/Operations.d.ts.map +0 -1
  328. package/dist/Operations.js +0 -102
  329. package/dist/OperationsRepo.d.ts +0 -41
  330. package/dist/OperationsRepo.d.ts.map +0 -1
  331. package/dist/OperationsRepo.js +0 -14
  332. package/dist/QueueMaker/service.d.ts +0 -11
  333. package/dist/QueueMaker/service.d.ts.map +0 -1
  334. package/dist/QueueMaker/service.js +0 -4
  335. package/dist/RequestContext.d.ts +0 -63
  336. package/dist/RequestContext.d.ts.map +0 -1
  337. package/dist/RequestContext.js +0 -49
  338. package/dist/Store/ContextMapContainer.d.ts +0 -14
  339. package/dist/Store/ContextMapContainer.d.ts.map +0 -1
  340. package/dist/Store/ContextMapContainer.js +0 -16
  341. package/dist/Store/service.d.ts +0 -108
  342. package/dist/Store/service.d.ts.map +0 -1
  343. package/dist/Store/service.js +0 -71
  344. package/dist/Store.d.ts +0 -2
  345. package/dist/Store.d.ts.map +0 -1
  346. package/dist/Store.js +0 -2
  347. package/dist/adapters/SQL/Model.d.ts +0 -479
  348. package/dist/adapters/SQL/Model.d.ts.map +0 -1
  349. package/dist/adapters/SQL/Model.js +0 -478
  350. package/dist/adapters/SQL.d.ts +0 -2
  351. package/dist/adapters/SQL.d.ts.map +0 -1
  352. package/dist/adapters/ServiceBus.d.ts +0 -58
  353. package/dist/adapters/ServiceBus.d.ts.map +0 -1
  354. package/dist/adapters/ServiceBus.js +0 -99
  355. package/dist/adapters/cosmos-client.d.ts +0 -14
  356. package/dist/adapters/cosmos-client.d.ts.map +0 -1
  357. package/dist/adapters/cosmos-client.js +0 -9
  358. package/dist/adapters/index.d.ts +0 -2
  359. package/dist/adapters/index.d.ts.map +0 -1
  360. package/dist/adapters/index.js +0 -2
  361. package/dist/adapters/logger.d.ts +0 -9
  362. package/dist/adapters/logger.d.ts.map +0 -1
  363. package/dist/adapters/logger.js +0 -3
  364. package/dist/adapters/memQueue.d.ts +0 -13
  365. package/dist/adapters/memQueue.d.ts.map +0 -1
  366. package/dist/adapters/memQueue.js +0 -20
  367. package/dist/adapters/mongo-client.d.ts +0 -10
  368. package/dist/adapters/mongo-client.d.ts.map +0 -1
  369. package/dist/adapters/mongo-client.js +0 -13
  370. package/dist/adapters/redis-client.d.ts +0 -39
  371. package/dist/adapters/redis-client.d.ts.map +0 -1
  372. package/dist/adapters/redis-client.js +0 -94
  373. package/dist/api/ContextProvider.d.ts +0 -31
  374. package/dist/api/ContextProvider.d.ts.map +0 -1
  375. package/dist/api/ContextProvider.js +0 -38
  376. package/dist/api/codec.d.ts +0 -5
  377. package/dist/api/codec.d.ts.map +0 -1
  378. package/dist/api/codec.js +0 -5
  379. package/dist/api/internal/RequestContextMiddleware.d.ts +0 -5
  380. package/dist/api/internal/RequestContextMiddleware.d.ts.map +0 -1
  381. package/dist/api/internal/RequestContextMiddleware.js +0 -35
  382. package/dist/api/internal/auth.d.ts +0 -15
  383. package/dist/api/internal/auth.d.ts.map +0 -1
  384. package/dist/api/internal/auth.js +0 -47
  385. package/dist/api/internal/events.d.ts +0 -9
  386. package/dist/api/internal/events.d.ts.map +0 -1
  387. package/dist/api/internal/events.js +0 -42
  388. package/dist/api/internal/health.d.ts +0 -3
  389. package/dist/api/internal/health.d.ts.map +0 -1
  390. package/dist/api/internal/health.js +0 -5
  391. package/dist/api/layerUtils.d.ts +0 -24
  392. package/dist/api/layerUtils.d.ts.map +0 -1
  393. package/dist/api/layerUtils.js +0 -16
  394. package/dist/api/middlewares.d.ts +0 -10
  395. package/dist/api/middlewares.d.ts.map +0 -1
  396. package/dist/api/reportError.d.ts +0 -4
  397. package/dist/api/reportError.d.ts.map +0 -1
  398. package/dist/api/reportError.js +0 -27
  399. package/dist/api/routing/middleware/RouterMiddleware.d.ts +0 -15
  400. package/dist/api/routing/middleware/RouterMiddleware.d.ts.map +0 -1
  401. package/dist/api/routing/middleware/middleware.d.ts +0 -9
  402. package/dist/api/routing/middleware/middleware.d.ts.map +0 -1
  403. package/dist/api/routing/middleware/middleware.js +0 -92
  404. package/dist/api/routing/middleware.d.ts +0 -4
  405. package/dist/api/routing/middleware.d.ts.map +0 -1
  406. package/dist/api/routing/schema/jwt.d.ts +0 -4
  407. package/dist/api/routing/schema/jwt.d.ts.map +0 -1
  408. package/dist/api/routing/schema/jwt.js +0 -12
  409. package/dist/api/routing/tsort.d.ts +0 -8
  410. package/dist/api/routing/tsort.d.ts.map +0 -1
  411. package/dist/api/routing/tsort.js +0 -51
  412. package/dist/api/routing/utils.d.ts +0 -19
  413. package/dist/api/routing/utils.d.ts.map +0 -1
  414. package/dist/api/routing/utils.js +0 -44
  415. package/dist/api/routing.d.ts +0 -138
  416. package/dist/api/routing.d.ts.map +0 -1
  417. package/dist/api/routing.js +0 -166
  418. package/dist/api/setupRequest.d.ts +0 -12
  419. package/dist/api/setupRequest.d.ts.map +0 -1
  420. package/dist/api/setupRequest.js +0 -44
  421. package/dist/api/util.d.ts +0 -3
  422. package/dist/api/util.d.ts.map +0 -1
  423. package/dist/api/util.js +0 -14
  424. package/eslint.config.mjs +0 -24
  425. package/src/Emailer/service.ts +0 -52
  426. package/src/Emailer.ts +0 -1
  427. package/src/Model/Repository/ext.ts +0 -283
  428. package/src/Model/Repository/internal/internal.ts +0 -577
  429. package/src/Model/Repository/legacy.ts +0 -27
  430. package/src/Model/Repository/makeRepo.ts +0 -139
  431. package/src/Model/Repository/service.ts +0 -627
  432. package/src/Model/Repository/validation.ts +0 -31
  433. package/src/Model/Repository.ts +0 -5
  434. package/src/Model/dsl.ts +0 -128
  435. package/src/Model/filter/filterApi.ts +0 -60
  436. package/src/Model/filter/types/errors.ts +0 -47
  437. package/src/Model/filter/types/fields.ts +0 -50
  438. package/src/Model/filter/types/path/common.ts +0 -404
  439. package/src/Model/filter/types/path/eager.ts +0 -298
  440. package/src/Model/filter/types/path/index.ts +0 -4
  441. package/src/Model/filter/types/utils.ts +0 -128
  442. package/src/Model/filter/types/validator.ts +0 -46
  443. package/src/Model/filter/types.ts +0 -6
  444. package/src/Model/query/dsl.ts +0 -2110
  445. package/src/Model/query/new-kid-interpreter.ts +0 -210
  446. package/src/Model/query.ts +0 -13
  447. package/src/Model.ts +0 -3
  448. package/src/Operations.ts +0 -235
  449. package/src/OperationsRepo.ts +0 -16
  450. package/src/QueueMaker/service.ts +0 -17
  451. package/src/RequestContext.ts +0 -63
  452. package/src/Store/ContextMapContainer.ts +0 -20
  453. package/src/Store/service.ts +0 -184
  454. package/src/Store.ts +0 -1
  455. package/src/adapters/ServiceBus.ts +0 -209
  456. package/src/adapters/index.ts +0 -0
  457. package/src/adapters/logger.ts +0 -3
  458. package/src/api/internal/auth.ts +0 -68
  459. package/src/api/routing/middleware.ts +0 -6
  460. package/src/api/routing.ts +0 -598
  461. package/src/api/setupRequest.ts +0 -84
  462. /package/src/{adapters/SQL.ts → SQL.ts} +0 -0
  463. /package/src/{api/codec.ts → codec.ts} +0 -0
  464. /package/src/{api/internal → internal}/health.ts +0 -0
  465. /package/src/{api/middlewares.ts → middlewares.ts} +0 -0
  466. /package/src/{api/routing → routing}/tsort.ts +0 -0
  467. /package/src/{api/util.ts → util.ts} +0 -0
@@ -0,0 +1,735 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+
3
+ import type { NonEmptyReadonlyArray } from "effect-app/Array"
4
+ import { toNonEmptyArray } from "effect-app/Array"
5
+ import * as Effect from "effect-app/Effect"
6
+ import type { FieldValues } from "effect-app/Model/filter/types"
7
+ import type { ComputedProjectionIrExpression } from "effect-app/Model/query"
8
+ import * as Option from "effect-app/Option"
9
+ import { type FilterArgs, type PersistenceModelType, type StorageConfig, type Store, type StoreConfig, storeId, StoreMaker } from "effect-app/Store"
10
+ import * as Context from "effect/Context"
11
+ import * as Layer from "effect/Layer"
12
+ import * as LayerMap from "effect/LayerMap"
13
+ import * as Struct from "effect/Struct"
14
+ import { SqlClient } from "effect/unstable/sql"
15
+ import { OptimisticConcurrencyException } from "../errors.js"
16
+ import { InfraLogger } from "../logger.js"
17
+ import { annotateDb, type DbSystem } from "../otel.js"
18
+ import { buildWhereSQLQuery, logQuery, type SQLDialect, sqliteDialect } from "./SQL/query.js"
19
+ import { makeETag } from "./utils.js"
20
+
21
+ export type WithNsTransactionFn = <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>
22
+
23
+ export class WithNsTransaction
24
+ extends Context.Service<WithNsTransaction, WithNsTransactionFn>()("effect-app/WithNsTransaction")
25
+ {}
26
+
27
+ /** @internal */
28
+ export const parseRow = <Encoded extends FieldValues>(
29
+ row: { id: string; _etag: string | null; data: string },
30
+ idKey: PropertyKey,
31
+ defaultValues: Partial<Encoded>
32
+ ): PersistenceModelType<Encoded> => {
33
+ const data = (typeof row.data === "string" ? JSON.parse(row.data) : row.data) as object
34
+ return { ...defaultValues, ...data, [idKey]: row.id, _etag: row._etag ?? undefined } as PersistenceModelType<Encoded>
35
+ }
36
+
37
+ const parseSelectRow = (
38
+ row: Record<string, unknown>,
39
+ idKey: PropertyKey
40
+ ): any => {
41
+ const result: Record<string, unknown> = {}
42
+ for (const [key, value] of Object.entries(row)) {
43
+ if (key === "id") {
44
+ result[idKey as string] = value
45
+ result["id"] = value
46
+ } else if (typeof value === "string") {
47
+ try {
48
+ result[key] = JSON.parse(value)
49
+ } catch {
50
+ result[key] = value
51
+ }
52
+ } else {
53
+ result[key] = value
54
+ }
55
+ }
56
+ return result
57
+ }
58
+
59
+ function makeSQLStoreInt(system: DbSystem, dialect: SQLDialect, jsonColumnType: string) {
60
+ return Effect.fnUntraced(function*({ prefix }: StorageConfig) {
61
+ const sql = yield* SqlClient.SqlClient
62
+ return {
63
+ make: Effect.fnUntraced(function*<IdKey extends keyof Encoded, Encoded extends FieldValues, R = never, E = never>(
64
+ name: string,
65
+ idKey: IdKey,
66
+ seed?: Effect.Effect<Iterable<Encoded>, E, R>,
67
+ config?: StoreConfig<Encoded>
68
+ ) {
69
+ type PM = PersistenceModelType<Encoded>
70
+ const tableName = `${prefix}${name}`
71
+ const defaultValues = config?.defaultValues ?? {}
72
+
73
+ const resolveNamespace = !config?.allowNamespace
74
+ ? Effect.succeed("primary")
75
+ : storeId.pipe(Effect.map((namespace) => {
76
+ if (namespace !== "primary" && !config.allowNamespace!(namespace)) {
77
+ throw new Error(`Namespace ${namespace} not allowed!`)
78
+ }
79
+ return namespace
80
+ }))
81
+
82
+ const ensureTable = sql
83
+ .unsafe(
84
+ `CREATE TABLE IF NOT EXISTS "${tableName}" (id TEXT NOT NULL, _namespace TEXT NOT NULL DEFAULT 'primary', _etag TEXT, data ${jsonColumnType} NOT NULL, PRIMARY KEY (id, _namespace))`
85
+ )
86
+ .pipe(
87
+ Effect.andThen(
88
+ sql.unsafe(
89
+ `CREATE TABLE IF NOT EXISTS "_migrations" (id TEXT NOT NULL, version TEXT NOT NULL, PRIMARY KEY (id, version))`
90
+ )
91
+ ),
92
+ Effect.orDie,
93
+ Effect.asVoid
94
+ )
95
+
96
+ const toRow = (e: PM) => {
97
+ const newE = makeETag(e)
98
+ const id = newE[idKey] as string
99
+ const { _etag, [idKey]: _id, ...rest } = newE as any
100
+ const data = JSON.stringify(rest)
101
+ return { id, _etag: newE._etag!, data, item: newE }
102
+ }
103
+
104
+ const exec = (query: string, params?: readonly unknown[]) => sql.unsafe(query, params as any).pipe(Effect.orDie)
105
+
106
+ const setInternal = Effect.fnUntraced(function*(e: PM, ns: string) {
107
+ const row = toRow(e)
108
+ if (e._etag) {
109
+ yield* exec(
110
+ `UPDATE "${tableName}" SET _etag = ?, data = ? WHERE id = ? AND _etag = ? AND _namespace = ?`,
111
+ [row._etag, row.data, row.id, e._etag, ns]
112
+ )
113
+ const existing = yield* exec(
114
+ `SELECT _etag FROM "${tableName}" WHERE id = ? AND _namespace = ?`,
115
+ [row.id, ns]
116
+ )
117
+ const current = (existing as any[])[0]
118
+ if (!current || current._etag !== row._etag) {
119
+ if (current) {
120
+ return yield* new OptimisticConcurrencyException({
121
+ type: name,
122
+ id: row.id,
123
+ current: current._etag,
124
+ found: e._etag,
125
+ code: 412
126
+ })
127
+ }
128
+ return yield* new OptimisticConcurrencyException({
129
+ type: name,
130
+ id: row.id,
131
+ current: "",
132
+ found: e._etag,
133
+ code: 404
134
+ })
135
+ }
136
+ } else {
137
+ yield* exec(
138
+ `INSERT INTO "${tableName}" (id, _namespace, _etag, data) VALUES (?, ?, ?, ?)`,
139
+ [row.id, ns, row._etag, row.data]
140
+ )
141
+ }
142
+ return row.item
143
+ })
144
+
145
+ const bulkSetInternal = (items: NonEmptyReadonlyArray<PM>, ns: string) =>
146
+ sql
147
+ .withTransaction(Effect.forEach(items, (e) => setInternal(e, ns)))
148
+ .pipe(
149
+ Effect.orDie,
150
+ Effect.map((_) => _ as unknown as NonEmptyReadonlyArray<PM>)
151
+ )
152
+
153
+ const ctx = yield* Effect.context<R>()
154
+ const seedCache = new Map<string, Effect.Effect<void>>()
155
+ const makeSeedEffect = Effect.fnUntraced(function*(ns: string) {
156
+ yield* ensureTable
157
+ if (!seed) return
158
+ const existing = yield* exec(
159
+ `SELECT id FROM "_migrations" WHERE id = ? AND version = ?`,
160
+ [`${tableName}::${ns}`, tableName]
161
+ )
162
+ if ((existing as any[]).length > 0) return
163
+ yield* InfraLogger.logInfo(`Seeding data for ${name} (namespace: ${ns})`)
164
+ const items = yield* seed.pipe(Effect.provide(ctx), Effect.orDie)
165
+ const ne = toNonEmptyArray([...items])
166
+ if (Option.isSome(ne)) yield* bulkSetInternal(ne.value, ns)
167
+ yield* exec(
168
+ `INSERT INTO "_migrations" (id, version) VALUES (?, ?)`,
169
+ [`${tableName}::${ns}`, tableName]
170
+ )
171
+ })
172
+ const seedNamespace = (ns: string) => {
173
+ let cached = seedCache.get(ns)
174
+ if (!cached) {
175
+ cached = Effect.cached(Effect.uninterruptible(makeSeedEffect(ns))).pipe(Effect.runSync)
176
+ seedCache.set(ns, cached)
177
+ }
178
+ return cached
179
+ }
180
+ const s: Store<IdKey, Encoded> = {
181
+ seedNamespace: (ns) => seedNamespace(ns),
182
+
183
+ all: resolveNamespace.pipe(
184
+ Effect.flatMap((ns) => {
185
+ const sqlText = `SELECT id, _etag, data FROM "${tableName}" WHERE _namespace = ?`
186
+ return exec(sqlText, [ns])
187
+ .pipe(
188
+ Effect.map((rows) => (rows as any[]).map((r) => parseRow<Encoded>(r, idKey, defaultValues))),
189
+ annotateDb({
190
+ operation: "all",
191
+ system,
192
+ collection: tableName,
193
+ namespace: ns,
194
+ entity: name,
195
+ query: sqlText
196
+ })
197
+ )
198
+ })
199
+ ),
200
+
201
+ find: (id) =>
202
+ resolveNamespace.pipe(
203
+ Effect.flatMap((ns) => {
204
+ const sqlText = `SELECT id, _etag, data FROM "${tableName}" WHERE id = ? AND _namespace = ?`
205
+ return exec(sqlText, [id, ns])
206
+ .pipe(
207
+ Effect.map((rows) => {
208
+ const row = (rows as any[])[0]
209
+ return row
210
+ ? Option.some(parseRow<Encoded>(row, idKey, defaultValues))
211
+ : Option.none()
212
+ }),
213
+ annotateDb({
214
+ operation: "find",
215
+ system,
216
+ collection: tableName,
217
+ namespace: ns,
218
+ entity: name,
219
+ query: sqlText,
220
+ extra: { "app.entity.id": id }
221
+ })
222
+ )
223
+ })
224
+ ),
225
+
226
+ filter: <U extends keyof Encoded = never>(f: FilterArgs<Encoded, U>) => {
227
+ const filter = f
228
+ .filter
229
+ type M = U extends undefined ? Encoded
230
+ : Pick<Encoded, U>
231
+ return resolveNamespace
232
+ .pipe(Effect
233
+ .flatMap((ns) =>
234
+ Effect
235
+ .sync(() => {
236
+ return buildWhereSQLQuery(
237
+ dialect,
238
+ idKey,
239
+ filter ? [{ t: "where-scope", result: filter, relation: "some" }] : [],
240
+ tableName,
241
+ defaultValues,
242
+ f
243
+ .select as
244
+ | NonEmptyReadonlyArray<
245
+ string | {
246
+ key: string
247
+ subKeys: readonly string[]
248
+ } | {
249
+ key: string
250
+ computed: ComputedProjectionIrExpression
251
+ }
252
+ >
253
+ | undefined,
254
+ f
255
+ .order,
256
+ f
257
+ .skip,
258
+ f
259
+ .limit,
260
+ ns
261
+ )
262
+ })
263
+ .pipe(
264
+ Effect
265
+ .tap((q) => logQuery(q)),
266
+ Effect.tap((q) => Effect.annotateCurrentSpan({ "db.query.text": q.sql })),
267
+ Effect.flatMap((q) =>
268
+ exec(q.sql, q.params).pipe(
269
+ Effect.map((rows) => {
270
+ if (f.select) {
271
+ return (rows as any[]).map((r) => {
272
+ const selected = parseSelectRow(r, idKey)
273
+ return {
274
+ ...Struct.pick(
275
+ defaultValues as any,
276
+ f.select!.filter((_) => typeof _ === "string") as never[]
277
+ ),
278
+ ...selected
279
+ } as M
280
+ })
281
+ }
282
+ return (rows as any[]).map((r) => parseRow<Encoded>(r, idKey, defaultValues) as any as M)
283
+ })
284
+ )
285
+ ),
286
+ annotateDb({
287
+ operation: "filter",
288
+ system,
289
+ collection: tableName,
290
+ namespace: ns,
291
+ entity: name
292
+ })
293
+ )
294
+ ))
295
+ },
296
+
297
+ set: (e) =>
298
+ resolveNamespace.pipe(Effect.flatMap((ns) =>
299
+ setInternal(e, ns).pipe(
300
+ annotateDb({
301
+ operation: "set",
302
+ system,
303
+ collection: tableName,
304
+ namespace: ns,
305
+ entity: name,
306
+ extra: { "app.entity.id": e[idKey] }
307
+ })
308
+ )
309
+ )),
310
+
311
+ batchSet: (items) =>
312
+ resolveNamespace.pipe(Effect.flatMap((ns) =>
313
+ bulkSetInternal(items, ns).pipe(
314
+ annotateDb({
315
+ operation: "batchSet",
316
+ system,
317
+ collection: tableName,
318
+ namespace: ns,
319
+ entity: name
320
+ })
321
+ )
322
+ )),
323
+
324
+ bulkSet: (items) =>
325
+ resolveNamespace.pipe(Effect.flatMap((ns) =>
326
+ bulkSetInternal(items, ns).pipe(
327
+ annotateDb({
328
+ operation: "bulkSet",
329
+ system,
330
+ collection: tableName,
331
+ namespace: ns,
332
+ entity: name
333
+ })
334
+ )
335
+ )),
336
+
337
+ batchRemove: (ids) => {
338
+ const placeholders = ids.map(() => "?").join(", ")
339
+ return resolveNamespace.pipe(Effect.flatMap((ns) => {
340
+ const sqlText = `DELETE FROM "${tableName}" WHERE id IN (${placeholders}) AND _namespace = ?`
341
+ return exec(sqlText, [...ids, ns])
342
+ .pipe(
343
+ Effect.asVoid,
344
+ annotateDb({
345
+ operation: "batchRemove",
346
+ system,
347
+ collection: tableName,
348
+ namespace: ns,
349
+ entity: name,
350
+ query: sqlText
351
+ })
352
+ )
353
+ }))
354
+ },
355
+
356
+ queryRaw: (query) =>
357
+ s.all.pipe(
358
+ Effect.map(query.memory),
359
+ annotateDb({
360
+ operation: "queryRaw",
361
+ system,
362
+ collection: tableName,
363
+ entity: name
364
+ })
365
+ )
366
+ }
367
+
368
+ // Eagerly seed primary namespace on initialization
369
+ yield* seedNamespace("primary")
370
+
371
+ return s
372
+ })
373
+ }
374
+ })
375
+ }
376
+
377
+ type WithNsSqlFn = <A, E2, R2>(
378
+ ns: string,
379
+ f: (sql: SqlClient.SqlClient) => Effect.Effect<A, E2, R2>
380
+ ) => Effect.Effect<A, E2, R2>
381
+
382
+ function makeSQLiteStorePerNs(
383
+ withNsSql: WithNsSqlFn,
384
+ { prefix }: StorageConfig
385
+ ) {
386
+ return {
387
+ make: Effect.fnUntraced(function*<IdKey extends keyof Encoded, Encoded extends FieldValues, R = never, E = never>(
388
+ name: string,
389
+ idKey: IdKey,
390
+ seed?: Effect.Effect<Iterable<Encoded>, E, R>,
391
+ config?: StoreConfig<Encoded>
392
+ ) {
393
+ type PM = PersistenceModelType<Encoded>
394
+ const tableName = `${prefix}${name}`
395
+ const defaultValues = config?.defaultValues ?? {}
396
+
397
+ const resolveNamespace = !config?.allowNamespace
398
+ ? Effect.succeed("primary")
399
+ : storeId.pipe(Effect.map((namespace) => {
400
+ if (namespace !== "primary" && !config.allowNamespace!(namespace)) {
401
+ throw new Error(`Namespace ${namespace} not allowed!`)
402
+ }
403
+ return namespace
404
+ }))
405
+
406
+ const toRow = (e: PM) => {
407
+ const newE = makeETag(e)
408
+ const id = newE[idKey] as string
409
+ const { _etag, [idKey]: _id, ...rest } = newE as any
410
+ const data = JSON.stringify(rest)
411
+ return { id, _etag: newE._etag!, data, item: newE }
412
+ }
413
+
414
+ const exec = (ns: string, query: string, params?: readonly unknown[]) =>
415
+ withNsSql(ns, (sql) => sql.unsafe(query, params as any).pipe(Effect.orDie))
416
+
417
+ const ensureTable = (ns: string) =>
418
+ withNsSql(ns, (sql) =>
419
+ sql
420
+ .unsafe(
421
+ `CREATE TABLE IF NOT EXISTS "${tableName}" (id TEXT NOT NULL PRIMARY KEY, _etag TEXT, data JSON NOT NULL)`
422
+ )
423
+ .pipe(
424
+ Effect.andThen(
425
+ sql.unsafe(
426
+ `CREATE TABLE IF NOT EXISTS "_migrations" (id TEXT NOT NULL, version TEXT NOT NULL, PRIMARY KEY (id, version))`
427
+ )
428
+ ),
429
+ Effect.orDie,
430
+ Effect.asVoid
431
+ ))
432
+
433
+ const setInternal = Effect.fnUntraced(function*(e: PM, ns: string) {
434
+ const row = toRow(e)
435
+ if (e._etag) {
436
+ yield* exec(
437
+ ns,
438
+ `UPDATE "${tableName}" SET _etag = ?, data = ? WHERE id = ? AND _etag = ?`,
439
+ [row._etag, row.data, row.id, e._etag]
440
+ )
441
+ const existing = yield* exec(
442
+ ns,
443
+ `SELECT _etag FROM "${tableName}" WHERE id = ?`,
444
+ [row.id]
445
+ )
446
+ const current = (existing as any[])[0]
447
+ if (!current || current._etag !== row._etag) {
448
+ if (current) {
449
+ return yield* new OptimisticConcurrencyException({
450
+ type: name,
451
+ id: row.id,
452
+ current: current._etag,
453
+ found: e._etag,
454
+ code: 412
455
+ })
456
+ }
457
+ return yield* new OptimisticConcurrencyException({
458
+ type: name,
459
+ id: row.id,
460
+ current: "",
461
+ found: e._etag,
462
+ code: 404
463
+ })
464
+ }
465
+ } else {
466
+ yield* exec(
467
+ ns,
468
+ `INSERT INTO "${tableName}" (id, _etag, data) VALUES (?, ?, ?)`,
469
+ [row.id, row._etag, row.data]
470
+ )
471
+ }
472
+ return row.item
473
+ })
474
+
475
+ const bulkSetInternal = (items: NonEmptyReadonlyArray<PM>, ns: string) =>
476
+ withNsSql(ns, (sql) =>
477
+ sql
478
+ .withTransaction(Effect.forEach(items, (e) => setInternal(e, ns)))
479
+ .pipe(
480
+ Effect.orDie,
481
+ Effect.map((_) => _ as unknown as NonEmptyReadonlyArray<PM>)
482
+ ))
483
+
484
+ const ctx = yield* Effect.context<R>()
485
+ const seedCache = new Map<string, Effect.Effect<void>>()
486
+ const makeSeedEffect = Effect.fnUntraced(function*(ns: string) {
487
+ yield* ensureTable(ns)
488
+ if (!seed) return
489
+ const existing = yield* exec(
490
+ ns,
491
+ `SELECT id FROM "_migrations" WHERE id = ? AND version = ?`,
492
+ [tableName, tableName]
493
+ )
494
+ if ((existing as any[]).length > 0) return
495
+ yield* InfraLogger.logInfo(`Seeding data for ${name} (namespace: ${ns})`)
496
+ const items = yield* seed.pipe(Effect.provide(ctx), Effect.orDie)
497
+ const ne = toNonEmptyArray([...items])
498
+ if (Option.isSome(ne)) yield* bulkSetInternal(ne.value, ns)
499
+ yield* exec(
500
+ ns,
501
+ `INSERT INTO "_migrations" (id, version) VALUES (?, ?)`,
502
+ [tableName, tableName]
503
+ )
504
+ })
505
+ const seedNamespace = (ns: string) => {
506
+ let cached = seedCache.get(ns)
507
+ if (!cached) {
508
+ cached = Effect.cached(Effect.uninterruptible(makeSeedEffect(ns))).pipe(Effect.runSync)
509
+ seedCache.set(ns, cached)
510
+ }
511
+ return cached
512
+ }
513
+
514
+ const s: Store<IdKey, Encoded> = {
515
+ seedNamespace: (ns) => seedNamespace(ns),
516
+
517
+ all: resolveNamespace.pipe(Effect.flatMap((ns) => {
518
+ const sqlText = `SELECT id, _etag, data FROM "${tableName}"`
519
+ return exec(ns, sqlText)
520
+ .pipe(
521
+ Effect.map((rows) => (rows as any[]).map((r) => parseRow<Encoded>(r, idKey, defaultValues))),
522
+ annotateDb({
523
+ operation: "all",
524
+ system: "sqlite",
525
+ collection: tableName,
526
+ namespace: ns,
527
+ entity: name,
528
+ query: sqlText
529
+ })
530
+ )
531
+ })),
532
+
533
+ find: (id) =>
534
+ resolveNamespace.pipe(
535
+ Effect.flatMap((ns) => {
536
+ const sqlText = `SELECT id, _etag, data FROM "${tableName}" WHERE id = ?`
537
+ return exec(ns, sqlText, [id])
538
+ .pipe(
539
+ Effect.map((rows) => {
540
+ const row = (rows as any[])[0]
541
+ return row
542
+ ? Option.some(parseRow<Encoded>(row, idKey, defaultValues))
543
+ : Option.none()
544
+ }),
545
+ annotateDb({
546
+ operation: "find",
547
+ system: "sqlite",
548
+ collection: tableName,
549
+ namespace: ns,
550
+ entity: name,
551
+ query: sqlText,
552
+ extra: { "app.entity.id": id }
553
+ })
554
+ )
555
+ })
556
+ ),
557
+
558
+ filter: <U extends keyof Encoded = never>(f: FilterArgs<Encoded, U>) => {
559
+ const filter = f
560
+ .filter
561
+ type M = U extends undefined ? Encoded
562
+ : Pick<Encoded, U>
563
+ return resolveNamespace
564
+ .pipe(Effect
565
+ .flatMap((ns) =>
566
+ Effect
567
+ .sync(() =>
568
+ buildWhereSQLQuery(
569
+ sqliteDialect,
570
+ idKey,
571
+ filter ? [{ t: "where-scope", result: filter, relation: "some" }] : [],
572
+ tableName,
573
+ defaultValues,
574
+ f
575
+ .select as
576
+ | NonEmptyReadonlyArray<
577
+ string | {
578
+ key: string
579
+ subKeys: readonly string[]
580
+ } | {
581
+ key: string
582
+ computed: ComputedProjectionIrExpression
583
+ }
584
+ >
585
+ | undefined,
586
+ f
587
+ .order as NonEmptyReadonlyArray<{ key: string; direction: "ASC" | "DESC" }> | undefined,
588
+ f
589
+ .skip,
590
+ f
591
+ .limit
592
+ )
593
+ )
594
+ .pipe(
595
+ Effect
596
+ .tap((q) => logQuery(q)),
597
+ Effect.tap((q) => Effect.annotateCurrentSpan({ "db.query.text": q.sql })),
598
+ Effect.flatMap((q) =>
599
+ exec(ns, q.sql, q.params).pipe(
600
+ Effect.map((rows) => {
601
+ if (f.select) {
602
+ return (rows as any[]).map((r) => {
603
+ const selected = parseSelectRow(r, idKey)
604
+ return {
605
+ ...Struct.pick(
606
+ defaultValues as any,
607
+ f.select!.filter((_) => typeof _ === "string") as never[]
608
+ ),
609
+ ...selected
610
+ } as M
611
+ })
612
+ }
613
+ return (rows as any[]).map((r) => parseRow<Encoded>(r, idKey, defaultValues) as any as M)
614
+ })
615
+ )
616
+ ),
617
+ annotateDb({
618
+ operation: "filter",
619
+ system: "sqlite",
620
+ collection: tableName,
621
+ namespace: ns,
622
+ entity: name
623
+ })
624
+ )
625
+ ))
626
+ },
627
+
628
+ set: (e) =>
629
+ resolveNamespace.pipe(Effect.flatMap((ns) =>
630
+ setInternal(e, ns).pipe(
631
+ annotateDb({
632
+ operation: "set",
633
+ system: "sqlite",
634
+ collection: tableName,
635
+ namespace: ns,
636
+ entity: name,
637
+ extra: { "app.entity.id": e[idKey] }
638
+ })
639
+ )
640
+ )),
641
+
642
+ batchSet: (items) =>
643
+ resolveNamespace.pipe(Effect.flatMap((ns) =>
644
+ bulkSetInternal(items, ns).pipe(
645
+ annotateDb({
646
+ operation: "batchSet",
647
+ system: "sqlite",
648
+ collection: tableName,
649
+ namespace: ns,
650
+ entity: name
651
+ })
652
+ )
653
+ )),
654
+
655
+ bulkSet: (items) =>
656
+ resolveNamespace.pipe(Effect.flatMap((ns) =>
657
+ bulkSetInternal(items, ns).pipe(
658
+ annotateDb({
659
+ operation: "bulkSet",
660
+ system: "sqlite",
661
+ collection: tableName,
662
+ namespace: ns,
663
+ entity: name
664
+ })
665
+ )
666
+ )),
667
+
668
+ batchRemove: (ids) => {
669
+ const placeholders = ids.map(() => "?").join(", ")
670
+ return resolveNamespace.pipe(Effect.flatMap((ns) => {
671
+ const sqlText = `DELETE FROM "${tableName}" WHERE id IN (${placeholders})`
672
+ return exec(ns, sqlText, [...ids])
673
+ .pipe(
674
+ Effect.asVoid,
675
+ annotateDb({
676
+ operation: "batchRemove",
677
+ system: "sqlite",
678
+ collection: tableName,
679
+ namespace: ns,
680
+ entity: name,
681
+ query: sqlText
682
+ })
683
+ )
684
+ }))
685
+ },
686
+
687
+ queryRaw: (query) =>
688
+ s.all.pipe(
689
+ Effect.map(query.memory),
690
+ annotateDb({
691
+ operation: "queryRaw",
692
+ system: "sqlite",
693
+ collection: tableName,
694
+ entity: name
695
+ })
696
+ )
697
+ }
698
+
699
+ yield* seedNamespace("primary")
700
+
701
+ return s
702
+ })
703
+ }
704
+ }
705
+
706
+ export function SQLiteStoreLayer(
707
+ cfg: StorageConfig,
708
+ options?: { makeSqlClientLayer?: (namespace: string) => Layer.Layer<SqlClient.SqlClient> }
709
+ ) {
710
+ if (options?.makeSqlClientLayer) {
711
+ return Layer.effectContext(
712
+ Effect.gen(function*() {
713
+ const layerMap = yield* LayerMap.make(
714
+ (namespace: string) => options.makeSqlClientLayer!(namespace),
715
+ { idleTimeToLive: "10 minutes" }
716
+ )
717
+
718
+ const withNsSql: WithNsSqlFn = (ns, f) => SqlClient.SqlClient.use(f).pipe(Effect.provide(layerMap.get(ns)))
719
+
720
+ const storeMaker = makeSQLiteStorePerNs(withNsSql, cfg)
721
+
722
+ const withTransaction: WithNsTransactionFn = (effect) =>
723
+ storeId.pipe(
724
+ Effect.flatMap((ns) => withNsSql(ns, (sql) => sql.withTransaction(effect).pipe(Effect.orDie)))
725
+ )
726
+
727
+ return StoreMaker.context(storeMaker).pipe(
728
+ Context.add(WithNsTransaction, withTransaction)
729
+ )
730
+ })
731
+ )
732
+ }
733
+ return StoreMaker
734
+ .toLayer(makeSQLStoreInt("sqlite", sqliteDialect, "JSON")(cfg))
735
+ }