@effect-app/infra 4.0.0-beta.26 → 4.0.0-beta.261

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 (505) hide show
  1. package/CHANGELOG.md +1973 -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/ClusterCosmos.d.ts +64 -0
  7. package/dist/ClusterCosmos.d.ts.map +1 -0
  8. package/dist/ClusterCosmos.js +501 -0
  9. package/dist/ClusterServiceBus.d.ts +67 -0
  10. package/dist/ClusterServiceBus.d.ts.map +1 -0
  11. package/dist/ClusterServiceBus.js +82 -0
  12. package/dist/ContextProvider.d.ts +34 -0
  13. package/dist/ContextProvider.d.ts.map +1 -0
  14. package/dist/ContextProvider.js +40 -0
  15. package/dist/Emailer/Sendgrid.d.ts +111 -147
  16. package/dist/Emailer/Sendgrid.d.ts.map +1 -1
  17. package/dist/Emailer/Sendgrid.js +24 -19
  18. package/dist/Emailer/fake.d.ts +2 -2
  19. package/dist/Emailer/fake.d.ts.map +1 -1
  20. package/dist/Emailer/fake.js +4 -4
  21. package/dist/MainFiberSet.d.ts +12 -9
  22. package/dist/MainFiberSet.d.ts.map +1 -1
  23. package/dist/MainFiberSet.js +10 -6
  24. package/dist/QueueMaker/SQLQueue.d.ts +8 -9
  25. package/dist/QueueMaker/SQLQueue.d.ts.map +1 -1
  26. package/dist/QueueMaker/SQLQueue.js +138 -120
  27. package/dist/QueueMaker/errors.d.ts +5 -3
  28. package/dist/QueueMaker/errors.d.ts.map +1 -1
  29. package/dist/QueueMaker/errors.js +4 -2
  30. package/dist/QueueMaker/memQueue.d.ts +10 -6
  31. package/dist/QueueMaker/memQueue.d.ts.map +1 -1
  32. package/dist/QueueMaker/memQueue.js +84 -68
  33. package/dist/QueueMaker/sbqueue.d.ts +9 -5
  34. package/dist/QueueMaker/sbqueue.d.ts.map +1 -1
  35. package/dist/QueueMaker/sbqueue.js +60 -58
  36. package/dist/RequestFiberSet.d.ts +10 -7
  37. package/dist/RequestFiberSet.d.ts.map +1 -1
  38. package/dist/RequestFiberSet.js +13 -8
  39. package/dist/SQL/Model.d.ts +468 -0
  40. package/dist/SQL/Model.d.ts.map +1 -0
  41. package/dist/SQL/Model.js +469 -0
  42. package/dist/SQL.d.ts +2 -0
  43. package/dist/SQL.d.ts.map +1 -0
  44. package/dist/{adapters/SQL.js → SQL.js} +1 -1
  45. package/dist/ServiceBus.d.ts +61 -0
  46. package/dist/ServiceBus.d.ts.map +1 -0
  47. package/dist/ServiceBus.js +108 -0
  48. package/dist/Store/Cosmos/query.d.ts +15 -4
  49. package/dist/Store/Cosmos/query.d.ts.map +1 -1
  50. package/dist/Store/Cosmos/query.js +179 -41
  51. package/dist/Store/Cosmos.d.ts +3 -3
  52. package/dist/Store/Cosmos.d.ts.map +1 -1
  53. package/dist/Store/Cosmos.js +344 -246
  54. package/dist/Store/Disk.d.ts +5 -5
  55. package/dist/Store/Disk.d.ts.map +1 -1
  56. package/dist/Store/Disk.js +78 -38
  57. package/dist/Store/Memory.d.ts +7 -10
  58. package/dist/Store/Memory.d.ts.map +1 -1
  59. package/dist/Store/Memory.js +326 -66
  60. package/dist/Store/SQL/Pg.d.ts +4 -0
  61. package/dist/Store/SQL/Pg.d.ts.map +1 -0
  62. package/dist/Store/SQL/Pg.js +232 -0
  63. package/dist/Store/SQL/query.d.ts +49 -0
  64. package/dist/Store/SQL/query.d.ts.map +1 -0
  65. package/dist/Store/SQL/query.js +527 -0
  66. package/dist/Store/SQL.d.ts +21 -0
  67. package/dist/Store/SQL.d.ts.map +1 -0
  68. package/dist/Store/SQL.js +449 -0
  69. package/dist/Store/codeFilter.d.ts +5 -5
  70. package/dist/Store/codeFilter.d.ts.map +1 -1
  71. package/dist/Store/codeFilter.js +6 -3
  72. package/dist/Store/index.d.ts +7 -5
  73. package/dist/Store/index.d.ts.map +1 -1
  74. package/dist/Store/index.js +18 -5
  75. package/dist/Store/utils.d.ts +4 -3
  76. package/dist/Store/utils.d.ts.map +1 -1
  77. package/dist/Store/utils.js +5 -5
  78. package/dist/WorkflowEngineCosmos.d.ts +29 -0
  79. package/dist/WorkflowEngineCosmos.d.ts.map +1 -0
  80. package/dist/WorkflowEngineCosmos.js +521 -0
  81. package/dist/WorkflowEngineSqlite.d.ts +24 -0
  82. package/dist/WorkflowEngineSqlite.d.ts.map +1 -0
  83. package/dist/WorkflowEngineSqlite.js +550 -0
  84. package/dist/arbs.d.ts +2 -2
  85. package/dist/arbs.d.ts.map +1 -1
  86. package/dist/arbs.js +5 -3
  87. package/dist/codec.d.ts +5 -0
  88. package/dist/codec.d.ts.map +1 -0
  89. package/dist/codec.js +5 -0
  90. package/dist/cosmos-client.d.ts +16 -0
  91. package/dist/cosmos-client.d.ts.map +1 -0
  92. package/dist/cosmos-client.js +11 -0
  93. package/dist/errorReporter.d.ts +7 -5
  94. package/dist/errorReporter.d.ts.map +1 -1
  95. package/dist/errorReporter.js +23 -27
  96. package/dist/errors.d.ts +1 -1
  97. package/dist/fileUtil.d.ts +2 -2
  98. package/dist/fileUtil.d.ts.map +1 -1
  99. package/dist/fileUtil.js +2 -2
  100. package/dist/index.d.ts +3 -2
  101. package/dist/index.d.ts.map +1 -1
  102. package/dist/index.js +3 -2
  103. package/dist/internal/RequestContextMiddleware.d.ts +5 -0
  104. package/dist/internal/RequestContextMiddleware.d.ts.map +1 -0
  105. package/dist/internal/RequestContextMiddleware.js +45 -0
  106. package/dist/internal/auth.d.ts +53 -0
  107. package/dist/internal/auth.d.ts.map +1 -0
  108. package/dist/internal/auth.js +180 -0
  109. package/dist/internal/events.d.ts +11 -0
  110. package/dist/internal/events.d.ts.map +1 -0
  111. package/dist/internal/events.js +49 -0
  112. package/dist/internal/health.d.ts +3 -0
  113. package/dist/internal/health.d.ts.map +1 -0
  114. package/dist/internal/health.js +5 -0
  115. package/dist/layerUtils.d.ts +32 -0
  116. package/dist/layerUtils.d.ts.map +1 -0
  117. package/dist/layerUtils.js +17 -0
  118. package/dist/logger/jsonLogger.d.ts +2 -2
  119. package/dist/logger/jsonLogger.d.ts.map +1 -1
  120. package/dist/logger/jsonLogger.js +5 -3
  121. package/dist/logger/logFmtLogger.d.ts +2 -2
  122. package/dist/logger/logFmtLogger.d.ts.map +1 -1
  123. package/dist/logger/logFmtLogger.js +3 -3
  124. package/dist/logger/shared.d.ts +3 -3
  125. package/dist/logger/shared.d.ts.map +1 -1
  126. package/dist/logger/shared.js +5 -5
  127. package/dist/logger.d.ts +1 -1
  128. package/dist/logger.d.ts.map +1 -1
  129. package/dist/memQueue.d.ts +15 -0
  130. package/dist/memQueue.d.ts.map +1 -0
  131. package/dist/memQueue.js +21 -0
  132. package/dist/middlewares.d.ts +10 -0
  133. package/dist/middlewares.d.ts.map +1 -0
  134. package/dist/{api/middlewares.js → middlewares.js} +1 -1
  135. package/dist/mongo-client.d.ts +11 -0
  136. package/dist/mongo-client.d.ts.map +1 -0
  137. package/dist/mongo-client.js +15 -0
  138. package/dist/otel.d.ts +75 -0
  139. package/dist/otel.d.ts.map +1 -0
  140. package/dist/otel.js +65 -0
  141. package/dist/rateLimit.d.ts +12 -4
  142. package/dist/rateLimit.d.ts.map +1 -1
  143. package/dist/rateLimit.js +7 -12
  144. package/dist/redis-client.d.ts +42 -0
  145. package/dist/redis-client.d.ts.map +1 -0
  146. package/dist/redis-client.js +98 -0
  147. package/dist/reportError.d.ts +4 -0
  148. package/dist/reportError.d.ts.map +1 -0
  149. package/dist/reportError.js +28 -0
  150. package/dist/routing/middleware/RouterMiddleware.d.ts +16 -0
  151. package/dist/routing/middleware/RouterMiddleware.d.ts.map +1 -0
  152. package/dist/{api/routing → routing}/middleware/RouterMiddleware.js +1 -1
  153. package/dist/routing/middleware/middleware.d.ts +48 -0
  154. package/dist/routing/middleware/middleware.d.ts.map +1 -0
  155. package/dist/routing/middleware/middleware.js +128 -0
  156. package/dist/routing/middleware.d.ts +3 -0
  157. package/dist/routing/middleware.d.ts.map +1 -0
  158. package/dist/{api/routing → routing}/middleware.js +1 -2
  159. package/dist/routing/schema/jwt.d.ts +4 -0
  160. package/dist/routing/schema/jwt.d.ts.map +1 -0
  161. package/dist/routing/schema/jwt.js +13 -0
  162. package/dist/routing/tsort.d.ts +8 -0
  163. package/dist/routing/tsort.d.ts.map +1 -0
  164. package/dist/routing/tsort.js +51 -0
  165. package/dist/routing/utils.d.ts +19 -0
  166. package/dist/routing/utils.d.ts.map +1 -0
  167. package/dist/routing/utils.js +45 -0
  168. package/dist/routing.d.ts +184 -0
  169. package/dist/routing.d.ts.map +1 -0
  170. package/dist/routing.js +236 -0
  171. package/dist/test.d.ts +3 -3
  172. package/dist/test.d.ts.map +1 -1
  173. package/dist/test.js +2 -2
  174. package/dist/util.d.ts +3 -0
  175. package/dist/util.d.ts.map +1 -0
  176. package/dist/util.js +14 -0
  177. package/dist/vitest.d.ts +1 -1
  178. package/docs/cluster-storage.md +26 -0
  179. package/docs/workflow-engine.md +262 -0
  180. package/examples/query.ts +47 -39
  181. package/package.json +31 -345
  182. package/run.sh +1 -0
  183. package/src/CUPS.ts +52 -13
  184. package/src/ClusterCosmos.ts +984 -0
  185. package/src/ClusterServiceBus.ts +242 -0
  186. package/src/{api/ContextProvider.ts → ContextProvider.ts} +19 -16
  187. package/src/Emailer/Sendgrid.ts +82 -59
  188. package/src/Emailer/fake.ts +3 -3
  189. package/src/MainFiberSet.ts +12 -10
  190. package/src/QueueMaker/SQLQueue.ts +153 -156
  191. package/src/QueueMaker/errors.ts +3 -1
  192. package/src/QueueMaker/memQueue.ts +113 -107
  193. package/src/QueueMaker/sbqueue.ts +78 -90
  194. package/src/RequestFiberSet.ts +13 -8
  195. package/src/{adapters/SQL → SQL}/Model.ts +42 -41
  196. package/src/ServiceBus.ts +219 -0
  197. package/src/Store/Cosmos/query.ts +216 -52
  198. package/src/Store/Cosmos.ts +493 -353
  199. package/src/Store/Disk.ts +109 -69
  200. package/src/Store/Memory.ts +365 -96
  201. package/src/Store/SQL/Pg.ts +363 -0
  202. package/src/Store/SQL/query.ts +603 -0
  203. package/src/Store/SQL.ts +735 -0
  204. package/src/Store/codeFilter.ts +8 -5
  205. package/src/Store/index.ts +21 -6
  206. package/src/Store/utils.ts +26 -24
  207. package/src/WorkflowEngineCosmos.ts +719 -0
  208. package/src/WorkflowEngineSqlite.ts +813 -0
  209. package/src/arbs.ts +5 -3
  210. package/src/{adapters/cosmos-client.ts → cosmos-client.ts} +5 -3
  211. package/src/errorReporter.ts +66 -76
  212. package/src/fileUtil.ts +1 -1
  213. package/src/index.ts +2 -1
  214. package/src/{api/internal → internal}/RequestContextMiddleware.ts +23 -6
  215. package/src/internal/auth.ts +272 -0
  216. package/src/{api/internal → internal}/events.ts +22 -13
  217. package/src/{api/layerUtils.ts → layerUtils.ts} +14 -10
  218. package/src/logger/jsonLogger.ts +4 -2
  219. package/src/logger/logFmtLogger.ts +2 -2
  220. package/src/logger/shared.ts +5 -4
  221. package/src/{adapters/memQueue.ts → memQueue.ts} +5 -4
  222. package/src/{adapters/mongo-client.ts → mongo-client.ts} +4 -2
  223. package/src/otel.ts +152 -0
  224. package/src/rateLimit.ts +34 -23
  225. package/src/{adapters/redis-client.ts → redis-client.ts} +7 -3
  226. package/src/{api/reportError.ts → reportError.ts} +3 -2
  227. package/src/{api/routing → routing}/middleware/RouterMiddleware.ts +5 -4
  228. package/src/{api/routing → routing}/middleware/middleware.ts +62 -17
  229. package/src/routing/middleware.ts +4 -0
  230. package/src/{api/routing → routing}/schema/jwt.ts +2 -1
  231. package/src/{api/routing → routing}/utils.ts +2 -1
  232. package/src/routing.ts +768 -0
  233. package/src/test.ts +2 -2
  234. package/test/auth.test.ts +101 -0
  235. package/test/cluster-cosmos.test.ts +590 -0
  236. package/test/cluster-servicebus.test.ts +180 -0
  237. package/test/cluster-sqlite.test.ts +207 -0
  238. package/test/contextProvider.test.ts +15 -12
  239. package/test/controller.test.ts +28 -32
  240. package/test/cosmos-query.test.ts +159 -0
  241. package/test/dist/_check-agg-infer.test-d.d.ts +2 -0
  242. package/test/dist/_check-agg-infer.test-d.d.ts.map +1 -0
  243. package/test/dist/_check-agg-infer.test-d.js +19 -0
  244. package/test/dist/_check-proj-infer.test-d.d.ts +2 -0
  245. package/test/dist/_check-proj-infer.test-d.d.ts.map +1 -0
  246. package/test/dist/_check-proj-infer.test-d.js +16 -0
  247. package/test/dist/_check-tighten.test-d.d.ts +2 -0
  248. package/test/dist/_check-tighten.test-d.d.ts.map +1 -0
  249. package/test/dist/_check-tighten.test-d.js +21 -0
  250. package/test/dist/auth.test.d.ts.map +1 -0
  251. package/test/dist/cluster-cosmos.test.d.ts.map +1 -0
  252. package/test/dist/cluster-servicebus.test.d.ts.map +1 -0
  253. package/test/dist/cluster-sqlite.test.d.ts.map +1 -0
  254. package/test/dist/contextProvider.test.d.ts.map +1 -1
  255. package/test/dist/controller.test.d.ts.map +1 -1
  256. package/test/dist/cosmos-query.test.d.ts.map +1 -0
  257. package/test/dist/date-query.test.d.ts.map +1 -0
  258. package/test/dist/fixtures.d.ts +30 -12
  259. package/test/dist/fixtures.d.ts.map +1 -1
  260. package/test/dist/fixtures.js +17 -10
  261. package/test/dist/query.test.d.ts.map +1 -1
  262. package/test/dist/rawQuery.test.d.ts.map +1 -1
  263. package/test/dist/repository-ext.test.d.ts.map +1 -0
  264. package/test/dist/requires.test.d.ts.map +1 -1
  265. package/test/dist/router-generator.test.d.ts.map +1 -0
  266. package/test/dist/routing-interruptibility.test.d.ts.map +1 -0
  267. package/test/dist/rpc-context-map-streaming.test.d.ts.map +1 -0
  268. package/test/dist/rpc-e2e-invalidation.test.d.ts.map +1 -0
  269. package/test/dist/rpc-multi-middleware.test.d.ts.map +1 -1
  270. package/test/dist/rpc-stream-fullstack.test.d.ts.map +1 -0
  271. package/test/dist/sql-store.test.d.ts.map +1 -0
  272. package/test/dist/workflow-engine-cosmos.test.d.ts.map +1 -0
  273. package/test/dist/workflow-engine-sqlite.test.d.ts.map +1 -0
  274. package/test/fixtures.ts +16 -9
  275. package/test/layerUtils.test.ts +2 -2
  276. package/test/query.test.ts +905 -40
  277. package/test/rawQuery.test.ts +340 -22
  278. package/test/repository-ext.test.ts +62 -0
  279. package/test/requires.test.ts +10 -5
  280. package/test/router-generator.test.ts +187 -0
  281. package/test/routing-interruptibility.test.ts +66 -0
  282. package/test/rpc-context-map-streaming.test.ts +262 -0
  283. package/test/rpc-e2e-invalidation.test.ts +256 -0
  284. package/test/rpc-multi-middleware.test.ts +85 -10
  285. package/test/rpc-stream-fullstack.test.ts +304 -0
  286. package/test/sql-store.test.ts +1711 -0
  287. package/test/validateSample.test.ts +26 -14
  288. package/test/workflow-engine-cosmos.test.ts +354 -0
  289. package/test/workflow-engine-sqlite.test.ts +299 -0
  290. package/tsconfig.examples.json +1 -1
  291. package/tsconfig.json +2 -1
  292. package/tsconfig.json.bak +2 -2
  293. package/tsconfig.src.json +35 -35
  294. package/tsconfig.test.json +2 -2
  295. package/dist/Emailer/service.d.ts +0 -55
  296. package/dist/Emailer/service.d.ts.map +0 -1
  297. package/dist/Emailer/service.js +0 -6
  298. package/dist/Emailer.d.ts +0 -2
  299. package/dist/Emailer.d.ts.map +0 -1
  300. package/dist/Emailer.js +0 -2
  301. package/dist/Model/Repository/ext.d.ts +0 -41
  302. package/dist/Model/Repository/ext.d.ts.map +0 -1
  303. package/dist/Model/Repository/ext.js +0 -65
  304. package/dist/Model/Repository/internal/internal.d.ts +0 -59
  305. package/dist/Model/Repository/internal/internal.d.ts.map +0 -1
  306. package/dist/Model/Repository/internal/internal.js +0 -316
  307. package/dist/Model/Repository/legacy.d.ts +0 -19
  308. package/dist/Model/Repository/legacy.d.ts.map +0 -1
  309. package/dist/Model/Repository/legacy.js +0 -2
  310. package/dist/Model/Repository/makeRepo.d.ts +0 -49
  311. package/dist/Model/Repository/makeRepo.d.ts.map +0 -1
  312. package/dist/Model/Repository/makeRepo.js +0 -24
  313. package/dist/Model/Repository/service.d.ts +0 -89
  314. package/dist/Model/Repository/service.d.ts.map +0 -1
  315. package/dist/Model/Repository/service.js +0 -2
  316. package/dist/Model/Repository/validation.d.ts +0 -42
  317. package/dist/Model/Repository/validation.d.ts.map +0 -1
  318. package/dist/Model/Repository/validation.js +0 -32
  319. package/dist/Model/Repository.d.ts +0 -6
  320. package/dist/Model/Repository.d.ts.map +0 -1
  321. package/dist/Model/Repository.js +0 -6
  322. package/dist/Model/dsl.d.ts +0 -32
  323. package/dist/Model/dsl.d.ts.map +0 -1
  324. package/dist/Model/dsl.js +0 -44
  325. package/dist/Model/filter/filterApi.d.ts +0 -30
  326. package/dist/Model/filter/filterApi.d.ts.map +0 -1
  327. package/dist/Model/filter/filterApi.js +0 -2
  328. package/dist/Model/filter/types/errors.d.ts +0 -29
  329. package/dist/Model/filter/types/errors.d.ts.map +0 -1
  330. package/dist/Model/filter/types/errors.js +0 -2
  331. package/dist/Model/filter/types/fields.d.ts +0 -15
  332. package/dist/Model/filter/types/fields.d.ts.map +0 -1
  333. package/dist/Model/filter/types/fields.js +0 -2
  334. package/dist/Model/filter/types/path/common.d.ts +0 -316
  335. package/dist/Model/filter/types/path/common.d.ts.map +0 -1
  336. package/dist/Model/filter/types/path/common.js +0 -2
  337. package/dist/Model/filter/types/path/eager.d.ts +0 -95
  338. package/dist/Model/filter/types/path/eager.d.ts.map +0 -1
  339. package/dist/Model/filter/types/path/eager.js +0 -31
  340. package/dist/Model/filter/types/path/index.d.ts +0 -4
  341. package/dist/Model/filter/types/path/index.d.ts.map +0 -1
  342. package/dist/Model/filter/types/path/index.js +0 -3
  343. package/dist/Model/filter/types/utils.d.ts +0 -79
  344. package/dist/Model/filter/types/utils.d.ts.map +0 -1
  345. package/dist/Model/filter/types/utils.js +0 -2
  346. package/dist/Model/filter/types/validator.d.ts +0 -30
  347. package/dist/Model/filter/types/validator.d.ts.map +0 -1
  348. package/dist/Model/filter/types/validator.js +0 -2
  349. package/dist/Model/filter/types.d.ts +0 -5
  350. package/dist/Model/filter/types.d.ts.map +0 -1
  351. package/dist/Model/filter/types.js +0 -7
  352. package/dist/Model/query/dsl.d.ts +0 -248
  353. package/dist/Model/query/dsl.d.ts.map +0 -1
  354. package/dist/Model/query/dsl.js +0 -104
  355. package/dist/Model/query/new-kid-interpreter.d.ts +0 -28
  356. package/dist/Model/query/new-kid-interpreter.d.ts.map +0 -1
  357. package/dist/Model/query/new-kid-interpreter.js +0 -165
  358. package/dist/Model/query.d.ts +0 -15
  359. package/dist/Model/query.d.ts.map +0 -1
  360. package/dist/Model/query.js +0 -3
  361. package/dist/Model.d.ts +0 -4
  362. package/dist/Model.d.ts.map +0 -1
  363. package/dist/Model.js +0 -4
  364. package/dist/Operations.d.ts +0 -55
  365. package/dist/Operations.d.ts.map +0 -1
  366. package/dist/Operations.js +0 -102
  367. package/dist/OperationsRepo.d.ts +0 -41
  368. package/dist/OperationsRepo.d.ts.map +0 -1
  369. package/dist/OperationsRepo.js +0 -14
  370. package/dist/QueueMaker/service.d.ts +0 -11
  371. package/dist/QueueMaker/service.d.ts.map +0 -1
  372. package/dist/QueueMaker/service.js +0 -4
  373. package/dist/RequestContext.d.ts +0 -63
  374. package/dist/RequestContext.d.ts.map +0 -1
  375. package/dist/RequestContext.js +0 -49
  376. package/dist/Store/ContextMapContainer.d.ts +0 -14
  377. package/dist/Store/ContextMapContainer.d.ts.map +0 -1
  378. package/dist/Store/ContextMapContainer.js +0 -16
  379. package/dist/Store/service.d.ts +0 -108
  380. package/dist/Store/service.d.ts.map +0 -1
  381. package/dist/Store/service.js +0 -71
  382. package/dist/Store.d.ts +0 -2
  383. package/dist/Store.d.ts.map +0 -1
  384. package/dist/Store.js +0 -2
  385. package/dist/adapters/SQL/Model.d.ts +0 -479
  386. package/dist/adapters/SQL/Model.d.ts.map +0 -1
  387. package/dist/adapters/SQL/Model.js +0 -478
  388. package/dist/adapters/SQL.d.ts +0 -2
  389. package/dist/adapters/SQL.d.ts.map +0 -1
  390. package/dist/adapters/ServiceBus.d.ts +0 -58
  391. package/dist/adapters/ServiceBus.d.ts.map +0 -1
  392. package/dist/adapters/ServiceBus.js +0 -99
  393. package/dist/adapters/cosmos-client.d.ts +0 -14
  394. package/dist/adapters/cosmos-client.d.ts.map +0 -1
  395. package/dist/adapters/cosmos-client.js +0 -9
  396. package/dist/adapters/index.d.ts +0 -2
  397. package/dist/adapters/index.d.ts.map +0 -1
  398. package/dist/adapters/index.js +0 -2
  399. package/dist/adapters/logger.d.ts +0 -9
  400. package/dist/adapters/logger.d.ts.map +0 -1
  401. package/dist/adapters/logger.js +0 -3
  402. package/dist/adapters/memQueue.d.ts +0 -13
  403. package/dist/adapters/memQueue.d.ts.map +0 -1
  404. package/dist/adapters/memQueue.js +0 -20
  405. package/dist/adapters/mongo-client.d.ts +0 -10
  406. package/dist/adapters/mongo-client.d.ts.map +0 -1
  407. package/dist/adapters/mongo-client.js +0 -13
  408. package/dist/adapters/redis-client.d.ts +0 -39
  409. package/dist/adapters/redis-client.d.ts.map +0 -1
  410. package/dist/adapters/redis-client.js +0 -94
  411. package/dist/api/ContextProvider.d.ts +0 -31
  412. package/dist/api/ContextProvider.d.ts.map +0 -1
  413. package/dist/api/ContextProvider.js +0 -38
  414. package/dist/api/codec.d.ts +0 -5
  415. package/dist/api/codec.d.ts.map +0 -1
  416. package/dist/api/codec.js +0 -5
  417. package/dist/api/internal/RequestContextMiddleware.d.ts +0 -5
  418. package/dist/api/internal/RequestContextMiddleware.d.ts.map +0 -1
  419. package/dist/api/internal/RequestContextMiddleware.js +0 -35
  420. package/dist/api/internal/auth.d.ts +0 -15
  421. package/dist/api/internal/auth.d.ts.map +0 -1
  422. package/dist/api/internal/auth.js +0 -47
  423. package/dist/api/internal/events.d.ts +0 -9
  424. package/dist/api/internal/events.d.ts.map +0 -1
  425. package/dist/api/internal/events.js +0 -42
  426. package/dist/api/internal/health.d.ts +0 -3
  427. package/dist/api/internal/health.d.ts.map +0 -1
  428. package/dist/api/internal/health.js +0 -5
  429. package/dist/api/layerUtils.d.ts +0 -24
  430. package/dist/api/layerUtils.d.ts.map +0 -1
  431. package/dist/api/layerUtils.js +0 -16
  432. package/dist/api/middlewares.d.ts +0 -10
  433. package/dist/api/middlewares.d.ts.map +0 -1
  434. package/dist/api/reportError.d.ts +0 -4
  435. package/dist/api/reportError.d.ts.map +0 -1
  436. package/dist/api/reportError.js +0 -27
  437. package/dist/api/routing/middleware/RouterMiddleware.d.ts +0 -15
  438. package/dist/api/routing/middleware/RouterMiddleware.d.ts.map +0 -1
  439. package/dist/api/routing/middleware/middleware.d.ts +0 -9
  440. package/dist/api/routing/middleware/middleware.d.ts.map +0 -1
  441. package/dist/api/routing/middleware/middleware.js +0 -92
  442. package/dist/api/routing/middleware.d.ts +0 -4
  443. package/dist/api/routing/middleware.d.ts.map +0 -1
  444. package/dist/api/routing/schema/jwt.d.ts +0 -4
  445. package/dist/api/routing/schema/jwt.d.ts.map +0 -1
  446. package/dist/api/routing/schema/jwt.js +0 -12
  447. package/dist/api/routing/tsort.d.ts +0 -8
  448. package/dist/api/routing/tsort.d.ts.map +0 -1
  449. package/dist/api/routing/tsort.js +0 -51
  450. package/dist/api/routing/utils.d.ts +0 -19
  451. package/dist/api/routing/utils.d.ts.map +0 -1
  452. package/dist/api/routing/utils.js +0 -44
  453. package/dist/api/routing.d.ts +0 -138
  454. package/dist/api/routing.d.ts.map +0 -1
  455. package/dist/api/routing.js +0 -166
  456. package/dist/api/setupRequest.d.ts +0 -12
  457. package/dist/api/setupRequest.d.ts.map +0 -1
  458. package/dist/api/setupRequest.js +0 -44
  459. package/dist/api/util.d.ts +0 -3
  460. package/dist/api/util.d.ts.map +0 -1
  461. package/dist/api/util.js +0 -14
  462. package/eslint.config.mjs +0 -24
  463. package/src/Emailer/service.ts +0 -52
  464. package/src/Emailer.ts +0 -1
  465. package/src/Model/Repository/ext.ts +0 -283
  466. package/src/Model/Repository/internal/internal.ts +0 -577
  467. package/src/Model/Repository/legacy.ts +0 -27
  468. package/src/Model/Repository/makeRepo.ts +0 -139
  469. package/src/Model/Repository/service.ts +0 -627
  470. package/src/Model/Repository/validation.ts +0 -31
  471. package/src/Model/Repository.ts +0 -5
  472. package/src/Model/dsl.ts +0 -128
  473. package/src/Model/filter/filterApi.ts +0 -60
  474. package/src/Model/filter/types/errors.ts +0 -47
  475. package/src/Model/filter/types/fields.ts +0 -50
  476. package/src/Model/filter/types/path/common.ts +0 -404
  477. package/src/Model/filter/types/path/eager.ts +0 -298
  478. package/src/Model/filter/types/path/index.ts +0 -4
  479. package/src/Model/filter/types/utils.ts +0 -128
  480. package/src/Model/filter/types/validator.ts +0 -46
  481. package/src/Model/filter/types.ts +0 -6
  482. package/src/Model/query/dsl.ts +0 -2110
  483. package/src/Model/query/new-kid-interpreter.ts +0 -210
  484. package/src/Model/query.ts +0 -13
  485. package/src/Model.ts +0 -3
  486. package/src/Operations.ts +0 -235
  487. package/src/OperationsRepo.ts +0 -16
  488. package/src/QueueMaker/service.ts +0 -17
  489. package/src/RequestContext.ts +0 -63
  490. package/src/Store/ContextMapContainer.ts +0 -20
  491. package/src/Store/service.ts +0 -184
  492. package/src/Store.ts +0 -1
  493. package/src/adapters/ServiceBus.ts +0 -209
  494. package/src/adapters/index.ts +0 -0
  495. package/src/adapters/logger.ts +0 -3
  496. package/src/api/internal/auth.ts +0 -68
  497. package/src/api/routing/middleware.ts +0 -6
  498. package/src/api/routing.ts +0 -598
  499. package/src/api/setupRequest.ts +0 -84
  500. /package/src/{adapters/SQL.ts → SQL.ts} +0 -0
  501. /package/src/{api/codec.ts → codec.ts} +0 -0
  502. /package/src/{api/internal → internal}/health.ts +0 -0
  503. /package/src/{api/middlewares.ts → middlewares.ts} +0 -0
  504. /package/src/{api/routing → routing}/tsort.ts +0 -0
  505. /package/src/{api/util.ts → util.ts} +0 -0
