@effect-app/infra 4.0.0-beta.99 → 4.0.0

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 (486) hide show
  1. package/CHANGELOG.md +2884 -0
  2. package/_check.sh +1 -1
  3. package/dist/CUPS.d.ts +28 -9
  4. package/dist/CUPS.d.ts.map +1 -1
  5. package/dist/CUPS.js +35 -14
  6. package/dist/ClusterCosmos.d.ts +67 -0
  7. package/dist/ClusterCosmos.d.ts.map +1 -0
  8. package/dist/ClusterCosmos.js +588 -0
  9. package/dist/ClusterServiceBus.d.ts +67 -0
  10. package/dist/ClusterServiceBus.d.ts.map +1 -0
  11. package/dist/ClusterServiceBus.js +84 -0
  12. package/dist/{api/ContextProvider.d.ts → ContextProvider.d.ts} +7 -4
  13. package/dist/ContextProvider.d.ts.map +1 -0
  14. package/dist/ContextProvider.js +40 -0
  15. package/dist/Emailer/Sendgrid.d.ts +110 -146
  16. package/dist/Emailer/Sendgrid.d.ts.map +1 -1
  17. package/dist/Emailer/Sendgrid.js +24 -19
  18. package/dist/Emailer/fake.d.ts +1 -1
  19. package/dist/Emailer/fake.d.ts.map +1 -1
  20. package/dist/Emailer/fake.js +4 -4
  21. package/dist/MainFiberSet.d.ts +11 -7
  22. package/dist/MainFiberSet.d.ts.map +1 -1
  23. package/dist/MainFiberSet.js +22 -6
  24. package/dist/QueueMaker/errors.d.ts +3 -1
  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 +34 -45
  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 +16 -4
  33. package/dist/Store/Cosmos/query.d.ts.map +1 -1
  34. package/dist/Store/Cosmos/query.js +238 -42
  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 +394 -319
  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 +91 -39
  41. package/dist/Store/Memory.d.ts +7 -10
  42. package/dist/Store/Memory.d.ts.map +1 -1
  43. package/dist/Store/Memory.js +348 -78
  44. package/dist/Store/SQL/Pg.d.ts +2 -2
  45. package/dist/Store/SQL/Pg.d.ts.map +1 -1
  46. package/dist/Store/SQL/Pg.js +229 -154
  47. package/dist/Store/SQL/query.d.ts +19 -3
  48. package/dist/Store/SQL/query.d.ts.map +1 -1
  49. package/dist/Store/SQL/query.js +306 -12
  50. package/dist/Store/SQL.d.ts +22 -5
  51. package/dist/Store/SQL.d.ts.map +1 -1
  52. package/dist/Store/SQL.js +369 -98
  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 +71 -22
  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 +9 -6
  59. package/dist/Store/jsonDocument.d.ts +67 -0
  60. package/dist/Store/jsonDocument.d.ts.map +1 -0
  61. package/dist/Store/jsonDocument.js +107 -0
  62. package/dist/Store/utils.d.ts +21 -2
  63. package/dist/Store/utils.d.ts.map +1 -1
  64. package/dist/Store/utils.js +253 -10
  65. package/dist/WorkflowEngineCosmos.d.ts +30 -0
  66. package/dist/WorkflowEngineCosmos.d.ts.map +1 -0
  67. package/dist/WorkflowEngineCosmos.js +542 -0
  68. package/dist/WorkflowEngineSqlite.d.ts +24 -0
  69. package/dist/WorkflowEngineSqlite.d.ts.map +1 -0
  70. package/dist/WorkflowEngineSqlite.js +550 -0
  71. package/dist/arbs.d.ts +6 -3
  72. package/dist/arbs.d.ts.map +1 -1
  73. package/dist/arbs.js +20 -4
  74. package/dist/codec.d.ts.map +1 -0
  75. package/dist/codec.js +5 -0
  76. package/dist/cosmos-client.d.ts +40 -0
  77. package/dist/cosmos-client.d.ts.map +1 -0
  78. package/dist/cosmos-client.js +41 -0
  79. package/dist/errorReporter.d.ts +6 -4
  80. package/dist/errorReporter.d.ts.map +1 -1
  81. package/dist/errorReporter.js +23 -27
  82. package/dist/fileUtil.d.ts +1 -1
  83. package/dist/fileUtil.d.ts.map +1 -1
  84. package/dist/fileUtil.js +2 -2
  85. package/dist/index.d.ts +2 -1
  86. package/dist/index.d.ts.map +1 -1
  87. package/dist/index.js +3 -2
  88. package/dist/internal/RequestContextMiddleware.d.ts +5 -0
  89. package/dist/internal/RequestContextMiddleware.d.ts.map +1 -0
  90. package/dist/internal/RequestContextMiddleware.js +45 -0
  91. package/dist/internal/auth.d.ts +53 -0
  92. package/dist/internal/auth.d.ts.map +1 -0
  93. package/dist/internal/auth.js +180 -0
  94. package/dist/internal/events.d.ts +11 -0
  95. package/dist/internal/events.d.ts.map +1 -0
  96. package/dist/internal/events.js +49 -0
  97. package/dist/{api/internal → internal}/health.d.ts +1 -1
  98. package/dist/internal/health.d.ts.map +1 -0
  99. package/dist/internal/health.js +5 -0
  100. package/dist/{api/layerUtils.d.ts → layerUtils.d.ts} +10 -2
  101. package/dist/layerUtils.d.ts.map +1 -0
  102. package/dist/layerUtils.js +17 -0
  103. package/dist/logger/jsonLogger.d.ts +1 -1
  104. package/dist/logger/jsonLogger.d.ts.map +1 -1
  105. package/dist/logger/jsonLogger.js +5 -3
  106. package/dist/logger/logFmtLogger.d.ts +1 -1
  107. package/dist/logger/logFmtLogger.d.ts.map +1 -1
  108. package/dist/logger/logFmtLogger.js +3 -3
  109. package/dist/logger/shared.d.ts +2 -2
  110. package/dist/logger/shared.d.ts.map +1 -1
  111. package/dist/logger/shared.js +6 -6
  112. package/dist/logger.d.ts.map +1 -1
  113. package/dist/middlewares.d.ts.map +1 -0
  114. package/dist/{api/middlewares.js → middlewares.js} +1 -1
  115. package/dist/{adapters/mongo-client.d.ts → mongo-client.d.ts} +2 -1
  116. package/dist/mongo-client.d.ts.map +1 -0
  117. package/dist/mongo-client.js +15 -0
  118. package/dist/otel.d.ts +75 -0
  119. package/dist/otel.d.ts.map +1 -0
  120. package/dist/otel.js +84 -0
  121. package/dist/rateLimit.d.ts +11 -3
  122. package/dist/rateLimit.d.ts.map +1 -1
  123. package/dist/rateLimit.js +7 -12
  124. package/dist/{adapters/redis-client.d.ts → redis-client.d.ts} +4 -1
  125. package/dist/redis-client.d.ts.map +1 -0
  126. package/dist/redis-client.js +98 -0
  127. package/dist/{api/reportError.d.ts → reportError.d.ts} +1 -1
  128. package/dist/reportError.d.ts.map +1 -0
  129. package/dist/reportError.js +28 -0
  130. package/dist/{api/routing → routing}/middleware/RouterMiddleware.d.ts +2 -1
  131. package/dist/routing/middleware/RouterMiddleware.d.ts.map +1 -0
  132. package/dist/{api/routing → routing}/middleware/RouterMiddleware.js +1 -1
  133. package/dist/{api/routing → routing}/middleware/middleware.d.ts +11 -6
  134. package/dist/routing/middleware/middleware.d.ts.map +1 -0
  135. package/dist/routing/middleware/middleware.js +152 -0
  136. package/dist/{api/routing → routing}/middleware.d.ts +0 -1
  137. package/dist/routing/middleware.d.ts.map +1 -0
  138. package/dist/{api/routing → routing}/middleware.js +1 -2
  139. package/dist/routing/schema/jwt.d.ts.map +1 -0
  140. package/dist/routing/schema/jwt.js +12 -0
  141. package/dist/routing/tsort.d.ts.map +1 -0
  142. package/dist/routing/tsort.js +51 -0
  143. package/dist/{api/routing → routing}/utils.d.ts +3 -3
  144. package/dist/routing/utils.d.ts.map +1 -0
  145. package/dist/routing/utils.js +45 -0
  146. package/dist/routing.d.ts +182 -0
  147. package/dist/routing.d.ts.map +1 -0
  148. package/dist/routing.js +256 -0
  149. package/dist/test.d.ts +2 -2
  150. package/dist/test.d.ts.map +1 -1
  151. package/dist/test.js +5 -5
  152. package/dist/util.d.ts.map +1 -0
  153. package/dist/util.js +14 -0
  154. package/docs/cluster-storage.md +26 -0
  155. package/docs/workflow-engine.md +262 -0
  156. package/examples/query.ts +23 -19
  157. package/package.json +36 -364
  158. package/src/CUPS.ts +53 -14
  159. package/src/ClusterCosmos.ts +1170 -0
  160. package/src/ClusterServiceBus.ts +244 -0
  161. package/src/{api/ContextProvider.ts → ContextProvider.ts} +10 -7
  162. package/src/Emailer/Sendgrid.ts +83 -60
  163. package/src/Emailer/fake.ts +4 -4
  164. package/src/MainFiberSet.ts +31 -12
  165. package/src/QueueMaker/errors.ts +3 -1
  166. package/src/{adapters/SQL → SQL}/Model.ts +48 -47
  167. package/src/SQL.ts +1 -0
  168. package/src/Store/Cosmos/query.ts +275 -55
  169. package/src/Store/Cosmos.ts +597 -511
  170. package/src/Store/Disk.ts +145 -71
  171. package/src/Store/Memory.ts +420 -115
  172. package/src/Store/SQL/Pg.ts +352 -268
  173. package/src/Store/SQL/query.ts +366 -20
  174. package/src/Store/SQL.ts +742 -293
  175. package/src/Store/codeFilter.ts +78 -28
  176. package/src/Store/index.ts +18 -13
  177. package/src/Store/jsonDocument.ts +143 -0
  178. package/src/Store/utils.ts +307 -30
  179. package/src/WorkflowEngineCosmos.ts +749 -0
  180. package/src/WorkflowEngineSqlite.ts +813 -0
  181. package/src/arbs.ts +25 -5
  182. package/src/cosmos-client.ts +72 -0
  183. package/src/errorReporter.ts +68 -78
  184. package/src/fileUtil.ts +1 -1
  185. package/src/index.ts +2 -1
  186. package/src/{api/internal → internal}/RequestContextMiddleware.ts +23 -6
  187. package/src/internal/auth.ts +272 -0
  188. package/src/{api/internal → internal}/events.ts +18 -9
  189. package/src/{api/layerUtils.ts → layerUtils.ts} +7 -3
  190. package/src/logger/jsonLogger.ts +5 -3
  191. package/src/logger/logFmtLogger.ts +3 -3
  192. package/src/logger/shared.ts +6 -5
  193. package/src/middlewares.ts +10 -0
  194. package/src/{adapters/mongo-client.ts → mongo-client.ts} +3 -1
  195. package/src/otel.ts +177 -0
  196. package/src/rateLimit.ts +35 -24
  197. package/src/{adapters/redis-client.ts → redis-client.ts} +6 -2
  198. package/src/{api/reportError.ts → reportError.ts} +3 -2
  199. package/src/{api/routing → routing}/middleware/RouterMiddleware.ts +2 -1
  200. package/src/{api/routing → routing}/middleware/middleware.ts +75 -50
  201. package/src/routing/middleware.ts +4 -0
  202. package/src/{api/routing → routing}/schema/jwt.ts +2 -2
  203. package/src/{api/routing → routing}/utils.ts +2 -1
  204. package/src/routing.ts +823 -0
  205. package/src/test.ts +6 -6
  206. package/src/vitest.ts +1 -1
  207. package/test/arbs-magnitude.test.ts +33 -0
  208. package/test/arbs.test.ts +41 -0
  209. package/test/auth.test.ts +101 -0
  210. package/test/cluster-cosmos.test.ts +634 -0
  211. package/test/cluster-servicebus.test.ts +180 -0
  212. package/test/cluster-sqlite.test.ts +207 -0
  213. package/test/contextProvider.test.ts +11 -8
  214. package/test/controller.test.ts +23 -28
  215. package/test/cosmos-container-throughput.test.ts +80 -0
  216. package/test/cosmos-query.test.ts +368 -0
  217. package/test/dist/arbs-magnitude.test.d.ts.map +1 -0
  218. package/test/dist/arbs.test.d.ts.map +1 -0
  219. package/test/dist/auth.test.d.ts.map +1 -0
  220. package/test/dist/cluster-cosmos.test.d.ts.map +1 -0
  221. package/test/dist/cluster-servicebus.test.d.ts.map +1 -0
  222. package/test/dist/cluster-sqlite.test.d.ts.map +1 -0
  223. package/test/dist/contextProvider.test.d.ts.map +1 -1
  224. package/test/dist/controller.test.d.ts.map +1 -1
  225. package/test/dist/cosmos-container-throughput.test.d.ts.map +1 -0
  226. package/test/dist/cosmos-query.test.d.ts.map +1 -0
  227. package/test/dist/fixtures.d.ts +17 -9
  228. package/test/dist/fixtures.d.ts.map +1 -1
  229. package/test/dist/fixtures.js +8 -3
  230. package/test/dist/json-lower.test.d.ts.map +1 -0
  231. package/test/dist/query.test.d.ts.map +1 -1
  232. package/test/dist/rawQuery.test.d.ts.map +1 -1
  233. package/test/dist/repository-ext.test.d.ts.map +1 -0
  234. package/test/dist/repository-legacy-document.test.d.ts.map +1 -0
  235. package/test/dist/requires.test.d.ts.map +1 -1
  236. package/test/dist/router-generator.test.d.ts.map +1 -0
  237. package/test/dist/routing-interruptibility.test.d.ts.map +1 -0
  238. package/test/dist/rpc-context-map-streaming.test.d.ts.map +1 -0
  239. package/test/dist/rpc-e2e-invalidation.test.d.ts.map +1 -0
  240. package/test/dist/rpc-multi-middleware.test.d.ts.map +1 -1
  241. package/test/dist/rpc-stream-fullstack.test.d.ts.map +1 -0
  242. package/test/dist/workflow-engine-cosmos.test.d.ts.map +1 -0
  243. package/test/dist/workflow-engine-sqlite.test.d.ts.map +1 -0
  244. package/test/fixtures.ts +7 -2
  245. package/test/json-lower.test.ts +129 -0
  246. package/test/layerUtils.test.ts +2 -2
  247. package/test/query.test.ts +1232 -42
  248. package/test/rawQuery.test.ts +432 -7
  249. package/test/repository-ext.test.ts +456 -0
  250. package/test/repository-legacy-document.test.ts +394 -0
  251. package/test/requires.test.ts +7 -3
  252. package/test/router-generator.test.ts +187 -0
  253. package/test/routing-interruptibility.test.ts +66 -0
  254. package/test/rpc-context-map-streaming.test.ts +265 -0
  255. package/test/rpc-e2e-invalidation.test.ts +421 -0
  256. package/test/rpc-multi-middleware.test.ts +17 -11
  257. package/test/rpc-stream-fullstack.test.ts +307 -0
  258. package/test/sql-store.test.ts +1202 -47
  259. package/test/validateSample.test.ts +70 -42
  260. package/test/workflow-engine-cosmos.test.ts +345 -0
  261. package/test/workflow-engine-sqlite.test.ts +297 -0
  262. package/tsconfig.examples.json +1 -1
  263. package/tsconfig.json +9 -1
  264. package/tsconfig.src.json +35 -35
  265. package/tsconfig.test.json +2 -2
  266. package/dist/Emailer/service.d.ts +0 -55
  267. package/dist/Emailer/service.d.ts.map +0 -1
  268. package/dist/Emailer/service.js +0 -6
  269. package/dist/Emailer.d.ts +0 -2
  270. package/dist/Emailer.d.ts.map +0 -1
  271. package/dist/Emailer.js +0 -2
  272. package/dist/Model/Repository/ext.d.ts +0 -41
  273. package/dist/Model/Repository/ext.d.ts.map +0 -1
  274. package/dist/Model/Repository/ext.js +0 -65
  275. package/dist/Model/Repository/internal/internal.d.ts +0 -59
  276. package/dist/Model/Repository/internal/internal.d.ts.map +0 -1
  277. package/dist/Model/Repository/internal/internal.js +0 -320
  278. package/dist/Model/Repository/legacy.d.ts +0 -19
  279. package/dist/Model/Repository/legacy.d.ts.map +0 -1
  280. package/dist/Model/Repository/legacy.js +0 -2
  281. package/dist/Model/Repository/makeRepo.d.ts +0 -49
  282. package/dist/Model/Repository/makeRepo.d.ts.map +0 -1
  283. package/dist/Model/Repository/makeRepo.js +0 -24
  284. package/dist/Model/Repository/service.d.ts +0 -89
  285. package/dist/Model/Repository/service.d.ts.map +0 -1
  286. package/dist/Model/Repository/service.js +0 -2
  287. package/dist/Model/Repository/validation.d.ts +0 -43
  288. package/dist/Model/Repository/validation.d.ts.map +0 -1
  289. package/dist/Model/Repository/validation.js +0 -32
  290. package/dist/Model/Repository.d.ts +0 -6
  291. package/dist/Model/Repository.d.ts.map +0 -1
  292. package/dist/Model/Repository.js +0 -6
  293. package/dist/Model/dsl.d.ts +0 -32
  294. package/dist/Model/dsl.d.ts.map +0 -1
  295. package/dist/Model/dsl.js +0 -44
  296. package/dist/Model/filter/filterApi.d.ts +0 -30
  297. package/dist/Model/filter/filterApi.d.ts.map +0 -1
  298. package/dist/Model/filter/filterApi.js +0 -2
  299. package/dist/Model/filter/types/errors.d.ts +0 -29
  300. package/dist/Model/filter/types/errors.d.ts.map +0 -1
  301. package/dist/Model/filter/types/errors.js +0 -2
  302. package/dist/Model/filter/types/fields.d.ts +0 -15
  303. package/dist/Model/filter/types/fields.d.ts.map +0 -1
  304. package/dist/Model/filter/types/fields.js +0 -2
  305. package/dist/Model/filter/types/path/common.d.ts +0 -316
  306. package/dist/Model/filter/types/path/common.d.ts.map +0 -1
  307. package/dist/Model/filter/types/path/common.js +0 -2
  308. package/dist/Model/filter/types/path/eager.d.ts +0 -95
  309. package/dist/Model/filter/types/path/eager.d.ts.map +0 -1
  310. package/dist/Model/filter/types/path/eager.js +0 -31
  311. package/dist/Model/filter/types/path/index.d.ts +0 -4
  312. package/dist/Model/filter/types/path/index.d.ts.map +0 -1
  313. package/dist/Model/filter/types/path/index.js +0 -3
  314. package/dist/Model/filter/types/utils.d.ts +0 -79
  315. package/dist/Model/filter/types/utils.d.ts.map +0 -1
  316. package/dist/Model/filter/types/utils.js +0 -2
  317. package/dist/Model/filter/types/validator.d.ts +0 -30
  318. package/dist/Model/filter/types/validator.d.ts.map +0 -1
  319. package/dist/Model/filter/types/validator.js +0 -2
  320. package/dist/Model/filter/types.d.ts +0 -5
  321. package/dist/Model/filter/types.d.ts.map +0 -1
  322. package/dist/Model/filter/types.js +0 -7
  323. package/dist/Model/query/dsl.d.ts +0 -248
  324. package/dist/Model/query/dsl.d.ts.map +0 -1
  325. package/dist/Model/query/dsl.js +0 -104
  326. package/dist/Model/query/new-kid-interpreter.d.ts +0 -28
  327. package/dist/Model/query/new-kid-interpreter.d.ts.map +0 -1
  328. package/dist/Model/query/new-kid-interpreter.js +0 -165
  329. package/dist/Model/query.d.ts +0 -15
  330. package/dist/Model/query.d.ts.map +0 -1
  331. package/dist/Model/query.js +0 -3
  332. package/dist/Model.d.ts +0 -4
  333. package/dist/Model.d.ts.map +0 -1
  334. package/dist/Model.js +0 -4
  335. package/dist/Operations.d.ts +0 -55
  336. package/dist/Operations.d.ts.map +0 -1
  337. package/dist/Operations.js +0 -102
  338. package/dist/OperationsRepo.d.ts +0 -41
  339. package/dist/OperationsRepo.d.ts.map +0 -1
  340. package/dist/OperationsRepo.js +0 -14
  341. package/dist/QueueMaker/SQLQueue.d.ts +0 -14
  342. package/dist/QueueMaker/SQLQueue.d.ts.map +0 -1
  343. package/dist/QueueMaker/SQLQueue.js +0 -132
  344. package/dist/QueueMaker/memQueue.d.ts +0 -11
  345. package/dist/QueueMaker/memQueue.d.ts.map +0 -1
  346. package/dist/QueueMaker/memQueue.js +0 -76
  347. package/dist/QueueMaker/sbqueue.d.ts +0 -12
  348. package/dist/QueueMaker/sbqueue.d.ts.map +0 -1
  349. package/dist/QueueMaker/sbqueue.js +0 -91
  350. package/dist/QueueMaker/service.d.ts +0 -11
  351. package/dist/QueueMaker/service.d.ts.map +0 -1
  352. package/dist/QueueMaker/service.js +0 -4
  353. package/dist/RequestContext.d.ts +0 -68
  354. package/dist/RequestContext.d.ts.map +0 -1
  355. package/dist/RequestContext.js +0 -49
  356. package/dist/RequestFiberSet.d.ts +0 -36
  357. package/dist/RequestFiberSet.d.ts.map +0 -1
  358. package/dist/RequestFiberSet.js +0 -78
  359. package/dist/Store/ContextMapContainer.d.ts +0 -25
  360. package/dist/Store/ContextMapContainer.d.ts.map +0 -1
  361. package/dist/Store/ContextMapContainer.js +0 -77
  362. package/dist/Store/service.d.ts +0 -111
  363. package/dist/Store/service.d.ts.map +0 -1
  364. package/dist/Store/service.js +0 -79
  365. package/dist/Store.d.ts +0 -2
  366. package/dist/Store.d.ts.map +0 -1
  367. package/dist/Store.js +0 -2
  368. package/dist/adapters/SQL/Model.d.ts.map +0 -1
  369. package/dist/adapters/SQL/Model.js +0 -478
  370. package/dist/adapters/SQL.d.ts.map +0 -1
  371. package/dist/adapters/ServiceBus.d.ts +0 -58
  372. package/dist/adapters/ServiceBus.d.ts.map +0 -1
  373. package/dist/adapters/ServiceBus.js +0 -99
  374. package/dist/adapters/cosmos-client.d.ts +0 -14
  375. package/dist/adapters/cosmos-client.d.ts.map +0 -1
  376. package/dist/adapters/cosmos-client.js +0 -9
  377. package/dist/adapters/index.d.ts +0 -2
  378. package/dist/adapters/index.d.ts.map +0 -1
  379. package/dist/adapters/index.js +0 -2
  380. package/dist/adapters/logger.d.ts +0 -9
  381. package/dist/adapters/logger.d.ts.map +0 -1
  382. package/dist/adapters/logger.js +0 -3
  383. package/dist/adapters/memQueue.d.ts +0 -13
  384. package/dist/adapters/memQueue.d.ts.map +0 -1
  385. package/dist/adapters/memQueue.js +0 -20
  386. package/dist/adapters/mongo-client.d.ts.map +0 -1
  387. package/dist/adapters/mongo-client.js +0 -13
  388. package/dist/adapters/redis-client.d.ts.map +0 -1
  389. package/dist/adapters/redis-client.js +0 -94
  390. package/dist/api/ContextProvider.d.ts.map +0 -1
  391. package/dist/api/ContextProvider.js +0 -38
  392. package/dist/api/codec.d.ts.map +0 -1
  393. package/dist/api/codec.js +0 -5
  394. package/dist/api/internal/RequestContextMiddleware.d.ts +0 -5
  395. package/dist/api/internal/RequestContextMiddleware.d.ts.map +0 -1
  396. package/dist/api/internal/RequestContextMiddleware.js +0 -35
  397. package/dist/api/internal/auth.d.ts +0 -15
  398. package/dist/api/internal/auth.d.ts.map +0 -1
  399. package/dist/api/internal/auth.js +0 -47
  400. package/dist/api/internal/events.d.ts +0 -9
  401. package/dist/api/internal/events.d.ts.map +0 -1
  402. package/dist/api/internal/events.js +0 -42
  403. package/dist/api/internal/health.d.ts.map +0 -1
  404. package/dist/api/internal/health.js +0 -5
  405. package/dist/api/layerUtils.d.ts.map +0 -1
  406. package/dist/api/layerUtils.js +0 -16
  407. package/dist/api/middlewares.d.ts.map +0 -1
  408. package/dist/api/reportError.d.ts.map +0 -1
  409. package/dist/api/reportError.js +0 -27
  410. package/dist/api/routing/middleware/RouterMiddleware.d.ts.map +0 -1
  411. package/dist/api/routing/middleware/middleware.d.ts.map +0 -1
  412. package/dist/api/routing/middleware/middleware.js +0 -130
  413. package/dist/api/routing/middleware.d.ts.map +0 -1
  414. package/dist/api/routing/schema/jwt.d.ts.map +0 -1
  415. package/dist/api/routing/schema/jwt.js +0 -12
  416. package/dist/api/routing/tsort.d.ts.map +0 -1
  417. package/dist/api/routing/tsort.js +0 -51
  418. package/dist/api/routing/utils.d.ts.map +0 -1
  419. package/dist/api/routing/utils.js +0 -44
  420. package/dist/api/routing.d.ts +0 -134
  421. package/dist/api/routing.d.ts.map +0 -1
  422. package/dist/api/routing.js +0 -167
  423. package/dist/api/setupRequest.d.ts +0 -15
  424. package/dist/api/setupRequest.d.ts.map +0 -1
  425. package/dist/api/setupRequest.js +0 -49
  426. package/dist/api/util.d.ts.map +0 -1
  427. package/dist/api/util.js +0 -14
  428. package/eslint.config.mjs +0 -24
  429. package/src/Emailer/service.ts +0 -52
  430. package/src/Emailer.ts +0 -1
  431. package/src/Model/Repository/ext.ts +0 -283
  432. package/src/Model/Repository/internal/internal.ts +0 -580
  433. package/src/Model/Repository/legacy.ts +0 -27
  434. package/src/Model/Repository/makeRepo.ts +0 -139
  435. package/src/Model/Repository/service.ts +0 -627
  436. package/src/Model/Repository/validation.ts +0 -31
  437. package/src/Model/Repository.ts +0 -5
  438. package/src/Model/dsl.ts +0 -128
  439. package/src/Model/filter/filterApi.ts +0 -60
  440. package/src/Model/filter/types/errors.ts +0 -47
  441. package/src/Model/filter/types/fields.ts +0 -50
  442. package/src/Model/filter/types/path/common.ts +0 -404
  443. package/src/Model/filter/types/path/eager.ts +0 -298
  444. package/src/Model/filter/types/path/index.ts +0 -4
  445. package/src/Model/filter/types/utils.ts +0 -128
  446. package/src/Model/filter/types/validator.ts +0 -46
  447. package/src/Model/filter/types.ts +0 -6
  448. package/src/Model/query/dsl.ts +0 -2110
  449. package/src/Model/query/new-kid-interpreter.ts +0 -210
  450. package/src/Model/query.ts +0 -13
  451. package/src/Model.ts +0 -3
  452. package/src/Operations.ts +0 -235
  453. package/src/OperationsRepo.ts +0 -16
  454. package/src/QueueMaker/SQLQueue.ts +0 -190
  455. package/src/QueueMaker/memQueue.ts +0 -130
  456. package/src/QueueMaker/sbqueue.ts +0 -137
  457. package/src/QueueMaker/service.ts +0 -17
  458. package/src/RequestContext.ts +0 -63
  459. package/src/RequestFiberSet.ts +0 -105
  460. package/src/Store/ContextMapContainer.ts +0 -116
  461. package/src/Store/index.test.ts.bak +0 -112
  462. package/src/Store/service.ts +0 -193
  463. package/src/Store.ts +0 -1
  464. package/src/adapters/SQL.ts +0 -1
  465. package/src/adapters/ServiceBus.ts +0 -209
  466. package/src/adapters/cosmos-client.ts +0 -16
  467. package/src/adapters/index.ts +0 -0
  468. package/src/adapters/logger.ts +0 -3
  469. package/src/adapters/memQueue.ts +0 -21
  470. package/src/api/internal/auth.ts +0 -68
  471. package/src/api/middlewares.ts +0 -10
  472. package/src/api/routing/middleware.ts +0 -6
  473. package/src/api/routing.ts +0 -598
  474. package/src/api/setupRequest.ts +0 -104
  475. package/test/dist/date-query.test.d.ts.map +0 -1
  476. package/tsconfig.json.bak +0 -12
  477. /package/dist/{adapters/SQL.d.ts → SQL.d.ts} +0 -0
  478. /package/dist/{api/codec.d.ts → codec.d.ts} +0 -0
  479. /package/dist/{api/middlewares.d.ts → middlewares.d.ts} +0 -0
  480. /package/dist/{api/routing → routing}/schema/jwt.d.ts +0 -0
  481. /package/dist/{api/routing → routing}/tsort.d.ts +0 -0
  482. /package/dist/{api/util.d.ts → util.d.ts} +0 -0
  483. /package/src/{api/codec.ts → codec.ts} +0 -0
  484. /package/src/{api/internal → internal}/health.ts +0 -0
  485. /package/src/{api/routing → routing}/tsort.ts +0 -0
  486. /package/src/{api/util.ts → util.ts} +0 -0
