@effect-app/infra 4.0.0-beta.247 → 4.0.0-beta.249

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 (378) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/ContextProvider.d.ts +34 -0
  3. package/dist/ContextProvider.d.ts.map +1 -0
  4. package/dist/ContextProvider.js +40 -0
  5. package/dist/Emailer/Sendgrid.d.ts +109 -145
  6. package/dist/Emailer/Sendgrid.d.ts.map +1 -1
  7. package/dist/Emailer/Sendgrid.js +4 -3
  8. package/dist/Emailer/fake.d.ts +2 -2
  9. package/dist/Emailer/fake.d.ts.map +1 -1
  10. package/dist/Emailer/fake.js +2 -2
  11. package/dist/QueueMaker/SQLQueue.d.ts +2 -2
  12. package/dist/QueueMaker/SQLQueue.d.ts.map +1 -1
  13. package/dist/QueueMaker/SQLQueue.js +4 -4
  14. package/dist/QueueMaker/memQueue.d.ts +2 -2
  15. package/dist/QueueMaker/memQueue.d.ts.map +1 -1
  16. package/dist/QueueMaker/memQueue.js +4 -4
  17. package/dist/QueueMaker/sbqueue.d.ts +2 -2
  18. package/dist/QueueMaker/sbqueue.d.ts.map +1 -1
  19. package/dist/QueueMaker/sbqueue.js +4 -4
  20. package/dist/RequestFiberSet.js +2 -2
  21. package/dist/{adapters/SQL → SQL}/Model.d.ts +2 -2
  22. package/dist/SQL/Model.d.ts.map +1 -0
  23. package/dist/SQL/Model.js +469 -0
  24. package/dist/{adapters/SQL.d.ts → SQL.d.ts} +1 -1
  25. package/dist/SQL.d.ts.map +1 -0
  26. package/dist/{adapters/SQL.js → SQL.js} +1 -1
  27. package/dist/{adapters/ServiceBus.d.ts → ServiceBus.d.ts} +1 -1
  28. package/dist/ServiceBus.d.ts.map +1 -0
  29. package/dist/ServiceBus.js +108 -0
  30. package/dist/Store/ContextMapContainer.d.ts +2 -2
  31. package/dist/Store/ContextMapContainer.d.ts.map +1 -1
  32. package/dist/Store/ContextMapContainer.js +2 -2
  33. package/dist/Store/Cosmos/query.d.ts +4 -4
  34. package/dist/Store/Cosmos/query.d.ts.map +1 -1
  35. package/dist/Store/Cosmos/query.js +1 -1
  36. package/dist/Store/Cosmos.d.ts +2 -2
  37. package/dist/Store/Cosmos.d.ts.map +1 -1
  38. package/dist/Store/Cosmos.js +3 -3
  39. package/dist/Store/Disk.d.ts +3 -3
  40. package/dist/Store/Disk.d.ts.map +1 -1
  41. package/dist/Store/Disk.js +2 -2
  42. package/dist/Store/Memory.d.ts +3 -3
  43. package/dist/Store/Memory.d.ts.map +1 -1
  44. package/dist/Store/Memory.js +2 -2
  45. package/dist/Store/SQL/Pg.d.ts +2 -2
  46. package/dist/Store/SQL/Pg.d.ts.map +1 -1
  47. package/dist/Store/SQL/Pg.js +2 -2
  48. package/dist/Store/SQL/query.d.ts +3 -3
  49. package/dist/Store/SQL/query.d.ts.map +1 -1
  50. package/dist/Store/SQL/query.js +1 -1
  51. package/dist/Store/SQL.d.ts +3 -3
  52. package/dist/Store/SQL.d.ts.map +1 -1
  53. package/dist/Store/SQL.js +2 -2
  54. package/dist/Store/codeFilter.d.ts +4 -4
  55. package/dist/Store/codeFilter.d.ts.map +1 -1
  56. package/dist/Store/codeFilter.js +1 -1
  57. package/dist/Store/index.d.ts +3 -4
  58. package/dist/Store/index.d.ts.map +1 -1
  59. package/dist/Store/index.js +2 -3
  60. package/dist/Store/utils.d.ts +2 -2
  61. package/dist/Store/utils.d.ts.map +1 -1
  62. package/dist/Store/utils.js +1 -1
  63. package/dist/{api/codec.d.ts → codec.d.ts} +1 -1
  64. package/dist/codec.d.ts.map +1 -0
  65. package/dist/codec.js +5 -0
  66. package/dist/{adapters/cosmos-client.d.ts → cosmos-client.d.ts} +1 -1
  67. package/dist/cosmos-client.d.ts.map +1 -0
  68. package/dist/cosmos-client.js +11 -0
  69. package/dist/errorReporter.d.ts +1 -1
  70. package/dist/errorReporter.d.ts.map +1 -1
  71. package/dist/errorReporter.js +2 -2
  72. package/dist/index.d.ts +3 -2
  73. package/dist/index.d.ts.map +1 -1
  74. package/dist/index.js +3 -2
  75. package/dist/{api/internal → internal}/RequestContextMiddleware.d.ts +2 -2
  76. package/dist/internal/RequestContextMiddleware.d.ts.map +1 -0
  77. package/dist/internal/RequestContextMiddleware.js +46 -0
  78. package/dist/{api/internal → internal}/auth.d.ts +1 -1
  79. package/dist/internal/auth.d.ts.map +1 -0
  80. package/dist/internal/auth.js +180 -0
  81. package/dist/{api/internal → internal}/events.d.ts +1 -1
  82. package/dist/internal/events.d.ts.map +1 -0
  83. package/dist/internal/events.js +49 -0
  84. package/dist/{api/internal → internal}/health.d.ts +1 -1
  85. package/dist/internal/health.d.ts.map +1 -0
  86. package/dist/internal/health.js +5 -0
  87. package/dist/layerUtils.d.ts +32 -0
  88. package/dist/layerUtils.d.ts.map +1 -0
  89. package/dist/layerUtils.js +17 -0
  90. package/dist/logger/jsonLogger.d.ts +1 -1
  91. package/dist/logger/jsonLogger.d.ts.map +1 -1
  92. package/dist/logger/jsonLogger.js +2 -2
  93. package/dist/logger/logFmtLogger.d.ts +1 -1
  94. package/dist/logger/logFmtLogger.d.ts.map +1 -1
  95. package/dist/logger/logFmtLogger.js +2 -2
  96. package/dist/logger/shared.d.ts +2 -2
  97. package/dist/logger/shared.d.ts.map +1 -1
  98. package/dist/logger/shared.js +2 -2
  99. package/dist/logger.d.ts +1 -1
  100. package/dist/{adapters/memQueue.d.ts → memQueue.d.ts} +1 -1
  101. package/dist/memQueue.d.ts.map +1 -0
  102. package/dist/memQueue.js +21 -0
  103. package/dist/{api/middlewares.d.ts → middlewares.d.ts} +1 -1
  104. package/dist/middlewares.d.ts.map +1 -0
  105. package/dist/{api/middlewares.js → middlewares.js} +1 -1
  106. package/dist/{adapters/mongo-client.d.ts → mongo-client.d.ts} +1 -1
  107. package/dist/mongo-client.d.ts.map +1 -0
  108. package/dist/mongo-client.js +15 -0
  109. package/dist/{adapters/redis-client.d.ts → redis-client.d.ts} +1 -1
  110. package/dist/redis-client.d.ts.map +1 -0
  111. package/dist/redis-client.js +98 -0
  112. package/dist/reportError.d.ts +4 -0
  113. package/dist/reportError.d.ts.map +1 -0
  114. package/dist/reportError.js +28 -0
  115. package/dist/{api/routing → routing}/middleware/RouterMiddleware.d.ts +1 -1
  116. package/dist/routing/middleware/RouterMiddleware.d.ts.map +1 -0
  117. package/dist/{api/routing → routing}/middleware/RouterMiddleware.js +1 -1
  118. package/dist/{api/routing → routing}/middleware/middleware.d.ts +2 -2
  119. package/dist/routing/middleware/middleware.d.ts.map +1 -0
  120. package/dist/routing/middleware/middleware.js +128 -0
  121. package/dist/{api/routing → routing}/middleware.d.ts +1 -1
  122. package/dist/routing/middleware.d.ts.map +1 -0
  123. package/dist/{api/routing → routing}/middleware.js +1 -1
  124. package/dist/{api/routing → routing}/schema/jwt.d.ts +1 -1
  125. package/dist/routing/schema/jwt.d.ts.map +1 -0
  126. package/dist/routing/schema/jwt.js +13 -0
  127. package/dist/routing/tsort.d.ts +8 -0
  128. package/dist/routing/tsort.d.ts.map +1 -0
  129. package/dist/routing/tsort.js +51 -0
  130. package/dist/{api/routing → routing}/utils.d.ts +1 -1
  131. package/dist/routing/utils.d.ts.map +1 -0
  132. package/dist/routing/utils.js +45 -0
  133. package/dist/routing.d.ts +184 -0
  134. package/dist/routing.d.ts.map +1 -0
  135. package/dist/{api/routing.js → routing.js} +1 -1
  136. package/dist/{api/setupRequest.d.ts → setupRequest.d.ts} +2 -2
  137. package/dist/setupRequest.d.ts.map +1 -0
  138. package/dist/setupRequest.js +70 -0
  139. package/dist/{api/util.d.ts → util.d.ts} +1 -1
  140. package/dist/util.d.ts.map +1 -0
  141. package/dist/util.js +14 -0
  142. package/examples/query.ts +2 -2
  143. package/package.json +84 -200
  144. package/src/Emailer/Sendgrid.ts +20 -5
  145. package/src/Emailer/fake.ts +1 -1
  146. package/src/QueueMaker/SQLQueue.ts +3 -3
  147. package/src/QueueMaker/memQueue.ts +3 -3
  148. package/src/QueueMaker/sbqueue.ts +3 -3
  149. package/src/RequestFiberSet.ts +1 -1
  150. package/src/{adapters/SQL → SQL}/Model.ts +1 -1
  151. package/src/{adapters/ServiceBus.ts → ServiceBus.ts} +1 -1
  152. package/src/Store/ContextMapContainer.ts +1 -1
  153. package/src/Store/Cosmos/query.ts +3 -3
  154. package/src/Store/Cosmos.ts +4 -4
  155. package/src/Store/Disk.ts +2 -2
  156. package/src/Store/Memory.ts +4 -4
  157. package/src/Store/SQL/Pg.ts +3 -3
  158. package/src/Store/SQL/query.ts +2 -2
  159. package/src/Store/SQL.ts +3 -3
  160. package/src/Store/codeFilter.ts +3 -3
  161. package/src/Store/index.ts +2 -4
  162. package/src/Store/utils.ts +1 -1
  163. package/src/errorReporter.ts +1 -1
  164. package/src/index.ts +2 -1
  165. package/src/{api/internal → internal}/RequestContextMiddleware.ts +3 -3
  166. package/src/{api/internal → internal}/events.ts +2 -2
  167. package/src/{api/layerUtils.ts → layerUtils.ts} +1 -1
  168. package/src/logger/jsonLogger.ts +1 -1
  169. package/src/logger/logFmtLogger.ts +1 -1
  170. package/src/logger/shared.ts +1 -1
  171. package/src/{adapters/redis-client.ts → redis-client.ts} +1 -1
  172. package/src/{api/reportError.ts → reportError.ts} +1 -1
  173. package/src/{api/routing → routing}/middleware/middleware.ts +4 -4
  174. package/src/{api/routing.ts → routing.ts} +13 -13
  175. package/src/{api/setupRequest.ts → setupRequest.ts} +3 -3
  176. package/test/auth.test.ts +1 -1
  177. package/test/contextProvider.test.ts +1 -1
  178. package/test/controller.test.ts +3 -3
  179. package/test/cosmos-query.test.ts +1 -1
  180. package/test/dist/controller.test.d.ts.map +1 -1
  181. package/test/dist/query.test.d.ts.map +1 -1
  182. package/test/dist/rawQuery.test.d.ts.map +1 -1
  183. package/test/layerUtils.test.ts +1 -1
  184. package/test/query.test.ts +4 -4
  185. package/test/rawQuery.test.ts +4 -4
  186. package/test/repository-ext.test.ts +3 -3
  187. package/test/router-generator.test.ts +3 -3
  188. package/test/routing-interruptibility.test.ts +2 -2
  189. package/test/rpc-context-map-streaming.test.ts +3 -3
  190. package/test/rpc-e2e-invalidation.test.ts +2 -2
  191. package/test/rpc-multi-middleware.test.ts +1 -1
  192. package/test/rpc-stream-fullstack.test.ts +2 -2
  193. package/test/validateSample.test.ts +3 -3
  194. package/dist/Emailer/service.d.ts +0 -64
  195. package/dist/Emailer/service.d.ts.map +0 -1
  196. package/dist/Emailer/service.js +0 -7
  197. package/dist/Emailer.d.ts +0 -2
  198. package/dist/Emailer.d.ts.map +0 -1
  199. package/dist/Emailer.js +0 -2
  200. package/dist/Model/Repository/Registry.d.ts +0 -21
  201. package/dist/Model/Repository/Registry.d.ts.map +0 -1
  202. package/dist/Model/Repository/Registry.js +0 -18
  203. package/dist/Model/Repository/ext.d.ts +0 -60
  204. package/dist/Model/Repository/ext.d.ts.map +0 -1
  205. package/dist/Model/Repository/ext.js +0 -122
  206. package/dist/Model/Repository/internal/internal.d.ts +0 -62
  207. package/dist/Model/Repository/internal/internal.d.ts.map +0 -1
  208. package/dist/Model/Repository/internal/internal.js +0 -398
  209. package/dist/Model/Repository/legacy.d.ts +0 -21
  210. package/dist/Model/Repository/legacy.d.ts.map +0 -1
  211. package/dist/Model/Repository/legacy.js +0 -2
  212. package/dist/Model/Repository/makeRepo.d.ts +0 -53
  213. package/dist/Model/Repository/makeRepo.d.ts.map +0 -1
  214. package/dist/Model/Repository/makeRepo.js +0 -27
  215. package/dist/Model/Repository/service.d.ts +0 -97
  216. package/dist/Model/Repository/service.d.ts.map +0 -1
  217. package/dist/Model/Repository/service.js +0 -2
  218. package/dist/Model/Repository/validation.d.ts +0 -71
  219. package/dist/Model/Repository/validation.d.ts.map +0 -1
  220. package/dist/Model/Repository/validation.js +0 -32
  221. package/dist/Model/Repository.d.ts +0 -7
  222. package/dist/Model/Repository.d.ts.map +0 -1
  223. package/dist/Model/Repository.js +0 -7
  224. package/dist/Model/dsl.d.ts +0 -33
  225. package/dist/Model/dsl.d.ts.map +0 -1
  226. package/dist/Model/dsl.js +0 -43
  227. package/dist/Model/filter/filterApi.d.ts +0 -30
  228. package/dist/Model/filter/filterApi.d.ts.map +0 -1
  229. package/dist/Model/filter/filterApi.js +0 -2
  230. package/dist/Model/filter/types/errors.d.ts +0 -29
  231. package/dist/Model/filter/types/errors.d.ts.map +0 -1
  232. package/dist/Model/filter/types/errors.js +0 -2
  233. package/dist/Model/filter/types/fields.d.ts +0 -15
  234. package/dist/Model/filter/types/fields.d.ts.map +0 -1
  235. package/dist/Model/filter/types/fields.js +0 -2
  236. package/dist/Model/filter/types/path/common.d.ts +0 -316
  237. package/dist/Model/filter/types/path/common.d.ts.map +0 -1
  238. package/dist/Model/filter/types/path/common.js +0 -2
  239. package/dist/Model/filter/types/path/eager.d.ts +0 -95
  240. package/dist/Model/filter/types/path/eager.d.ts.map +0 -1
  241. package/dist/Model/filter/types/path/eager.js +0 -31
  242. package/dist/Model/filter/types/path/index.d.ts +0 -4
  243. package/dist/Model/filter/types/path/index.d.ts.map +0 -1
  244. package/dist/Model/filter/types/path/index.js +0 -3
  245. package/dist/Model/filter/types/utils.d.ts +0 -79
  246. package/dist/Model/filter/types/utils.d.ts.map +0 -1
  247. package/dist/Model/filter/types/utils.js +0 -2
  248. package/dist/Model/filter/types/validator.d.ts +0 -30
  249. package/dist/Model/filter/types/validator.d.ts.map +0 -1
  250. package/dist/Model/filter/types/validator.js +0 -2
  251. package/dist/Model/filter/types.d.ts +0 -5
  252. package/dist/Model/filter/types.d.ts.map +0 -1
  253. package/dist/Model/filter/types.js +0 -7
  254. package/dist/Model/query/dsl.d.ts +0 -446
  255. package/dist/Model/query/dsl.d.ts.map +0 -1
  256. package/dist/Model/query/dsl.js +0 -339
  257. package/dist/Model/query/new-kid-interpreter.d.ts +0 -136
  258. package/dist/Model/query/new-kid-interpreter.d.ts.map +0 -1
  259. package/dist/Model/query/new-kid-interpreter.js +0 -336
  260. package/dist/Model/query.d.ts +0 -15
  261. package/dist/Model/query.d.ts.map +0 -1
  262. package/dist/Model/query.js +0 -3
  263. package/dist/Model.d.ts +0 -5
  264. package/dist/Model.d.ts.map +0 -1
  265. package/dist/Model.js +0 -5
  266. package/dist/QueueMaker/service.d.ts +0 -13
  267. package/dist/QueueMaker/service.d.ts.map +0 -1
  268. package/dist/QueueMaker/service.js +0 -4
  269. package/dist/RequestContext.d.ts +0 -103
  270. package/dist/RequestContext.d.ts.map +0 -1
  271. package/dist/RequestContext.js +0 -49
  272. package/dist/Store/service.d.ts +0 -138
  273. package/dist/Store/service.d.ts.map +0 -1
  274. package/dist/Store/service.js +0 -95
  275. package/dist/Store.d.ts +0 -2
  276. package/dist/Store.d.ts.map +0 -1
  277. package/dist/Store.js +0 -2
  278. package/dist/adapters/SQL/Model.d.ts.map +0 -1
  279. package/dist/adapters/SQL/Model.js +0 -469
  280. package/dist/adapters/SQL.d.ts.map +0 -1
  281. package/dist/adapters/ServiceBus.d.ts.map +0 -1
  282. package/dist/adapters/ServiceBus.js +0 -108
  283. package/dist/adapters/cosmos-client.d.ts.map +0 -1
  284. package/dist/adapters/cosmos-client.js +0 -11
  285. package/dist/adapters/index.d.ts +0 -8
  286. package/dist/adapters/index.d.ts.map +0 -1
  287. package/dist/adapters/index.js +0 -8
  288. package/dist/adapters/logger.d.ts +0 -9
  289. package/dist/adapters/logger.d.ts.map +0 -1
  290. package/dist/adapters/logger.js +0 -3
  291. package/dist/adapters/memQueue.d.ts.map +0 -1
  292. package/dist/adapters/memQueue.js +0 -21
  293. package/dist/adapters/mongo-client.d.ts.map +0 -1
  294. package/dist/adapters/mongo-client.js +0 -15
  295. package/dist/adapters/redis-client.d.ts.map +0 -1
  296. package/dist/adapters/redis-client.js +0 -98
  297. package/dist/api/ContextProvider.d.ts +0 -34
  298. package/dist/api/ContextProvider.d.ts.map +0 -1
  299. package/dist/api/ContextProvider.js +0 -40
  300. package/dist/api/codec.d.ts.map +0 -1
  301. package/dist/api/codec.js +0 -5
  302. package/dist/api/internal/RequestContextMiddleware.d.ts.map +0 -1
  303. package/dist/api/internal/RequestContextMiddleware.js +0 -46
  304. package/dist/api/internal/auth.d.ts.map +0 -1
  305. package/dist/api/internal/auth.js +0 -180
  306. package/dist/api/internal/events.d.ts.map +0 -1
  307. package/dist/api/internal/events.js +0 -49
  308. package/dist/api/internal/health.d.ts.map +0 -1
  309. package/dist/api/internal/health.js +0 -5
  310. package/dist/api/layerUtils.d.ts +0 -32
  311. package/dist/api/layerUtils.d.ts.map +0 -1
  312. package/dist/api/layerUtils.js +0 -17
  313. package/dist/api/middlewares.d.ts.map +0 -1
  314. package/dist/api/reportError.d.ts +0 -4
  315. package/dist/api/reportError.d.ts.map +0 -1
  316. package/dist/api/reportError.js +0 -28
  317. package/dist/api/routing/middleware/RouterMiddleware.d.ts.map +0 -1
  318. package/dist/api/routing/middleware/middleware.d.ts.map +0 -1
  319. package/dist/api/routing/middleware/middleware.js +0 -128
  320. package/dist/api/routing/middleware.d.ts.map +0 -1
  321. package/dist/api/routing/schema/jwt.d.ts.map +0 -1
  322. package/dist/api/routing/schema/jwt.js +0 -13
  323. package/dist/api/routing/tsort.d.ts +0 -8
  324. package/dist/api/routing/tsort.d.ts.map +0 -1
  325. package/dist/api/routing/tsort.js +0 -51
  326. package/dist/api/routing/utils.d.ts.map +0 -1
  327. package/dist/api/routing/utils.js +0 -45
  328. package/dist/api/routing.d.ts +0 -184
  329. package/dist/api/routing.d.ts.map +0 -1
  330. package/dist/api/setupRequest.d.ts.map +0 -1
  331. package/dist/api/setupRequest.js +0 -70
  332. package/dist/api/util.d.ts.map +0 -1
  333. package/dist/api/util.js +0 -14
  334. package/src/Emailer/service.ts +0 -62
  335. package/src/Emailer.ts +0 -1
  336. package/src/Model/Repository/Registry.ts +0 -34
  337. package/src/Model/Repository/ext.ts +0 -375
  338. package/src/Model/Repository/internal/internal.ts +0 -692
  339. package/src/Model/Repository/legacy.ts +0 -29
  340. package/src/Model/Repository/makeRepo.ts +0 -144
  341. package/src/Model/Repository/service.ts +0 -639
  342. package/src/Model/Repository/validation.ts +0 -31
  343. package/src/Model/Repository.ts +0 -6
  344. package/src/Model/dsl.ts +0 -129
  345. package/src/Model/filter/filterApi.ts +0 -60
  346. package/src/Model/filter/types/errors.ts +0 -47
  347. package/src/Model/filter/types/fields.ts +0 -50
  348. package/src/Model/filter/types/path/common.ts +0 -404
  349. package/src/Model/filter/types/path/eager.ts +0 -297
  350. package/src/Model/filter/types/path/index.ts +0 -4
  351. package/src/Model/filter/types/utils.ts +0 -128
  352. package/src/Model/filter/types/validator.ts +0 -46
  353. package/src/Model/filter/types.ts +0 -6
  354. package/src/Model/query/dsl.ts +0 -2546
  355. package/src/Model/query/new-kid-interpreter.ts +0 -484
  356. package/src/Model/query.ts +0 -13
  357. package/src/Model.ts +0 -4
  358. package/src/QueueMaker/service.ts +0 -19
  359. package/src/RequestContext.ts +0 -62
  360. package/src/Store/service.ts +0 -233
  361. package/src/Store.ts +0 -1
  362. package/src/adapters/index.ts +0 -7
  363. package/src/adapters/logger.ts +0 -3
  364. /package/src/{api/ContextProvider.ts → ContextProvider.ts} +0 -0
  365. /package/src/{adapters/SQL.ts → SQL.ts} +0 -0
  366. /package/src/{api/codec.ts → codec.ts} +0 -0
  367. /package/src/{adapters/cosmos-client.ts → cosmos-client.ts} +0 -0
  368. /package/src/{api/internal → internal}/auth.ts +0 -0
  369. /package/src/{api/internal → internal}/health.ts +0 -0
  370. /package/src/{adapters/memQueue.ts → memQueue.ts} +0 -0
  371. /package/src/{api/middlewares.ts → middlewares.ts} +0 -0
  372. /package/src/{adapters/mongo-client.ts → mongo-client.ts} +0 -0
  373. /package/src/{api/routing → routing}/middleware/RouterMiddleware.ts +0 -0
  374. /package/src/{api/routing → routing}/middleware.ts +0 -0
  375. /package/src/{api/routing → routing}/schema/jwt.ts +0 -0
  376. /package/src/{api/routing → routing}/tsort.ts +0 -0
  377. /package/src/{api/routing → routing}/utils.ts +0 -0
  378. /package/src/{api/util.ts → util.ts} +0 -0
