@effect-app/infra 4.0.0-beta.28 → 4.0.0-beta.281

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 (477) hide show
  1. package/CHANGELOG.md +2130 -0
  2. package/_check.sh +1 -1
  3. package/dist/CUPS.d.ts +29 -10
  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 +547 -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 +110 -146
  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 +1 -1
  19. package/dist/Emailer/fake.d.ts.map +1 -1
  20. package/dist/Emailer/fake.js +4 -4
  21. package/dist/MainFiberSet.d.ts +11 -8
  22. package/dist/MainFiberSet.d.ts.map +1 -1
  23. package/dist/MainFiberSet.js +10 -6
  24. package/dist/QueueMaker/SQLQueue.d.ts +7 -8
  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 +4 -2
  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 +9 -5
  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 +8 -4
  34. package/dist/QueueMaker/sbqueue.d.ts.map +1 -1
  35. package/dist/QueueMaker/sbqueue.js +60 -58
  36. package/dist/RequestFiberSet.d.ts +9 -6
  37. package/dist/RequestFiberSet.d.ts.map +1 -1
  38. package/dist/RequestFiberSet.js +13 -8
  39. package/dist/{adapters/SQL → SQL}/Model.d.ts +31 -42
  40. package/dist/SQL/Model.d.ts.map +1 -0
  41. package/dist/SQL/Model.js +469 -0
  42. package/dist/SQL.d.ts.map +1 -0
  43. package/dist/{adapters/SQL.js → SQL.js} +1 -1
  44. package/dist/{adapters/ServiceBus.d.ts → ServiceBus.d.ts} +13 -10
  45. package/dist/ServiceBus.d.ts.map +1 -0
  46. package/dist/ServiceBus.js +108 -0
  47. package/dist/Store/Cosmos/query.d.ts +14 -3
  48. package/dist/Store/Cosmos/query.d.ts.map +1 -1
  49. package/dist/Store/Cosmos/query.js +179 -41
  50. package/dist/Store/Cosmos.d.ts +2 -2
  51. package/dist/Store/Cosmos.d.ts.map +1 -1
  52. package/dist/Store/Cosmos.js +385 -254
  53. package/dist/Store/Disk.d.ts +4 -4
  54. package/dist/Store/Disk.d.ts.map +1 -1
  55. package/dist/Store/Disk.js +79 -39
  56. package/dist/Store/Memory.d.ts +5 -9
  57. package/dist/Store/Memory.d.ts.map +1 -1
  58. package/dist/Store/Memory.js +324 -67
  59. package/dist/Store/SQL/Pg.d.ts +4 -0
  60. package/dist/Store/SQL/Pg.d.ts.map +1 -0
  61. package/dist/Store/SQL/Pg.js +232 -0
  62. package/dist/Store/SQL/query.d.ts +49 -0
  63. package/dist/Store/SQL/query.d.ts.map +1 -0
  64. package/dist/Store/SQL/query.js +527 -0
  65. package/dist/Store/SQL.d.ts +21 -0
  66. package/dist/Store/SQL.d.ts.map +1 -0
  67. package/dist/Store/SQL.js +456 -0
  68. package/dist/Store/codeFilter.d.ts +4 -4
  69. package/dist/Store/codeFilter.d.ts.map +1 -1
  70. package/dist/Store/codeFilter.js +6 -4
  71. package/dist/Store/index.d.ts +6 -4
  72. package/dist/Store/index.d.ts.map +1 -1
  73. package/dist/Store/index.js +18 -5
  74. package/dist/Store/utils.d.ts +5 -2
  75. package/dist/Store/utils.d.ts.map +1 -1
  76. package/dist/Store/utils.js +9 -5
  77. package/dist/WorkflowEngineCosmos.d.ts +29 -0
  78. package/dist/WorkflowEngineCosmos.d.ts.map +1 -0
  79. package/dist/WorkflowEngineCosmos.js +542 -0
  80. package/dist/WorkflowEngineSqlite.d.ts +24 -0
  81. package/dist/WorkflowEngineSqlite.d.ts.map +1 -0
  82. package/dist/WorkflowEngineSqlite.js +550 -0
  83. package/dist/arbs.d.ts +1 -1
  84. package/dist/arbs.d.ts.map +1 -1
  85. package/dist/arbs.js +5 -3
  86. package/dist/codec.d.ts.map +1 -0
  87. package/dist/codec.js +5 -0
  88. package/dist/{adapters/cosmos-client.d.ts → cosmos-client.d.ts} +4 -2
  89. package/dist/cosmos-client.d.ts.map +1 -0
  90. package/dist/cosmos-client.js +11 -0
  91. package/dist/errorReporter.d.ts +6 -4
  92. package/dist/errorReporter.d.ts.map +1 -1
  93. package/dist/errorReporter.js +23 -27
  94. package/dist/fileUtil.d.ts +1 -1
  95. package/dist/fileUtil.d.ts.map +1 -1
  96. package/dist/fileUtil.js +2 -2
  97. package/dist/index.d.ts +2 -1
  98. package/dist/index.d.ts.map +1 -1
  99. package/dist/index.js +3 -2
  100. package/dist/internal/RequestContextMiddleware.d.ts +5 -0
  101. package/dist/internal/RequestContextMiddleware.d.ts.map +1 -0
  102. package/dist/internal/RequestContextMiddleware.js +45 -0
  103. package/dist/internal/auth.d.ts +53 -0
  104. package/dist/internal/auth.d.ts.map +1 -0
  105. package/dist/internal/auth.js +180 -0
  106. package/dist/internal/events.d.ts +11 -0
  107. package/dist/internal/events.d.ts.map +1 -0
  108. package/dist/internal/events.js +49 -0
  109. package/dist/internal/health.d.ts.map +1 -0
  110. package/dist/internal/health.js +5 -0
  111. package/dist/{api/layerUtils.d.ts → layerUtils.d.ts} +14 -6
  112. package/dist/layerUtils.d.ts.map +1 -0
  113. package/dist/layerUtils.js +17 -0
  114. package/dist/logger/jsonLogger.d.ts +1 -1
  115. package/dist/logger/jsonLogger.d.ts.map +1 -1
  116. package/dist/logger/jsonLogger.js +5 -3
  117. package/dist/logger/logFmtLogger.d.ts +1 -1
  118. package/dist/logger/logFmtLogger.d.ts.map +1 -1
  119. package/dist/logger/logFmtLogger.js +3 -3
  120. package/dist/logger/shared.d.ts +2 -2
  121. package/dist/logger/shared.d.ts.map +1 -1
  122. package/dist/logger/shared.js +5 -5
  123. package/dist/logger.d.ts.map +1 -1
  124. package/dist/{adapters/memQueue.d.ts → memQueue.d.ts} +4 -2
  125. package/dist/memQueue.d.ts.map +1 -0
  126. package/dist/memQueue.js +21 -0
  127. package/dist/middlewares.d.ts.map +1 -0
  128. package/dist/{api/middlewares.js → middlewares.js} +1 -1
  129. package/dist/{adapters/mongo-client.d.ts → mongo-client.d.ts} +3 -2
  130. package/dist/mongo-client.d.ts.map +1 -0
  131. package/dist/mongo-client.js +15 -0
  132. package/dist/otel.d.ts +75 -0
  133. package/dist/otel.d.ts.map +1 -0
  134. package/dist/otel.js +65 -0
  135. package/dist/rateLimit.d.ts +11 -3
  136. package/dist/rateLimit.d.ts.map +1 -1
  137. package/dist/rateLimit.js +7 -12
  138. package/dist/{adapters/redis-client.d.ts → redis-client.d.ts} +5 -2
  139. package/dist/redis-client.d.ts.map +1 -0
  140. package/dist/redis-client.js +98 -0
  141. package/dist/{api/reportError.d.ts → reportError.d.ts} +1 -1
  142. package/dist/reportError.d.ts.map +1 -0
  143. package/dist/reportError.js +28 -0
  144. package/dist/{api/routing → routing}/middleware/RouterMiddleware.d.ts +4 -3
  145. package/dist/routing/middleware/RouterMiddleware.d.ts.map +1 -0
  146. package/dist/{api/routing → routing}/middleware/RouterMiddleware.js +1 -1
  147. package/dist/routing/middleware/middleware.d.ts +48 -0
  148. package/dist/routing/middleware/middleware.d.ts.map +1 -0
  149. package/dist/routing/middleware/middleware.js +128 -0
  150. package/dist/{api/routing → routing}/middleware.d.ts +0 -1
  151. package/dist/routing/middleware.d.ts.map +1 -0
  152. package/dist/{api/routing → routing}/middleware.js +1 -2
  153. package/dist/routing/schema/jwt.d.ts.map +1 -0
  154. package/dist/routing/schema/jwt.js +13 -0
  155. package/dist/routing/tsort.d.ts.map +1 -0
  156. package/dist/routing/tsort.js +51 -0
  157. package/dist/{api/routing → routing}/utils.d.ts +3 -3
  158. package/dist/routing/utils.d.ts.map +1 -0
  159. package/dist/routing/utils.js +45 -0
  160. package/dist/routing.d.ts +182 -0
  161. package/dist/routing.d.ts.map +1 -0
  162. package/dist/routing.js +235 -0
  163. package/dist/test.d.ts +2 -2
  164. package/dist/test.d.ts.map +1 -1
  165. package/dist/test.js +2 -2
  166. package/dist/util.d.ts.map +1 -0
  167. package/dist/util.js +14 -0
  168. package/docs/cluster-storage.md +26 -0
  169. package/docs/workflow-engine.md +262 -0
  170. package/examples/query.ts +47 -39
  171. package/package.json +33 -352
  172. package/src/CUPS.ts +53 -14
  173. package/src/ClusterCosmos.ts +1118 -0
  174. package/src/ClusterServiceBus.ts +242 -0
  175. package/src/{api/ContextProvider.ts → ContextProvider.ts} +20 -17
  176. package/src/Emailer/Sendgrid.ts +83 -60
  177. package/src/Emailer/fake.ts +4 -4
  178. package/src/MainFiberSet.ts +15 -13
  179. package/src/QueueMaker/SQLQueue.ts +154 -157
  180. package/src/QueueMaker/errors.ts +3 -1
  181. package/src/QueueMaker/memQueue.ts +115 -109
  182. package/src/QueueMaker/sbqueue.ts +80 -92
  183. package/src/RequestFiberSet.ts +14 -9
  184. package/src/{adapters/SQL → SQL}/Model.ts +42 -41
  185. package/src/SQL.ts +1 -0
  186. package/src/ServiceBus.ts +219 -0
  187. package/src/Store/Cosmos/query.ts +218 -54
  188. package/src/Store/Cosmos.ts +529 -365
  189. package/src/Store/Disk.ts +112 -70
  190. package/src/Store/Memory.ts +365 -99
  191. package/src/Store/SQL/Pg.ts +363 -0
  192. package/src/Store/SQL/query.ts +603 -0
  193. package/src/Store/SQL.ts +746 -0
  194. package/src/Store/codeFilter.ts +8 -6
  195. package/src/Store/index.ts +25 -10
  196. package/src/Store/utils.ts +32 -25
  197. package/src/WorkflowEngineCosmos.ts +749 -0
  198. package/src/WorkflowEngineSqlite.ts +813 -0
  199. package/src/arbs.ts +5 -3
  200. package/src/{adapters/cosmos-client.ts → cosmos-client.ts} +5 -3
  201. package/src/errorReporter.ts +68 -78
  202. package/src/fileUtil.ts +1 -1
  203. package/src/index.ts +2 -1
  204. package/src/{api/internal → internal}/RequestContextMiddleware.ts +23 -6
  205. package/src/internal/auth.ts +272 -0
  206. package/src/{api/internal → internal}/events.ts +22 -13
  207. package/src/{api/layerUtils.ts → layerUtils.ts} +14 -10
  208. package/src/logger/jsonLogger.ts +5 -3
  209. package/src/logger/logFmtLogger.ts +3 -3
  210. package/src/logger/shared.ts +5 -4
  211. package/src/{adapters/memQueue.ts → memQueue.ts} +5 -4
  212. package/src/middlewares.ts +10 -0
  213. package/src/{adapters/mongo-client.ts → mongo-client.ts} +4 -2
  214. package/src/otel.ts +152 -0
  215. package/src/rateLimit.ts +34 -23
  216. package/src/{adapters/redis-client.ts → redis-client.ts} +7 -3
  217. package/src/{api/reportError.ts → reportError.ts} +3 -2
  218. package/src/{api/routing → routing}/middleware/RouterMiddleware.ts +5 -4
  219. package/src/{api/routing → routing}/middleware/middleware.ts +62 -17
  220. package/src/routing/middleware.ts +4 -0
  221. package/src/{api/routing → routing}/schema/jwt.ts +2 -1
  222. package/src/{api/routing → routing}/utils.ts +2 -1
  223. package/src/routing.ts +766 -0
  224. package/src/test.ts +4 -4
  225. package/src/vitest.ts +1 -1
  226. package/test/auth.test.ts +101 -0
  227. package/test/cluster-cosmos.test.ts +612 -0
  228. package/test/cluster-servicebus.test.ts +180 -0
  229. package/test/cluster-sqlite.test.ts +205 -0
  230. package/test/contextProvider.test.ts +15 -12
  231. package/test/controller.test.ts +28 -32
  232. package/test/cosmos-query.test.ts +159 -0
  233. package/test/dist/auth.test.d.ts.map +1 -0
  234. package/test/dist/cluster-cosmos.test.d.ts.map +1 -0
  235. package/test/dist/cluster-servicebus.test.d.ts.map +1 -0
  236. package/test/dist/cluster-sqlite.test.d.ts.map +1 -0
  237. package/test/dist/contextProvider.test.d.ts.map +1 -1
  238. package/test/dist/controller.test.d.ts.map +1 -1
  239. package/test/dist/cosmos-query.test.d.ts.map +1 -0
  240. package/test/dist/fixtures.d.ts +29 -11
  241. package/test/dist/fixtures.d.ts.map +1 -1
  242. package/test/dist/fixtures.js +17 -10
  243. package/test/dist/query.test.d.ts.map +1 -1
  244. package/test/dist/rawQuery.test.d.ts.map +1 -1
  245. package/test/dist/repository-ext.test.d.ts.map +1 -0
  246. package/test/dist/requires.test.d.ts.map +1 -1
  247. package/test/dist/router-generator.test.d.ts.map +1 -0
  248. package/test/dist/routing-interruptibility.test.d.ts.map +1 -0
  249. package/test/dist/rpc-context-map-streaming.test.d.ts.map +1 -0
  250. package/test/dist/rpc-e2e-invalidation.test.d.ts.map +1 -0
  251. package/test/dist/rpc-multi-middleware.test.d.ts.map +1 -1
  252. package/test/dist/rpc-stream-fullstack.test.d.ts.map +1 -0
  253. package/test/dist/sql-store.test.d.ts.map +1 -0
  254. package/test/dist/workflow-engine-cosmos.test.d.ts.map +1 -0
  255. package/test/dist/workflow-engine-sqlite.test.d.ts.map +1 -0
  256. package/test/fixtures.ts +16 -9
  257. package/test/layerUtils.test.ts +2 -2
  258. package/test/query.test.ts +905 -40
  259. package/test/rawQuery.test.ts +340 -22
  260. package/test/repository-ext.test.ts +62 -0
  261. package/test/requires.test.ts +10 -5
  262. package/test/router-generator.test.ts +187 -0
  263. package/test/routing-interruptibility.test.ts +66 -0
  264. package/test/rpc-context-map-streaming.test.ts +262 -0
  265. package/test/rpc-e2e-invalidation.test.ts +256 -0
  266. package/test/rpc-multi-middleware.test.ts +85 -10
  267. package/test/rpc-stream-fullstack.test.ts +304 -0
  268. package/test/sql-store.test.ts +1711 -0
  269. package/test/validateSample.test.ts +26 -14
  270. package/test/workflow-engine-cosmos.test.ts +345 -0
  271. package/test/workflow-engine-sqlite.test.ts +297 -0
  272. package/tsconfig.examples.json +1 -1
  273. package/tsconfig.json +3 -1
  274. package/tsconfig.src.json +35 -35
  275. package/tsconfig.test.json +2 -2
  276. package/dist/Emailer/service.d.ts +0 -55
  277. package/dist/Emailer/service.d.ts.map +0 -1
  278. package/dist/Emailer/service.js +0 -6
  279. package/dist/Emailer.d.ts +0 -2
  280. package/dist/Emailer.d.ts.map +0 -1
  281. package/dist/Emailer.js +0 -2
  282. package/dist/Model/Repository/ext.d.ts +0 -41
  283. package/dist/Model/Repository/ext.d.ts.map +0 -1
  284. package/dist/Model/Repository/ext.js +0 -65
  285. package/dist/Model/Repository/internal/internal.d.ts +0 -59
  286. package/dist/Model/Repository/internal/internal.d.ts.map +0 -1
  287. package/dist/Model/Repository/internal/internal.js +0 -316
  288. package/dist/Model/Repository/legacy.d.ts +0 -19
  289. package/dist/Model/Repository/legacy.d.ts.map +0 -1
  290. package/dist/Model/Repository/legacy.js +0 -2
  291. package/dist/Model/Repository/makeRepo.d.ts +0 -49
  292. package/dist/Model/Repository/makeRepo.d.ts.map +0 -1
  293. package/dist/Model/Repository/makeRepo.js +0 -24
  294. package/dist/Model/Repository/service.d.ts +0 -89
  295. package/dist/Model/Repository/service.d.ts.map +0 -1
  296. package/dist/Model/Repository/service.js +0 -2
  297. package/dist/Model/Repository/validation.d.ts +0 -42
  298. package/dist/Model/Repository/validation.d.ts.map +0 -1
  299. package/dist/Model/Repository/validation.js +0 -32
  300. package/dist/Model/Repository.d.ts +0 -6
  301. package/dist/Model/Repository.d.ts.map +0 -1
  302. package/dist/Model/Repository.js +0 -6
  303. package/dist/Model/dsl.d.ts +0 -32
  304. package/dist/Model/dsl.d.ts.map +0 -1
  305. package/dist/Model/dsl.js +0 -44
  306. package/dist/Model/filter/filterApi.d.ts +0 -30
  307. package/dist/Model/filter/filterApi.d.ts.map +0 -1
  308. package/dist/Model/filter/filterApi.js +0 -2
  309. package/dist/Model/filter/types/errors.d.ts +0 -29
  310. package/dist/Model/filter/types/errors.d.ts.map +0 -1
  311. package/dist/Model/filter/types/errors.js +0 -2
  312. package/dist/Model/filter/types/fields.d.ts +0 -15
  313. package/dist/Model/filter/types/fields.d.ts.map +0 -1
  314. package/dist/Model/filter/types/fields.js +0 -2
  315. package/dist/Model/filter/types/path/common.d.ts +0 -316
  316. package/dist/Model/filter/types/path/common.d.ts.map +0 -1
  317. package/dist/Model/filter/types/path/common.js +0 -2
  318. package/dist/Model/filter/types/path/eager.d.ts +0 -95
  319. package/dist/Model/filter/types/path/eager.d.ts.map +0 -1
  320. package/dist/Model/filter/types/path/eager.js +0 -31
  321. package/dist/Model/filter/types/path/index.d.ts +0 -4
  322. package/dist/Model/filter/types/path/index.d.ts.map +0 -1
  323. package/dist/Model/filter/types/path/index.js +0 -3
  324. package/dist/Model/filter/types/utils.d.ts +0 -79
  325. package/dist/Model/filter/types/utils.d.ts.map +0 -1
  326. package/dist/Model/filter/types/utils.js +0 -2
  327. package/dist/Model/filter/types/validator.d.ts +0 -30
  328. package/dist/Model/filter/types/validator.d.ts.map +0 -1
  329. package/dist/Model/filter/types/validator.js +0 -2
  330. package/dist/Model/filter/types.d.ts +0 -5
  331. package/dist/Model/filter/types.d.ts.map +0 -1
  332. package/dist/Model/filter/types.js +0 -7
  333. package/dist/Model/query/dsl.d.ts +0 -248
  334. package/dist/Model/query/dsl.d.ts.map +0 -1
  335. package/dist/Model/query/dsl.js +0 -104
  336. package/dist/Model/query/new-kid-interpreter.d.ts +0 -28
  337. package/dist/Model/query/new-kid-interpreter.d.ts.map +0 -1
  338. package/dist/Model/query/new-kid-interpreter.js +0 -165
  339. package/dist/Model/query.d.ts +0 -15
  340. package/dist/Model/query.d.ts.map +0 -1
  341. package/dist/Model/query.js +0 -3
  342. package/dist/Model.d.ts +0 -4
  343. package/dist/Model.d.ts.map +0 -1
  344. package/dist/Model.js +0 -4
  345. package/dist/Operations.d.ts +0 -55
  346. package/dist/Operations.d.ts.map +0 -1
  347. package/dist/Operations.js +0 -102
  348. package/dist/OperationsRepo.d.ts +0 -41
  349. package/dist/OperationsRepo.d.ts.map +0 -1
  350. package/dist/OperationsRepo.js +0 -14
  351. package/dist/QueueMaker/service.d.ts +0 -11
  352. package/dist/QueueMaker/service.d.ts.map +0 -1
  353. package/dist/QueueMaker/service.js +0 -4
  354. package/dist/RequestContext.d.ts +0 -63
  355. package/dist/RequestContext.d.ts.map +0 -1
  356. package/dist/RequestContext.js +0 -49
  357. package/dist/Store/ContextMapContainer.d.ts +0 -14
  358. package/dist/Store/ContextMapContainer.d.ts.map +0 -1
  359. package/dist/Store/ContextMapContainer.js +0 -16
  360. package/dist/Store/service.d.ts +0 -108
  361. package/dist/Store/service.d.ts.map +0 -1
  362. package/dist/Store/service.js +0 -71
  363. package/dist/Store.d.ts +0 -2
  364. package/dist/Store.d.ts.map +0 -1
  365. package/dist/Store.js +0 -2
  366. package/dist/adapters/SQL/Model.d.ts.map +0 -1
  367. package/dist/adapters/SQL/Model.js +0 -478
  368. package/dist/adapters/SQL.d.ts.map +0 -1
  369. package/dist/adapters/ServiceBus.d.ts.map +0 -1
  370. package/dist/adapters/ServiceBus.js +0 -99
  371. package/dist/adapters/cosmos-client.d.ts.map +0 -1
  372. package/dist/adapters/cosmos-client.js +0 -9
  373. package/dist/adapters/index.d.ts +0 -2
  374. package/dist/adapters/index.d.ts.map +0 -1
  375. package/dist/adapters/index.js +0 -2
  376. package/dist/adapters/logger.d.ts +0 -9
  377. package/dist/adapters/logger.d.ts.map +0 -1
  378. package/dist/adapters/logger.js +0 -3
  379. package/dist/adapters/memQueue.d.ts.map +0 -1
  380. package/dist/adapters/memQueue.js +0 -20
  381. package/dist/adapters/mongo-client.d.ts.map +0 -1
  382. package/dist/adapters/mongo-client.js +0 -13
  383. package/dist/adapters/redis-client.d.ts.map +0 -1
  384. package/dist/adapters/redis-client.js +0 -94
  385. package/dist/api/ContextProvider.d.ts +0 -31
  386. package/dist/api/ContextProvider.d.ts.map +0 -1
  387. package/dist/api/ContextProvider.js +0 -38
  388. package/dist/api/codec.d.ts.map +0 -1
  389. package/dist/api/codec.js +0 -5
  390. package/dist/api/internal/RequestContextMiddleware.d.ts +0 -5
  391. package/dist/api/internal/RequestContextMiddleware.d.ts.map +0 -1
  392. package/dist/api/internal/RequestContextMiddleware.js +0 -35
  393. package/dist/api/internal/auth.d.ts +0 -15
  394. package/dist/api/internal/auth.d.ts.map +0 -1
  395. package/dist/api/internal/auth.js +0 -47
  396. package/dist/api/internal/events.d.ts +0 -9
  397. package/dist/api/internal/events.d.ts.map +0 -1
  398. package/dist/api/internal/events.js +0 -42
  399. package/dist/api/internal/health.d.ts.map +0 -1
  400. package/dist/api/internal/health.js +0 -5
  401. package/dist/api/layerUtils.d.ts.map +0 -1
  402. package/dist/api/layerUtils.js +0 -16
  403. package/dist/api/middlewares.d.ts.map +0 -1
  404. package/dist/api/reportError.d.ts.map +0 -1
  405. package/dist/api/reportError.js +0 -27
  406. package/dist/api/routing/middleware/RouterMiddleware.d.ts.map +0 -1
  407. package/dist/api/routing/middleware/middleware.d.ts +0 -9
  408. package/dist/api/routing/middleware/middleware.d.ts.map +0 -1
  409. package/dist/api/routing/middleware/middleware.js +0 -92
  410. package/dist/api/routing/middleware.d.ts.map +0 -1
  411. package/dist/api/routing/schema/jwt.d.ts.map +0 -1
  412. package/dist/api/routing/schema/jwt.js +0 -12
  413. package/dist/api/routing/tsort.d.ts.map +0 -1
  414. package/dist/api/routing/tsort.js +0 -51
  415. package/dist/api/routing/utils.d.ts.map +0 -1
  416. package/dist/api/routing/utils.js +0 -44
  417. package/dist/api/routing.d.ts +0 -138
  418. package/dist/api/routing.d.ts.map +0 -1
  419. package/dist/api/routing.js +0 -166
  420. package/dist/api/setupRequest.d.ts +0 -12
  421. package/dist/api/setupRequest.d.ts.map +0 -1
  422. package/dist/api/setupRequest.js +0 -44
  423. package/dist/api/util.d.ts.map +0 -1
  424. package/dist/api/util.js +0 -14
  425. package/eslint.config.mjs +0 -24
  426. package/src/Emailer/service.ts +0 -52
  427. package/src/Emailer.ts +0 -1
  428. package/src/Model/Repository/ext.ts +0 -283
  429. package/src/Model/Repository/internal/internal.ts +0 -577
  430. package/src/Model/Repository/legacy.ts +0 -27
  431. package/src/Model/Repository/makeRepo.ts +0 -139
  432. package/src/Model/Repository/service.ts +0 -627
  433. package/src/Model/Repository/validation.ts +0 -31
  434. package/src/Model/Repository.ts +0 -5
  435. package/src/Model/dsl.ts +0 -128
  436. package/src/Model/filter/filterApi.ts +0 -60
  437. package/src/Model/filter/types/errors.ts +0 -47
  438. package/src/Model/filter/types/fields.ts +0 -50
  439. package/src/Model/filter/types/path/common.ts +0 -404
  440. package/src/Model/filter/types/path/eager.ts +0 -298
  441. package/src/Model/filter/types/path/index.ts +0 -4
  442. package/src/Model/filter/types/utils.ts +0 -128
  443. package/src/Model/filter/types/validator.ts +0 -46
  444. package/src/Model/filter/types.ts +0 -6
  445. package/src/Model/query/dsl.ts +0 -2110
  446. package/src/Model/query/new-kid-interpreter.ts +0 -210
  447. package/src/Model/query.ts +0 -13
  448. package/src/Model.ts +0 -3
  449. package/src/Operations.ts +0 -235
  450. package/src/OperationsRepo.ts +0 -16
  451. package/src/QueueMaker/service.ts +0 -17
  452. package/src/RequestContext.ts +0 -63
  453. package/src/Store/ContextMapContainer.ts +0 -20
  454. package/src/Store/index.test.ts.bak +0 -112
  455. package/src/Store/service.ts +0 -184
  456. package/src/Store.ts +0 -1
  457. package/src/adapters/SQL.ts +0 -1
  458. package/src/adapters/ServiceBus.ts +0 -209
  459. package/src/adapters/index.ts +0 -0
  460. package/src/adapters/logger.ts +0 -3
  461. package/src/api/internal/auth.ts +0 -68
  462. package/src/api/middlewares.ts +0 -10
  463. package/src/api/routing/middleware.ts +0 -6
  464. package/src/api/routing.ts +0 -598
  465. package/src/api/setupRequest.ts +0 -84
  466. package/tsconfig.json.bak +0 -12
  467. /package/dist/{adapters/SQL.d.ts → SQL.d.ts} +0 -0
  468. /package/dist/{api/codec.d.ts → codec.d.ts} +0 -0
  469. /package/dist/{api/internal → internal}/health.d.ts +0 -0
  470. /package/dist/{api/middlewares.d.ts → middlewares.d.ts} +0 -0
  471. /package/dist/{api/routing → routing}/schema/jwt.d.ts +0 -0
  472. /package/dist/{api/routing → routing}/tsort.d.ts +0 -0
  473. /package/dist/{api/util.d.ts → util.d.ts} +0 -0
  474. /package/src/{api/codec.ts → codec.ts} +0 -0
  475. /package/src/{api/internal → internal}/health.ts +0 -0
  476. /package/src/{api/routing → routing}/tsort.ts +0 -0
  477. /package/src/{api/util.ts → util.ts} +0 -0
