@effect-app/infra 4.0.0-beta.31 → 4.0.0-beta.310

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 (473) hide show
  1. package/CHANGELOG.md +2361 -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 +12 -8
  22. package/dist/MainFiberSet.d.ts.map +1 -1
  23. package/dist/MainFiberSet.js +23 -7
  24. package/dist/QueueMaker/errors.d.ts +4 -2
  25. package/dist/QueueMaker/errors.d.ts.map +1 -1
  26. package/dist/QueueMaker/errors.js +4 -2
  27. package/dist/{adapters/SQL → SQL}/Model.d.ts +31 -42
  28. package/dist/SQL/Model.d.ts.map +1 -0
  29. package/dist/SQL/Model.js +469 -0
  30. package/dist/SQL.d.ts.map +1 -0
  31. package/dist/{adapters/SQL.js → SQL.js} +1 -1
  32. package/dist/Store/Cosmos/query.d.ts +14 -3
  33. package/dist/Store/Cosmos/query.d.ts.map +1 -1
  34. package/dist/Store/Cosmos/query.js +179 -41
  35. package/dist/Store/Cosmos.d.ts +2 -2
  36. package/dist/Store/Cosmos.d.ts.map +1 -1
  37. package/dist/Store/Cosmos.js +385 -254
  38. package/dist/Store/Disk.d.ts +4 -4
  39. package/dist/Store/Disk.d.ts.map +1 -1
  40. package/dist/Store/Disk.js +79 -39
  41. package/dist/Store/Memory.d.ts +5 -9
  42. package/dist/Store/Memory.d.ts.map +1 -1
  43. package/dist/Store/Memory.js +324 -67
  44. package/dist/Store/SQL/Pg.d.ts +4 -0
  45. package/dist/Store/SQL/Pg.d.ts.map +1 -0
  46. package/dist/Store/SQL/Pg.js +253 -0
  47. package/dist/Store/SQL/query.d.ts +49 -0
  48. package/dist/Store/SQL/query.d.ts.map +1 -0
  49. package/dist/Store/SQL/query.js +527 -0
  50. package/dist/Store/SQL.d.ts +21 -0
  51. package/dist/Store/SQL.d.ts.map +1 -0
  52. package/dist/Store/SQL.js +472 -0
  53. package/dist/Store/codeFilter.d.ts +4 -4
  54. package/dist/Store/codeFilter.d.ts.map +1 -1
  55. package/dist/Store/codeFilter.js +6 -4
  56. package/dist/Store/index.d.ts +6 -4
  57. package/dist/Store/index.d.ts.map +1 -1
  58. package/dist/Store/index.js +18 -5
  59. package/dist/Store/utils.d.ts +5 -2
  60. package/dist/Store/utils.d.ts.map +1 -1
  61. package/dist/Store/utils.js +9 -5
  62. package/dist/WorkflowEngineCosmos.d.ts +29 -0
  63. package/dist/WorkflowEngineCosmos.d.ts.map +1 -0
  64. package/dist/WorkflowEngineCosmos.js +542 -0
  65. package/dist/WorkflowEngineSqlite.d.ts +24 -0
  66. package/dist/WorkflowEngineSqlite.d.ts.map +1 -0
  67. package/dist/WorkflowEngineSqlite.js +550 -0
  68. package/dist/arbs.d.ts +1 -1
  69. package/dist/arbs.d.ts.map +1 -1
  70. package/dist/arbs.js +5 -3
  71. package/dist/codec.d.ts.map +1 -0
  72. package/dist/codec.js +5 -0
  73. package/dist/{adapters/cosmos-client.d.ts → cosmos-client.d.ts} +4 -2
  74. package/dist/cosmos-client.d.ts.map +1 -0
  75. package/dist/cosmos-client.js +11 -0
  76. package/dist/errorReporter.d.ts +6 -4
  77. package/dist/errorReporter.d.ts.map +1 -1
  78. package/dist/errorReporter.js +23 -27
  79. package/dist/fileUtil.d.ts +1 -1
  80. package/dist/fileUtil.d.ts.map +1 -1
  81. package/dist/fileUtil.js +2 -2
  82. package/dist/index.d.ts +2 -1
  83. package/dist/index.d.ts.map +1 -1
  84. package/dist/index.js +3 -2
  85. package/dist/internal/RequestContextMiddleware.d.ts +5 -0
  86. package/dist/internal/RequestContextMiddleware.d.ts.map +1 -0
  87. package/dist/internal/RequestContextMiddleware.js +45 -0
  88. package/dist/internal/auth.d.ts +53 -0
  89. package/dist/internal/auth.d.ts.map +1 -0
  90. package/dist/internal/auth.js +180 -0
  91. package/dist/internal/events.d.ts +11 -0
  92. package/dist/internal/events.d.ts.map +1 -0
  93. package/dist/internal/events.js +49 -0
  94. package/dist/internal/health.d.ts.map +1 -0
  95. package/dist/internal/health.js +5 -0
  96. package/dist/{api/layerUtils.d.ts → layerUtils.d.ts} +14 -6
  97. package/dist/layerUtils.d.ts.map +1 -0
  98. package/dist/layerUtils.js +17 -0
  99. package/dist/logger/jsonLogger.d.ts +1 -1
  100. package/dist/logger/jsonLogger.d.ts.map +1 -1
  101. package/dist/logger/jsonLogger.js +5 -3
  102. package/dist/logger/logFmtLogger.d.ts +1 -1
  103. package/dist/logger/logFmtLogger.d.ts.map +1 -1
  104. package/dist/logger/logFmtLogger.js +3 -3
  105. package/dist/logger/shared.d.ts +2 -2
  106. package/dist/logger/shared.d.ts.map +1 -1
  107. package/dist/logger/shared.js +5 -5
  108. package/dist/logger.d.ts.map +1 -1
  109. package/dist/middlewares.d.ts.map +1 -0
  110. package/dist/{api/middlewares.js → middlewares.js} +1 -1
  111. package/dist/{adapters/mongo-client.d.ts → mongo-client.d.ts} +3 -2
  112. package/dist/mongo-client.d.ts.map +1 -0
  113. package/dist/mongo-client.js +15 -0
  114. package/dist/otel.d.ts +75 -0
  115. package/dist/otel.d.ts.map +1 -0
  116. package/dist/otel.js +84 -0
  117. package/dist/rateLimit.d.ts +11 -3
  118. package/dist/rateLimit.d.ts.map +1 -1
  119. package/dist/rateLimit.js +7 -12
  120. package/dist/{adapters/redis-client.d.ts → redis-client.d.ts} +5 -2
  121. package/dist/redis-client.d.ts.map +1 -0
  122. package/dist/redis-client.js +98 -0
  123. package/dist/{api/reportError.d.ts → reportError.d.ts} +1 -1
  124. package/dist/reportError.d.ts.map +1 -0
  125. package/dist/reportError.js +28 -0
  126. package/dist/{api/routing → routing}/middleware/RouterMiddleware.d.ts +4 -3
  127. package/dist/routing/middleware/RouterMiddleware.d.ts.map +1 -0
  128. package/dist/{api/routing → routing}/middleware/RouterMiddleware.js +1 -1
  129. package/dist/routing/middleware/middleware.d.ts +48 -0
  130. package/dist/routing/middleware/middleware.d.ts.map +1 -0
  131. package/dist/routing/middleware/middleware.js +152 -0
  132. package/dist/{api/routing → routing}/middleware.d.ts +0 -1
  133. package/dist/routing/middleware.d.ts.map +1 -0
  134. package/dist/{api/routing → routing}/middleware.js +1 -2
  135. package/dist/routing/schema/jwt.d.ts.map +1 -0
  136. package/dist/routing/schema/jwt.js +13 -0
  137. package/dist/routing/tsort.d.ts.map +1 -0
  138. package/dist/routing/tsort.js +51 -0
  139. package/dist/{api/routing → routing}/utils.d.ts +3 -3
  140. package/dist/routing/utils.d.ts.map +1 -0
  141. package/dist/routing/utils.js +45 -0
  142. package/dist/routing.d.ts +182 -0
  143. package/dist/routing.d.ts.map +1 -0
  144. package/dist/routing.js +256 -0
  145. package/dist/test.d.ts +2 -2
  146. package/dist/test.d.ts.map +1 -1
  147. package/dist/test.js +2 -2
  148. package/dist/util.d.ts.map +1 -0
  149. package/dist/util.js +14 -0
  150. package/docs/cluster-storage.md +26 -0
  151. package/docs/workflow-engine.md +262 -0
  152. package/examples/query.ts +47 -39
  153. package/package.json +38 -352
  154. package/src/CUPS.ts +53 -14
  155. package/src/ClusterCosmos.ts +1118 -0
  156. package/src/ClusterServiceBus.ts +242 -0
  157. package/src/{api/ContextProvider.ts → ContextProvider.ts} +20 -17
  158. package/src/Emailer/Sendgrid.ts +83 -60
  159. package/src/Emailer/fake.ts +4 -4
  160. package/src/MainFiberSet.ts +32 -13
  161. package/src/QueueMaker/errors.ts +3 -1
  162. package/src/{adapters/SQL → SQL}/Model.ts +42 -41
  163. package/src/SQL.ts +1 -0
  164. package/src/Store/Cosmos/query.ts +218 -54
  165. package/src/Store/Cosmos.ts +529 -365
  166. package/src/Store/Disk.ts +112 -70
  167. package/src/Store/Memory.ts +365 -99
  168. package/src/Store/SQL/Pg.ts +389 -0
  169. package/src/Store/SQL/query.ts +603 -0
  170. package/src/Store/SQL.ts +766 -0
  171. package/src/Store/codeFilter.ts +8 -6
  172. package/src/Store/index.ts +25 -10
  173. package/src/Store/utils.ts +32 -25
  174. package/src/WorkflowEngineCosmos.ts +749 -0
  175. package/src/WorkflowEngineSqlite.ts +813 -0
  176. package/src/arbs.ts +5 -3
  177. package/src/{adapters/cosmos-client.ts → cosmos-client.ts} +5 -3
  178. package/src/errorReporter.ts +68 -78
  179. package/src/fileUtil.ts +1 -1
  180. package/src/index.ts +2 -1
  181. package/src/{api/internal → internal}/RequestContextMiddleware.ts +23 -6
  182. package/src/internal/auth.ts +272 -0
  183. package/src/{api/internal → internal}/events.ts +22 -13
  184. package/src/{api/layerUtils.ts → layerUtils.ts} +14 -10
  185. package/src/logger/jsonLogger.ts +5 -3
  186. package/src/logger/logFmtLogger.ts +3 -3
  187. package/src/logger/shared.ts +5 -4
  188. package/src/middlewares.ts +10 -0
  189. package/src/{adapters/mongo-client.ts → mongo-client.ts} +4 -2
  190. package/src/otel.ts +177 -0
  191. package/src/rateLimit.ts +34 -23
  192. package/src/{adapters/redis-client.ts → redis-client.ts} +7 -3
  193. package/src/{api/reportError.ts → reportError.ts} +3 -2
  194. package/src/{api/routing → routing}/middleware/RouterMiddleware.ts +5 -4
  195. package/src/routing/middleware/middleware.ts +196 -0
  196. package/src/routing/middleware.ts +4 -0
  197. package/src/{api/routing → routing}/schema/jwt.ts +2 -1
  198. package/src/{api/routing → routing}/utils.ts +2 -1
  199. package/src/routing.ts +823 -0
  200. package/src/test.ts +4 -4
  201. package/src/vitest.ts +1 -1
  202. package/test/auth.test.ts +101 -0
  203. package/test/cluster-cosmos.test.ts +612 -0
  204. package/test/cluster-servicebus.test.ts +180 -0
  205. package/test/cluster-sqlite.test.ts +205 -0
  206. package/test/contextProvider.test.ts +15 -12
  207. package/test/controller.test.ts +28 -32
  208. package/test/cosmos-query.test.ts +228 -0
  209. package/test/dist/auth.test.d.ts.map +1 -0
  210. package/test/dist/cluster-cosmos.test.d.ts.map +1 -0
  211. package/test/dist/cluster-servicebus.test.d.ts.map +1 -0
  212. package/test/dist/cluster-sqlite.test.d.ts.map +1 -0
  213. package/test/dist/contextProvider.test.d.ts.map +1 -1
  214. package/test/dist/controller.test.d.ts.map +1 -1
  215. package/test/dist/cosmos-query.test.d.ts.map +1 -0
  216. package/test/dist/fixtures.d.ts +29 -11
  217. package/test/dist/fixtures.d.ts.map +1 -1
  218. package/test/dist/fixtures.js +17 -10
  219. package/test/dist/query.test.d.ts.map +1 -1
  220. package/test/dist/rawQuery.test.d.ts.map +1 -1
  221. package/test/dist/repository-ext.test.d.ts.map +1 -0
  222. package/test/dist/requires.test.d.ts.map +1 -1
  223. package/test/dist/router-generator.test.d.ts.map +1 -0
  224. package/test/dist/routing-interruptibility.test.d.ts.map +1 -0
  225. package/test/dist/rpc-context-map-streaming.test.d.ts.map +1 -0
  226. package/test/dist/rpc-e2e-invalidation.test.d.ts.map +1 -0
  227. package/test/dist/rpc-multi-middleware.test.d.ts.map +1 -1
  228. package/test/dist/rpc-stream-fullstack.test.d.ts.map +1 -0
  229. package/test/dist/sql-store.test.d.ts.map +1 -0
  230. package/test/dist/workflow-engine-cosmos.test.d.ts.map +1 -0
  231. package/test/dist/workflow-engine-sqlite.test.d.ts.map +1 -0
  232. package/test/fixtures.ts +16 -9
  233. package/test/layerUtils.test.ts +2 -2
  234. package/test/query.test.ts +1130 -41
  235. package/test/rawQuery.test.ts +340 -22
  236. package/test/repository-ext.test.ts +426 -0
  237. package/test/requires.test.ts +10 -5
  238. package/test/router-generator.test.ts +187 -0
  239. package/test/routing-interruptibility.test.ts +66 -0
  240. package/test/rpc-context-map-streaming.test.ts +262 -0
  241. package/test/rpc-e2e-invalidation.test.ts +418 -0
  242. package/test/rpc-multi-middleware.test.ts +85 -10
  243. package/test/rpc-stream-fullstack.test.ts +304 -0
  244. package/test/sql-store.test.ts +1711 -0
  245. package/test/validateSample.test.ts +26 -14
  246. package/test/workflow-engine-cosmos.test.ts +345 -0
  247. package/test/workflow-engine-sqlite.test.ts +297 -0
  248. package/tsconfig.examples.json +1 -1
  249. package/tsconfig.json +9 -2
  250. package/tsconfig.src.json +35 -35
  251. package/tsconfig.test.json +2 -2
  252. package/dist/Emailer/service.d.ts +0 -55
  253. package/dist/Emailer/service.d.ts.map +0 -1
  254. package/dist/Emailer/service.js +0 -6
  255. package/dist/Emailer.d.ts +0 -2
  256. package/dist/Emailer.d.ts.map +0 -1
  257. package/dist/Emailer.js +0 -2
  258. package/dist/Model/Repository/ext.d.ts +0 -41
  259. package/dist/Model/Repository/ext.d.ts.map +0 -1
  260. package/dist/Model/Repository/ext.js +0 -65
  261. package/dist/Model/Repository/internal/internal.d.ts +0 -59
  262. package/dist/Model/Repository/internal/internal.d.ts.map +0 -1
  263. package/dist/Model/Repository/internal/internal.js +0 -316
  264. package/dist/Model/Repository/legacy.d.ts +0 -19
  265. package/dist/Model/Repository/legacy.d.ts.map +0 -1
  266. package/dist/Model/Repository/legacy.js +0 -2
  267. package/dist/Model/Repository/makeRepo.d.ts +0 -49
  268. package/dist/Model/Repository/makeRepo.d.ts.map +0 -1
  269. package/dist/Model/Repository/makeRepo.js +0 -24
  270. package/dist/Model/Repository/service.d.ts +0 -89
  271. package/dist/Model/Repository/service.d.ts.map +0 -1
  272. package/dist/Model/Repository/service.js +0 -2
  273. package/dist/Model/Repository/validation.d.ts +0 -42
  274. package/dist/Model/Repository/validation.d.ts.map +0 -1
  275. package/dist/Model/Repository/validation.js +0 -32
  276. package/dist/Model/Repository.d.ts +0 -6
  277. package/dist/Model/Repository.d.ts.map +0 -1
  278. package/dist/Model/Repository.js +0 -6
  279. package/dist/Model/dsl.d.ts +0 -32
  280. package/dist/Model/dsl.d.ts.map +0 -1
  281. package/dist/Model/dsl.js +0 -44
  282. package/dist/Model/filter/filterApi.d.ts +0 -30
  283. package/dist/Model/filter/filterApi.d.ts.map +0 -1
  284. package/dist/Model/filter/filterApi.js +0 -2
  285. package/dist/Model/filter/types/errors.d.ts +0 -29
  286. package/dist/Model/filter/types/errors.d.ts.map +0 -1
  287. package/dist/Model/filter/types/errors.js +0 -2
  288. package/dist/Model/filter/types/fields.d.ts +0 -15
  289. package/dist/Model/filter/types/fields.d.ts.map +0 -1
  290. package/dist/Model/filter/types/fields.js +0 -2
  291. package/dist/Model/filter/types/path/common.d.ts +0 -316
  292. package/dist/Model/filter/types/path/common.d.ts.map +0 -1
  293. package/dist/Model/filter/types/path/common.js +0 -2
  294. package/dist/Model/filter/types/path/eager.d.ts +0 -95
  295. package/dist/Model/filter/types/path/eager.d.ts.map +0 -1
  296. package/dist/Model/filter/types/path/eager.js +0 -31
  297. package/dist/Model/filter/types/path/index.d.ts +0 -4
  298. package/dist/Model/filter/types/path/index.d.ts.map +0 -1
  299. package/dist/Model/filter/types/path/index.js +0 -3
  300. package/dist/Model/filter/types/utils.d.ts +0 -79
  301. package/dist/Model/filter/types/utils.d.ts.map +0 -1
  302. package/dist/Model/filter/types/utils.js +0 -2
  303. package/dist/Model/filter/types/validator.d.ts +0 -30
  304. package/dist/Model/filter/types/validator.d.ts.map +0 -1
  305. package/dist/Model/filter/types/validator.js +0 -2
  306. package/dist/Model/filter/types.d.ts +0 -5
  307. package/dist/Model/filter/types.d.ts.map +0 -1
  308. package/dist/Model/filter/types.js +0 -7
  309. package/dist/Model/query/dsl.d.ts +0 -248
  310. package/dist/Model/query/dsl.d.ts.map +0 -1
  311. package/dist/Model/query/dsl.js +0 -104
  312. package/dist/Model/query/new-kid-interpreter.d.ts +0 -28
  313. package/dist/Model/query/new-kid-interpreter.d.ts.map +0 -1
  314. package/dist/Model/query/new-kid-interpreter.js +0 -165
  315. package/dist/Model/query.d.ts +0 -15
  316. package/dist/Model/query.d.ts.map +0 -1
  317. package/dist/Model/query.js +0 -3
  318. package/dist/Model.d.ts +0 -4
  319. package/dist/Model.d.ts.map +0 -1
  320. package/dist/Model.js +0 -4
  321. package/dist/Operations.d.ts +0 -55
  322. package/dist/Operations.d.ts.map +0 -1
  323. package/dist/Operations.js +0 -102
  324. package/dist/OperationsRepo.d.ts +0 -41
  325. package/dist/OperationsRepo.d.ts.map +0 -1
  326. package/dist/OperationsRepo.js +0 -14
  327. package/dist/QueueMaker/SQLQueue.d.ts +0 -16
  328. package/dist/QueueMaker/SQLQueue.d.ts.map +0 -1
  329. package/dist/QueueMaker/SQLQueue.js +0 -130
  330. package/dist/QueueMaker/memQueue.d.ts +0 -11
  331. package/dist/QueueMaker/memQueue.d.ts.map +0 -1
  332. package/dist/QueueMaker/memQueue.js +0 -76
  333. package/dist/QueueMaker/sbqueue.d.ts +0 -12
  334. package/dist/QueueMaker/sbqueue.d.ts.map +0 -1
  335. package/dist/QueueMaker/sbqueue.js +0 -91
  336. package/dist/QueueMaker/service.d.ts +0 -11
  337. package/dist/QueueMaker/service.d.ts.map +0 -1
  338. package/dist/QueueMaker/service.js +0 -4
  339. package/dist/RequestContext.d.ts +0 -63
  340. package/dist/RequestContext.d.ts.map +0 -1
  341. package/dist/RequestContext.js +0 -49
  342. package/dist/RequestFiberSet.d.ts +0 -36
  343. package/dist/RequestFiberSet.d.ts.map +0 -1
  344. package/dist/RequestFiberSet.js +0 -78
  345. package/dist/Store/ContextMapContainer.d.ts +0 -14
  346. package/dist/Store/ContextMapContainer.d.ts.map +0 -1
  347. package/dist/Store/ContextMapContainer.js +0 -16
  348. package/dist/Store/service.d.ts +0 -108
  349. package/dist/Store/service.d.ts.map +0 -1
  350. package/dist/Store/service.js +0 -71
  351. package/dist/Store.d.ts +0 -2
  352. package/dist/Store.d.ts.map +0 -1
  353. package/dist/Store.js +0 -2
  354. package/dist/adapters/SQL/Model.d.ts.map +0 -1
  355. package/dist/adapters/SQL/Model.js +0 -478
  356. package/dist/adapters/SQL.d.ts.map +0 -1
  357. package/dist/adapters/ServiceBus.d.ts +0 -58
  358. package/dist/adapters/ServiceBus.d.ts.map +0 -1
  359. package/dist/adapters/ServiceBus.js +0 -99
  360. package/dist/adapters/cosmos-client.d.ts.map +0 -1
  361. package/dist/adapters/cosmos-client.js +0 -9
  362. package/dist/adapters/index.d.ts +0 -2
  363. package/dist/adapters/index.d.ts.map +0 -1
  364. package/dist/adapters/index.js +0 -2
  365. package/dist/adapters/logger.d.ts +0 -9
  366. package/dist/adapters/logger.d.ts.map +0 -1
  367. package/dist/adapters/logger.js +0 -3
  368. package/dist/adapters/memQueue.d.ts +0 -13
  369. package/dist/adapters/memQueue.d.ts.map +0 -1
  370. package/dist/adapters/memQueue.js +0 -20
  371. package/dist/adapters/mongo-client.d.ts.map +0 -1
  372. package/dist/adapters/mongo-client.js +0 -13
  373. package/dist/adapters/redis-client.d.ts.map +0 -1
  374. package/dist/adapters/redis-client.js +0 -94
  375. package/dist/api/ContextProvider.d.ts +0 -31
  376. package/dist/api/ContextProvider.d.ts.map +0 -1
  377. package/dist/api/ContextProvider.js +0 -38
  378. package/dist/api/codec.d.ts.map +0 -1
  379. package/dist/api/codec.js +0 -5
  380. package/dist/api/internal/RequestContextMiddleware.d.ts +0 -5
  381. package/dist/api/internal/RequestContextMiddleware.d.ts.map +0 -1
  382. package/dist/api/internal/RequestContextMiddleware.js +0 -35
  383. package/dist/api/internal/auth.d.ts +0 -15
  384. package/dist/api/internal/auth.d.ts.map +0 -1
  385. package/dist/api/internal/auth.js +0 -47
  386. package/dist/api/internal/events.d.ts +0 -9
  387. package/dist/api/internal/events.d.ts.map +0 -1
  388. package/dist/api/internal/events.js +0 -42
  389. package/dist/api/internal/health.d.ts.map +0 -1
  390. package/dist/api/internal/health.js +0 -5
  391. package/dist/api/layerUtils.d.ts.map +0 -1
  392. package/dist/api/layerUtils.js +0 -16
  393. package/dist/api/middlewares.d.ts.map +0 -1
  394. package/dist/api/reportError.d.ts.map +0 -1
  395. package/dist/api/reportError.js +0 -27
  396. package/dist/api/routing/middleware/RouterMiddleware.d.ts.map +0 -1
  397. package/dist/api/routing/middleware/middleware.d.ts +0 -9
  398. package/dist/api/routing/middleware/middleware.d.ts.map +0 -1
  399. package/dist/api/routing/middleware/middleware.js +0 -92
  400. package/dist/api/routing/middleware.d.ts.map +0 -1
  401. package/dist/api/routing/schema/jwt.d.ts.map +0 -1
  402. package/dist/api/routing/schema/jwt.js +0 -12
  403. package/dist/api/routing/tsort.d.ts.map +0 -1
  404. package/dist/api/routing/tsort.js +0 -51
  405. package/dist/api/routing/utils.d.ts.map +0 -1
  406. package/dist/api/routing/utils.js +0 -44
  407. package/dist/api/routing.d.ts +0 -138
  408. package/dist/api/routing.d.ts.map +0 -1
  409. package/dist/api/routing.js +0 -166
  410. package/dist/api/setupRequest.d.ts +0 -12
  411. package/dist/api/setupRequest.d.ts.map +0 -1
  412. package/dist/api/setupRequest.js +0 -44
  413. package/dist/api/util.d.ts.map +0 -1
  414. package/dist/api/util.js +0 -14
  415. package/eslint.config.mjs +0 -24
  416. package/src/Emailer/service.ts +0 -52
  417. package/src/Emailer.ts +0 -1
  418. package/src/Model/Repository/ext.ts +0 -283
  419. package/src/Model/Repository/internal/internal.ts +0 -577
  420. package/src/Model/Repository/legacy.ts +0 -27
  421. package/src/Model/Repository/makeRepo.ts +0 -139
  422. package/src/Model/Repository/service.ts +0 -627
  423. package/src/Model/Repository/validation.ts +0 -31
  424. package/src/Model/Repository.ts +0 -5
  425. package/src/Model/dsl.ts +0 -128
  426. package/src/Model/filter/filterApi.ts +0 -60
  427. package/src/Model/filter/types/errors.ts +0 -47
  428. package/src/Model/filter/types/fields.ts +0 -50
  429. package/src/Model/filter/types/path/common.ts +0 -404
  430. package/src/Model/filter/types/path/eager.ts +0 -298
  431. package/src/Model/filter/types/path/index.ts +0 -4
  432. package/src/Model/filter/types/utils.ts +0 -128
  433. package/src/Model/filter/types/validator.ts +0 -46
  434. package/src/Model/filter/types.ts +0 -6
  435. package/src/Model/query/dsl.ts +0 -2110
  436. package/src/Model/query/new-kid-interpreter.ts +0 -210
  437. package/src/Model/query.ts +0 -13
  438. package/src/Model.ts +0 -3
  439. package/src/Operations.ts +0 -235
  440. package/src/OperationsRepo.ts +0 -16
  441. package/src/QueueMaker/SQLQueue.ts +0 -189
  442. package/src/QueueMaker/memQueue.ts +0 -130
  443. package/src/QueueMaker/sbqueue.ts +0 -137
  444. package/src/QueueMaker/service.ts +0 -17
  445. package/src/RequestContext.ts +0 -63
  446. package/src/RequestFiberSet.ts +0 -105
  447. package/src/Store/ContextMapContainer.ts +0 -20
  448. package/src/Store/index.test.ts.bak +0 -112
  449. package/src/Store/service.ts +0 -184
  450. package/src/Store.ts +0 -1
  451. package/src/adapters/SQL.ts +0 -1
  452. package/src/adapters/ServiceBus.ts +0 -209
  453. package/src/adapters/index.ts +0 -0
  454. package/src/adapters/logger.ts +0 -3
  455. package/src/adapters/memQueue.ts +0 -21
  456. package/src/api/internal/auth.ts +0 -68
  457. package/src/api/middlewares.ts +0 -10
  458. package/src/api/routing/middleware/middleware.ts +0 -128
  459. package/src/api/routing/middleware.ts +0 -6
  460. package/src/api/routing.ts +0 -598
  461. package/src/api/setupRequest.ts +0 -84
  462. package/tsconfig.json.bak +0 -12
  463. /package/dist/{adapters/SQL.d.ts → SQL.d.ts} +0 -0
  464. /package/dist/{api/codec.d.ts → codec.d.ts} +0 -0
  465. /package/dist/{api/internal → internal}/health.d.ts +0 -0
  466. /package/dist/{api/middlewares.d.ts → middlewares.d.ts} +0 -0
  467. /package/dist/{api/routing → routing}/schema/jwt.d.ts +0 -0
  468. /package/dist/{api/routing → routing}/tsort.d.ts +0 -0
  469. /package/dist/{api/util.d.ts → util.d.ts} +0 -0
  470. /package/src/{api/codec.ts → codec.ts} +0 -0
  471. /package/src/{api/internal → internal}/health.ts +0 -0
  472. /package/src/{api/routing → routing}/tsort.ts +0 -0
  473. /package/src/{api/util.ts → util.ts} +0 -0