@@ -1,692 +0,0 @@
1
- /* eslint-disable @typescript-eslint/no-explicit-any */
2
-
3
- import * as Array from "effect-app/Array"
4
- import type { NonEmptyReadonlyArray } from "effect-app/Array"
5
- import { toNonEmptyArray } from "effect-app/Array"
6
- import * as Chunk from "effect-app/Chunk"
7
- import { NotFoundError } from "effect-app/client/errors"
8
- import * as Context from "effect-app/Context"
9
- import * as Effect from "effect-app/Effect"
10
- import { flatMapOption } from "effect-app/Effect"
11
- import * as Option from "effect-app/Option"
12
- import * as S from "effect-app/Schema"
13
- import { type Codec, NonNegativeInt } from "effect-app/Schema"
14
- import * as Equivalence from "effect/Equivalence"
15
- import { flow, pipe } from "effect/Function"
16
- import * as Pipeable from "effect/Pipeable"
17
- import * as PubSub from "effect/PubSub"
18
- import * as Result from "effect/Result"
19
- import * as SchemaAST from "effect/SchemaAST"
20
- import * as Unify from "effect/Unify"
21
- import { setupRequestContextFromCurrent } from "../../../api/setupRequest.js"
22
- import { type FilterArgs, type PersistenceModelType, type StoreConfig, StoreMaker } from "../../../Store.js"
23
- import { getContextMap } from "../../../Store/ContextMapContainer.js"
24
- import type { FieldValues } from "../../filter/types.js"
25
- import * as Q from "../../query.js"
26
- import type { Repository } from "../service.js"
27
- import { ValidationError, ValidationResult } from "../validation.js"
28
-
29
- const dedupe = Array.dedupeWith(Equivalence.String)
30
-
31
- /**
32
- * A base implementation to create a repository.
33
- */
34
- export function makeRepoInternal<
35
- Evt = never
36
- >() {
37
- return <
38
- ItemType extends string,
39
- R,
40
- Encoded extends FieldValues,
41
- T,
42
- IdKey extends keyof T & keyof Encoded
43
- >(
44
- name: ItemType,
45
- schema: S.Codec<T, Encoded, R>,
46
- mapFrom: (pm: Encoded) => Encoded,
47
- mapTo: (e: Encoded, etag: string | undefined) => PersistenceModelType<Encoded>,
48
- idKey: IdKey
49
- ) => {
50
- type PM = PersistenceModelType<Encoded>
51
- function mapToPersistenceModel(
52
- e: Encoded,
53
- getEtag: (id: string) => string | undefined
54
- ): PM {
55
- return mapTo(e, getEtag(e[idKey]))
56
- }
57
-
58
- function mapReverse(
59
- { _etag, ...e }: PM,
60
- setEtag: (id: string, eTag: string | undefined) => void
61
- ): Encoded {
62
- setEtag((e as any)[idKey], _etag)
63
- return mapFrom(e as unknown as Encoded)
64
- }
65
-
66
- const mkStore = makeStore<Encoded>()(name, schema, mapTo, idKey)
67
-
68
- function make<RInitial = never, E = never, RPublish = never, RCtx = never>(
69
- args: [Evt] extends [never] ? {
70
- schemaContext?: Context.Context<RCtx>
71
- makeInitial?: Effect.Effect<readonly T[], E, RInitial> | undefined
72
- config?: Omit<StoreConfig<Encoded>, "partitionValue"> & {
73
- partitionValue?: (e?: Encoded) => string
74
- }
75
- }
76
- : {
77
- schemaContext?: Context.Context<RCtx>
78
- publishEvents: (evt: NonEmptyReadonlyArray<Evt>) => Effect.Effect<void, never, RPublish>
79
- makeInitial?: Effect.Effect<readonly T[], E, RInitial> | undefined
80
- config?: Omit<StoreConfig<Encoded>, "partitionValue"> & {
81
- partitionValue?: (e?: Encoded) => string
82
- }
83
- }
84
- ) {
85
- return Effect
86
- .gen(function*() {
87
- const rctx: Context.Context<RCtx> = args.schemaContext ?? Context.empty() as any
88
- const provideRctx = Effect.provide(rctx)
89
- const encodeMany = flow(
90
- S.encodeEffect(S.Array(schema)),
91
- provideRctx,
92
- Effect.withSpan("encodeMany", { attributes: { "app.entity": name } }, { captureStackTrace: false })
93
- )
94
- const decode = flow(S.decodeEffectConcurrently(schema), provideRctx)
95
- const decodeMany = flow(
96
- S.decodeEffectConcurrently(S.Array(schema)),
97
- provideRctx
98
- )
99
-
100
- const store = yield* mkStore(args.makeInitial, args.config)
101
- const cms = Effect.map(getContextMap.pipe(Effect.orDie), (_) => ({
102
- get: (id: string) => _.get(`${name}.${id}`),
103
- set: (id: string, etag: string | undefined) => _.set(`${name}.${id}`, etag)
104
- }))
105
-
106
- const pub = "publishEvents" in args
107
- ? args.publishEvents
108
- : () => Effect.void
109
- const changeFeed = yield* PubSub.unbounded<[T[], "save" | "remove"]>()
110
-
111
- const allE = cms
112
- .pipe(Effect.flatMap((cm) => Effect.map(store.all, (_) => _.map((_) => mapReverse(_, cm.set)))))
113
-
114
- const all = Effect
115
- .flatMap(
116
- allE,
117
- (_) => decodeMany(_).pipe(Effect.orDie)
118
- )
119
- .pipe(
120
- Effect.map((_) => _ as T[]),
121
- Effect.withSpan("Repository.all", {
122
- kind: "client",
123
- attributes: { "app.entity": name }
124
- }, { captureStackTrace: false })
125
- )
126
-
127
- const fieldsSchema = schema as unknown as { fields: any }
128
- // assumes the id field never needs a service...
129
- const i = ("fields" in fieldsSchema ? S.Struct(fieldsSchema["fields"]) as unknown as typeof schema : schema)
130
- .pipe((_) => {
131
- let ast = _.ast
132
- if (ast._tag === "Declaration") ast = ast.typeParameters[0]!
133
-
134
- const pickIdFromAst = (a: SchemaAST.AST) => {
135
- // Unwrap Declaration (e.g. TaggedClass) to get the underlying Objects AST
136
- let inner = a
137
- if (inner._tag === "Declaration") inner = inner.typeParameters[0]!
138
- // Pick from the original AST to preserve the full encoding chain (e.g. decodeTo transformations).
139
- // Using toEncoded would lose transformation info needed to encode Type -> Encoded.
140
- if (SchemaAST.isObjects(inner)) {
141
- const field = inner.propertySignatures.find((_) => _.name === idKey)
142
- if (field) {
143
- return S.Struct({ [idKey]: S.make(field.type) }) as unknown as Codec<T, Encoded>
144
- }
145
- }
146
- return S.make(a) as unknown as Codec<T, Encoded>
147
- }
148
-
149
- return ast._tag === "Union"
150
- // we need to get the Objects (TypeLiteral), in case of class it has encoding chain...
151
- ? S.Union(
152
- ast.types.map((_) => pickIdFromAst(_))
153
- )
154
- : pickIdFromAst(ast)
155
- })
156
- const encodeId = flow(S.encodeEffect(i), provideRctx)
157
- const encodeIdOnly = (id: string) =>
158
- encodeId({ [idKey]: id } as any).pipe(
159
- Effect.map((_: Record<string, unknown>) => _[idKey as string] as Encoded[IdKey])
160
- )
161
- const findEId = Effect.fnUntraced(function*(id: Encoded[IdKey]) {
162
- yield* Effect.annotateCurrentSpan({ "app.entity.id": id })
163
-
164
- return yield* Effect.flatMap(
165
- store.find(id),
166
- (item) =>
167
- Effect.gen(function*() {
168
- const { set } = yield* cms
169
- return item.pipe(Option.map((_) => mapReverse(_, set)))
170
- })
171
- )
172
- })
173
- // TODO: select the particular field, instead of as struct
174
- const findE = Effect.fnUntraced(function*(id: T[IdKey]) {
175
- yield* Effect.annotateCurrentSpan({ "app.entity.id": id })
176
-
177
- return yield* pipe(
178
- encodeId({ [idKey]: id } as any),
179
- Effect.orDie,
180
- Effect.map((_) => (_ as any)[idKey]),
181
- Effect.flatMap(findEId)
182
- )
183
- })
184
-
185
- const find = Effect.fn("Repository.find", {
186
- kind: "client",
187
- attributes: { "app.entity": name }
188
- })(function*(id: T[IdKey]) {
189
- yield* Effect.annotateCurrentSpan({ "app.entity.id": id })
190
- return yield* flatMapOption(findE(id), (_) => Effect.orDie(decode(_)))
191
- })
192
-
193
- const saveAllE = (a: Iterable<Encoded>) =>
194
- flatMapOption(
195
- Effect
196
- .sync(() => toNonEmptyArray([...a])),
197
- (a) =>
198
- Effect.gen(function*() {
199
- const { get, set } = yield* cms
200
- const items = a.map((_) => mapToPersistenceModel(_, get))
201
- const ret = yield* store.batchSet(items)
202
- ret.forEach((_) => set(_[idKey], _._etag))
203
- })
204
- )
205
- .pipe(Effect.asVoid)
206
-
207
- const saveAll = (a: Iterable<T>) =>
208
- encodeMany(Array.fromIterable(a))
209
- .pipe(
210
- Effect.orDie,
211
- Effect.andThen(saveAllE)
212
- )
213
-
214
- const saveAndPublish = Effect.fn("Repository.saveAndPublish", { attributes: { "app.entity": name } })(
215
- function*(items: Iterable<T>, events: Iterable<Evt> = []) {
216
- const it = Chunk.fromIterable(items)
217
- const evts = [...events]
218
- yield* Effect.annotateCurrentSpan({
219
- "app.entity.ids": Chunk.map(it, (_) => _[idKey]),
220
- "app.event.count": evts.length
221
- })
222
- return yield* saveAll(it)
223
- .pipe(
224
- Effect.andThen(Effect.sync(() => toNonEmptyArray(evts))),
225
- // TODO: for full consistency the events should be stored within the same database transaction, and then picked up.
226
- (_) => flatMapOption(_, pub),
227
- Effect.andThen(PubSub.publish(changeFeed, [Chunk.toArray(it), "save"] as [T[], "save" | "remove"])),
228
- Effect.asVoid
229
- )
230
- }
231
- )
232
-
233
- const removeAndPublish = Effect.fn("Repository.removeAndPublish", { attributes: { "app.entity": name } })(
234
- function*(a: Iterable<T>, events: Iterable<Evt> = []) {
235
- const { set } = yield* cms
236
- const it = [...a]
237
- const evts = [...events]
238
- yield* Effect.annotateCurrentSpan({
239
- "app.entity.ids": it.map((_) => _[idKey]),
240
- "app.event.count": evts.length
241
- })
242
- const items = yield* encodeMany(it).pipe(Effect.orDie)
243
- if (Array.isReadonlyArrayNonEmpty(items)) {
244
- yield* store.batchRemove(
245
- items.map((_) => (_[idKey])),
246
- args.config?.partitionValue?.(items[0])
247
- )
248
- for (const e of items) {
249
- set(e[idKey], undefined)
250
- }
251
- yield* Effect
252
- .sync(() => toNonEmptyArray(evts))
253
- // TODO: for full consistency the events should be stored within the same database transaction, and then picked up.
254
- .pipe((_) => flatMapOption(_, pub))
255
-
256
- yield* PubSub.publish(changeFeed, [it, "remove"] as [T[], "save" | "remove"])
257
- }
258
- }
259
- )
260
-
261
- const removeById = Effect.fn("Repository.removeById", { attributes: { "app.entity": name } })(
262
- function*(idOrIds: T[IdKey] | ReadonlyArray<T[IdKey]>) {
263
- const ids = globalThis.Array.isArray(idOrIds)
264
- ? idOrIds as readonly T[IdKey][]
265
- : [idOrIds as T[IdKey]]
266
- if (!Array.isReadonlyArrayNonEmpty(ids)) {
267
- return
268
- }
269
- const { set } = yield* cms
270
- const eids = yield* Effect.forEach(ids, (_) => encodeIdOnly(_ as any)).pipe(Effect.orDie)
271
- yield* Effect.annotateCurrentSpan({ "app.entity.ids": eids })
272
- yield* store.batchRemove(eids)
273
- for (const id of eids) {
274
- set(id, undefined)
275
- }
276
- yield* PubSub.publish(changeFeed, [[], "remove"] as [T[], "save" | "remove"])
277
- }
278
- )
279
-
280
- const parseMany = Effect.fn("parseMany", {
281
- attributes: { "app.entity": name, "app.query.mode": "transform" }
282
- })(
283
- function*(items: readonly PM[]) {
284
- const cm = yield* cms
285
- return yield* decodeMany(items.map((_) => mapReverse(_, cm.set))).pipe(Effect.orDie)
286
- }
287
- )
288
- const decodeManyCache = new WeakMap<
289
- S.Codec<any, any, any>,
290
- (i: readonly any[]) => Effect.Effect<any, any, any>
291
- >()
292
- const getDecodeMany = (s: S.Codec<any, Encoded, any>) => {
293
- let dec = decodeManyCache.get(s)
294
- if (!dec) {
295
- dec = S.decodeEffectConcurrently(S.Array(s))
296
- decodeManyCache.set(s, dec)
297
- }
298
- return dec
299
- }
300
- const parseMany2 = Effect.fn("parseMany", {
301
- attributes: { "app.entity": name, "app.query.mode": "transform" }
302
- })(
303
- function*<A, R>(items: readonly PM[], schema: S.Codec<A, Encoded, R>) {
304
- const cm = yield* cms
305
- return yield* getDecodeMany(schema)(items.map((_) => mapReverse(_, cm.set))).pipe(Effect.orDie)
306
- }
307
- )
308
- const filter = <U extends keyof Encoded = keyof Encoded>(args: FilterArgs<Encoded, U>) =>
309
- store
310
- .filter(
311
- // always enforce id and _etag because they are system fields, required for etag tracking etc
312
- {
313
- ...args,
314
- select: args.select
315
- ? dedupe([...args.select, idKey, "_etag" as any])
316
- : undefined
317
- } as typeof args
318
- )
319
- .pipe(
320
- Effect.tap((items) =>
321
- Effect.map(cms, ({ set }) => items.forEach((_) => set((_ as Encoded)[idKey], (_ as PM)._etag)))
322
- )
323
- )
324
-
325
- // TODO: For raw we should use S.from, and drop the R...
326
- const query: {
327
- <A, R, From extends FieldValues>(
328
- q: Q.QueryProjection<Encoded extends From ? From : never, A, R>
329
- ): Effect.Effect<readonly A[], S.SchemaError, Exclude<R, RCtx>>
330
- <A, R, EncodedRefined extends Encoded = Encoded>(
331
- q: Q.QAll<NoInfer<Encoded>, NoInfer<EncodedRefined>, A, R>
332
- ): Effect.Effect<readonly A[], never, Exclude<R, RCtx>>
333
- } = (<A, R, EncodedRefined extends Encoded = Encoded>(q: Q.QAll<Encoded, EncodedRefined, A, R>) => {
334
- const a = Q.toFilter(q, schema)
335
- // Mode dispatch — see `Q.project` JSDoc for the contract:
336
- // aggregate: GROUP BY + aggregate functions at DB level; decode raw rows with schema; SchemaError surfaces.
337
- // project : decode raw encoded rows with schema; no PM reverse-mapping; SchemaError surfaces.
338
- // collect : same as project, but schema yields Option and None rows are dropped.
339
- // transform: PM reverse-map (re-inject _etag/PM state from cms cache) then decode; orDie.
340
- const eff = a.mode === "aggregate"
341
- ? store
342
- // `a.select` contains `{ key, aggregate }` items not expressible in FilterFunc<Encoded, U>'s
343
- // `U extends keyof Encoded` generic. Cast is unavoidable until FilterFunc supports aggregate mode.
344
- .filter(a as any)
345
- // Decode raw aggregate rows directly — no PM reverse-mapping, no id/_etag needed.
346
- .pipe(
347
- Effect.andThen(
348
- flow(
349
- S.decodeEffectConcurrently(S.Array(a.schema ?? schema)),
350
- provideRctx,
351
- Effect.withSpan("parseMany", {
352
- attributes: { "app.entity": name, "app.query.mode": "aggregate" }
353
- })
354
- )
355
- )
356
- )
357
- : a.mode === "project"
358
- ? filter(a)
359
- // TODO: mapFrom but need to support per field and dependencies
360
- .pipe(
361
- Effect.andThen(
362
- flow(
363
- S.decodeEffectConcurrently(S.Array(a.schema ?? schema)),
364
- provideRctx,
365
- Effect.withSpan("parseMany", {
366
- attributes: { "app.entity": name, "app.query.mode": "project" }
367
- })
368
- )
369
- )
370
- )
371
- : a.mode === "collect"
372
- ? filter(a)
373
- // TODO: mapFrom but need to support per field and dependencies
374
- .pipe(
375
- Effect.flatMap(flow(
376
- S.decodeEffectConcurrently(S.Array(a.schema)),
377
- Effect.map(Array.getSomes),
378
- provideRctx,
379
- Effect.withSpan("parseMany", {
380
- attributes: { "app.entity": name, "app.query.mode": "collect" }
381
- })
382
- ))
383
- )
384
- : Effect.flatMap(
385
- filter(a),
386
- (_) =>
387
- Unify.unify(
388
- a.schema
389
- // TODO: partial may not match?
390
- ? parseMany2(_ as any, a.schema as any)
391
- : parseMany(_ as any)
392
- )
393
- )
394
- return pipe(
395
- a.ttype === "one"
396
- ? Effect.flatMap(
397
- eff,
398
- flow(
399
- Array.head,
400
- Option.match({
401
- onNone: () => Effect.fail(new NotFoundError({ id: "query", /* TODO */ type: name })),
402
- onSome: Effect.succeed
403
- })
404
- )
405
- )
406
- : a.ttype === "count"
407
- ? Effect
408
- .map(eff, (_) => NonNegativeInt(_.length))
409
- .pipe(Effect.catchTag("SchemaError", (e) => Effect.die(e)))
410
- : eff,
411
- Effect.tap((r) =>
412
- Effect.annotateCurrentSpan({
413
- "app.query.ttype": a.ttype,
414
- "app.query.mode": a.mode,
415
- "db.response.returned_rows": Array.isArray(r) ? r.length : 1
416
- })
417
- ),
418
- Effect.withSpan("Repository.query", {
419
- kind: "client",
420
- attributes: { "app.entity": name }
421
- }, { captureStackTrace: false })
422
- )
423
- }) as any
424
-
425
- const validateSample = Effect.fn("Repository.validateSample", { attributes: { "app.entity": name } })(
426
- function*(options?: {
427
- percentage?: number
428
- maxItems?: number
429
- }) {
430
- const percentage = options?.percentage ?? 0.1 // default 10%
431
- const maxItems = options?.maxItems
432
-
433
- // 1. get all IDs with projection (bypasses main schema decode)
434
- const allIds = yield* store
435
- .filter({
436
- t: null as unknown as Encoded,
437
- select: [idKey as keyof Encoded]
438
- })
439
- .pipe(Effect.withSpan("Repository.filter", {
440
- kind: "client",
441
- attributes: { "app.entity": name }
442
- }, { captureStackTrace: false }))
443
-
444
- // 2. random subset
445
- const shuffled = [...allIds].sort(() => Math.random() - 0.5)
446
- const sampleSize = Math.min(
447
- maxItems ?? Infinity,
448
- Math.ceil(allIds.length * percentage)
449
- )
450
- const sample = shuffled.slice(0, sampleSize)
451
-
452
- // 3. validate each item
453
- const errors: ValidationError[] = []
454
-
455
- for (const item of sample) {
456
- const id = item[idKey]
457
- const rawResult = yield* store.find(id).pipe(
458
- Effect.withSpan("Repository.find", {
459
- kind: "client",
460
- attributes: { "app.entity": name, "app.entity.id": id }
461
- }, { captureStackTrace: false })
462
- )
463
-
464
- if (Option.isNone(rawResult)) continue
465
-
466
- const rawData = rawResult.value as Encoded
467
- const jitMResult = mapFrom(rawData) // apply jitM
468
-
469
- const decodeResult = yield* S.decodeEffectConcurrently(schema)(jitMResult).pipe(
470
- Effect.result,
471
- provideRctx
472
- )
473
-
474
- if (Result.isFailure(decodeResult)) {
475
- errors.push(
476
- ValidationError.make({
477
- id,
478
- rawData,
479
- jitMResult,
480
- error: decodeResult.failure
481
- })
482
- )
483
- }
484
- }
485
-
486
- return ValidationResult.make({
487
- total: NonNegativeInt(allIds.length),
488
- sampled: NonNegativeInt(sample.length),
489
- valid: NonNegativeInt(sample.length - errors.length),
490
- errors
491
- })
492
- }
493
- )
494
-
495
- const r = {
496
- changeFeed,
497
- itemType: name,
498
- idKey,
499
- find,
500
- all,
501
- saveAndPublish,
502
- removeAndPublish,
503
- removeById,
504
- seedNamespace: (namespace: string) => store.seedNamespace(namespace),
505
- validateSample,
506
- queryRaw<A, Out, QR>(schema: S.Codec<A, Out, QR>, q: Q.RawQuery<Encoded, Out>) {
507
- const dec = S.decodeEffectConcurrently(S.Array(schema))
508
- return store.queryRaw(q).pipe(
509
- Effect.flatMap(dec),
510
- Effect.withSpan("Repository.queryRaw", {
511
- kind: "client",
512
- attributes: { "app.entity": name }
513
- }, { captureStackTrace: false })
514
- )
515
- },
516
- query(q: any) {
517
- // eslint-disable-next-line prefer-rest-params
518
- return query(typeof q === "function" ? Pipeable.pipeArguments(Q.make(), arguments) : q) as any
519
- },
520
- /**
521
- * @internal
522
- */
523
- mapped: <A, R>(schema: S.Codec<A, any, R>) => {
524
- const dec = S.decodeEffectConcurrently(schema)
525
- const encMany = S.encodeEffect(S.Array(schema))
526
- const decMany = S.decodeEffectConcurrently(S.Array(schema))
527
- const spanAttrs = { kind: "client" as const, attributes: { "app.entity": name } }
528
- return {
529
- all: allE.pipe(
530
- Effect.flatMap(decMany),
531
- Effect.map((_) => _ as any[]),
532
- Effect.withSpan("Repository.mapped.all", spanAttrs, { captureStackTrace: false })
533
- ),
534
- find: (id: T[IdKey]) =>
535
- flatMapOption(findE(id), dec).pipe(
536
- Effect.withSpan("Repository.mapped.find", {
537
- ...spanAttrs,
538
- attributes: { ...spanAttrs.attributes, "app.entity.id": id }
539
- }, { captureStackTrace: false })
540
- ),
541
- // query: (q: any) => {
542
- // const a = Q.toFilter(q)
543
-
544
- // return filter(a)
545
- // .pipe(
546
- // Effect.flatMap(decMany),
547
- // Effect.map((_) => _ as any[]),
548
- // Effect.withSpan("Repository.mapped.query [effect-app/infra]", {
549
- // captureStackTrace: false,
550
- // attributes: {
551
- // "repository.model_name": name,
552
- // query: { ...a, schema: a.schema ? "__SCHEMA__" : a.schema, filter: a.filter.build() }
553
- // }
554
- // })
555
- // )
556
- // },
557
- save: (...xes: any[]) =>
558
- Effect.flatMap(encMany(xes), (_) => saveAllE(_)).pipe(
559
- Effect.withSpan("Repository.mapped.save", spanAttrs, { captureStackTrace: false })
560
- )
561
- }
562
- }
563
- }
564
- return r as Repository<T, Encoded, Evt, ItemType, IdKey, Exclude<R, RCtx>, RPublish, RCtx>
565
- })
566
- .pipe(Effect
567
- // .withSpan("Repository.make [effect-app/infra]", { attributes: { "repository.model_name": name } })
568
- .withLogSpan("Repository.make: " + name))
569
- }
570
-
571
- return {
572
- make,
573
- Q: Q.make<Encoded>()
574
- }
575
- }
576
- }
577
-
578
- const pluralize = (s: string) =>
579
- s.endsWith("s")
580
- ? s + "es"
581
- : s.endsWith("y")
582
- ? s.substring(0, s.length - 1) + "ies"
583
- : s + "s"
584
-
585
- export function makeStore<Encoded extends FieldValues>() {
586
- return <
587
- ItemType extends string,
588
- R,
589
- E,
590
- T,
591
- IdKey extends keyof Encoded
592
- >(
593
- name: ItemType,
594
- schema: S.Codec<T, E, R>,
595
- mapTo: (e: E, etag: string | undefined) => Encoded,
596
- idKey: IdKey
597
- ) => {
598
- function makeStore<RInitial = never, EInitial = never>(
599
- makeInitial?: Effect.Effect<readonly T[], EInitial, RInitial>,
600
- config?: Omit<StoreConfig<Encoded>, "partitionValue"> & {
601
- partitionValue?: (e?: Encoded) => string
602
- }
603
- ) {
604
- function encodeToEncoded() {
605
- const getEtag = () => undefined
606
- return (t: T) =>
607
- S.encodeEffect(schema)(t).pipe(
608
- Effect.orDie,
609
- Effect.map((_) => mapToPersistenceModel(_, getEtag))
610
- )
611
- }
612
-
613
- function mapToPersistenceModel(
614
- e: E,
615
- getEtag: (id: string) => string | undefined
616
- ): Encoded {
617
- return mapTo(e, getEtag((e as any)[idKey] as string))
618
- }
619
-
620
- return Effect.gen(function*() {
621
- const { make } = yield* StoreMaker
622
-
623
- const store = yield* make<IdKey, Encoded, RInitial | R, EInitial>(
624
- pluralize(name),
625
- idKey,
626
- makeInitial
627
- ? makeInitial
628
- .pipe(
629
- Effect.flatMap(Effect.forEach(encodeToEncoded())),
630
- setupRequestContextFromCurrent("Repository.makeInitial [effect-app/infra]", {
631
- attributes: { "app.entity": name }
632
- })
633
- )
634
- : undefined,
635
- {
636
- ...config,
637
- partitionValue: config?.partitionValue
638
- ?? ((_) => "primary") /*(isIntegrationEvent(r) ? r.companyId : r.id*/
639
- }
640
- )
641
-
642
- return store
643
- })
644
- }
645
-
646
- return makeStore
647
- }
648
- }
649
-
650
- export interface Repos<
651
- T,
652
- Encoded extends { id: string },
653
- RSchema,
654
- Evt,
655
- ItemType extends string,
656
- IdKey extends keyof T,
657
- RPublish
658
- > {
659
- make<RInitial = never, E = never, R2 = never>(
660
- args: [Evt] extends [never] ? {
661
- makeInitial?: Effect.Effect<readonly T[], E, RInitial> | undefined
662
- config?: Omit<StoreConfig<Encoded>, "partitionValue"> & {
663
- partitionValue?: (e?: Encoded) => string
664
- }
665
- }
666
- : {
667
- publishEvents: (evt: NonEmptyReadonlyArray<Evt>) => Effect.Effect<void, never, R2>
668
- makeInitial?: Effect.Effect<readonly T[], E, RInitial> | undefined
669
- config?: Omit<StoreConfig<Encoded>, "partitionValue"> & {
670
- partitionValue?: (e?: Encoded) => string
671
- }
672
- }
673
- ): Effect.Effect<Repository<T, Encoded, Evt, ItemType, IdKey, RSchema, RPublish>, E, StoreMaker | RInitial | R2>
674
- makeWith<Out, RInitial = never, E = never, R2 = never>(
675
- args: [Evt] extends [never] ? {
676
- makeInitial?: Effect.Effect<readonly T[], E, RInitial> | undefined
677
- config?: Omit<StoreConfig<Encoded>, "partitionValue"> & {
678
- partitionValue?: (e?: Encoded) => string
679
- }
680
- }
681
- : {
682
- publishEvents: (evt: NonEmptyReadonlyArray<Evt>) => Effect.Effect<void, never, R2>
683
- makeInitial?: Effect.Effect<readonly T[], E, RInitial> | undefined
684
- config?: Omit<StoreConfig<Encoded>, "partitionValue"> & {
685
- partitionValue?: (e?: Encoded) => string
686
- }
687
- },
688
- f: (r: Repository<T, Encoded, Evt, ItemType, IdKey, RSchema, RPublish>) => Out
689
- ): Effect.Effect<Out, E, StoreMaker | RInitial | R2>
690
- readonly Q: ReturnType<typeof Q.make<Encoded>>
691
- readonly type: Repository<T, Encoded, Evt, ItemType, IdKey, RSchema, RPublish>
692
- }