@@ -0,0 +1,242 @@
1
+ import { ServiceBusClient, type ServiceBusClientOptions, type ServiceBusMessage, type ServiceBusReceiverOptions, type ServiceBusSenderOptions, type SubscribeOptions } from "@azure/service-bus"
2
+ import * as Context from "effect-app/Context"
3
+ import * as Effect from "effect-app/Effect"
4
+ import * as Layer from "effect-app/Layer"
5
+ import * as Data from "effect/Data"
6
+ import * as Scope from "effect/Scope"
7
+ import * as ClusterError from "effect/unstable/cluster/ClusterError"
8
+ import { Persisted } from "effect/unstable/cluster/ClusterSchema"
9
+ import type * as Message from "effect/unstable/cluster/Message"
10
+ import type * as MessageStorage from "effect/unstable/cluster/MessageStorage"
11
+ import type * as RunnerHealth from "effect/unstable/cluster/RunnerHealth"
12
+ import * as Runners from "effect/unstable/cluster/Runners"
13
+ import type * as RunnerStorage from "effect/unstable/cluster/RunnerStorage"
14
+ import * as Sharding from "effect/unstable/cluster/Sharding"
15
+ import type * as ShardingConfig from "effect/unstable/cluster/ShardingConfig"
16
+ import * as Snowflake from "effect/unstable/cluster/Snowflake"
17
+ import type * as Rpc from "effect/unstable/rpc/Rpc"
18
+
19
+ export interface ClusterServiceBusSender {
20
+ readonly sendMessages: (messages: ServiceBusMessage) => Promise<void>
21
+ readonly close: () => Promise<void>
22
+ }
23
+
24
+ export interface ClusterServiceBusSubscription {
25
+ readonly close: () => Promise<void>
26
+ }
27
+
28
+ export interface ClusterServiceBusReceiver {
29
+ readonly subscribe: (
30
+ handlers: {
31
+ readonly processMessage: () => Promise<void>
32
+ readonly processError: (args: {
33
+ readonly error: Error
34
+ readonly entityPath?: string | undefined
35
+ readonly errorSource: string
36
+ readonly fullyQualifiedNamespace: string
37
+ }) => Promise<void>
38
+ },
39
+ options?: SubscribeOptions | undefined
40
+ ) => ClusterServiceBusSubscription
41
+ readonly close: () => Promise<void>
42
+ }
43
+
44
+ export interface ClusterServiceBusClient {
45
+ readonly createSender: (
46
+ topicName: string,
47
+ options?: ServiceBusSenderOptions | undefined
48
+ ) => ClusterServiceBusSender
49
+ readonly createReceiver: (
50
+ topicName: string,
51
+ subscriptionName: string,
52
+ options?: ServiceBusReceiverOptions | undefined
53
+ ) => ClusterServiceBusReceiver
54
+ readonly close: () => Promise<void>
55
+ }
56
+
57
+ export class ClusterServiceBus extends Context.Service<ClusterServiceBus, {
58
+ readonly client: ClusterServiceBusClient
59
+ }>()("@effect-app/infra/ClusterServiceBus") {}
60
+
61
+ export interface TopicOptions {
62
+ readonly topicName: string
63
+ readonly senderOptions?: ServiceBusSenderOptions | undefined
64
+ }
65
+
66
+ export interface SubscriptionOptions extends TopicOptions {
67
+ readonly subscriptionName: string
68
+ readonly receiverOptions?: ServiceBusReceiverOptions | undefined
69
+ readonly subscribeOptions?: SubscribeOptions | undefined
70
+ }
71
+
72
+ export interface StorageNotification {
73
+ readonly _tag: "EffectClusterStorageNotification"
74
+ readonly envelopeId: string
75
+ readonly requestId: string
76
+ readonly shardId: string
77
+ readonly entityType: string
78
+ readonly entityId: string
79
+ }
80
+
81
+ export const layerClient = (
82
+ connectionString: string,
83
+ options?: ServiceBusClientOptions | undefined
84
+ ): Layer.Layer<ClusterServiceBus> =>
85
+ Layer.effect(
86
+ ClusterServiceBus,
87
+ Effect.acquireRelease(
88
+ Effect.sync(() => ClusterServiceBus.of({ client: new ServiceBusClient(connectionString, options) })),
89
+ ({ client }) => Effect.promise(() => client.close()).pipe(Effect.ignore)
90
+ )
91
+ )
92
+
93
+ export const layerClientFrom = (client: ClusterServiceBusClient): Layer.Layer<ClusterServiceBus> =>
94
+ Layer.succeed(ClusterServiceBus)(ClusterServiceBus.of({ client }))
95
+
96
+ export const makeRunners: (
97
+ options: TopicOptions
98
+ ) => Effect.Effect<
99
+ Runners.Runners["Service"],
100
+ never,
101
+ | ClusterServiceBus
102
+ | MessageStorage.MessageStorage
103
+ | ShardingConfig.ShardingConfig
104
+ | Snowflake.Generator
105
+ | Scope.Scope
106
+ > = Effect.fnUntraced(function*(options) {
107
+ const serviceBus = yield* ClusterServiceBus
108
+ const scope = yield* Effect.scope
109
+ const sender = serviceBus.client.createSender(options.topicName, options.senderOptions)
110
+
111
+ yield* Scope.addFinalizer(scope, Effect.promise(() => sender.close()).pipe(Effect.ignore))
112
+
113
+ const publish = <R extends Rpc.Any>(message: Message.Outgoing<R>) =>
114
+ Effect
115
+ .tryPromise({
116
+ try: () => sender.sendMessages(storageNotification(message)),
117
+ catch: (cause) => new ServiceBusPublishError({ cause })
118
+ })
119
+ .pipe(
120
+ Effect.catch((cause) => Effect.logDebug("Could not publish cluster storage notification", cause))
121
+ )
122
+
123
+ return yield* Runners.make({
124
+ ping: (address) => Effect.fail(new ClusterError.RunnerUnavailable({ address })),
125
+ send: ({ address, message }) => {
126
+ const persisted = Context.get(message.rpc.annotations, Persisted)
127
+ return (persisted ? publish(message) : Effect.void).pipe(
128
+ Effect.andThen(Effect.fail(new ClusterError.RunnerUnavailable({ address })))
129
+ )
130
+ },
131
+ notify: ({ message }) => publish(message),
132
+ onRunnerUnavailable: () => Effect.void
133
+ })
134
+ })
135
+
136
+ export const layerRunners = (
137
+ options: TopicOptions
138
+ ): Layer.Layer<
139
+ Runners.Runners,
140
+ never,
141
+ ClusterServiceBus | MessageStorage.MessageStorage | ShardingConfig.ShardingConfig
142
+ > =>
143
+ Layer.effect(Runners.Runners, makeRunners(options)).pipe(
144
+ Layer.provide(Snowflake.layerGenerator)
145
+ )
146
+
147
+ export const makeStoragePoller: (
148
+ options: SubscriptionOptions
149
+ ) => Effect.Effect<void, never, ClusterServiceBus | Sharding.Sharding | Scope.Scope> = Effect.fnUntraced(
150
+ function*(options) {
151
+ const serviceBus = yield* ClusterServiceBus
152
+ const sharding = yield* Sharding.Sharding
153
+ const scope = yield* Effect.scope
154
+ const receiver = serviceBus.client.createReceiver(
155
+ options.topicName,
156
+ options.subscriptionName,
157
+ {
158
+ receiveMode: "receiveAndDelete",
159
+ ...options.receiverOptions
160
+ }
161
+ )
162
+ const subscription = receiver.subscribe(
163
+ {
164
+ processMessage: () =>
165
+ Effect.runPromise(
166
+ sharding.pollStorage.pipe(
167
+ Effect.catchCause((cause) => Effect.logDebug("Could not wake cluster storage poller", cause))
168
+ )
169
+ ),
170
+ processError: (args) =>
171
+ Effect.runPromise(
172
+ Effect.logDebug("Error receiving cluster storage notification", args.error).pipe(
173
+ Effect.annotateLogs({
174
+ entityPath: args.entityPath,
175
+ errorSource: args.errorSource,
176
+ fullyQualifiedNamespace: args.fullyQualifiedNamespace
177
+ })
178
+ )
179
+ )
180
+ },
181
+ options.subscribeOptions
182
+ )
183
+
184
+ yield* Scope.addFinalizer(
185
+ scope,
186
+ Effect.promise(() => subscription.close()).pipe(
187
+ Effect.andThen(Effect.promise(() => receiver.close())),
188
+ Effect.ignore
189
+ )
190
+ )
191
+ }
192
+ )
193
+
194
+ export const layerStoragePoller = (
195
+ options: SubscriptionOptions
196
+ ): Layer.Layer<never, never, ClusterServiceBus | Sharding.Sharding> => Layer.effectDiscard(makeStoragePoller(options))
197
+
198
+ export const layer = (
199
+ options: SubscriptionOptions
200
+ ): Layer.Layer<
201
+ Sharding.Sharding | Runners.Runners,
202
+ never,
203
+ | ClusterServiceBus
204
+ | MessageStorage.MessageStorage
205
+ | RunnerHealth.RunnerHealth
206
+ | RunnerStorage.RunnerStorage
207
+ | ShardingConfig.ShardingConfig
208
+ > => {
209
+ const sharding = Sharding.layer.pipe(
210
+ Layer.provideMerge(layerRunners(options))
211
+ )
212
+ return Layer.merge(
213
+ sharding,
214
+ layerStoragePoller(options).pipe(
215
+ Layer.provide(sharding)
216
+ )
217
+ )
218
+ }
219
+
220
+ const storageNotification = <R extends Rpc.Any>(message: Message.Outgoing<R>): ServiceBusMessage => {
221
+ const envelope = message.envelope
222
+ const envelopeId = envelope._tag === "Request" ? envelope.requestId : envelope.id
223
+ const body: StorageNotification = {
224
+ _tag: "EffectClusterStorageNotification",
225
+ envelopeId: String(envelopeId),
226
+ requestId: String(envelope.requestId),
227
+ shardId: envelope.address.shardId.toString(),
228
+ entityType: envelope.address.entityType,
229
+ entityId: envelope.address.entityId
230
+ }
231
+ return {
232
+ body,
233
+ contentType: "application/json",
234
+ correlationId: body.requestId,
235
+ messageId: body.envelopeId,
236
+ subject: body._tag
237
+ }
238
+ }
239
+
240
+ class ServiceBusPublishError extends Data.TaggedError("ServiceBusPublishError")<{
241
+ readonly cause: unknown
242
+ }> {}
@@ -1,9 +1,13 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
- import { Effect, Layer, type NonEmptyReadonlyArray, pipe, type Scope, ServiceMap } from "effect-app"
2
+ import type { NonEmptyReadonlyArray } from "effect-app/Array"
3
+ import * as Context from "effect-app/Context"
4
+ import * as Effect from "effect-app/Effect"
5
+ import * as Layer from "effect-app/Layer"
6
+ import { pipe } from "effect/Function"
7
+ import type * as Scope from "effect/Scope"
3
8
 