@@ -0,0 +1,426 @@
1
+ import { describe, expect, it } from "@effect/vitest"
2
+ import * as DataDependencies from "effect-app/DataDependencies"
3
+ import * as Effect from "effect-app/Effect"
4
+ import * as Layer from "effect-app/Layer"
5
+ import { Q } from "effect-app/Model"
6
+ import { makeRepo, repositoryDependency } from "effect-app/Model/Repository"
7
+ import { RepositoryRegistryLive } from "effect-app/Model/Repository/Registry"
8
+ import * as S from "effect-app/Schema"
9
+ import { setupRequestContextFromCurrent } from "effect-app/setupRequest"
10
+ import * as Ref from "effect/Ref"
11
+ import * as Tracer from "effect/Tracer"
12
+ import { MemoryStoreLive } from "../src/Store/Memory.js"
13
+
14
+ class BatchItem extends S.Class<BatchItem>("BatchItem")({
15
+ id: S.String,
16
+ label: S.String
17
+ }) {}
18
+
19
+ class DependencyItem extends S.Class<DependencyItem>("DependencyItem")({
20
+ id: S.String,
21
+ label: repositoryDependency(S.StringId)
22
+ }) {}
23
+
24
+ class NestedDependencyItem extends S.Class<NestedDependencyItem>("NestedDependencyItem")({
25
+ id: S.String,
26
+ parts: S.Array(S.Struct({ id: repositoryDependency(S.String) }))
27
+ }) {}
28
+
29
+ const TestStoreLive = Layer.merge(MemoryStoreLive, RepositoryRegistryLive)
30
+
31
+ const A = S.TaggedStruct("A", { id: S.String })
32
+ const B = S.TaggedStruct("B", { id: S.String })
33
+ const C = S.TaggedStruct("C", { id: S.String })
34
+
35
+ const union = S.Union([A, B, C])
36
+
37
+ const a = S.Struct({ id: S.String })
38
+
39
+ const nestedSourceItem = S.TaggedStruct("source-item", {
40
+ id: S.StringId,
41
+ label: S.String
42
+ })
43
+ const nestedProjectedItem = S.TaggedStruct("source-item", {
44
+ id: S.StringId
45
+ })
46
+ type NestedProjectedItem = typeof nestedProjectedItem.Type
47
+ const nestedSource = S.Struct({
48
+ id: S.String,
49
+ items: S.NonEmptyArray(nestedSourceItem),
50
+ label: S.String
51
+ })
52
+ const nestedProjection = S.Struct({
53
+ id: S.String,
54
+ items: S.NonEmptyArray(nestedProjectedItem)
55
+ })
56
+
57
+ const nestedProjectedItemsOf = (
58
+ items: readonly [NestedProjectedItem, ...NestedProjectedItem[]]
59
+ ) => items
60
+
61
+ const nestedUnionSourceA = S.TaggedStruct("nested-a", {
62
+ id: S.String,
63
+ items: S.NonEmptyArray(nestedSourceItem),
64
+ label: S.String
65
+ })
66
+ const nestedUnionSourceB = S.TaggedStruct("nested-b", {
67
+ id: S.String,
68
+ items: S.NonEmptyArray(nestedSourceItem),
69
+ count: S.Number
70
+ })
71
+ const nestedUnionSource = S.Union([nestedUnionSourceA, nestedUnionSourceB])
72
+ const nestedUnionProjection = S.Union([
73
+ nestedUnionSourceA.mapFields((fields) => ({
74
+ id: fields.id,
75
+ _tag: fields._tag,
76
+ items: S.NonEmptyArray(nestedProjectedItem)
77
+ })),
78
+ nestedUnionSourceB.mapFields((fields) => ({
79
+ id: fields.id,
80
+ _tag: fields._tag,
81
+ items: S.NonEmptyArray(nestedProjectedItem)
82
+ }))
83
+ ])
84
+
85
+ describe("repository ext save/remove batching", () => {
86
+ it.effect("supports projecting full repository schema", () =>
87
+ Effect
88
+ .gen(function*() {
89
+ const unionRepo = yield* makeRepo("UnionItem", union, {})
90
+ const aRepo = yield* makeRepo("AItem", a, {})
91
+ const ARepo = yield* makeRepo("TaggedAItem", A, {})
92
+
93
+ expect(yield* unionRepo.query(Q.project(union))).toEqual([])
94
+ expect(yield* aRepo.query(Q.project(a))).toEqual([])
95
+ expect(yield* ARepo.query(Q.project(A))).toEqual([])
96
+ })
97
+ .pipe(
98
+ setupRequestContextFromCurrent(),
99
+ Effect.provide(TestStoreLive)
100
+ ))
101
+
102
+ it.effect("supports nested DTO subset projections", () =>
103
+ Effect
104
+ .gen(function*() {
105
+ const repo = yield* makeRepo("NestedProjectionItem", nestedSource, {})
106
+ const unionRepo = yield* makeRepo("NestedUnionProjectionItem", nestedUnionSource, {})
107
+ const result = yield* repo.query(Q.project(nestedProjection, "project"))
108
+ const unionResult = yield* unionRepo.query(Q.project(nestedUnionProjection, "project"))
109
+
110
+ result.forEach((_) => nestedProjectedItemsOf(_.items))
111
+ unionResult.forEach((_) => nestedProjectedItemsOf(_.items))
112
+ expect(result).toEqual([])
113
+ expect(unionResult).toEqual([])
114
+ })
115
+ .pipe(
116
+ setupRequestContextFromCurrent(),
117
+ Effect.provide(TestStoreLive)
118
+ ))
119
+
120
+ it.effect("supports save batching overload", () =>
121
+ Effect
122
+ .gen(function*() {
123
+ const repo = yield* makeRepo("BatchItem", BatchItem, {})
124
+ const items = [
125
+ new BatchItem({ id: "1", label: "one" }),
126
+ new BatchItem({ id: "2", label: "two" }),
127
+ new BatchItem({ id: "3", label: "three" }),
128
+ new BatchItem({ id: "4", label: "four" })
129
+ ] as const
130
+
131
+ yield* repo.save(items, { batch: 2 })
132
+
133
+ const all = yield* repo.all
134
+ expect(all).toHaveLength(4)
135
+ expect(all.map((_) => _.id).toSorted()).toEqual(["1", "2", "3", "4"])
136
+ })
137
+ .pipe(
138
+ setupRequestContextFromCurrent(),
139
+ Effect.provide(TestStoreLive)
140
+ ))
141
+
142
+ it.effect("supports remove batching overload", () =>
143
+ Effect
144
+ .gen(function*() {
145
+ const repo = yield* makeRepo("BatchItem", BatchItem, {})
146
+ const items = [
147
+ new BatchItem({ id: "1", label: "one" }),
148
+ new BatchItem({ id: "2", label: "two" }),
149
+ new BatchItem({ id: "3", label: "three" }),
150
+ new BatchItem({ id: "4", label: "four" })
151
+ ] as const
152
+
153
+ yield* repo.save(items)
154
+ yield* repo.remove([items[0], items[1], items[2]], { batch: true })
155
+
156
+ const all = yield* repo.all
157
+ expect(all).toHaveLength(1)
158
+ expect(all[0]?.id).toBe("4")
159
+ })
160
+ .pipe(
161
+ setupRequestContextFromCurrent(),
162
+ Effect.provide(TestStoreLive)
163
+ ))
164
+
165
+ it.effect("records repository read and write dependencies", () =>
166
+ Effect
167
+ .gen(function*() {
168
+ const readsRef = yield* Ref.make(DataDependencies.empty())
169
+ const writesRef = yield* Ref.make(DataDependencies.empty())
170
+ const recorder = DataDependencies.makeDataDependencyRecorder(readsRef, writesRef)
171
+
172
+ yield* Effect
173
+ .gen(function*() {
174
+ const repo = yield* makeRepo("DependencyItem", BatchItem, {})
175
+ yield* repo.save(new BatchItem({ id: "1", label: "one" }))
176
+ yield* repo.all
177
+ yield* repo.find("1")
178
+ yield* repo.removeById("1")
179
+ })
180
+ .pipe(Effect.provideService(DataDependencies.DataDependencyRecorder, recorder))
181
+
182
+ expect(yield* Ref.get(readsRef)).toEqual(new Set([DataDependencies.repo("DependencyItem")]))
183
+ expect(yield* Ref.get(writesRef)).toEqual(new Set([DataDependencies.repo("DependencyItem", ["1"])]))
184
+ })
185
+ .pipe(
186
+ setupRequestContextFromCurrent(),
187
+ Effect.provide(TestStoreLive)
188
+ ))
189
+
190
+ it.effect("narrows direct repository reads to the requested entity", () =>
191
+ Effect
192
+ .gen(function*() {
193
+ const readsRef = yield* Ref.make(DataDependencies.empty())
194
+ const writesRef = yield* Ref.make(DataDependencies.empty())
195
+ const recorder = DataDependencies.makeDataDependencyRecorder(readsRef, writesRef)
196
+
197
+ yield* Effect
198
+ .gen(function*() {
199
+ const repo = yield* makeRepo("DependencyItem", BatchItem, {})
200
+ yield* repo.find("1")
201
+ })
202
+ .pipe(Effect.provideService(DataDependencies.DataDependencyRecorder, recorder))
203
+
204
+ expect(yield* Ref.get(readsRef)).toEqual(new Set([DataDependencies.repo("DependencyItem", ["1"])]))
205
+ })
206
+ .pipe(
207
+ setupRequestContextFromCurrent(),
208
+ Effect.provide(TestStoreLive)
209
+ ))
210
+
211
+ it("matches entity dependencies by overlapping ids with a coarse fallback", () => {
212
+ const item1 = new Set([DataDependencies.repo("DependencyItem", ["1"])])
213
+ const item2 = new Set([DataDependencies.repo("DependencyItem", ["2"])])
214
+ const collection = new Set([DataDependencies.repo("DependencyItem")])
215
+
216
+ expect(DataDependencies.intersects(item1, item2)).toBe(false)
217
+ expect(DataDependencies.intersects(item1, item1)).toBe(true)
218
+ expect(DataDependencies.intersects(collection, item2)).toBe(true)
219
+ })
220
+
221
+ it("decodes repository dependencies produced before entity ids were added", () => {
222
+ expect(
223
+ S.decodeUnknownSync(DataDependencies.DataDependency)({
224
+ type: "repo",
225
+ name: "DependencyItem"
226
+ })
227
+ )
228
+ .toEqual(DataDependencies.repo("DependencyItem"))
229
+ })
230
+
231
+ it.effect("derives matching read and write scopes from a schema annotation", () =>
232
+ Effect
233
+ .gen(function*() {
234
+ const readsRef = yield* Ref.make(DataDependencies.empty())
235
+ const writesRef = yield* Ref.make(DataDependencies.empty())
236
+ const recorder = DataDependencies.makeDataDependencyRecorder(readsRef, writesRef)
237
+
238
+ yield* Effect
239
+ .gen(function*() {
240
+ const repo = yield* makeRepo("DependencyItem", DependencyItem, {})
241
+ yield* repo.save(new DependencyItem({ id: "1", label: S.StringId("label-one") }))
242
+ yield* repo.query(Q.where("label", "label-one"))
243
+ })
244
+ .pipe(Effect.provideService(DataDependencies.DataDependencyRecorder, recorder))
245
+
246
+ expect(yield* Ref.get(readsRef)).toEqual(new Set([DataDependencies.repo("DependencyItem", ["label-one"])]))
247
+ expect(yield* Ref.get(writesRef)).toEqual(
248
+ new Set([DataDependencies.repo("DependencyItem", ["1", "label-one"])])
249
+ )
250
+ })
251
+ .pipe(
252
+ setupRequestContextFromCurrent(),
253
+ Effect.provide(TestStoreLive)
254
+ ))
255
+
256
+ it.effect("derives a nested annotated relationship scope from whereSome", () =>
257
+ Effect
258
+ .gen(function*() {
259
+ const readsRef = yield* Ref.make(DataDependencies.empty())
260
+ const writesRef = yield* Ref.make(DataDependencies.empty())
261
+ const recorder = DataDependencies.makeDataDependencyRecorder(readsRef, writesRef)
262
+
263
+ yield* Effect
264
+ .gen(function*() {
265
+ const repo = yield* makeRepo("NestedDependencyItem", NestedDependencyItem, {})
266
+ yield* repo.save(new NestedDependencyItem({ id: "root", parts: [{ id: "part-1" }] }))
267
+ yield* repo.query(Q.whereSome("parts", Q.where("id", "part-1")))
268
+ })
269
+ .pipe(Effect.provideService(DataDependencies.DataDependencyRecorder, recorder))
270
+
271
+ expect(yield* Ref.get(readsRef)).toEqual(
272
+ new Set([DataDependencies.repo("NestedDependencyItem", ["part-1"])])
273
+ )
274
+ expect(yield* Ref.get(writesRef)).toEqual(
275
+ new Set([DataDependencies.repo("NestedDependencyItem", ["root", "part-1"])])
276
+ )
277
+ })
278
+ .pipe(
279
+ setupRequestContextFromCurrent(),
280
+ Effect.provide(TestStoreLive)
281
+ ))
282
+
283
+ it.effect("records previous and next relationship aliases", () =>
284
+ Effect
285
+ .gen(function*() {
286
+ const readsRef = yield* Ref.make(DataDependencies.empty())
287
+ const writesRef = yield* Ref.make(DataDependencies.empty())
288
+ const recorder = DataDependencies.makeDataDependencyRecorder(readsRef, writesRef)
289
+
290
+ yield* Effect
291
+ .gen(function*() {
292
+ const repo = yield* makeRepo("DependencyItem", BatchItem, {
293
+ dependencyIds: (item) => [item.id, `label-${item.label}`]
294
+ })
295
+ yield* repo.save(new BatchItem({ id: "1", label: "old" }))
296
+ yield* recorder.drainWrites
297
+
298
+ yield* repo.save(new BatchItem({ id: "1", label: "new" }))
299
+ expect(yield* recorder.drainWrites).toEqual(
300
+ new Set([DataDependencies.repo("DependencyItem", ["1", "label-new", "label-old"])])
301
+ )
302
+
303
+ yield* repo.removeById("1")
304
+ expect(yield* recorder.drainWrites).toEqual(
305
+ new Set([DataDependencies.repo("DependencyItem", ["1", "label-new"])])
306
+ )
307
+ })
308
+ .pipe(Effect.provideService(DataDependencies.DataDependencyRecorder, recorder))
309
+ })
310
+ .pipe(
311
+ setupRequestContextFromCurrent(),
312
+ Effect.provide(TestStoreLive)
313
+ ))
314
+
315
+ it.effect("records repository and affected-query write dependencies", () =>
316
+ Effect
317
+ .gen(function*() {
318
+ const readsRef = yield* Ref.make(DataDependencies.empty())
319
+ const writesRef = yield* Ref.make(DataDependencies.empty())
320
+ const recorder = DataDependencies.makeDataDependencyRecorder(readsRef, writesRef)
321
+
322
+ yield* Effect
323
+ .gen(function*() {
324
+ const repo = yield* makeRepo("DependencyItem", BatchItem, {
325
+ dependencyIds: (item) => [item.id, `alias-${item.id}`],
326
+ additionalWriteDependencies: (item) => [
327
+ DataDependencies.signal("DependencyItem.List", [item.label])
328
+ ]
329
+ })
330
+ yield* repo.save(new BatchItem({ id: "1", label: "one" }))
331
+ yield* DataDependencies.read(DataDependencies.signal("DependencyItem.List", ["one"]))
332
+ })
333
+ .pipe(Effect.provideService(DataDependencies.DataDependencyRecorder, recorder))
334
+
335
+ expect(yield* Ref.get(readsRef)).toEqual(
336
+ new Set([DataDependencies.signal("DependencyItem.List", ["one"])])
337
+ )
338
+ expect(yield* Ref.get(writesRef)).toEqual(
339
+ new Set([
340
+ DataDependencies.repo("DependencyItem", ["1", "alias-1"]),
341
+ DataDependencies.signal("DependencyItem.List", ["one"])
342
+ ])
343
+ )
344
+ })
345
+ .pipe(
346
+ setupRequestContextFromCurrent(),
347
+ Effect.provide(TestStoreLive)
348
+ ))
349
+
350
+ it.effect("invalidates derived dependencies from previous saves and removeById", () =>
351
+ Effect
352
+ .gen(function*() {
353
+ const readsRef = yield* Ref.make(DataDependencies.empty())
354
+ const writesRef = yield* Ref.make(DataDependencies.empty())
355
+ const recorder = DataDependencies.makeDataDependencyRecorder(readsRef, writesRef)
356
+
357
+ yield* Effect
358
+ .gen(function*() {
359
+ const repo = yield* makeRepo("DerivedDependencyItem", BatchItem, {
360
+ additionalWriteDependencies: (item) => [
361
+ DataDependencies.signal("DerivedDependencyItem.List", [item.label])
362
+ ]
363
+ })
364
+ yield* repo.save(new BatchItem({ id: "1", label: "old" }))
365
+ yield* recorder.drainWrites
366
+
367
+ yield* repo.save(new BatchItem({ id: "1", label: "new" }))
368
+ expect(yield* recorder.drainWrites).toEqual(
369
+ new Set([
370
+ DataDependencies.repo("DerivedDependencyItem", ["1"]),
371
+ DataDependencies.signal("DerivedDependencyItem.List", ["new", "old"])
372
+ ])
373
+ )
374
+
375
+ yield* repo.removeById("1")
376
+ expect(yield* recorder.drainWrites).toEqual(
377
+ new Set([
378
+ DataDependencies.repo("DerivedDependencyItem", ["1"]),
379
+ DataDependencies.signal("DerivedDependencyItem.List", ["new"])
380
+ ])
381
+ )
382
+ })
383
+ .pipe(Effect.provideService(DataDependencies.DataDependencyRecorder, recorder))
384
+ })
385
+ .pipe(
386
+ setupRequestContextFromCurrent(),
387
+ Effect.provide(TestStoreLive)
388
+ ))
389
+
390
+ it.effect("records schema timing on repository spans without codec child spans", () =>
391
+ Effect
392
+ .gen(function*() {
393
+ const spans: Tracer.NativeSpan[] = []
394
+ const tracer = Tracer.make({
395
+ span(options) {
396
+ const span = new Tracer.NativeSpan(options)
397
+ spans.push(span)
398
+ return span
399
+ }
400
+ })
401
+
402
+ yield* Effect
403
+ .gen(function*() {
404
+ const repo = yield* makeRepo("TelemetryItem", BatchItem, {})
405
+ yield* repo.save(new BatchItem({ id: "1", label: "one" }))
406
+ yield* repo.all
407
+ })
408
+ .pipe(Effect.provideService(Tracer.Tracer, tracer))
409
+
410
+ expect(spans.map((_) => _.name)).not.toContain("parseMany")
411
+ expect(spans.map((_) => _.name)).not.toContain("encodeMany")
412
+
413
+ const saveSpan = spans.find((_) => _.name === "Repository.saveAndPublish")
414
+ const allSpan = spans.find((_) => _.name === "Repository.all")
415
+ expect(saveSpan?.attributes.get("app.schema.encode.duration_ms")).toEqual(expect.any(Number))
416
+ expect(saveSpan?.attributes.get("app.schema.item_count")).toBe(1)
417
+ expect(saveSpan?.attributes.get("db.operation.duration_ms")).toEqual(expect.any(Number))
418
+ expect(allSpan?.attributes.get("app.schema.decode.duration_ms")).toEqual(expect.any(Number))
419
+ expect(allSpan?.attributes.get("app.schema.item_count")).toBe(1)
420
+ expect(allSpan?.attributes.get("db.operation.duration_ms")).toEqual(expect.any(Number))
421
+ })
422
+ .pipe(
423
+ setupRequestContextFromCurrent(),
424
+ Effect.provide(TestStoreLive)
425
+ ))
426
+ })
@@ -1,10 +1,14 @@
1
1
  import { describe, expect, expectTypeOf, it } from "@effect/vitest"
