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

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 (474) hide show
  1. package/CHANGELOG.md +2385 -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 +2 -2
  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 +5 -5
  109. package/dist/logger.d.ts.map +1 -1
  110. package/dist/middlewares.d.ts.map +1 -0
  111. package/dist/{api/middlewares.js → middlewares.js} +1 -1
  112. package/dist/{adapters/mongo-client.d.ts → mongo-client.d.ts} +3 -2
  113. package/dist/mongo-client.d.ts.map +1 -0
  114. package/dist/mongo-client.js +15 -0
  115. package/dist/otel.d.ts +75 -0
  116. package/dist/otel.d.ts.map +1 -0
  117. package/dist/otel.js +84 -0
  118. package/dist/rateLimit.d.ts +11 -3
  119. package/dist/rateLimit.d.ts.map +1 -1
  120. package/dist/rateLimit.js +7 -12
  121. package/dist/{adapters/redis-client.d.ts → redis-client.d.ts} +5 -2
  122. package/dist/redis-client.d.ts.map +1 -0
  123. package/dist/redis-client.js +98 -0
  124. package/dist/{api/reportError.d.ts → reportError.d.ts} +1 -1
  125. package/dist/reportError.d.ts.map +1 -0
  126. package/dist/reportError.js +28 -0
  127. package/dist/{api/routing → routing}/middleware/RouterMiddleware.d.ts +4 -3
  128. package/dist/routing/middleware/RouterMiddleware.d.ts.map +1 -0
  129. package/dist/{api/routing → routing}/middleware/RouterMiddleware.js +1 -1
  130. package/dist/routing/middleware/middleware.d.ts +48 -0
  131. package/dist/routing/middleware/middleware.d.ts.map +1 -0
  132. package/dist/routing/middleware/middleware.js +152 -0
  133. package/dist/{api/routing → routing}/middleware.d.ts +0 -1
  134. package/dist/routing/middleware.d.ts.map +1 -0
  135. package/dist/{api/routing → routing}/middleware.js +1 -2
  136. package/dist/routing/schema/jwt.d.ts.map +1 -0
  137. package/dist/routing/schema/jwt.js +12 -0
  138. package/dist/routing/tsort.d.ts.map +1 -0
  139. package/dist/routing/tsort.js +51 -0
  140. package/dist/{api/routing → routing}/utils.d.ts +3 -3
  141. package/dist/routing/utils.d.ts.map +1 -0
  142. package/dist/routing/utils.js +45 -0
  143. package/dist/routing.d.ts +182 -0
  144. package/dist/routing.d.ts.map +1 -0
  145. package/dist/routing.js +256 -0
  146. package/dist/test.d.ts +2 -2
  147. package/dist/test.d.ts.map +1 -1
  148. package/dist/test.js +5 -5
  149. package/dist/util.d.ts.map +1 -0
  150. package/dist/util.js +14 -0
  151. package/docs/cluster-storage.md +26 -0
  152. package/docs/workflow-engine.md +262 -0
  153. package/examples/query.ts +47 -39
  154. package/package.json +38 -352
  155. package/src/CUPS.ts +53 -14
  156. package/src/ClusterCosmos.ts +1118 -0
  157. package/src/ClusterServiceBus.ts +242 -0
  158. package/src/{api/ContextProvider.ts → ContextProvider.ts} +20 -17
  159. package/src/Emailer/Sendgrid.ts +83 -60
  160. package/src/Emailer/fake.ts +4 -4
  161. package/src/MainFiberSet.ts +32 -13
  162. package/src/QueueMaker/errors.ts +3 -1
  163. package/src/{adapters/SQL → SQL}/Model.ts +42 -41
  164. package/src/SQL.ts +1 -0
  165. package/src/Store/Cosmos/query.ts +218 -54
  166. package/src/Store/Cosmos.ts +529 -365
  167. package/src/Store/Disk.ts +112 -70
  168. package/src/Store/Memory.ts +365 -99
  169. package/src/Store/SQL/Pg.ts +389 -0
  170. package/src/Store/SQL/query.ts +603 -0
  171. package/src/Store/SQL.ts +766 -0
  172. package/src/Store/codeFilter.ts +8 -6
  173. package/src/Store/index.ts +25 -10
  174. package/src/Store/utils.ts +32 -25
  175. package/src/WorkflowEngineCosmos.ts +749 -0
  176. package/src/WorkflowEngineSqlite.ts +813 -0
  177. package/src/arbs.ts +6 -4
  178. package/src/{adapters/cosmos-client.ts → cosmos-client.ts} +5 -3
  179. package/src/errorReporter.ts +68 -78
  180. package/src/fileUtil.ts +1 -1
  181. package/src/index.ts +2 -1
  182. package/src/{api/internal → internal}/RequestContextMiddleware.ts +23 -6
  183. package/src/internal/auth.ts +272 -0
  184. package/src/{api/internal → internal}/events.ts +22 -13
  185. package/src/{api/layerUtils.ts → layerUtils.ts} +14 -10
  186. package/src/logger/jsonLogger.ts +5 -3
  187. package/src/logger/logFmtLogger.ts +3 -3
  188. package/src/logger/shared.ts +5 -4
  189. package/src/middlewares.ts +10 -0
  190. package/src/{adapters/mongo-client.ts → mongo-client.ts} +4 -2
  191. package/src/otel.ts +177 -0
  192. package/src/rateLimit.ts +35 -24
  193. package/src/{adapters/redis-client.ts → redis-client.ts} +7 -3
  194. package/src/{api/reportError.ts → reportError.ts} +3 -2
  195. package/src/{api/routing → routing}/middleware/RouterMiddleware.ts +5 -4
  196. package/src/routing/middleware/middleware.ts +196 -0
  197. package/src/routing/middleware.ts +4 -0
  198. package/src/{api/routing → routing}/schema/jwt.ts +2 -2
  199. package/src/{api/routing → routing}/utils.ts +2 -1
  200. package/src/routing.ts +823 -0
  201. package/src/test.ts +6 -6
  202. package/src/vitest.ts +1 -1
  203. package/test/auth.test.ts +101 -0
  204. package/test/cluster-cosmos.test.ts +612 -0
  205. package/test/cluster-servicebus.test.ts +180 -0
  206. package/test/cluster-sqlite.test.ts +207 -0
  207. package/test/contextProvider.test.ts +15 -12
  208. package/test/controller.test.ts +28 -32
  209. package/test/cosmos-query.test.ts +228 -0
  210. package/test/dist/auth.test.d.ts.map +1 -0
  211. package/test/dist/cluster-cosmos.test.d.ts.map +1 -0
  212. package/test/dist/cluster-servicebus.test.d.ts.map +1 -0
  213. package/test/dist/cluster-sqlite.test.d.ts.map +1 -0
  214. package/test/dist/contextProvider.test.d.ts.map +1 -1
  215. package/test/dist/controller.test.d.ts.map +1 -1
  216. package/test/dist/cosmos-query.test.d.ts.map +1 -0
  217. package/test/dist/fixtures.d.ts +29 -11
  218. package/test/dist/fixtures.d.ts.map +1 -1
  219. package/test/dist/fixtures.js +17 -10
  220. package/test/dist/query.test.d.ts.map +1 -1
  221. package/test/dist/rawQuery.test.d.ts.map +1 -1
  222. package/test/dist/repository-ext.test.d.ts.map +1 -0
  223. package/test/dist/requires.test.d.ts.map +1 -1
  224. package/test/dist/router-generator.test.d.ts.map +1 -0
  225. package/test/dist/routing-interruptibility.test.d.ts.map +1 -0
  226. package/test/dist/rpc-context-map-streaming.test.d.ts.map +1 -0
  227. package/test/dist/rpc-e2e-invalidation.test.d.ts.map +1 -0
  228. package/test/dist/rpc-multi-middleware.test.d.ts.map +1 -1
  229. package/test/dist/rpc-stream-fullstack.test.d.ts.map +1 -0
  230. package/test/dist/sql-store.test.d.ts.map +1 -0
  231. package/test/dist/workflow-engine-cosmos.test.d.ts.map +1 -0
  232. package/test/dist/workflow-engine-sqlite.test.d.ts.map +1 -0
  233. package/test/fixtures.ts +16 -9
  234. package/test/layerUtils.test.ts +2 -2
  235. package/test/query.test.ts +1130 -41
  236. package/test/rawQuery.test.ts +340 -22
  237. package/test/repository-ext.test.ts +426 -0
  238. package/test/requires.test.ts +10 -5
  239. package/test/router-generator.test.ts +187 -0
  240. package/test/routing-interruptibility.test.ts +66 -0
  241. package/test/rpc-context-map-streaming.test.ts +262 -0
  242. package/test/rpc-e2e-invalidation.test.ts +418 -0
  243. package/test/rpc-multi-middleware.test.ts +85 -10
  244. package/test/rpc-stream-fullstack.test.ts +304 -0
  245. package/test/sql-store.test.ts +1711 -0
  246. package/test/validateSample.test.ts +26 -14
  247. package/test/workflow-engine-cosmos.test.ts +345 -0
  248. package/test/workflow-engine-sqlite.test.ts +297 -0
  249. package/tsconfig.examples.json +1 -1
  250. package/tsconfig.json +9 -2
  251. package/tsconfig.src.json +35 -35
  252. package/tsconfig.test.json +2 -2
  253. package/dist/Emailer/service.d.ts +0 -55
  254. package/dist/Emailer/service.d.ts.map +0 -1
  255. package/dist/Emailer/service.js +0 -6
  256. package/dist/Emailer.d.ts +0 -2
  257. package/dist/Emailer.d.ts.map +0 -1
  258. package/dist/Emailer.js +0 -2
  259. package/dist/Model/Repository/ext.d.ts +0 -41
  260. package/dist/Model/Repository/ext.d.ts.map +0 -1
  261. package/dist/Model/Repository/ext.js +0 -65
  262. package/dist/Model/Repository/internal/internal.d.ts +0 -59
  263. package/dist/Model/Repository/internal/internal.d.ts.map +0 -1
  264. package/dist/Model/Repository/internal/internal.js +0 -316
  265. package/dist/Model/Repository/legacy.d.ts +0 -19
  266. package/dist/Model/Repository/legacy.d.ts.map +0 -1
  267. package/dist/Model/Repository/legacy.js +0 -2
  268. package/dist/Model/Repository/makeRepo.d.ts +0 -49
  269. package/dist/Model/Repository/makeRepo.d.ts.map +0 -1
  270. package/dist/Model/Repository/makeRepo.js +0 -24
  271. package/dist/Model/Repository/service.d.ts +0 -89
  272. package/dist/Model/Repository/service.d.ts.map +0 -1
  273. package/dist/Model/Repository/service.js +0 -2
  274. package/dist/Model/Repository/validation.d.ts +0 -42
  275. package/dist/Model/Repository/validation.d.ts.map +0 -1
  276. package/dist/Model/Repository/validation.js +0 -32
  277. package/dist/Model/Repository.d.ts +0 -6
  278. package/dist/Model/Repository.d.ts.map +0 -1
  279. package/dist/Model/Repository.js +0 -6
  280. package/dist/Model/dsl.d.ts +0 -32
  281. package/dist/Model/dsl.d.ts.map +0 -1
  282. package/dist/Model/dsl.js +0 -44
  283. package/dist/Model/filter/filterApi.d.ts +0 -30
  284. package/dist/Model/filter/filterApi.d.ts.map +0 -1
  285. package/dist/Model/filter/filterApi.js +0 -2
  286. package/dist/Model/filter/types/errors.d.ts +0 -29
  287. package/dist/Model/filter/types/errors.d.ts.map +0 -1
  288. package/dist/Model/filter/types/errors.js +0 -2
  289. package/dist/Model/filter/types/fields.d.ts +0 -15
  290. package/dist/Model/filter/types/fields.d.ts.map +0 -1
  291. package/dist/Model/filter/types/fields.js +0 -2
  292. package/dist/Model/filter/types/path/common.d.ts +0 -316
  293. package/dist/Model/filter/types/path/common.d.ts.map +0 -1
  294. package/dist/Model/filter/types/path/common.js +0 -2
  295. package/dist/Model/filter/types/path/eager.d.ts +0 -95
  296. package/dist/Model/filter/types/path/eager.d.ts.map +0 -1
  297. package/dist/Model/filter/types/path/eager.js +0 -31
  298. package/dist/Model/filter/types/path/index.d.ts +0 -4
  299. package/dist/Model/filter/types/path/index.d.ts.map +0 -1
  300. package/dist/Model/filter/types/path/index.js +0 -3
  301. package/dist/Model/filter/types/utils.d.ts +0 -79
  302. package/dist/Model/filter/types/utils.d.ts.map +0 -1
  303. package/dist/Model/filter/types/utils.js +0 -2
  304. package/dist/Model/filter/types/validator.d.ts +0 -30
  305. package/dist/Model/filter/types/validator.d.ts.map +0 -1
  306. package/dist/Model/filter/types/validator.js +0 -2
  307. package/dist/Model/filter/types.d.ts +0 -5
  308. package/dist/Model/filter/types.d.ts.map +0 -1
  309. package/dist/Model/filter/types.js +0 -7
  310. package/dist/Model/query/dsl.d.ts +0 -248
  311. package/dist/Model/query/dsl.d.ts.map +0 -1
  312. package/dist/Model/query/dsl.js +0 -104
  313. package/dist/Model/query/new-kid-interpreter.d.ts +0 -28
  314. package/dist/Model/query/new-kid-interpreter.d.ts.map +0 -1
  315. package/dist/Model/query/new-kid-interpreter.js +0 -165
  316. package/dist/Model/query.d.ts +0 -15
  317. package/dist/Model/query.d.ts.map +0 -1
  318. package/dist/Model/query.js +0 -3
  319. package/dist/Model.d.ts +0 -4
  320. package/dist/Model.d.ts.map +0 -1
  321. package/dist/Model.js +0 -4
  322. package/dist/Operations.d.ts +0 -55
  323. package/dist/Operations.d.ts.map +0 -1
  324. package/dist/Operations.js +0 -102
  325. package/dist/OperationsRepo.d.ts +0 -41
  326. package/dist/OperationsRepo.d.ts.map +0 -1
  327. package/dist/OperationsRepo.js +0 -14
  328. package/dist/QueueMaker/SQLQueue.d.ts +0 -16
  329. package/dist/QueueMaker/SQLQueue.d.ts.map +0 -1
  330. package/dist/QueueMaker/SQLQueue.js +0 -130
  331. package/dist/QueueMaker/memQueue.d.ts +0 -11
  332. package/dist/QueueMaker/memQueue.d.ts.map +0 -1
  333. package/dist/QueueMaker/memQueue.js +0 -76
  334. package/dist/QueueMaker/sbqueue.d.ts +0 -12
  335. package/dist/QueueMaker/sbqueue.d.ts.map +0 -1
  336. package/dist/QueueMaker/sbqueue.js +0 -91
  337. package/dist/QueueMaker/service.d.ts +0 -11
  338. package/dist/QueueMaker/service.d.ts.map +0 -1
  339. package/dist/QueueMaker/service.js +0 -4
  340. package/dist/RequestContext.d.ts +0 -63
  341. package/dist/RequestContext.d.ts.map +0 -1
  342. package/dist/RequestContext.js +0 -49
  343. package/dist/RequestFiberSet.d.ts +0 -36
  344. package/dist/RequestFiberSet.d.ts.map +0 -1
  345. package/dist/RequestFiberSet.js +0 -78
  346. package/dist/Store/ContextMapContainer.d.ts +0 -14
  347. package/dist/Store/ContextMapContainer.d.ts.map +0 -1
  348. package/dist/Store/ContextMapContainer.js +0 -16
  349. package/dist/Store/service.d.ts +0 -108
  350. package/dist/Store/service.d.ts.map +0 -1
  351. package/dist/Store/service.js +0 -71
  352. package/dist/Store.d.ts +0 -2
  353. package/dist/Store.d.ts.map +0 -1
  354. package/dist/Store.js +0 -2
  355. package/dist/adapters/SQL/Model.d.ts.map +0 -1
  356. package/dist/adapters/SQL/Model.js +0 -478
  357. package/dist/adapters/SQL.d.ts.map +0 -1
  358. package/dist/adapters/ServiceBus.d.ts +0 -58
  359. package/dist/adapters/ServiceBus.d.ts.map +0 -1
  360. package/dist/adapters/ServiceBus.js +0 -99
  361. package/dist/adapters/cosmos-client.d.ts.map +0 -1
  362. package/dist/adapters/cosmos-client.js +0 -9
  363. package/dist/adapters/index.d.ts +0 -2
  364. package/dist/adapters/index.d.ts.map +0 -1
  365. package/dist/adapters/index.js +0 -2
  366. package/dist/adapters/logger.d.ts +0 -9
  367. package/dist/adapters/logger.d.ts.map +0 -1
  368. package/dist/adapters/logger.js +0 -3
  369. package/dist/adapters/memQueue.d.ts +0 -13
  370. package/dist/adapters/memQueue.d.ts.map +0 -1
  371. package/dist/adapters/memQueue.js +0 -20
  372. package/dist/adapters/mongo-client.d.ts.map +0 -1
  373. package/dist/adapters/mongo-client.js +0 -13
  374. package/dist/adapters/redis-client.d.ts.map +0 -1
  375. package/dist/adapters/redis-client.js +0 -94
  376. package/dist/api/ContextProvider.d.ts +0 -31
  377. package/dist/api/ContextProvider.d.ts.map +0 -1
  378. package/dist/api/ContextProvider.js +0 -38
  379. package/dist/api/codec.d.ts.map +0 -1
  380. package/dist/api/codec.js +0 -5
  381. package/dist/api/internal/RequestContextMiddleware.d.ts +0 -5
  382. package/dist/api/internal/RequestContextMiddleware.d.ts.map +0 -1
  383. package/dist/api/internal/RequestContextMiddleware.js +0 -35
  384. package/dist/api/internal/auth.d.ts +0 -15
  385. package/dist/api/internal/auth.d.ts.map +0 -1
  386. package/dist/api/internal/auth.js +0 -47
  387. package/dist/api/internal/events.d.ts +0 -9
  388. package/dist/api/internal/events.d.ts.map +0 -1
  389. package/dist/api/internal/events.js +0 -42
  390. package/dist/api/internal/health.d.ts.map +0 -1
  391. package/dist/api/internal/health.js +0 -5
  392. package/dist/api/layerUtils.d.ts.map +0 -1
  393. package/dist/api/layerUtils.js +0 -16
  394. package/dist/api/middlewares.d.ts.map +0 -1
  395. package/dist/api/reportError.d.ts.map +0 -1
  396. package/dist/api/reportError.js +0 -27
  397. package/dist/api/routing/middleware/RouterMiddleware.d.ts.map +0 -1
  398. package/dist/api/routing/middleware/middleware.d.ts +0 -9
  399. package/dist/api/routing/middleware/middleware.d.ts.map +0 -1
  400. package/dist/api/routing/middleware/middleware.js +0 -92
  401. package/dist/api/routing/middleware.d.ts.map +0 -1
  402. package/dist/api/routing/schema/jwt.d.ts.map +0 -1
  403. package/dist/api/routing/schema/jwt.js +0 -12
  404. package/dist/api/routing/tsort.d.ts.map +0 -1
  405. package/dist/api/routing/tsort.js +0 -51
  406. package/dist/api/routing/utils.d.ts.map +0 -1
  407. package/dist/api/routing/utils.js +0 -44
  408. package/dist/api/routing.d.ts +0 -138
  409. package/dist/api/routing.d.ts.map +0 -1
  410. package/dist/api/routing.js +0 -166
  411. package/dist/api/setupRequest.d.ts +0 -12
  412. package/dist/api/setupRequest.d.ts.map +0 -1
  413. package/dist/api/setupRequest.js +0 -44
  414. package/dist/api/util.d.ts.map +0 -1
  415. package/dist/api/util.js +0 -14
  416. package/eslint.config.mjs +0 -24
  417. package/src/Emailer/service.ts +0 -52
  418. package/src/Emailer.ts +0 -1
  419. package/src/Model/Repository/ext.ts +0 -283
  420. package/src/Model/Repository/internal/internal.ts +0 -577
  421. package/src/Model/Repository/legacy.ts +0 -27
  422. package/src/Model/Repository/makeRepo.ts +0 -139
  423. package/src/Model/Repository/service.ts +0 -627
  424. package/src/Model/Repository/validation.ts +0 -31
  425. package/src/Model/Repository.ts +0 -5
  426. package/src/Model/dsl.ts +0 -128
  427. package/src/Model/filter/filterApi.ts +0 -60
  428. package/src/Model/filter/types/errors.ts +0 -47
  429. package/src/Model/filter/types/fields.ts +0 -50
  430. package/src/Model/filter/types/path/common.ts +0 -404
  431. package/src/Model/filter/types/path/eager.ts +0 -298
  432. package/src/Model/filter/types/path/index.ts +0 -4
  433. package/src/Model/filter/types/utils.ts +0 -128
  434. package/src/Model/filter/types/validator.ts +0 -46
  435. package/src/Model/filter/types.ts +0 -6
  436. package/src/Model/query/dsl.ts +0 -2110
  437. package/src/Model/query/new-kid-interpreter.ts +0 -210
  438. package/src/Model/query.ts +0 -13
  439. package/src/Model.ts +0 -3
  440. package/src/Operations.ts +0 -235
  441. package/src/OperationsRepo.ts +0 -16
  442. package/src/QueueMaker/SQLQueue.ts +0 -189
  443. package/src/QueueMaker/memQueue.ts +0 -130
  444. package/src/QueueMaker/sbqueue.ts +0 -137
  445. package/src/QueueMaker/service.ts +0 -17
  446. package/src/RequestContext.ts +0 -63
  447. package/src/RequestFiberSet.ts +0 -105
  448. package/src/Store/ContextMapContainer.ts +0 -20
  449. package/src/Store/index.test.ts.bak +0 -112
  450. package/src/Store/service.ts +0 -184
  451. package/src/Store.ts +0 -1
  452. package/src/adapters/SQL.ts +0 -1
  453. package/src/adapters/ServiceBus.ts +0 -209
  454. package/src/adapters/index.ts +0 -0
  455. package/src/adapters/logger.ts +0 -3
  456. package/src/adapters/memQueue.ts +0 -21
  457. package/src/api/internal/auth.ts +0 -68
  458. package/src/api/middlewares.ts +0 -10
  459. package/src/api/routing/middleware/middleware.ts +0 -128
  460. package/src/api/routing/middleware.ts +0 -6
  461. package/src/api/routing.ts +0 -598
  462. package/src/api/setupRequest.ts +0 -84
  463. package/tsconfig.json.bak +0 -12
  464. /package/dist/{adapters/SQL.d.ts → SQL.d.ts} +0 -0
  465. /package/dist/{api/codec.d.ts → codec.d.ts} +0 -0
  466. /package/dist/{api/internal → internal}/health.d.ts +0 -0
  467. /package/dist/{api/middlewares.d.ts → middlewares.d.ts} +0 -0
  468. /package/dist/{api/routing → routing}/schema/jwt.d.ts +0 -0
  469. /package/dist/{api/routing → routing}/tsort.d.ts +0 -0
  470. /package/dist/{api/util.d.ts → util.d.ts} +0 -0
  471. /package/src/{api/codec.ts → codec.ts} +0 -0
  472. /package/src/{api/internal → internal}/health.ts +0 -0
  473. /package/src/{api/routing → routing}/tsort.ts +0 -0
  474. /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
+ >()