4
9
  import { type HttpRouter } from "effect-app/http"
5
10
  import { type EffectGenUtils } from "effect-app/utils/gen"
6
- import { type Yieldable } from "effect/Effect"
7
11
  import { type ContextTagWithDefault, type GetContext, type LayerUtils, mergeContexts } from "./layerUtils.js"
8
12
 
9
13
  export interface ContextProviderId {
@@ -23,7 +27,7 @@ type TDepsArr<TDeps extends ReadonlyArray<any>> = {
23
27
  // E = never => the context provided cannot trigger errors
24
28
  // TODO: remove HttpLayerRouter.Provided - it's not even relevant outside of Http context, while ContextProviders are for anywhere. Only support Scope.Scope?
25
29
  // _R extends HttpLayerRouter.Provided => the context provided can only have what HttpLayerRouter.Provided provides as requirements
26
- ContextTagWithDefault.Base<Effect.Effect<ServiceMap.ServiceMap<infer _1>, never, infer _R>> // & { _tag: infer _2 }>
30
+ ContextTagWithDefault.Base<Effect.Effect<Context.Context<infer _1>, never, infer _R>> // & { _tag: infer _2 }>
27
31
  ? [_R] extends [HttpRouter.Provided] ? TDeps[K]
28
32
  : `HttpLayerRouter.Provided is the only requirement ${TDeps[K]["Service"][
29
33
  "_tag"
@@ -38,7 +42,7 @@ type TDepsArr<TDeps extends ReadonlyArray<any>> = {
38
42
  > // & { _tag: infer _3 }
39
43
  ) // [_YW] extends [never] if no yield* is used and just some context is returned
40
44
  ? [_YW] extends [never] ? TDeps[K]
41
- : [_YW] extends [Yieldable<any, infer _2, never, infer _R>] ? [_R] extends [HttpRouter.Provided] ? TDeps[K]
45
+ : [_YW] extends [Effect.Effect<any, never, infer _R>] ? [_R] extends [HttpRouter.Provided] ? TDeps[K]
42
46
  : `HttpLayerRouter.Provided is the only requirement ${TDeps[K]["Service"][
43
47
  "_tag"
44
48
  ]}'s returned effect can have`
@@ -58,9 +62,9 @@ export const mergeContextProviders = <
58
62
  Effect.Effect<
59
63
  // we need to merge all contexts into one
60
64
  // v4: Service.Shape extracts the service value type (v3's Tag.Identifier)
61
- ServiceMap.ServiceMap<GetContext<EffectGenUtils.Success<ServiceMap.Service.Shape<TDeps[number]>>>>,
65
+ Context.Context<GetContext<EffectGenUtils.Success<Context.Service.Shape<TDeps[number]>>>>,
62
66
  never,
63
- EffectGenUtils.ServiceMap<ServiceMap.Service.Shape<TDeps[number]>>
67
+ EffectGenUtils.Context<Context.Service.Shape<TDeps[number]>>
64
68
  >,
65
69
  LayerUtils.GetLayersError<{ [K in keyof TDeps]: TDeps[K]["Default"] }>,
66
70
  LayerUtils.GetLayersSuccess<{ [K in keyof TDeps]: TDeps[K]["Default"] }>
@@ -78,14 +82,14 @@ export const mergeContextProviders = <
78
82
  handle: handle[Symbol.toStringTag] === "GeneratorFunction" ? Effect.fnUntraced(handle)() : handle
79
83
  }
80
84
  ))