2
- import { Effect, Layer, Result, S, ServiceMap } from "effect-app"
3
2
  import { NotLoggedInError, UnauthorizedError } from "effect-app/client"
3
+ import * as Context from "effect-app/Context"
4
+ import * as Effect from "effect-app/Effect"
4
5
  import { HttpHeaders } from "effect-app/http"
6
+ import * as Layer from "effect-app/Layer"
5
7
  import * as RpcX from "effect-app/rpc"
6
8
  import { MiddlewareMaker } from "effect-app/rpc"
9
+ import * as S from "effect-app/Schema"
7
10
  import type { unhandled } from "effect-app/Types"
11
+ import * as Result from "effect/Result"
8
12
  import { Rpc } from "effect/unstable/rpc"
9
13
  import { type SuccessValue } from "effect/unstable/rpc/RpcMiddleware"
10
14
  import { AllowAnonymous, AllowAnonymousLive, RequestContextMap, RequireRoles, RequireRolesLive, Some, SomeElseMiddleware, SomeElseMiddlewareLive, SomeMiddleware, SomeMiddlewareLive, SomeService, Test, TestLive } from "./fixtures.js"
@@ -63,11 +67,12 @@ const testSuite = (_mw: typeof middleware3) =>
63
67
  "works",
64
68
  Effect.fn(function*() {
65
69
  const defaultOpts = {
70
+ client: null as any, // TODO?
66
71
  headers: HttpHeaders.fromRecordUnsafe({}),
67
72
  payload: { _tag: "Test" },
68
73
  clientId: 0,
69
74
  requestId: "test-id" as any,
70
- rpc: { ...TestRpc, annotations: ServiceMap.make(_mw.requestContext, {}) }
75
+ rpc: { ...TestRpc, annotations: Context.make(_mw.requestContext, {}) }
71
76
  }
72
77
  const next = Effect.void as unknown as Effect.Effect<SuccessValue, unhandled, never>
73
78
  const layer = _mw.layer.pipe(
@@ -89,7 +94,7 @@ const testSuite = (_mw: typeof middleware3) =>
89
94
  headers: HttpHeaders.fromRecordUnsafe({ "x-user": "test-user", "x-is-manager": "true" }),
90
95
  rpc: {
91
96
  ...defaultOpts.rpc,
92
- annotations: ServiceMap.make(_mw.requestContext, { requireRoles: ["manager"] })
97
+ annotations: Context.make(_mw.requestContext, { requireRoles: ["manager"] })
93
98
  }
94
99
  })
95
100
  )