@@ -1,7 +1,13 @@
1
- import { Duration, Effect, pipe, S, Schedule, Stream } from "effect-app"
1
+ import * as Effect from "effect-app/Effect"
2
2
  import { HttpHeaders, HttpServerResponse } from "effect-app/http"
3
- import { reportError } from "../../errorReporter.js"
4
- import { setupRequestContextFromCurrent } from "../setupRequest.js"
3
+ import * as S from "effect-app/Schema"
4
+ import { setupStreamingRequestContextFromCurrent } from "effect-app/setupRequest"
5
+ import { storeId } from "effect-app/Store"
6
+ import * as Duration from "effect/Duration"
7
+ import { pipe } from "effect/Function"
8
+ import * as Schedule from "effect/Schedule"
9
+ import * as Stream from "effect/Stream"
10
+ import { reportError } from "../errorReporter.ts"
5
11
 
6
12
  // Tell the client to retry every 10 seconds if connectivity is lost
7
13
  const setRetry = Stream.succeed("retry: 10000")
@@ -22,16 +28,19 @@ export const makeSSE = <A extends { id: any }, SI, SRD, SRE>(
22
28
  // https://discord.com/channels/795981131316985866/1098177242598756412/1389646879675125861
23
29
  Effect
24
30
  .gen(function*() {
25
- yield* Effect.annotateCurrentSpan({ connectionId: id.toString() })
26
- yield* Effect.logInfo("$ start listening to events, id: " + id.toString())
27
- yield* Effect.addFinalizer(() => Effect.logInfo("$ end listening to events, id: " + id.toString()))
31
+ const ns = yield* storeId
32
+ yield* Effect.annotateCurrentSpan({ "network.connection.id": id.toString() })
33
+ yield* Effect.logInfo("$ start listening to events, id: " + id.toString() + ", ns: " + ns)
34
+ yield* Effect.addFinalizer(() =>
35
+ Effect.logInfo("$ end listening to events, id: " + id.toString() + ", ns: " + ns)
36
+ )
28
37
 
29
38
  const enc = new TextEncoder()
30
39
 
31
40
  const encode = S.encodeEffect(S.fromJsonString(S.toCodecJson(schema)))
32
41
 
33
42
  const eventStream = Stream.mapEffect(
34
- events,
43
+ Stream.filter(events, (_) => _.namespace === ns),
35
44
  (_) =>
36
45
  encode(_.evt)
37
46
  .pipe(Effect.map((data) => `id: ${_.evt.id}\ndata: ${data}`))
@@ -42,7 +51,7 @@ export const makeSSE = <A extends { id: any }, SI, SRD, SRE>(
42
51
  Stream.merge(keepAlive),
43
52
  // Keep this unary so pipe receives a function, not a Stream value.
44
53
  (self) => Stream.merge(self, eventStream, { haltStrategy: "either" }),
45
- Stream.tapCause((cause) => Effect.logError("SSE error", cause)),
54
+ Stream.tapCause((cause) => Effect.logError("SSE error, id: " + id.toString() + ", ns: " + ns, cause)),
46
55
  Stream.map((_) => enc.encode(_ + "\n\n"))
47
56
  )
48
57
 
@@ -65,4 +74,4 @@ export const makeSSE = <A extends { id: any }, SI, SRD, SRE>(
65
74
  )
66
75
  return res
67
76
  })
68
- .pipe(Effect.tapCause(reportError("Request")), setupRequestContextFromCurrent("events"))
77
+ .pipe(Effect.tapCause(reportError("Request")), setupStreamingRequestContextFromCurrent("events"))
@@ -1,6 +1,10 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
- import { Context, Effect, type Layer, type NonEmptyReadonlyArray, Option } from "effect-app"
3
- import { InfraLogger } from "../logger.js"
2
+ import type { NonEmptyReadonlyArray } from "effect-app/Array"
3
+ import * as Context from "effect-app/Context"
4
+ import * as Effect from "effect-app/Effect"
5
+ import type * as Layer from "effect-app/Layer"
6
+ import * as Option from "effect-app/Option"
7
+ import { InfraLogger } from "./logger.ts"
4
8
 
5
9
  // TODO: These LayerUtils are flaky, like in dependencies as a readonly array, it breaks when there are two entries
6
10
  // we should look at Service.MakeDeps[E/RIn/ROut] etc.
@@ -33,7 +37,7 @@ export type ContextTagWithDefault<Id, A, LayerE, LayerR> =
33
37
  }
34
38
 
35
39
  export namespace ContextTagWithDefault {
36
- export type Base<A> = ContextTagWithDefault<any, A, any, any>
40
+ export type Base<A> = { readonly Service: A } & { Default: Layer.Layer<any, any, any> }
37
41
  }
38
42
 
39
43
  export type GetContext<T> = T extends Context.Context<infer Y> ? Y : never
@@ -1,7 +1,9 @@
1
- import { Array, Cause, Logger } from "effect-app"
1
+ import * as Array from "effect-app/Array"
2
+ import { spanAttributes } from "effect-app/RequestContext"
3
+ import * as Cause from "effect/Cause"
4
+ import * as Logger from "effect/Logger"
2
5
  import { CurrentLogAnnotations, CurrentLogSpans } from "effect/References"
3
- import { spanAttributes } from "../RequestContext.js"
4
- import { getRequestContextFromFiber } from "./shared.js"
6
+ import { getRequestContextFromFiber } from "./shared.ts"
5
7
 
6
8
  export const jsonLogger = Logger.make<unknown, void>(
7
9
  ({ cause, date, fiber, logLevel, message }) => {
@@ -1,6 +1,6 @@
1
- import { Logger } from "effect-app"
2
- import { spanAttributes } from "../RequestContext.js"
3
- import { getRequestContextFromFiber } from "./shared.js"
1
+ import { spanAttributes } from "effect-app/RequestContext"
2
+ import * as Logger from "effect/Logger"
3
+ import { getRequestContextFromFiber } from "./shared.ts"
4
4
 
5
5
  export const logfmtLogger = Logger.make<unknown, void>(
6
6
  (options) => {
@@ -1,13 +1,14 @@
1
- import { type Fiber, Option } from "effect-app"
1
+ import * as Option from "effect-app/Option"
2
+ import { LocaleRef, RequestContext } from "effect-app/RequestContext"
2
3
  import { NonEmptyString255 } from "effect-app/Schema"
3
- import { LocaleRef, RequestContext } from "../RequestContext.js"
4
- import { storeId } from "../Store/Memory.js"
4
+ import { storeId } from "effect-app/Store"
5
+ import type * as Fiber from "effect/Fiber"
5
6
 
6
7
  export function getRequestContextFromFiber(fiber: Fiber.Fiber<unknown, unknown>) {
7
- const span = Option.fromNullishOr(fiber.currentSpan)
8
+ const span = Option.fromNullishOr(fiber.cache.span)
8
9
  const locale = fiber.getRef(LocaleRef)
9
10
  const namespace = fiber.getRef(storeId)
10
- return new RequestContext({
11
+ return RequestContext.make({
11
12
  span: Option.map(span, (s) => ({ spanId: s.spanId, traceId: s.traceId, sampled: s.sampled })).pipe(
12
13
  Option.getOrElse(() => ({ spanId: "bogus", sampled: true, traceId: "bogus" }))
13
14
  ),
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Mechanism for extendning behaviour of all handlers on the server.
3
+ *
4
+ * @since 1.0.0
5
+ */
6
+
7
+ export * from "./internal/auth.ts"
8
+ export * from "./internal/events.ts"
9
+ export * from "./internal/health.ts"
10
+ export * from "./internal/RequestContextMiddleware.ts"
@@ -1,4 +1,6 @@
1
- import { Context, Effect, Layer } from "effect-app"
1
+ import * as Context from "effect-app/Context"
2
+ import * as Effect from "effect-app/Effect"
3
+ import * as Layer from "effect-app/Layer"
2
4
  import { MongoClient as MongoClient_ } from "mongodb"
3
5
 
4
6
  // TODO: we should probably share a single client...
package/src/otel.ts ADDED
@@ -0,0 +1,177 @@
1
+ /**
2
+ * OpenTelemetry semantic-convention helpers for span attributes.
3
+ *
4
+ * Aligns repository / queue / cache adapters with stable OTel semconv keys so
5
+ * downstream collectors and dashboards work without per-adapter mappings.
6
+ *
7
+ * - Database: https://opentelemetry.io/docs/specs/semconv/database/
8
+ * - Messaging: https://opentelemetry.io/docs/specs/semconv/messaging/
9
+ * - Cosmos DB: https://opentelemetry.io/docs/specs/semconv/database/cosmosdb/
10
+ */
11
+
12
+ import * as Effect from "effect-app/Effect"
13
+ import * as Metric from "effect/Metric"
14
+
15
+ export type DbSystem =
16
+ | "postgresql"
17
+ | "sqlite"
18
+ | "cosmosdb"
19
+ | "mongodb"
20
+ | "redis"
21
+ | "other_sql"
22
+ | "memory"
23
+ | "disk"
24
+
25
+ export interface DbSpanOptions {
26
+ /** OTel `db.operation.name` (e.g. `find`, `all`, `filter`, `set`). */
27
+ readonly operation: string
28
+ readonly system: DbSystem
29
+ /** Logical collection / table / container name. */
30
+ readonly collection: string
31
+ /** Tenant / namespace / database name. */
32
+ readonly namespace?: string | undefined
33
+ /** Application-level entity / model name (custom: `app.entity`). */
34
+ readonly entity?: string | undefined
35
+ /** Sanitized / parameterized query text. Never include bound values. */
36
+ readonly query?: string | undefined
37
+ /** Optional fragments merged into final attributes (e.g. id, partition). */
38
+ readonly extra?: Record<string, unknown> | undefined
39
+ }
40
+
41
+ const dbAttributes = (a: DbSpanOptions): Record<string, unknown> => ({
42
+ "db.system.name": a.system,
43
+ "db.operation.name": a.operation,
44
+ "db.collection.name": a.collection,
45
+ ...(a.namespace !== undefined && { "db.namespace": a.namespace }),
46
+ ...(a.query !== undefined && { "db.query.text": a.query }),
47
+ ...(a.entity !== undefined && { "app.entity": a.entity }),
48
+ ...a.extra
49
+ })
50
+
51
+ const dbOperationDuration = Metric.histogram("db.client.operation.duration", {
52
+ boundaries: [0.1, 0.5, 1, 2, 5, 10, 25, 50, 100, 250, 500, 1_000, 2_500, 5_000, 10_000],
53
+ description: "Caller-observed database operation duration in milliseconds"
54
+ })
55
+
56
+ const timeDbOperation = (a: DbSpanOptions) => <A, E, R>(self: Effect.Effect<A, E, R>): Effect.Effect<A, E, R> =>
57
+ Effect.clockWith((clock) => {
58
+ const startedAt = clock.currentTimeNanosUnsafe()
59
+ return Effect.onExit(self, () => {
60
+ const durationMs = Number(clock.currentTimeNanosUnsafe() - startedAt) / 1_000_000
61
+ return Effect.all([
62
+ Effect.annotateCurrentSpan({ "db.operation.duration_ms": durationMs }),
63
+ Metric.update(
64
+ Metric.withAttributes(dbOperationDuration, {
65
+ "db.system.name": a.system,
66
+ "db.operation.name": a.operation,
67
+ ...(a.entity !== undefined && { "app.entity": a.entity })
68
+ }),
69
+ durationMs
70
+ )
71
+ ], { discard: true })
72
+ })
73
+ })
74
+
75
+ /**
76
+ * Wrap an effect with an OTel-semconv database span.
77
+ *
78
+ * Span name follows the low-cardinality convention: `<operation> <collection>`.
79
+ */
80
+ export const withDbSpan = (a: DbSpanOptions) =>
81
+ Effect.withSpan(
82
+ `${a.operation} ${a.collection}`,
83
+ { attributes: dbAttributes(a), kind: "client" as const },
84
+ { captureStackTrace: false }
85
+ )
86
+
87
+ /**
88
+ * Annotate the current span with OTel-semconv database attributes.
89
+ *
90
+ * Use when the caller already owns the span (e.g. a repository) and the
91
+ * adapter should only contribute db.* semconv attrs without opening a child.
92
+ * Annotates before running so attrs persist even on failure.
93
+ * No-op if there is no current span.
94
+ */
95
+ export const annotateDb = (a: DbSpanOptions) => <A, E, R>(self: Effect.Effect<A, E, R>): Effect.Effect<A, E, R> =>
96
+ Effect.flatMap(Effect.annotateCurrentSpan(dbAttributes(a)), () => self.pipe(timeDbOperation(a)))
97
+
98
+ /** Annotate the current span with response metrics from a DB call. */
99
+ export const annotateDbResponse = (m: {
100
+ readonly returnedRows?: number | undefined
101
+ readonly responseBytes?: number | undefined
102
+ }) =>
103
+ Effect.annotateCurrentSpan({
104
+ ...(m.returnedRows !== undefined && { "db.response.returned_rows": m.returnedRows }),
105
+ ...(m.responseBytes !== undefined && { "db.response.body.size": m.responseBytes })
106
+ })
107
+
108
+ /** Cosmos-specific response annotations. */
109
+ export const annotateCosmosResponse = (m: {
110
+ readonly requestCharge?: number | undefined
111
+ readonly returnedRows?: number | undefined
112
+ readonly responseBytes?: number | undefined
113
+ readonly statusCode?: number | undefined
114
+ }) =>
115
+ Effect.annotateCurrentSpan({
116
+ ...(m.requestCharge !== undefined && { "azure.cosmosdb.operation.request_charge": m.requestCharge }),
117
+ ...(m.statusCode !== undefined && { "db.response.status_code": String(m.statusCode) }),
118
+ ...(m.returnedRows !== undefined && { "db.response.returned_rows": m.returnedRows }),
119
+ ...(m.responseBytes !== undefined && { "db.response.body.size": m.responseBytes })
120
+ })
121
+
122
+ export type MessagingSystem =
123
+ | "servicebus"
124
+ | "rabbitmq"
125
+ | "kafka"
126
+ | "memory"
127
+ | "sql"
128
+
129
+ export type MessagingOperation =
130
+ | "publish"
131
+ | "create"
132
+ | "receive"
133
+ | "process"
134
+ | "settle"
135
+
136
+ export interface MessagingSpanOptions {
137
+ readonly operation: MessagingOperation
138
+ readonly system: MessagingSystem
139
+ /** Queue / topic name. */
140
+ readonly destination: string
141
+ readonly messageId?: string | undefined
142
+ readonly conversationId?: string | undefined
143
+ readonly bodySize?: number | undefined
144
+ readonly extra?: Record<string, unknown> | undefined
145
+ }
146
+
147
+ const messagingAttributes = (a: MessagingSpanOptions): Record<string, unknown> => ({
148
+ "messaging.system": a.system,
149
+ "messaging.operation.name": a.operation,
150
+ "messaging.destination.name": a.destination,
151
+ ...(a.messageId !== undefined && { "messaging.message.id": a.messageId }),
152
+ ...(a.conversationId !== undefined && { "messaging.message.conversation_id": a.conversationId }),
153
+ ...(a.bodySize !== undefined && { "messaging.message.body.size": a.bodySize }),
154
+ ...a.extra
155
+ })
156
+
157
+ /** Wrap an effect with an OTel-semconv messaging span. */
158
+ export const withMessagingSpan = (
159
+ a: MessagingSpanOptions,
160
+ kind: "producer" | "consumer"
161
+ ) =>
162
+ Effect.withSpan(
163
+ `${a.operation} ${a.destination}`,
164
+ { kind, attributes: messagingAttributes(a) },
165
+ { captureStackTrace: false }
166
+ )
167
+
168
+ /** Build messaging span options without wrapping (for Effect.fn / setupRequestContextWithCustomSpan). */
169
+ export const messagingSpanArgs = (
170
+ a: MessagingSpanOptions,
171
+ kind: "producer" | "consumer"
172
+ ) =>
173
+ ({
174
+ name: `${a.operation} ${a.destination}`,
175
+ kind,
176
+ attributes: messagingAttributes(a)
177
+ }) as const
package/src/rateLimit.ts CHANGED
@@ -20,8 +20,13 @@
20
20
  // }
21
21
  // }
22
22
 
23
- import { Array, type Duration, Effect, type NonEmptyArray } from "effect-app"
23
+ import * as Array from "effect-app/Array"
24
+ import type { NonEmptyArray } from "effect-app/Array"
25
+ import * as Effect from "effect-app/Effect"
26
+ import { dual } from "effect-app/Function"
27
+ import type * as Duration from "effect/Duration"
24
28
  import type { Semaphore } from "effect/Semaphore"
29
+ import type { Concurrency } from "effect/Types"
25
30
 
26
31
  /**
27
32
  * Executes the specified effect, acquiring the specified number of permits
@@ -45,36 +50,42 @@ export function SEM_withPermitsDuration(permits: number, duration: Duration.Dura
45
50
  }
46
51
  }
47
52
 
48
- export function batchPar<R, E, A, R2, E2, A2, T>(
49
- n: number,
50
- forEachItem: (item: T, iWithinBatch: number, batchI: number) => Effect.Effect<A, E, R>,
51
- forEachBatch: (a: NonEmptyArray<A>, i: number) => Effect.Effect<A2, E2, R2>
52
- ) {
53
- return (items: Iterable<T>) =>
54
- Effect.forEach(
55
- Array.chunksOf(items, n),
56
- (_, i) =>
57
- Effect
58
- .forEach(_, (_, j) => forEachItem(_, j, i), { concurrency: "inherit" })
59
- .pipe(Effect.flatMap((_) => forEachBatch(_, i))),
60
- { concurrency: "inherit" }
61
- )
53
+ export interface BatchOptions {
54
+ readonly concurrency?: Concurrency | undefined
62
55
  }
63
56
 
64
- export function batch<R, E, A, R2, E2, A2, T>(
65
- n: number,
66
- forEachItem: (item: T, iWithinBatch: number, batchI: number) => Effect.Effect<A, E, R>,
67
- forEachBatch: (a: NonEmptyArray<A>, i: number) => Effect.Effect<A2, E2, R2>
68
- ) {
69
- return (items: Iterable<T>) =>
57
+ export const batch: {
58
+ <T, A, E, R, A2, E2, R2>(
59
+ n: number,
60
+ forEachItem: (item: T, iWithinBatch: number, batchI: number) => Effect.Effect<A, E, R>,
61
+ forEachBatch: (a: NonEmptyArray<A>, i: number) => Effect.Effect<A2, E2, R2>,
62
+ options?: BatchOptions
63
+ ): (items: Iterable<T>) => Effect.Effect<Array<A2>, E | E2, R | R2>
64
+ <T, A, E, R, A2, E2, R2>(
65
+ items: Iterable<T>,
66
+ n: number,
67
+ forEachItem: (item: T, iWithinBatch: number, batchI: number) => Effect.Effect<A, E, R>,
68
+ forEachBatch: (a: NonEmptyArray<A>, i: number) => Effect.Effect<A2, E2, R2>,
69
+ options?: BatchOptions
70
+ ): Effect.Effect<Array<A2>, E | E2, R | R2>
71
+ } = dual(
72
+ (args) => typeof args[0] !== "number",
73
+ <T, A, E, R, A2, E2, R2>(
74
+ items: Iterable<T>,
75
+ n: number,
76
+ forEachItem: (item: T, iWithinBatch: number, batchI: number) => Effect.Effect<A, E, R>,
77
+ forEachBatch: (a: NonEmptyArray<A>, i: number) => Effect.Effect<A2, E2, R2>,
78
+ options?: BatchOptions
79
+ ) =>
70
80
  Effect.forEach(
71
81
  Array.chunksOf(items, n),
72
82
  (_, i) =>
73
83
  Effect
74
- .forEach(_, (_, j) => forEachItem(_, j, i), { concurrency: "inherit" })
75
- .pipe(Effect.flatMap((_) => forEachBatch(_, i)))
84
+ .forEach(_, (_, j) => forEachItem(_, j, i), { concurrency: options?.concurrency })
85
+ .pipe(Effect.flatMap((_) => forEachBatch(_, i))),
86
+ { concurrency: options?.concurrency }
76
87
  )
77
- }
88
+ )
78
89
 
79
90
  // export function rateLimit(
80
91
  // n: number,
@@ -1,10 +1,14 @@
1
- import { Context, Data, Effect, Layer, Option } from "effect-app"
1
+ import * as Context from "effect-app/Context"
2
+ import * as Effect from "effect-app/Effect"
3
+ import * as Layer from "effect-app/Layer"
4
+ import * as Option from "effect-app/Option"
5
+ import * as Data from "effect/Data"
2
6
  import type { RedisClient as Client } from "redis"
3
7
  import Redlock from "redlock"
4
8
 
5
9
  export class ConnectionException extends Data.TaggedError("ConnectionException")<{ cause: Error; message: string }> {
6
10
  constructor(cause: Error) {
7
- super({ message: "A connection error ocurred", cause })
11
+ super({ message: "A connection error occurred", cause })
8
12
  }
9
13
  }
10
14
 
@@ -1,5 +1,6 @@
1
- import { Cause, Effect } from "effect-app"
2
- import { logError, reportError } from "../errorReporter.js"
1
+ import * as Effect from "effect-app/Effect"
2
+ import * as Cause from "effect/Cause"
3
+ import { logError, reportError } from "./errorReporter.ts"
3
4
 
4
5
  // const onExitReportError = (name: string, unknownOnly?: boolean) => {
5
6
  // const report = reportError(name)
@@ -1,7 +1,8 @@
1
1
  /* eslint-disable @typescript-eslint/no-unsafe-assignment */
2
2
  /* eslint-disable @typescript-eslint/no-unsafe-return */
3
3
  /* eslint-disable @typescript-eslint/no-explicit-any */
4
- import { type Context, type Layer } from "effect-app"
4
+ import type * as Context from "effect-app/Context"
5
+ import type * as Layer from "effect-app/Layer"
5
6
  import { type GetContextConfig, type RpcContextMap } from "effect-app/rpc/RpcContextMap"
6
7
  import { type RpcMiddlewareV4 } from "effect-app/rpc/RpcMiddleware"
7
8
  // module:
@@ -1,22 +1,67 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
- import { Cause, Config, Effect, Layer, Schema } from "effect"
3
2
  import { ConfigureInterruptibilityMiddleware, DevMode, DevModeMiddleware, LoggerMiddleware, RequestCacheMiddleware } from "effect-app/middleware"
4
3
  import { RpcContextMap, type RpcMiddleware } from "effect-app/rpc"
5
4
  import { pretty } from "effect-app/utils"
6
- import { type Rpc } from "effect/unstable/rpc"
7
- import { SqlClient } from "effect/unstable/sql"
8
- import { logError, reportError } from "../../../errorReporter.js"
9
- import { InfraLogger } from "../../../logger.js"
10
- import { determineMethod, isCommand } from "../utils.js"
5
+ import * as Array from "effect/Array"
6
+ import * as Cause from "effect/Cause"
7
+ import * as Config from "effect/Config"
8
+ import * as Context from "effect/Context"
9
+ import * as Effect from "effect/Effect"
10
+ import * as Layer from "effect/Layer"
11
+ import { type Rpc } from "effect/rpc"
12
+ import * as Schema from "effect/Schema"
13
+ import { logError, reportError } from "../../errorReporter.ts"
14
+ import { InfraLogger } from "../../logger.ts"
15
+ import { WithNsTransaction } from "../../Store/SQL.ts"
11
16
 
12
17
  const logRequestError = logError("Request")
13
18
  const reportRequestError = reportError("Request")
14
19
 
20
+ // Summarize an rpc payload for the `rpc.request.payload` span attribute.
21
+ // Scalars are kept (long strings snipped), nested objects are recursed into up
22
+ // to `PAYLOAD_MAX_DEPTH` so useful inputs (carrier, packageType, dimensions, ids,
23
+ // …) are captured. Arrays are sampled to the first `PAYLOAD_ARRAY_HEAD` elements
24
+ // (with a `…N more` marker when longer) so pack/pick item arrays — one entry per
25
+ // article, quantity folded into `amount` — are diagnosable without dumping the
26
+ // whole tail on every (high-frequency) SaveItems.
27
+ const PAYLOAD_MAX_DEPTH = 4
28
+ const PAYLOAD_ARRAY_HEAD = 20
29
+ const REDACTED_KEYS = new Set(["password", "secret", "token"])
30
+
31
+ const summarizePayloadValue = (key: string, value: unknown, depth: number): unknown => {
32
+ if (REDACTED_KEYS.has(key)) return "<redacted>"
33
+ if (typeof value === "string") return value.length > 256 ? value.substring(0, 253) + "..." : value
34
+ if (typeof value === "number" || typeof value === "boolean") return value
35
+ if (value === null || value === undefined) return `${value}`
36
+ if (Array.isArray(value)) {
37
+ if (depth >= PAYLOAD_MAX_DEPTH) return `Array[${value.length}]`
38
+ const head = value.slice(0, PAYLOAD_ARRAY_HEAD).map((v) => summarizePayloadValue(key, v, depth + 1))
39
+ return value.length > PAYLOAD_ARRAY_HEAD ? [...head, `…${value.length - PAYLOAD_ARRAY_HEAD} more`] : head
40
+ }
41
+ if (typeof value === "object") {
42
+ return depth >= PAYLOAD_MAX_DEPTH
43
+ ? `Object[${Object.keys(value).length}]`
44
+ : Object.entries(value).reduce((prev, [k, v]) => {
45
+ prev[k] = summarizePayloadValue(k, v, depth + 1)
46
+ return prev
47
+ }, {} as Record<string, unknown>)
48
+ }
49
+ return typeof value
50
+ }
51
+
52
+ const summarizePayload = (payload: unknown): unknown =>
53
+ typeof payload === "object" && payload !== null
54
+ ? Object.entries(payload).reduce((prev, [key, value]) => {
55
+ prev[key] = summarizePayloadValue(key, value, 1)
56
+ return prev
57
+ }, {} as Record<string, unknown>)
58
+ : payload
59
+
15
60
  // TODO: do we need this as middleware or just as layer?
16
61
  export const DevModeLive = Layer.effect(
17
62
  DevMode,
18
63
  Effect.gen(function*() {
19
- const env = yield* Config.string("env").pipe(Config.withDefault("local-dev"))
64
+ const env = yield* Config.String("env").pipe(Config.withDefault("local-dev"))
20
65
  return env !== "prod"
21
66
  })
22
67
  )
@@ -29,22 +74,20 @@ export const RequestCacheMiddlewareLive = Layer.succeed(
29
74
  const isOptimisticConcurrencyException = (input: unknown) =>
30
75
  typeof input === "object" && input !== null && "_tag" in input && input._tag === "OptimisticConcurrencyException"
31
76
 
77
+ export const RequestType = Context.Reference<"command" | "query">(
78
+ "@effect-app/infra/routing/RequestType",
79
+ { defaultValue: () => "query" }
80
+ )
81
+
32
82
  export const ConfigureInterruptibilityMiddlewareLive = Layer.effect(
33
83
  ConfigureInterruptibilityMiddleware,
34
84
  Effect.gen(function*() {
35
- const cache = new Map()
36
- const getCached = (key: string, schema: Schema.Top) => {
37
- const existing = cache.get(key)
38
- if (existing) return existing
39
- const n = determineMethod(key, schema)
40
- cache.set(key, n)
41
- return n
42
- }
43
85
  return (effect, { rpc }) => {
44
- const method = getCached(rpc._tag, rpc.payloadSchema)
86
+ const requestType = Context.get(rpc.annotations, RequestType)
87
+ const isCommand = requestType === "command"
45
88
 
46
- effect = isCommand(method)
47
- ? Effect.retry(Effect.uninterruptible(effect), { times: 1, while: isOptimisticConcurrencyException })
89
+ effect = isCommand
90
+ ? Effect.retry(effect, { times: 1, while: isOptimisticConcurrencyException })
48
91
  : Effect.interruptible(effect)
49
92
 
50
93
  return effect
@@ -60,25 +103,8 @@ export const LoggerMiddlewareLive = Layer
60
103
  return (effect, { headers, payload, rpc }) =>
61
104
  Effect
62
105
  .annotateCurrentSpan({
63
- "request.name": rpc._tag,
64
- "requestInput": typeof payload === "object" && payload !== null
65
- ? Object.entries(payload).reduce((prev, [key, value]: [string, unknown]) => {
66
- prev[key] = key === "password"
67
- ? "<redacted>"
68
- : typeof value === "string" || typeof value === "number" || typeof value === "boolean"
69
- ? typeof value === "string" && value.length > 256
70
- ? (value.substring(0, 253) + "...")
71
- : value
72
- : Array.isArray(value)
73
- ? `Array[${value.length}]`
74
- : value === null || value === undefined
75
- ? `${value}`
76
- : typeof value === "object" && value
77
- ? `Object[${Object.keys(value).length}]`
78
- : typeof value
79
- return prev
80
- }, {} as Record<string, string | number | boolean>)
81
- : payload
106
+ "rpc.method": rpc._tag,
107
+ "rpc.request.payload": summarizePayload(payload)
82
108
  })
83
109
  .pipe(
84
110
  Effect.andThen(effect),
@@ -142,11 +168,11 @@ export const DefaultGenericMiddlewaresLive = Layer.mergeAll(
142
168
  * }) {}
143
169
  * ```
144
170
  */
145
- export const requiresTransactionConfig = RpcContextMap.makeCustom()(Schema.Never, false as boolean)
171
+ export const requiresTransactionConfig = RpcContextMap.makeCustom()(Schema.Never, false)
146
172
 
147
173
  /**
148
174
  * Creates the middleware Effect for SQL transaction wrapping.
149
- * Requires `SqlClient` directly (not via serviceOption).
175
+ * Requires `WithNsTransaction` service.
150
176
  * Reads `requiresTransaction` from the RPC config; defaults to `false`.
151
177
  *
152
178
  * @example
@@ -157,15 +183,14 @@ export const requiresTransactionConfig = RpcContextMap.makeCustom()(Schema.Never
157
183
  * )
158
184
  * ```
159
185
  */
160
- export const makeSqlTransactionMiddleware = (
186
+ export const makeSqlTransactionMiddleware = Effect.fnUntraced(function*(
161
187
  rcm: { getConfig: (rpc: Rpc.AnyWithProps) => { readonly requiresTransaction?: boolean } }
162
- ) =>
163
- Effect.gen(function*() {
164
- const sql = yield* SqlClient.SqlClient
165
- const mw: RpcMiddleware.RpcMiddlewareV4<never, never, never> = (effect, { rpc }) => {
166
- const { requiresTransaction } = rcm.getConfig(rpc)
167
- if (requiresTransaction !== true) return effect
168
- return sql.withTransaction(effect).pipe(Effect.orDie)
169
- }
170
- return mw
171
- })
188
+ ) {
189
+ const withTx = yield* WithNsTransaction
190
+ const mw: RpcMiddleware.RpcMiddlewareV4<never, never, never> = (effect, { rpc }) => {
191
+ const { requiresTransaction } = rcm.getConfig(rpc)
192
+ if (requiresTransaction !== true) return effect
193
+ return withTx(effect)
194
+ }
195
+ return mw
196
+ })
@@ -0,0 +1,4 @@
1
+ // codegen:start {preset: barrel, include: ./middleware/*.ts, nodir: false }
2
+ export * from "./middleware/middleware.ts"
3
+ export * from "./middleware/RouterMiddleware.ts"
4
+ // codegen:end
@@ -1,7 +1,7 @@
1
1
  /* eslint-disable @typescript-eslint/no-unsafe-assignment */
2
2
  /* eslint-disable @typescript-eslint/no-explicit-any */
3
- import { Effect, Option } from "effect"
4
3
  import * as S from "effect-app/Schema"
4
+ import * as Effect from "effect/Effect"
5
5
  import { jwtDecode, type JwtDecodeOptions } from "jwt-decode"
6
6
 
7
7
  export const parseJwt = <Sch extends S.Top>(
@@ -15,7 +15,7 @@ export const parseJwt = <Sch extends S.Top>(
15
15
  (s, _options) =>
16
16
  Effect.try({
17
17
  try: () => jwtDecode(s, options),
18
- catch: (e: any) => new S.SchemaIssue.InvalidValue(Option.some(s), { message: e?.message })
18
+ catch: (e: any) => new S.SchemaIssue.InvalidValue({ message: e?.message }, s)
19
19
  })
20
20
  )
21
21
  .pipe(S.decodeTo(schema) as any)
@@ -1,5 +1,6 @@
1
- import { S, SchemaAST } from "effect-app"
1
+ import * as S from "effect-app/Schema"
2
2
  import type { AST } from "effect-app/Schema"
3
+ import * as SchemaAST from "effect-app/SchemaAST"
3
4
 
4
5
  const get = ["Get", "Index", "List", "All", "Find", "Search"]
5
6
  const del = ["Delete", "Remove", "Destroy"]