81
- // services are effects which return some ServiceMap.ServiceMap<...>
85
+ // services are effects which return some Context.Context<...>
82
86
  const context = yield* mergeContexts(services as any)
83
87
  return context
84
88
  })
85
89
  }) as any
86
90
  })
87
91
 
88
- // Effect Rpc Middleware: for single tag providing, we could use Provides, for providing ServiceMap or Layer (bad boy) we could use Wrap..
92
+ // Effect Rpc Middleware: for single tag providing, we could use Provides, for providing Context or Layer (bad boy) we could use Wrap..
89
93
  export const ContextProvider = <
90
94
  ContextProviderA,
91
95
  MakeContextProviderE,
@@ -97,9 +101,8 @@ export const ContextProvider = <
97
101
  effect: Effect.Effect<
98
102
  | Effect.Effect<ContextProviderA, never, ContextProviderR>
99
103
  | (() => Generator<
100
- Yieldable<any, any, never, ContextProviderR>,
101
- ContextProviderA,
102
- any
104
+ Effect.Effect<any, never, ContextProviderR>,
105
+ ContextProviderA
103
106
  >),
104
107
  MakeContextProviderE,
105
108
  MakeContextProviderR | Scope.Scope
@@ -107,7 +110,7 @@ export const ContextProvider = <
107
110
  dependencies?: Dependencies