@@ -127,7 +132,7 @@ const testSuite = (_mw: typeof middleware3) =>
127
132
  Object.assign({ ...defaultOpts }, {
128
133
  rpc: {
129
134
  ...defaultOpts.rpc,
130
- annotations: ServiceMap.make(_mw.requestContext, { requireRoles: ["manager"] })
135
+ annotations: Context.make(_mw.requestContext, { requireRoles: ["manager"] })
131
136
  }
132
137
  })
133
138
  )
@@ -153,7 +158,7 @@ const testSuite = (_mw: typeof middleware3) =>
153
158
  {
154
159
  rpc: {
155
160
  ...defaultOpts.rpc,
156
- annotations: ServiceMap.make(_mw.requestContext, { requireRoles: ["manager"] })
161
+ annotations: Context.make(_mw.requestContext, { requireRoles: ["manager"] })
157
162
  }
158
163
  }
159
164
  )
@@ -0,0 +1,187 @@
1
+ import { type MakeContext, type MakeErrors, makeRouter } from "@effect-app/infra/routing"
2
+ import { expectTypeOf, it } from "@effect/vitest"
3
+ import { InvalidStateError, makeRpcClient, UnauthorizedError } from "effect-app/client"
4
+ import * as Context from "effect-app/Context"
5
+ import * as Effect from "effect-app/Effect"
6
+ import * as Layer from "effect-app/Layer"
7
+ import { DefaultGenericMiddlewares } from "effect-app/middleware"
8
+ import { makeAllDSL, makeOneDSL } from "effect-app/Model"
9
+ import { type FixEnv } from "effect-app/Pure"
10
+ import * as RpcX from "effect-app/rpc"
11
+ import { MiddlewareMaker } from "effect-app/rpc"
12
+ import * as S from "effect-app/Schema"
13
+ import { type TypeTestId } from "effect-app/TypeTest"
14
+ import { type ConfigError } from "effect/Config"
15
+ import { type RpcSerialization } from "effect/unstable/rpc/RpcSerialization"
16
+ import { DefaultGenericMiddlewaresLive, DevModeMiddlewareLive } from "../src/routing/middleware.js"
17
+ import { AllowAnonymous, AllowAnonymousLive, RequestContextMap, RequireRoles, RequireRolesLive, Some, SomeElse, SomeService, Test, TestLive } from "./fixtures.js"
18
+
19
+ // Inline minimal context provider (provides `Some`)
20
+ class CtxProvider extends RpcX.RpcMiddleware.Tag<CtxProvider, { provides: Some }>()("CtxProvider") {
21
+ static Default = Layer.make(this, {
22
+ *make() {
23
+ return Effect.fnUntraced(function*(effect) {
24
+ return yield* Effect.provideService(effect, Some, Some.of({ a: 1 }))
25
+ })
26
+ }
27
+ })
28
+ }
29
+
30
+ // Provides `SomeElse` so AllowAnonymous's requirement is met.
31
+ class SomeElseProvider extends RpcX.RpcMiddleware.Tag<SomeElseProvider, { provides: SomeElse }>()("SomeElseProvider") {
32
+ static Default = Layer.make(this, {
33
+ *make() {
34
+ return Effect.fnUntraced(function*(effect) {
35
+ return yield* Effect.provideService(effect, SomeElse, SomeElse.of({ b: 2 }))
36
+ })
37
+ }
38
+ })
39
+ }
40
+
41
+ class mw extends MiddlewareMaker
42
+ .Tag<mw>()("mw", RequestContextMap)
43
+ .middleware(RequireRoles, Test)
44
+ .middleware(AllowAnonymous)
45
+ .middleware(CtxProvider)
46
+ .middleware(...DefaultGenericMiddlewares, SomeElseProvider)
47
+ {
48
+ static Default = this.layer.pipe(
49
+ Layer.provide([
50
+ RequireRolesLive,
51
+ TestLive,
52
+ AllowAnonymousLive,
53
+ CtxProvider.Default,
54
+ SomeElseProvider.Default,
55
+ DefaultGenericMiddlewaresLive,
56
+ DevModeMiddlewareLive,
57
+ SomeService.Default
58
+ ])
59
+ )
60
+ }
61
+
62
+ const { TaggedRequestFor } = makeRpcClient(mw)
63
+ const Req = TaggedRequestFor("GenRouter")
64
+
65
+ class GetThing extends Req.Query<GetThing>()("GetThing", { id: S.String }, {
66
+ success: S.String,
67
+ error: UnauthorizedError
68
+ }) {}
69
+ class DoThing extends Req.Command<DoThing>()("DoThing", { id: S.String }, { success: S.Void }) {}
70
+
71
+ const Resource = { GetThing, DoThing }
72
+
73
+ const { Router, matchAll } = makeRouter(mw.Default)
74
+
75
+ class ThingRepo extends Context.Service<ThingRepo>()("ThingRepo", {
76
+ make: Effect.succeed({ get: (id: string) => Effect.succeed(id + "!") })
77
+ }) {
78
+ static Default = Layer.effect(this, this.make)
79
+ }
80
+
81
+ // Case under test:
82
+ // `match({})` is given handlers as **shorthand generator methods** (`*GetThing(req) { ... }`).
83
+ // tsgo (>= 7 dev) infers `TNext = unknown` for these shorthand generators while TS6 infers `never`.
84
+ // `HandlerWithInputGen` in routing.ts must accept both — see the structural fix.
85
+ const router = Router(Resource)({
86
+ dependencies: [ThingRepo.Default],
87
+ *effect(match) {
88
+ const repo = yield* ThingRepo
89
+
90
+ if (Math.random() > 0.5) return yield* new InvalidStateError("nope")
91
+
92
+ return match({
93
+ *GetThing(req) {
94
+ const some = yield* Some
95
+ if (req.id === "boom") {
96
+ return yield* Effect.fail(new UnauthorizedError())
97
+ }
98
+ return yield* repo.get(req.id + String(some.a))
99
+ },
100
+ *DoThing(_req) {
101
+ yield* Effect.succeed(1)
102
+ }
103
+ })
104
+ }
105
+ })
106
+
107
+ // Same scenario but using the `raw:` variant — exercises the `raw` path of `HandlerWithInputGen`.
108
+ const routerRaw = Router({ GetThing })({
109
+ *effect(match) {
110
+ return match({
111
+ GetThing: {
112
+ *raw(req) {
113
+ const some = yield* Some
114
+ return yield* Effect.succeed(req.id + String(some.a))
115
+ }
116
+ }
117
+ })
118
+ }
119
+ })
120
+
121
+ it("router with generator-method handlers compiles", () => {
122
+ expectTypeOf(router).toMatchTypeOf<
123
+ Layer.Layer<never, ConfigError | InvalidStateError, SomeService | RpcSerialization>
124
+ >()
125
+ expectTypeOf(routerRaw).toMatchTypeOf<Layer.Layer<never, ConfigError, SomeService | RpcSerialization>>()
126
+ })
127
+
128
+ // Type-level assertions: verify generator yields propagate to MakeErrors / MakeContext
129
+ type Errors = MakeErrors<typeof router[TypeTestId]>
130
+ type Ctx = MakeContext<typeof router[TypeTestId]>
131
+ expectTypeOf<Errors>().toEqualTypeOf<InvalidStateError>()
132
+ expectTypeOf<Ctx>().toEqualTypeOf<ThingRepo>()
133
+
134
+ const matched = matchAll({ router })
135
+ expectTypeOf(matched).toMatchTypeOf<
136
+ Layer.Layer<never, ConfigError | InvalidStateError, SomeService | RpcSerialization>
137
+ >()
138
+
139
+ // ---------------------------------------------------------------------------
140
+ // DSL R-inference regression
141
+ // ---------------------------------------------------------------------------
142
+ // `OneDSL`/`OneDSLExt.update`/`.modify` previously annotated the callback's
143
+ // effect R as `FixEnv<R, Evt, S1, S2>`. That deadlocked inference of `R`
144
+ // (TS6 → `never`, tsgo → `unknown`), causing yielded effects to leak
145
+ // `unknown` in the R slot when consumed by generator handlers.
146
+ // The fix uses bare `R` in the callback and `FixEnv<R, …>` only on the return.
147
+ class Item extends S.Class<Item>("Item")({ id: S.String, label: S.String }) {}
148
+ class Dep extends Context.Service<Dep>()("Dep", { make: Effect.succeed({ tag: "dep" as const }) }) {}
149
+
150
+ type Evt = { _tag: "Updated"; id: string }
151
+
152
+ const Items$ = makeAllDSL<Item, Evt>()
153
+ const Item$ = makeOneDSL<Item, Evt>()
154
+
155
+ // Callback body uses generator syntax (TNext = unknown under tsgo) and yields
156
+ // a service-dependent effect — R must be inferred as `Dep` (plus the
157
+ // canonical PureEnvEnv contributed by FixEnv on the return).
158
+ const oneUpdate = Item$.update((item) =>
159
+ Effect.gen(function*() {
160
+ const dep = yield* Dep
161
+ return new Item({ id: item.id, label: item.label + dep.tag })
162
+ })
163
+ )
164
+
165
+ const allUpdate = Items$.update((items) =>
166
+ Effect.gen(function*() {
167
+ const dep = yield* Dep
168
+ return items.map((_) => new Item({ id: _.id, label: _.label + dep.tag }))
169
+ })
170
+ )
171
+
172
+ const oneModify = Item$.modify((item, _dsl) =>
173
+ Effect.gen(function*() {
174
+ const dep = yield* Dep
175
+ return { ...item, tag: dep.tag }
176
+ })
177
+ )
178
+
179
+ // `R` should be `FixEnv<Dep, Evt, …>` — never collapsed to `unknown`/`never`.
180
+ // The regression manifested as `unknown` here, breaking `Dep` assignability.
181
+ expectTypeOf(oneUpdate).toMatchTypeOf<Effect.Effect<Item, never, FixEnv<Dep, Evt, Item, Item>>>()
182
+ expectTypeOf(allUpdate).toMatchTypeOf<
183
+ Effect.Effect<readonly Item[], never, FixEnv<Dep, Evt, readonly Item[], readonly Item[]>>
184
+ >()
185
+ expectTypeOf(oneModify).toMatchTypeOf<
186
+ Effect.Effect<{ tag: "dep"; id: string; label: string }, never, FixEnv<Dep, Evt, Item, Item>>
187
+ >()