package/src/routing.ts ADDED
@@ -0,0 +1,766 @@
1
+ /* eslint-disable @typescript-eslint/no-unsafe-assignment */
2
+ /* eslint-disable @typescript-eslint/no-unsafe-argument */
3
+ /* eslint-disable @typescript-eslint/no-empty-object-type */
4
+ /* eslint-disable @typescript-eslint/no-explicit-any */
5
+ import type { NonEmptyReadonlyArray } from "effect-app/Array"
6
+ import { getMeta } from "effect-app/client"
7
+ import * as Config from "effect-app/Config"
8
+ import * as Effect from "effect-app/Effect"
9
+ import { type HttpHeaders } from "effect-app/http"
10
+ import * as Layer from "effect-app/Layer"
11
+ import { Invalidation } from "effect-app/rpc"
12
+ import { type GetEffectContext, type GetEffectError, type RpcContextMap } from "effect-app/rpc/RpcContextMap"
13
+ import * as S from "effect-app/Schema"
14
+ import { type TypeTestId } from "effect-app/TypeTest"
15
+ import { typedKeysOf, typedValuesOf } from "effect-app/utils"
16
+ import * as Predicate from "effect/Predicate"
17
+ import * as Ref from "effect/Ref"
18
+ import type * as Scope from "effect/Scope"
19
+ import * as Stream from "effect/Stream"
20
+ import { Rpc, RpcGroup, type RpcSerialization, RpcServer } from "effect/unstable/rpc"
21
+ import { type LayerUtils } from "./layerUtils.ts"
22
+ import { RequestType as RequestTypeAnnotation } from "./routing/middleware.ts"
23
+
24
+ export * from "./routing/middleware.ts"
25
+
26
+ export const applyRequestTypeInterruptibility = <A, E, R>(
27
+ requestType: "command" | "query",
28
+ effect: Effect.Effect<A, E, R>
29
+ ) => requestType === "command" ? Rpc.uninterruptible(effect) : effect
30
+
31
+ // it's the result of extending S.Req setting success, config
32
+ // it's a schema plus some metadata
33
+ export type AnyRequestModule = S.Top & {
34
+ _tag: string // unique identifier for the request module
35
+ type: "command" | "query"
36
+ stream: boolean
37
+ config: any // ?
38
+ success: S.Top // validates the success response
39
+ error: S.Top // validates the failure response
40
+ }
41
+
42
+ // builder pattern for adding actions to a router until all actions are added
43
+ export interface AddAction<Actions extends AnyRequestModule, Accum extends Record<string, any> = {}> {
44
+ accum: Accum
45
+ add<A extends Handler<Actions, any, any>>(
46
+ a: A
47
+ ): A extends Handler<infer M extends AnyRequestModule, any, any> ? Exclude<Actions, M> extends never ?
48
+ & Accum
49
+ & { [K in M["_tag"]]: A }
50
+ :
51
+ & AddAction<
52
+ Exclude<Actions, M>,
53
+ & Accum
54
+ & { [K in M["_tag"]]: A }
55
+ >
56
+ & Accum
57
+ & { [K in M["_tag"]]: A }
58
+ : never
59
+ }
60
+
61
+ // note:
62
+ // "d" stands for decoded i.e. the Type
63
+ // "raw" stands for encoded i.e. the Encoded
64
+ const RequestTypes = {
65
+ DECODED: "d",
66
+ RAW: "raw"
67
+ } as const
68
+ type RequestType = typeof RequestTypes[keyof typeof RequestTypes]
69
+
70
+ type GetSuccess<T> = T extends { success: S.Top } ? T["success"] : typeof S.Void
71
+ type GetFailure<T extends { error?: S.Top }> = T["error"] extends never ? typeof S.Never : T["error"]
72
+
73
+ type GetSuccessShape<Action extends { success?: S.Top }, RT extends RequestType> = {
74
+ d: GetSuccess<Action>["Type"]
75
+ raw: GetSuccess<Action>["Encoded"]
76
+ }[RT]
77
+
78
+ interface HandlerBase<Action extends AnyRequestModule, RT extends RequestType, A, E, R> {
79
+ new(): {}
80
+ _tag: RT
81
+ stack: string
82
+ handler: (
83
+ req: Action["Type"],
84
+ headers: HttpHeaders.Headers
85
+ ) => Effect.Effect<A, E, R> | Stream.Stream<A, E, R>
86
+ }
87
+
88
+ export interface Handler<Action extends AnyRequestModule, RT extends RequestType, R> extends
89
+ HandlerBase<
90
+ Action,
91
+ RT,
92
+ GetSuccessShape<Action, RT>,
93
+ GetFailure<Action>["Type"] | S.SchemaError,
94
+ R
95
+ >
96
+ {}
97
+
98
+ type AnyHandler<Action extends AnyRequestModule> = Handler<
99
+ Action,
100
+ RequestType,
101
+ any // R
102
+ >
103
+
104
+ // a Resource is typically the whole module with all the exported sh*t
105
+ // this helper retrieves only the entities (classes) which are built by extending S.Req
106
+ type FilterRequestModules<T> = {
107
+ [K in keyof T as T[K] extends AnyRequestModule ? K : never]: T[K]
108
+ }
109
+
110
+ type RpcRouteR<
111
+ T extends [any, (req: any, headers: HttpHeaders.Headers) => Effect.Effect<any, any, any>]
112
+ > = T extends [
113
+ any,
114
+ (...args: any[]) => Effect.Effect<any, any, infer R>
115
+ ] ? R
116
+ : never
117
+
118
+ type EffectMatch<
119
+ Resource extends Record<string, any>,
120
+ RequestContextMap extends Record<string, any>,
121
+ RT extends RequestType,
122
+ Key extends keyof Resource
123
+ > = <A extends GetSuccessShape<Resource[Key], RT>, R2 = never, E = never>(
124
+ f: (req: Resource[Key]["Type"]) => Effect.Effect<A, E, R2>
125
+ ) => Handler<
126
+ Resource[Key],
127
+ RT,
128
+ Exclude<
129
+ Exclude<R2, GetEffectContext<RequestContextMap, Resource[Key]["config"]>>,
130
+ Scope.Scope
131
+ >
132
+ >
133
+
134
+ type StreamMatch<
135
+ Resource extends Record<string, any>,
136
+ RequestContextMap extends Record<string, any>,
137
+ RT extends RequestType,
138
+ Key extends keyof Resource
139
+ > = <A extends GetSuccessShape<Resource[Key], RT>, R2 = never, E = never>(
140
+ f: (req: Resource[Key]["Type"]) => Stream.Stream<A, E, R2>
141
+ ) => Handler<
142
+ Resource[Key],
143
+ RT,
144
+ Exclude<
145
+ Exclude<R2, GetEffectContext<RequestContextMap, Resource[Key]["config"]>>,
146
+ Scope.Scope
147
+ >
148
+ >
149
+
150
+ // Stream resources only accept Stream / Effect<Stream> handlers; non-stream resources
151
+ // only accept Effect handlers. Discriminated by the request module's `stream` flag.
152
+ type Match<
153
+ Resource extends Record<string, any>,
154
+ RequestContextMap extends Record<string, any>,
155
+ RT extends RequestType,
156
+ Key extends keyof Resource
157
+ > = Resource[Key] extends { stream: true } ? StreamMatch<Resource, RequestContextMap, RT, Key>
158
+ : EffectMatch<Resource, RequestContextMap, RT, Key>
159
+
160
+ export type RouteMatcher<
161
+ RequestContextMap extends Record<string, any>,
162
+ Resource extends Record<string, any>
163
+ > = {
164
+ // use Resource as Key over using Keys, so that the Go To on X.Action remain in tact in Controllers files
165
+ /**
166
+ * Requires the Type shape
167
+ */
168
+ [Key in keyof FilterRequestModules<Resource>]:
169
+ & Match<Resource, RequestContextMap, typeof RequestTypes.DECODED, Key>
170
+ & {
171
+ success: Resource[Key]["success"]
172
+ successRaw: S.Codec<Resource[Key]["success"]["Encoded"]>
173
+ error: Resource[Key]["error"]
174
+ /**
175
+ * Requires the Encoded shape (e.g directly undecoded from DB, so that we don't do multiple Decode/Encode)
176
+ */
177
+ raw: Match<Resource, RequestContextMap, typeof RequestTypes.RAW, Key>
178
+ }
179
+ }
180
+
181
+ export const skipOnProd = Effect
182
+ .gen(function*() {
183
+ const env = yield* Config.string("env")
184
+ return env !== "prod"
185
+ })
186
+ .pipe(Effect.orDie)
187
+
188
+ // Type helpers to extract middleware information from a resource's request classes.
189
+ type MiddlewareOf<M extends Record<string, any>> = Exclude<
190
+ { [K in keyof M]: M[K] extends { readonly middleware?: infer MW } ? NonNullable<MW> : never }[keyof M],
191
+ never
192
+ >
193
+ type ProvidesOf<MW> = MW extends { readonly provides: infer P } ? P : never
194
+ type RequestContextMapOf<MW> = MW extends {
195
+ requestContextMap: infer RCM extends Record<string, RpcContextMap.Any>
196
+ } ? RCM
197
+ : Record<string, never>
198
+ type LayerNormalize<L> = L extends Layer.Layer<any, infer E, infer R> ? Layer.Layer<never, E, R>
199
+ : Layer.Layer<never, never, never>
200
+ type LayerSuccess<L> = L extends Layer.Layer<infer A, any, any> ? A : never
201
+
202
+ /**
203
+ * Middleware tags are typically passed to `makeRpcClient` as the class value, so
204
+ * the captured `MW` is a constructor type. Layers carry the *instance* type as
205
+ * their success channel. Bridge the two so the constraint compares like-with-like.
206
+ *
207
+ * Effect middleware classes declare `new(_: never): Shape` which the standard
208
+ * `T extends abstract new (...args: any) => infer I` form sometimes fails to
209
+ * narrow. Use the `prototype` member instead — it is always the instance type.
210
+ */
211
+ type MWService<MW> = MW extends { readonly prototype: infer P } ? P : MW
212
+
213
+ /**
214
+ * Type-level guard: emits a structural mismatch on `Resource` when the middleware
215
+ * service identifier extracted from the resource's request classes is not provided
216
+ * by the layer passed to `makeRouter`. When `MW` is `never` (no middleware on the
217
+ * resource) or already a subtype of the layer's success, this resolves to `unknown`
218
+ * and intersects harmlessly with `Resource`.
219
+ */
220
+ type EnsureMiddlewareProvided<Live, MW> = [MW] extends [never] ? unknown
221
+ : [MWService<MW>] extends [LayerSuccess<Live>] ? unknown
222
+ : {
223
+ readonly __middlewareNotProvidedByRouterLayer: {
224
+ readonly expected: MWService<MW>
225
+ readonly providedByLayer: LayerSuccess<Live>
226
+ }
227
+ }
228
+
229
+ // Safe wrappers that check the constraint before calling GetEffectContext/GetEffectError.
230
+ // These avoid TypeScript constraint errors when the RC map type is deferred (generic).
231
+ type SafeGetEffectContext<RCM, Config> = RCM extends Record<string, RpcContextMap.Any> ? GetEffectContext<RCM, Config>
232
+ : never
233
+ type SafeGetEffectError<RCM, Config> = RCM extends Record<string, RpcContextMap.Any> ? GetEffectError<RCM, Config>
234
+ : never
235
+
236
+ export const makeRouter = <Live extends Layer.Layer<any, any, any> = Layer.Layer<any, never, never>>(
237
+ middlewareLive?: Live
238
+ ) => {
239
+ type ResourceMWDefault = LayerNormalize<Live>
240
+
241
+ /**
242
+ * Create a Router for specified resource.
243
+ * Middleware schema/tag is read from the request classes (stored via `makeRpcClient`).
244
+ * The middleware **Live** layer is the one passed to `makeRouter`.
245
+ * If `check` is provided, the router will only be created if the effect succeeds with true.
246
+ */
247
+ function matchFor<
248
+ const Resource extends Record<string, any>,
249
+ MW = MiddlewareOf<Resource>
250
+ >(
251
+ rsc: Resource & EnsureMiddlewareProvided<Live, MW>,
252
+ options?: { check?: Effect.Effect<boolean> }
253
+ ) {
254
+ // MW is a defaulted type parameter so TypeScript evaluates MiddlewareOf<Resource>
255
+ // eagerly at each call site, producing a concrete type instead of a deferred conditional.
256
+ type ResourceRequestContextMap = RequestContextMapOf<MW>
257
+ type ResourceContextProviderA = ProvidesOf<MW>
258
+
259
+ type HandlerContext<Action extends AnyRequestModule> =
260
+ | SafeGetEffectContext<ResourceRequestContextMap, Action["config"]>
261
+ | ResourceContextProviderA
262
+
263
+ type HandlerWithInputGen<
264
+ Action extends AnyRequestModule,
265
+ RT extends RequestType
266
+ > = (
267
+ req: Action["Type"]
268
+ ) => Generator<
269
+ Effect.Effect<
270
+ any,
271
+ GetFailure<Action>["Type"] | S.SchemaError,
272
+ // the actual implementation of the handler may just require the dynamic context provided by the middleware
273
+ // and the per request context provided by the context provider
274
+ HandlerContext<Action>
275
+ >,
276
+ GetSuccessShape<Action, RT>,
277
+ never
278
+ >
279
+
280
+ type HandlerWithInputEff<
281
+ Action extends AnyRequestModule,
282
+ RT extends RequestType
283
+ > = (
284
+ req: Action["Type"]
285
+ ) => Effect.Effect<
286
+ GetSuccessShape<Action, RT>,
287
+ GetFailure<Action>["Type"] | S.SchemaError,
288
+ // the actual implementation of the handler may just require the dynamic context provided by the middleware
289
+ // and the per request context provided by the context provider
290
+ HandlerContext<Action>
291
+ >
292
+
293
+ type HandlerWithInputStream<
294
+ Action extends AnyRequestModule,
295
+ RT extends RequestType
296
+ > = (
297
+ req: Action["Type"]
298
+ ) => Stream.Stream<
299
+ GetSuccessShape<Action, RT>,
300
+ GetFailure<Action>["Type"] | S.SchemaError,
301
+ HandlerContext<Action>
302
+ >
303
+
304
+ // Stream resources only accept `(req) => Stream`; non-stream only Effect / Generator.
305
+ type Handlers<Action extends AnyRequestModule, RT extends RequestType> = Action extends { stream: true }
306
+ ? HandlerWithInputStream<Action, RT>
307
+ : HandlerWithInputGen<Action, RT> | HandlerWithInputEff<Action, RT>
308
+
309
+ type HandlersDecoded<Action extends AnyRequestModule> = Handlers<Action, typeof RequestTypes.DECODED>
310
+
311
+ type HandlersRaw<Action extends AnyRequestModule> = Action extends { stream: true }
312
+ ? { raw: HandlerWithInputStream<Action, typeof RequestTypes.RAW> }
313
+ :
314
+ | { raw: HandlerWithInputGen<Action, typeof RequestTypes.RAW> }
315
+ | { raw: HandlerWithInputEff<Action, typeof RequestTypes.RAW> }
316
+
317
+ type AnyHandlers<Action extends AnyRequestModule> = HandlersRaw<Action> | HandlersDecoded<Action>
318
+
319
+ const meta = getMeta(rsc)
320
+
321
+ type RequestModules = FilterRequestModules<Resource>
322
+ const requestModules = typedKeysOf(rsc).reduce((acc, cur) => {
323
+ if (Predicate.isObjectKeyword(rsc[cur]) && rsc[cur]["success"]) {
324
+ acc[cur as keyof RequestModules] = rsc[cur]
325
+ }
326
+ return acc
327
+ }, {} as RequestModules)
328
+
329
+ const routeMatcher = typedKeysOf(requestModules).reduce(
330
+ (prev, cur) => {
331
+ ;(prev as any)[cur] = Object.assign((handlerImpl: any) => {
332
+ // handlerImpl is the actual handler implementation
333
+ if (handlerImpl[Symbol.toStringTag] === "GeneratorFunction") handlerImpl = Effect.fnUntraced(handlerImpl)
334
+ const stack = new Error().stack?.split("\n").slice(2).join("\n")
335
+ // oxlint-disable-next-line typescript/no-extraneous-class
336
+ return class {
337
+ static request = rsc[cur]
338
+ static stack = stack
339
+ static _tag = RequestTypes.DECODED
340
+ static handler = handlerImpl
341
+ }
342
+ }, {
343
+ success: rsc[cur].success,
344
+ successRaw: S.toEncoded(rsc[cur].success),
345
+ error: rsc[cur].error,
346
+ raw: // "Raw" variations are for when you don't want to decode just to encode it again on the response
347
+ // e.g for direct projection from DB
348
+ // but more importantly, to skip Effectful decoders, like to resolve relationships from the database or remote client.
349
+ (handlerImpl: any) => {
350
+ if (handlerImpl[Symbol.toStringTag] === "GeneratorFunction") handlerImpl = Effect.fnUntraced(handlerImpl)
351
+ const stack = new Error().stack?.split("\n").slice(2).join("\n")
352
+ // oxlint-disable-next-line typescript/no-extraneous-class
353
+ return class {
354
+ static request = rsc[cur]
355
+ static stack = stack
356
+ static _tag = RequestTypes.RAW
357
+ static handler = handlerImpl
358
+ }
359
+ }
360
+ })
361
+ return prev
362
+ },
363
+ {} as RouteMatcher<ResourceRequestContextMap, Resource>
364
+ )
365
+
366
+ const router3: <
367
+ const Impl extends {
368
+ [K in keyof FilterRequestModules<Resource>]: AnyHandlers<Resource[K]>
369
+ }
370
+ >(
371
+ impl: Impl
372
+ ) => {
373
+ [K in keyof Impl & keyof FilterRequestModules<Resource>]: Handler<
374
+ FilterRequestModules<Resource>[K],
375
+ Impl[K] extends { raw: any } ? typeof RequestTypes.RAW : typeof RequestTypes.DECODED,
376
+ Exclude<
377
+ Exclude<
378
+ // retrieves context R from the actual implementation of the handler
379
+ Impl[K] extends { raw: any }
380
+ ? Impl[K]["raw"] extends (...args: any[]) => Effect.Effect<any, any, infer R> ? R
381
+ : Impl[K]["raw"] extends (...args: any[]) => Stream.Stream<any, any, infer R> ? R
382
+ : Impl[K]["raw"] extends (...args: any[]) => Generator<
383
+ Effect.Effect<any, any, infer R>
384
+ > ? R
385
+ : never
386
+ : Impl[K] extends (...args: any[]) => Effect.Effect<any, any, infer R> ? R
387
+ : Impl[K] extends (...args: any[]) => Stream.Stream<any, any, infer R> ? R
388
+ : Impl[K] extends (...args: any[]) => Generator<
389
+ Effect.Effect<any, any, infer R>
390
+ > ? R
391
+ : never,
392
+ | SafeGetEffectContext<ResourceRequestContextMap, Resource[K]["config"]>
393
+ | ResourceContextProviderA
394
+ >,
395
+ Scope.Scope
396
+ >
397
+ >
398
+ } = (impl: Record<keyof RequestModules, any>) =>
399
+ typedKeysOf(impl).reduce((acc, cur) => {
400
+ acc[cur] = "raw" in impl[cur] ? routeMatcher[cur].raw(impl[cur].raw) : routeMatcher[cur](impl[cur])
401
+ return acc
402
+ }, {} as any)
403
+
404
+ const makeRoutes = <
405
+ MakeE,
406
+ MakeR,
407
+ THandlers extends {
408
+ // important to keep them separate via | for type checking!!
409
+ [K in keyof RequestModules]: AnyHandler<Resource[K]>
410
+ },
411
+ MakeDependencies extends NonEmptyReadonlyArray<Layer.Any> | never[]
412
+ >(
413
+ dependencies: MakeDependencies,
414
+ make: (
415
+ match: any
416
+ ) =>
417
+ | Effect.Effect<THandlers, MakeE, MakeR>
418
+ | Generator<Effect.Effect<any, MakeE, MakeR>, THandlers>
419
+ ) => {
420
+ const dependenciesL = (dependencies ? Layer.mergeAll(...dependencies as any) : Layer.empty) as Layer.Layer<
421
+ LayerUtils.GetLayersSuccess<MakeDependencies>,
422
+ LayerUtils.GetLayersError<MakeDependencies>,
423
+ LayerUtils.GetLayersContext<MakeDependencies>
424
+ >
425
+
426
+ const layer = Effect
427
+ .gen(function*() {
428
+ const finalMake = ((make as any)[Symbol.toStringTag] === "GeneratorFunction"
429
+ ? Effect.fnUntraced(make as any)(router3) as any
430
+ : make(router3) as any) as Effect.Effect<THandlers, MakeE, MakeR>
431
+
432
+ const controllers = yield* finalMake
433
+
434
+ // Read the middleware from the resource's request classes at runtime
435
+ const mw = meta.middleware as any
436
+
437
+ // return make.pipe(Effect.map((c) => controllers(c, dependencies)))
438
+ const mapped = typedKeysOf(requestModules).reduce((acc, cur) => {
439
+ const handler = controllers[cur as keyof typeof controllers]
440
+ const resource = rsc[cur]
441
+
442
+ acc[cur] = [
443
+ handler._tag === RequestTypes.RAW
444
+ ? class extends (resource as any) {
445
+ static success = S.toEncoded(resource.success)
446
+ } as any
447
+ : resource,
448
+ (payload: any, headers: any) => {
449
+ const result: any = handler.handler(payload, headers)
450
+ if (resource.stream) {
451
+ // Wrap stream items as { _tag: "value", value } and append a final
452
+ // { _tag: "done", metadata } chunk carrying accumulated invalidation keys.
453
+ // V2: on failure, convert to { _tag: "error", error, metadata } chunk so
454
+ // clients can invalidate queries even when the stream fails.
455
+ const keysRef = Ref.makeUnsafe<ReadonlyArray<Invalidation.InvalidationKey>>([])
456
+ const invalidationSet = Invalidation.makeInvalidationSet(keysRef)
457
+ return Stream.concat(
458
+ (result as Stream.Stream<any, any, any>).pipe(
459
+ Stream.map((item: any) => ({ _tag: "value" as const, value: item })),
460
+ Stream.provideService(Invalidation.InvalidationSet, invalidationSet),
461
+ // V3: after each value chunk, drain accumulated keys and emit a "metadata"
462
+ // chunk if any keys were collected since the last drain. This lets clients
463
+ // invalidate queries mid-stream without waiting for the "done" chunk.
464
+ Stream.flatMap((valueChunk: any) =>
465
+ Stream
466
+ .fromEffect(
467
+ Ref.getAndSet(keysRef, []).pipe(
468
+ Effect.map((keys) =>
469
+ keys.length > 0
470
+ ? [
471
+ valueChunk,
472
+ { _tag: "metadata" as const, metadata: { invalidateQueries: keys } }
473
+ ]
474
+ : [valueChunk]
475
+ )
476
+ )
477
+ )
478
+ .pipe(Stream.flatMap(Stream.fromIterable))
479
+ ),
480
+ // V2: catch stream failures and embed them in the stream as an error chunk
481
+ Stream.catch((err: any) =>
482
+ Stream.fromEffect(
483
+ Ref.get(keysRef).pipe(
484
+ Effect.flatMap((keys) =>
485
+ Effect.fail({
486
+ _tag: "error" as const,
487
+ error: err,
488
+ metadata: { invalidateQueries: keys }
489
+ })
490
+ )
491
+ )
492
+ )
493
+ )
494
+ ),
495
+ Stream.fromEffect(
496
+ Ref.get(keysRef).pipe(
497
+ Effect.map((keys) => ({ _tag: "done" as const, metadata: { invalidateQueries: keys } }))
498
+ )
499
+ )
500
+ )
501
+ }
502
+
503
+ let effect = Effect
504
+ .annotateCurrentSpan({
505
+ "rpc.system": "effect-app",
506
+ "rpc.service": meta.moduleName,
507
+ "rpc.method": resource._tag,
508
+ "code.function.name": resource._tag,
509
+ "code.namespace": meta.moduleName,
510
+ "app.rpc.type": resource.type
511
+ })
512
+ .pipe(Effect.andThen(result as Effect.Effect<unknown, unknown, unknown>))
513
+
514
+ // Commands: provide a request-scoped `InvalidationSet` and wrap both
515
+ // success (`CommandResponseWithMetaData`) and handler-thrown failure
516
+ // (`CommandFailureWithMetaData`) so the client receives accumulated
517
+ // invalidation keys on either path. Middleware-thrown errors bypass the
518
+ // wrap (they fail the outer effect before reaching this `.catch`) and
519
+ // flow raw on the Cause; client decodes them via the rpc's
520
+ // `middlewares[*].error` failure-union channel.
521
+ if (resource.type === "command") {
522
+ const keysRef = Ref.makeUnsafe<ReadonlyArray<Invalidation.InvalidationKey>>([])
523
+ const invalidationSet = Invalidation.makeInvalidationSet(keysRef)
524
+ effect = effect.pipe(
525
+ Effect.provideService(Invalidation.InvalidationSet, invalidationSet),
526
+ Effect.flatMap((value) =>
527
+ Ref.get(keysRef).pipe(
528
+ Effect.map((keys) => ({ payload: value, metadata: { invalidateQueries: keys } }) as any)
529
+ )
530
+ ),
531
+ Effect.catch((err: any) =>
532
+ Ref.get(keysRef).pipe(
533
+ Effect.flatMap((keys) =>
534
+ Effect.fail({
535
+ _tag: "CommandFailureWithMetaData" as const,
536
+ error: err,
537
+ metadata: { invalidateQueries: keys }
538
+ })
539
+ )
540
+ )
541
+ )
542
+ )
543
+ }
544
+
545
+ return applyRequestTypeInterruptibility(resource.type, effect)
546
+ }
547
+ ] as const
548
+ return acc
549
+ }, {} as any) as {
550
+ [K in keyof RequestModules]: [
551
+ Resource[K],
552
+ (
553
+ req: any,
554
+ headers: HttpHeaders.Headers
555
+ ) => Effect.Effect<
556
+ Effect.Success<ReturnType<THandlers[K]["handler"]>>,
557
+ | Effect.Error<ReturnType<THandlers[K]["handler"]>>
558
+ | SafeGetEffectError<ResourceRequestContextMap, Resource[K]["config"]>,
559
+ Exclude<
560
+ Effect.Services<ReturnType<THandlers[K]["handler"]>>,
561
+ ResourceContextProviderA | SafeGetEffectContext<ResourceRequestContextMap, Resource[K]["config"]>
562
+ >
563
+ >
564
+ ]
565
+ }
566
+
567
+ const rpcs = RpcGroup
568
+ .make(
569
+ ...typedValuesOf(mapped).map(([resource]) => {
570
+ const isStream = resource.stream
571
+ const isCommand = resource.type === "command"
572
+ return (isCommand
573
+ ? isStream
574
+ ? Invalidation.makeStreamRpc(resource._tag, {
575
+ payload: resource,
576
+ success: resource.success,
577
+ error: resource.error,
578
+ stream: true as const
579
+ })
580
+ : Invalidation.makeCommandRpc(resource._tag, {
581
+ payload: resource,
582
+ success: resource.success,
583
+ error: resource.error
584
+ })
585
+ : Rpc.make(resource._tag, {
586
+ payload: resource,
587
+ success: resource.success,
588
+ error: resource.error,
589
+ stream: isStream
590
+ }))
591
+ .annotate(mw.requestContext, resource.config ?? {})
592
+ .annotate(RequestTypeAnnotation, resource.type)
593
+ })
594
+ )
595
+ .prefix(`${meta.moduleName}.`)
596
+ .middleware(mw)
597
+
598
+ const rpc = rpcs
599
+ .toLayer(Effect.gen(function*() {
600
+ return typedValuesOf(mapped).reduce((acc, [resource, handler]) => {
601
+ acc[`${meta.moduleName}.${resource._tag}`] = handler
602
+ return acc
603
+ }, {} as Record<string, any>) as any // TODO
604
+ })) as unknown as Layer.Layer<
605
+ { [K in keyof RequestModules]: Rpc.Handler<K> },
606
+ MakeE,
607
+ RpcRouteR<typeof mapped[keyof typeof mapped]>
608
+ >
609
+
610
+ return RpcServer
611
+ .layerHttp({
612
+ group: rpcs,
613
+ path: ("/rpc/" + meta.moduleName) as `/${typeof meta.moduleName}`,
614
+ protocol: "http"
615
+ })
616
+ .pipe(Layer.provide(rpc))
617
+ })
618
+ .pipe(Layer.unwrap)
619
+
620
+ const routes = layer.pipe(
621
+ Layer.provide([
622
+ dependenciesL,
623
+ (middlewareLive ?? Layer.empty) as Layer.Layer<any, any, any>
624
+ ])
625
+ )
626
+
627
+ const check = options?.check
628
+ return check
629
+ ? Effect
630
+ .gen(function*() {
631
+ if (!(yield* check)) {
632
+ yield* Effect.logWarning(`Skipping router for module ${meta.moduleName}`)
633
+ return Layer.empty
634
+ }
635
+ return routes
636
+ })
637
+ .pipe(Layer.unwrap)
638
+ : routes
639
+ }
640
+
641
+ const effect: {
642
+ // Multiple times duplicated the "good" overload, so that errors will only mention the last overload when failing
643
+ <
644
+ const Make extends {
645
+ dependencies?: ReadonlyArray<Layer.Any>
646
+ effect: (match: typeof router3) => Generator<
647
+ Effect.Effect<
648
+ any,
649
+ any,
650
+ any
651
+ >,
652
+ { [K in keyof FilterRequestModules<Resource>]: AnyHandler<Resource[K]> }
653
+ >
654
+ /** @deprecated */
655
+ readonly ಠ_ಠ: never
656
+ }
657
+ >(
658
+ make: Make
659
+ ):
660
+ & Layer.Layer<
661
+ never,
662
+ | MakeErrors<Make>
663
+ | MakeDepsE<Make>
664
+ | Layer.Error<ResourceMWDefault>,
665
+ | MakeDepsIn<Make>
666
+ | Layer.Services<ResourceMWDefault>
667
+ | Exclude<
668
+ MakeContext<Make>,
669
+ MakeDepsOut<Make>
670
+ >
671
+ | RpcSerialization.RpcSerialization
672
+ >
673
+ & {
674
+ // just for type testing purposes
675
+ [TypeTestId]: Make
676
+ }
677
+ <
678
+ const Make extends {
679
+ dependencies?: ReadonlyArray<Layer.Any>
680
+ // v4: generators yield Yieldable with asEffect()
681
+ effect: (match: typeof router3) => Generator<
682
+ Effect.Effect<any, any, any>,
683
+ { [K in keyof FilterRequestModules<Resource>]: AnyHandler<Resource[K]> }
684
+ >
685
+ }
686
+ >(
687
+ make: Make
688
+ ):
689
+ & Layer.Layer<
690
+ never,
691
+ | MakeErrors<Make>
692
+ | MakeDepsE<Make>
693
+ | Layer.Error<ResourceMWDefault>,
694
+ | MakeDepsIn<Make>
695
+ | Layer.Services<ResourceMWDefault>
696
+ | Exclude<
697
+ MakeContext<Make>,
698
+ MakeDepsOut<Make>
699
+ >
700
+ | RpcSerialization.RpcSerialization
701
+ >
702
+ & {
703
+ // just for type testing purposes
704
+ readonly [TypeTestId]: Make
705
+ }
706
+ } =
707
+ ((make: { dependencies: any; effect: any }) =>
708
+ Object.assign(makeRoutes(make.dependencies, make.effect), { make })) as any
709
+
710
+ return effect
711
+ }
712
+
713
+ function matchAll<
714
+ T extends {
715
+ [key: string]: Layer.Layer<never, any, any>
716
+ }
717
+ >(
718
+ handlers: T
719
+ ) {
720
+ const routers = typedValuesOf(handlers)
721
+
722
+ return Layer.mergeAll(...routers as [any]) as unknown as Layer.Layer<
723
+ never,
724
+ Layer.Error<typeof handlers[keyof typeof handlers]>,
725
+ Layer.Services<typeof handlers[keyof typeof handlers]>
726
+ >
727
+ }
728
+
729
+ return {
730
+ matchAll,
731
+ Router: matchFor
732
+ }
733
+ }
734
+
735
+ export type MakeDeps<Make> = Make extends { readonly dependencies: ReadonlyArray<Layer.Any> }
736
+ ? Make["dependencies"][number]
737
+ : never
738
+
739
+ export type MakeErrors<Make> = /*Make extends { readonly effect: (_: any) => Effect.Effect<any, infer E, any> } ? E
740
+ : Make extends { readonly effect: (_: any) => Effect.Effect<any, never, any> } ? never
741
+ : */
742
+ // v4: generators yield Effect values
743
+ Make extends { readonly effect: (_: any) => Generator<Effect.Effect<any, never, any>, any> } ? never
744
+ : Make extends { readonly effect: (_: any) => Generator<Effect.Effect<any, infer E, any>, any> } ? E
745
+ : never
746
+
747
+ export type MakeContext<Make> = /*Make extends { readonly effect: (_: any) => Effect.Effect<any, any, infer R> } ? R
748
+ : Make extends { readonly effect: (_: any) => Effect.Effect<any, any, never> } ? never
749
+ : */
750
+ // v4: generators yield Effect values
751
+ Make extends { readonly effect: (_: any) => Generator<Effect.Effect<any, any, never>, any> } ? never
752
+ : Make extends { readonly effect: (_: any) => Generator<Effect.Effect<any, any, infer R>, any> } ? R
753
+ : never
754
+
755
+ export type MakeHandlers<Make, _Handlers extends Record<string, any>> = /*Make extends
756
+ { readonly effect: (_: any) => Effect.Effect<{ [K in keyof Handlers]: AnyHandler<Handlers[K]> }, any, any> }
757
+ ? Effect.Success<ReturnType<Make["effect"]>>
758
+ : */
759
+ Make extends { readonly effect: (_: any) => Generator<any, infer S> } ? S
760
+ : never
761
+
762
+ export type MakeDepsE<Make> = Layer.Error<MakeDeps<Make>>
763
+
764
+ export type MakeDepsIn<Make> = Layer.Services<MakeDeps<Make>>
765
+
766
+ export type MakeDepsOut<Make> = Layer.Success<MakeDeps<Make>>