108
111
  }
109
112
  ) => {
110
- const ctx = ServiceMap.Service<
113
+ const ctx = Context.Service<
111
114
  ContextProviderId,
112
115
  Effect.Effect<ContextProviderA, never, ContextProviderR>
113
116
  >(
@@ -146,17 +149,17 @@ export const MergedContextProvider = <
146
149
  Effect.Effect<
147
150
  // we need to merge all contexts into one
148
151
  // v4: Service.Shape extracts the service value type (v3's Tag.Identifier)
149
- ServiceMap.ServiceMap<GetContext<EffectGenUtils.Success<ServiceMap.Service.Shape<TDeps[number]>>>>,
152
+ Context.Context<GetContext<EffectGenUtils.Success<Context.Service.Shape<TDeps[number]>>>>,
150
153
  never,
151
- EffectGenUtils.ServiceMap<ServiceMap.Service.Shape<TDeps[number]>>
154
+ EffectGenUtils.Context<Context.Service.Shape<TDeps[number]>>
152
155
  >,
153
156
  LayerUtils.GetLayersError<{ [K in keyof TDeps]: TDeps[K]["Default"] }>,
154
157
  // v4: Identifier here is correct — it's the nominal service identity for layer provide/exclude
155
158
  | Exclude<
156
- ServiceMap.Service.Identifier<TDeps[number]>,
159
+ Context.Service.Identifier<TDeps[number]>,
157
160
  LayerUtils.GetLayersSuccess<{ [K in keyof TDeps]: TDeps[K]["Default"] }>
158
161
  >
159
162
  | LayerUtils.GetLayersContext<{ [K in keyof TDeps]: TDeps[K]["Default"] }>
160
163
  >
161
164
 
162
- export const EmptyContextProvider = ContextProvider({ effect: Effect.succeed(Effect.succeed(ServiceMap.empty())) })
165
+ export const EmptyContextProvider = ContextProvider({ effect: Effect.succeed(Effect.succeed(Context.empty())) })
@@ -1,63 +1,85 @@
1
- import type { EmailData } from "@sendgrid/helpers/classes/email-address.js"
2
1
  import type { MailContent } from "@sendgrid/helpers/classes/mail.js"
3
2
  import sgMail from "@sendgrid/mail"
4
- import { Array, Effect, Equivalence, Redacted } from "effect-app"
3
+ import * as Array from "effect-app/Array"
4
+ import * as Effect from "effect-app/Effect"
5
+ import { type EmailData, Emailer, type EmailMsg, type EmailMsgOptionalFrom, SendMailError } from "effect-app/Emailer"
5
6
  import { dropUndefinedT } from "effect-app/utils"
7
+ import * as Equivalence from "effect/Equivalence"
8
+ import * as Redacted from "effect/Redacted"
6
9
  import { inspect } from "util"
7
10
  import { InfraLogger } from "../logger.js"
8
- import { Emailer, type EmailMsg, type EmailMsgOptionalFrom, type SendgridConfig, SendMailError } from "./service.js"
9
11
 
10
- const makeSendgrid = ({ apiKey, defaultFrom, defaultReplyTo, realMail, subjectPrefix }: SendgridConfig) =>
12
+ export interface SendgridConfig {
13
+ defaultReplyTo?: EmailData
14
+ subjectPrefix: string
15
+ realMail: boolean
16
+ defaultFrom: EmailData
17
+ apiKey: Redacted.Redacted
18
+ /**
19
+ * Email address used for fake/test recipients. Use `{i}` as a placeholder for
20
+ * an auto-incrementing index to ensure uniqueness.
21
+ *
22
+ * @example "test+{i}@example.com"
23
+ */
24
+ fakeMailAddress: string
25
+ }
26
+
27
+ const makeSendgrid = (
28
+ { apiKey, defaultFrom, defaultReplyTo, fakeMailAddress, realMail, subjectPrefix }: SendgridConfig
29
+ ) =>
11
30
  Effect.sync(() => {
12
31
  sgMail.setApiKey(Redacted.value(apiKey))
13
32
 
14
33
  return Emailer.of({
15
- sendMail: Effect.fn("Sendgrid.sendMail")(function*(msg_: EmailMsgOptionalFrom) {
16
- const msg: EmailMsg = dropUndefinedT({
17
- ...msg_,
18
- from: msg_.from ?? defaultFrom,
19
- replyTo: msg_.replyTo ?? (msg_.from ? undefined : defaultReplyTo)
20
- })
21
- const render = renderMessage(!realMail)
34
+ sendMail: Effect.fn("Emailer.sendMail", { attributes: { "messaging.system": "sendgrid" } })(
35
+ function*(msg_: EmailMsgOptionalFrom) {
36
+ const replyTo = msg_.replyTo ?? (msg_.from ? undefined : defaultReplyTo)
37
+ const msg = dropUndefinedT({
38
+ ...msg_,
39
+ from: msg_.from ?? defaultFrom,
40
+ replyTo
41
+ }) satisfies EmailMsg
42
+ const render = renderMessage(!realMail, fakeMailAddress)
22
43
 
23
- const renderedMsg_ = render(msg)
24
- const renderedMsg = {
25
- ...renderedMsg_ as Omit<typeof renderedMsg_, "content">,
26
- subject: `${subjectPrefix}${renderedMsg_.subject}`,
27
- ..."content" in renderedMsg_
28
- ? { content: [...renderedMsg_.content] as [MailContent, ...MailContent[]] }
29
- : {}
30
- }
31
- yield* InfraLogger.logDebug("Sending email").pipe(Effect.annotateLogs("msg", inspect(renderedMsg, false, 5)))
44
+ const renderedMsg_ = render(msg)
45
+ const renderedMsg = {
46
+ ...renderedMsg_ as Omit<typeof renderedMsg_, "content">,
47
+ subject: `${subjectPrefix}${renderedMsg_.subject}`,
48
+ ..."content" in renderedMsg_
49
+ ? { content: [...renderedMsg_.content] as [MailContent, ...MailContent[]] }
50
+ : {}
51
+ }
52
+ yield* InfraLogger.logDebug("Sending email").pipe(Effect.annotateLogs("msg", inspect(renderedMsg, false, 5)))
32
53
 
33
- const ret = yield* Effect
34
- .callback<
35
- [sgMail.ClientResponse, Record<string, unknown>],
36
- Error | sgMail.ResponseError
37
- >(
38
- (resume) =>
39
- void sgMail.send(
40
- renderedMsg as any, // sue me
41
- msg.isMultiple ?? true,
42
- (err, result) =>
43
- err
44
- ? resume(Effect.fail(err))
45
- : resume(Effect.sync(() => result))
46
- )
47
- )
48
- .pipe(Effect.mapError((raw) => new SendMailError({ raw })))
54
+ const ret = yield* Effect
55
+ .callback<
56
+ [sgMail.ClientResponse, Record<string, unknown>],
57
+ Error | sgMail.ResponseError
58
+ >(
59
+ (resume) =>
60
+ void sgMail.send(
61
+ renderedMsg as any, // sue me
62
+ msg.isMultiple ?? true,
63
+ (err, result) =>
64
+ err
65
+ ? resume(Effect.fail(err))
66
+ : resume(Effect.sync(() => result))
67
+ )
68
+ )
69
+ .pipe(Effect.mapError((raw) => new SendMailError({ raw })))
49
70
 
50
- // const event = {
51
- // name: "EmailSent",
52
- // properties: {
53
- // templateId: msg.templateId
54
- // }
55
- // }
56
- // yield* InfraLogger.logDebug("Tracking email event").annotateLogs("event", event.$$.pretty)
57
- // const { trackEvent } = yield* AiContextService
58
- // trackEvent(event)
59
- return ret
60
- })
71
+ // const event = {
72
+ // name: "EmailSent",
73
+ // properties: {
74
+ // templateId: msg.templateId
75
+ // }
76
+ // }
77
+ // yield* InfraLogger.logDebug("Tracking email event").annotateLogs("event", event.$$.pretty)
78
+ // const { trackEvent } = yield* AiContextService
79
+ // trackEvent(event)
80
+ return ret
81
+ }
82
+ )
61
83
  })
62
84
  })
63
85
 
@@ -68,23 +90,24 @@ export function Sendgrid(config: SendgridConfig) {
68
90
  /**
69
91
  * @hidden
70
92
  */
71
- export function renderMessage(forceFake: boolean) {
93
+ export function renderMessage(forceFake: boolean, fakeMailAddress: string) {
72
94
  let i = 0
73
95
  const makeId = () => i++
96
+ const makeFakeEmail = () => fakeMailAddress.replace("{i}", String(makeId()))
74
97
  return forceFake
75
98
  ? (msg: EmailMsg) =>
76
99
  dropUndefinedT({
77
100
  ...msg,
78
- to: msg.to && renderFake(msg.to, makeId),
79
- cc: msg.cc && renderFake(msg.cc, makeId),
80
- bcc: msg.bcc && renderFake(msg.bcc, makeId)
101
+ to: msg.to && renderFake(msg.to, makeFakeEmail),
102
+ cc: msg.cc && renderFake(msg.cc, makeFakeEmail),
103
+ bcc: msg.bcc && renderFake(msg.bcc, makeFakeEmail)
81
104
  })
82
105
  : (msg: EmailMsg) =>
83
106
  dropUndefinedT({
84
107
  ...msg,
85
- to: msg.to && renderFakeIfTest(msg.to, makeId),
86
- cc: msg.cc && renderFakeIfTest(msg.cc, makeId),
87
- bcc: msg.bcc && renderFakeIfTest(msg.bcc, makeId)
108
+ to: msg.to && renderFakeIfTest(msg.to, makeFakeEmail),
109
+ cc: msg.cc && renderFakeIfTest(msg.cc, makeFakeEmail),
110
+ bcc: msg.bcc && renderFakeIfTest(msg.bcc, makeFakeEmail)
88
111
  })
89
112
  }
90
113
 
@@ -100,10 +123,10 @@ export function isTestAddress(to: EmailData) {
100
123
  )
101
124
  }
102
125
 
103
- function renderFake(addr: EmailData | readonly EmailData[], makeId: () => number) {
126
+ function renderFake(addr: EmailData | readonly EmailData[], makeEmail: () => string) {
104
127
  return {
105
128
  name: renderMailData(addr),
106
- email: `test+${makeId()}@nomizz.com`
129
+ email: makeEmail()
107
130
  }
108
131
  }
109
132
  const eq = Equivalence.mapInput(
@@ -117,14 +140,14 @@ function isEmailDataArray(md: EmailData | readonly EmailData[]): md is readonly
117
140
 
118
141
  // TODO: should just not add any already added email address
119
142
  // https://stackoverflow.com/a/53603076/11595834
120
- function renderFakeIfTest(addr: EmailData | readonly EmailData[], makeId: () => number) {
143
+ function renderFakeIfTest(addr: EmailData | readonly EmailData[], makeEmail: () => string) {
121
144
  if (isEmailDataArray(addr)) {
122
145
  return Array.dedupeWith(
123
- addr.map((x) => (isTestAddress(x) ? renderFake(x, makeId) : x)),
146
+ addr.map((x) => (isTestAddress(x) ? renderFake(x, makeEmail) : x)),
124
147
  eq
125
148
  )
126
149
  }
127
- return isTestAddress(addr) ? renderFake(addr, makeId) : addr
150
+ return isTestAddress(addr) ? renderFake(addr, makeEmail) : addr
128
151
  }
129
152
 
130
153
  function renderMailData(md: EmailData | readonly EmailData[]): string {
@@ -1,13 +1,13 @@
1
- import { Effect } from "effect-app"
1
+ import * as Effect from "effect-app/Effect"
2
+ import { Emailer } from "effect-app/Emailer"
2
3
  import { pretty } from "effect-app/utils"
3
4
  import { InfraLogger } from "../logger.js"
4
- import { Emailer } from "./service.js"
5
5
 
6
6
  const makeFake = InfraLogger
7
7
  .logInfo("FAKE Emailer Service enabled")
8
8
  .pipe(Effect.map(() =>
9
9
  Emailer.of({
10
- sendMail: Effect.fn("Fake.sendMail")((msg) =>
10
+ sendMail: Effect.fn("Emailer.sendMail", { attributes: { "messaging.system": "fake" } })((msg) =>
11
11
  InfraLogger
12
12
  .logDebug(`Fake send mail`)
13
13
  .pipe(Effect.annotateLogs("msg", pretty(msg)))
@@ -1,14 +1,17 @@
1
- import { Effect, Fiber, FiberSet, Layer, ServiceMap } from "effect-app"
2
- import type {} from "effect/Scope"
1
+ import * as Context from "effect-app/Context"
2
+ import * as Effect from "effect-app/Effect"
3
+ import * as Layer from "effect-app/Layer"
4
+ import * as Fiber from "effect/Fiber"
5
+ import * as FiberSet from "effect/FiberSet"
6
+
3
7
  import { InfraLogger } from "./logger.js"
4
8
  import { reportNonInterruptedFailureCause } from "./QueueMaker/errors.js"
5
9
  import { setRootParentSpan } from "./RequestFiberSet.js"
6
10
 
7
11
  const make = Effect.gen(function*() {
8
12
  const set = yield* FiberSet.make<unknown, never>()
9
- const add = (...fibers: Fiber.Fiber<never, never>[]) =>
10
- Effect.sync(() => fibers.forEach((_) => FiberSet.addUnsafe(set, _)))
11
- const addAll = (fibers: readonly Fiber.Fiber<never, never>[]) =>
13
+ const add = (...fibers: Fiber.Fiber<never>[]) => Effect.sync(() => fibers.forEach((_) => FiberSet.addUnsafe(set, _)))
14
+ const addAll = (fibers: readonly Fiber.Fiber<never>[]) =>
12
15
  Effect.sync(() => fibers.forEach((_) => FiberSet.addUnsafe(set, _)))
13
16
  const join = FiberSet.size(set).pipe(
14
17
  Effect.andThen((count) => InfraLogger.logDebug(`Joining ${count} current fibers on the MainFiberSet`)),
@@ -62,15 +65,14 @@ const make = Effect.gen(function*() {
62
65
  * you should register these long running fibers in a FiberSet, and join them at the end of your main program.
63
66
  * This way any errors will blow up the main program instead of fibers dying unknowingly.
64
67
  */
65
- export class MainFiberSet extends ServiceMap.Service<MainFiberSet>()("MainFiberSet", { make }) {
68
+ export class MainFiberSet extends Context.Service<MainFiberSet>()("MainFiberSet", { make }) {
66
69
  static readonly Live = Layer.effect(this, this.make)
67
- static readonly JoinLive = this.asEffect().pipe(
70
+ static readonly JoinLive = this.pipe(
68
71
  Effect.andThen((_) => _.join),
69
72
  Layer.effectDiscard,
70
73
  Layer.provide(this.Live)
71
74
  )
72
- static readonly run = <A, R>(self: Effect.Effect<A, never, R>) =>
73
- this.asEffect().pipe(Effect.andThen((_) => _.run(self)))
75
+ static readonly run = <A, R>(self: Effect.Effect<A, never, R>) => this.pipe(Effect.andThen((_) => _.run(self)))
74
76
  static readonly forkDaemonReport = <A, E, R>(self: Effect.Effect<A, E, R>) =>
75
- this.asEffect().pipe(Effect.andThen((_) => _.forkDaemonReport(self)))
77
+ this.pipe(Effect.andThen((_) => _.forkDaemonReport(self)))
76
78
  }