@effect-app/infra 4.0.0-beta.22 → 4.0.0-beta.221

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 (337) hide show
  1. package/CHANGELOG.md +1648 -0
  2. package/_check.sh +1 -1
  3. package/dist/CUPS.d.ts +12 -7
  4. package/dist/CUPS.d.ts.map +1 -1
  5. package/dist/CUPS.js +16 -12
  6. package/dist/Emailer/Sendgrid.d.ts +15 -15
  7. package/dist/Emailer/Sendgrid.d.ts.map +1 -1
  8. package/dist/Emailer/Sendgrid.js +20 -16
  9. package/dist/Emailer/fake.d.ts +1 -1
  10. package/dist/Emailer/fake.js +2 -2
  11. package/dist/Emailer/service.d.ts +13 -4
  12. package/dist/Emailer/service.d.ts.map +1 -1
  13. package/dist/Emailer/service.js +4 -3
  14. package/dist/Emailer.d.ts +1 -1
  15. package/dist/MainFiberSet.d.ts +12 -9
  16. package/dist/MainFiberSet.d.ts.map +1 -1
  17. package/dist/MainFiberSet.js +7 -3
  18. package/dist/Model/Repository/Registry.d.ts +21 -0
  19. package/dist/Model/Repository/Registry.d.ts.map +1 -0
  20. package/dist/Model/Repository/Registry.js +18 -0
  21. package/dist/Model/Repository/ext.d.ts +35 -16
  22. package/dist/Model/Repository/ext.d.ts.map +1 -1
  23. package/dist/Model/Repository/ext.js +60 -3
  24. package/dist/Model/Repository/internal/internal.d.ts +9 -6
  25. package/dist/Model/Repository/internal/internal.d.ts.map +1 -1
  26. package/dist/Model/Repository/internal/internal.js +115 -51
  27. package/dist/Model/Repository/legacy.d.ts +4 -2
  28. package/dist/Model/Repository/legacy.d.ts.map +1 -1
  29. package/dist/Model/Repository/makeRepo.d.ts +10 -6
  30. package/dist/Model/Repository/makeRepo.d.ts.map +1 -1
  31. package/dist/Model/Repository/makeRepo.js +5 -2
  32. package/dist/Model/Repository/service.d.ts +32 -24
  33. package/dist/Model/Repository/service.d.ts.map +1 -1
  34. package/dist/Model/Repository/validation.d.ts +47 -18
  35. package/dist/Model/Repository/validation.d.ts.map +1 -1
  36. package/dist/Model/Repository/validation.js +6 -6
  37. package/dist/Model/Repository.d.ts +2 -1
  38. package/dist/Model/Repository.d.ts.map +1 -1
  39. package/dist/Model/Repository.js +2 -1
  40. package/dist/Model/dsl.d.ts +6 -5
  41. package/dist/Model/dsl.d.ts.map +1 -1
  42. package/dist/Model/dsl.js +2 -3
  43. package/dist/Model/filter/filterApi.d.ts +5 -5
  44. package/dist/Model/filter/filterApi.d.ts.map +1 -1
  45. package/dist/Model/filter/types/errors.d.ts +1 -1
  46. package/dist/Model/filter/types/fields.d.ts +1 -1
  47. package/dist/Model/filter/types/path/common.d.ts +1 -1
  48. package/dist/Model/filter/types/path/eager.d.ts +1 -1
  49. package/dist/Model/filter/types/path/eager.d.ts.map +1 -1
  50. package/dist/Model/filter/types/path/eager.js +1 -1
  51. package/dist/Model/filter/types/path/index.d.ts +1 -1
  52. package/dist/Model/filter/types/utils.d.ts +1 -1
  53. package/dist/Model/filter/types/validator.d.ts +1 -1
  54. package/dist/Model/filter/types.d.ts +1 -1
  55. package/dist/Model/query/dsl.d.ts +142 -17
  56. package/dist/Model/query/dsl.d.ts.map +1 -1
  57. package/dist/Model/query/dsl.js +190 -5
  58. package/dist/Model/query/new-kid-interpreter.d.ts +77 -8
  59. package/dist/Model/query/new-kid-interpreter.d.ts.map +1 -1
  60. package/dist/Model/query/new-kid-interpreter.js +127 -6
  61. package/dist/Model/query.d.ts +1 -1
  62. package/dist/Model.d.ts +2 -1
  63. package/dist/Model.d.ts.map +1 -1
  64. package/dist/Model.js +2 -1
  65. package/dist/QueueMaker/SQLQueue.d.ts +7 -8
  66. package/dist/QueueMaker/SQLQueue.d.ts.map +1 -1
  67. package/dist/QueueMaker/SQLQueue.js +135 -117
  68. package/dist/QueueMaker/errors.d.ts +5 -3
  69. package/dist/QueueMaker/errors.d.ts.map +1 -1
  70. package/dist/QueueMaker/errors.js +4 -2
  71. package/dist/QueueMaker/memQueue.d.ts +9 -5
  72. package/dist/QueueMaker/memQueue.d.ts.map +1 -1
  73. package/dist/QueueMaker/memQueue.js +81 -65
  74. package/dist/QueueMaker/sbqueue.d.ts +8 -4
  75. package/dist/QueueMaker/sbqueue.d.ts.map +1 -1
  76. package/dist/QueueMaker/sbqueue.js +57 -55
  77. package/dist/QueueMaker/service.d.ts +4 -2
  78. package/dist/QueueMaker/service.d.ts.map +1 -1
  79. package/dist/QueueMaker/service.js +1 -1
  80. package/dist/RequestContext.d.ts +75 -35
  81. package/dist/RequestContext.d.ts.map +1 -1
  82. package/dist/RequestContext.js +14 -14
  83. package/dist/RequestFiberSet.d.ts +10 -7
  84. package/dist/RequestFiberSet.d.ts.map +1 -1
  85. package/dist/RequestFiberSet.js +8 -3
  86. package/dist/Store/ContextMapContainer.d.ts +22 -3
  87. package/dist/Store/ContextMapContainer.d.ts.map +1 -1
  88. package/dist/Store/ContextMapContainer.js +17 -3
  89. package/dist/Store/Cosmos/query.d.ts +7 -2
  90. package/dist/Store/Cosmos/query.d.ts.map +1 -1
  91. package/dist/Store/Cosmos/query.js +115 -35
  92. package/dist/Store/Cosmos.d.ts +2 -2
  93. package/dist/Store/Cosmos.d.ts.map +1 -1
  94. package/dist/Store/Cosmos.js +343 -244
  95. package/dist/Store/Disk.d.ts +3 -3
  96. package/dist/Store/Disk.d.ts.map +1 -1
  97. package/dist/Store/Disk.js +76 -36
  98. package/dist/Store/Memory.d.ts +7 -4
  99. package/dist/Store/Memory.d.ts.map +1 -1
  100. package/dist/Store/Memory.js +251 -58
  101. package/dist/Store/SQL/Pg.d.ts +4 -0
  102. package/dist/Store/SQL/Pg.d.ts.map +1 -0
  103. package/dist/Store/SQL/Pg.js +233 -0
  104. package/dist/Store/SQL/query.d.ts +43 -0
  105. package/dist/Store/SQL/query.d.ts.map +1 -0
  106. package/dist/Store/SQL/query.js +478 -0
  107. package/dist/Store/SQL.d.ts +21 -0
  108. package/dist/Store/SQL.d.ts.map +1 -0
  109. package/dist/Store/SQL.js +450 -0
  110. package/dist/Store/codeFilter.d.ts +2 -2
  111. package/dist/Store/codeFilter.d.ts.map +1 -1
  112. package/dist/Store/codeFilter.js +6 -3
  113. package/dist/Store/index.d.ts +6 -3
  114. package/dist/Store/index.d.ts.map +1 -1
  115. package/dist/Store/index.js +18 -4
  116. package/dist/Store/service.d.ts +26 -8
  117. package/dist/Store/service.d.ts.map +1 -1
  118. package/dist/Store/service.js +25 -6
  119. package/dist/Store/utils.d.ts +3 -2
  120. package/dist/Store/utils.d.ts.map +1 -1
  121. package/dist/Store/utils.js +5 -5
  122. package/dist/Store.d.ts +1 -1
  123. package/dist/adapters/SQL/Model.d.ts +32 -43
  124. package/dist/adapters/SQL/Model.d.ts.map +1 -1
  125. package/dist/adapters/SQL/Model.js +30 -39
  126. package/dist/adapters/SQL.d.ts +1 -1
  127. package/dist/adapters/ServiceBus.d.ts +14 -11
  128. package/dist/adapters/ServiceBus.d.ts.map +1 -1
  129. package/dist/adapters/ServiceBus.js +30 -21
  130. package/dist/adapters/cosmos-client.d.ts +5 -3
  131. package/dist/adapters/cosmos-client.d.ts.map +1 -1
  132. package/dist/adapters/cosmos-client.js +5 -3
  133. package/dist/adapters/index.d.ts +8 -2
  134. package/dist/adapters/index.d.ts.map +1 -1
  135. package/dist/adapters/index.js +8 -2
  136. package/dist/adapters/logger.d.ts +2 -2
  137. package/dist/adapters/logger.d.ts.map +1 -1
  138. package/dist/adapters/memQueue.d.ts +5 -3
  139. package/dist/adapters/memQueue.d.ts.map +1 -1
  140. package/dist/adapters/memQueue.js +6 -5
  141. package/dist/adapters/mongo-client.d.ts +4 -3
  142. package/dist/adapters/mongo-client.d.ts.map +1 -1
  143. package/dist/adapters/mongo-client.js +5 -3
  144. package/dist/adapters/redis-client.d.ts +6 -3
  145. package/dist/adapters/redis-client.d.ts.map +1 -1
  146. package/dist/adapters/redis-client.js +7 -3
  147. package/dist/api/ContextProvider.d.ts +12 -8
  148. package/dist/api/ContextProvider.d.ts.map +1 -1
  149. package/dist/api/ContextProvider.js +9 -7
  150. package/dist/api/codec.d.ts +1 -1
  151. package/dist/api/internal/RequestContextMiddleware.d.ts +3 -3
  152. package/dist/api/internal/RequestContextMiddleware.d.ts.map +1 -1
  153. package/dist/api/internal/RequestContextMiddleware.js +10 -6
  154. package/dist/api/internal/auth.d.ts +45 -7
  155. package/dist/api/internal/auth.d.ts.map +1 -1
  156. package/dist/api/internal/auth.js +162 -29
  157. package/dist/api/internal/events.d.ts +6 -4
  158. package/dist/api/internal/events.d.ts.map +1 -1
  159. package/dist/api/internal/events.js +16 -9
  160. package/dist/api/internal/health.d.ts +1 -1
  161. package/dist/api/layerUtils.d.ts +10 -6
  162. package/dist/api/layerUtils.d.ts.map +1 -1
  163. package/dist/api/layerUtils.js +7 -6
  164. package/dist/api/middlewares.d.ts +1 -1
  165. package/dist/api/reportError.d.ts +2 -2
  166. package/dist/api/reportError.d.ts.map +1 -1
  167. package/dist/api/reportError.js +3 -2
  168. package/dist/api/routing/middleware/RouterMiddleware.d.ts +5 -4
  169. package/dist/api/routing/middleware/RouterMiddleware.d.ts.map +1 -1
  170. package/dist/api/routing/middleware/middleware.d.ts +42 -3
  171. package/dist/api/routing/middleware/middleware.d.ts.map +1 -1
  172. package/dist/api/routing/middleware/middleware.js +53 -17
  173. package/dist/api/routing/middleware.d.ts +1 -2
  174. package/dist/api/routing/middleware.d.ts.map +1 -1
  175. package/dist/api/routing/middleware.js +1 -2
  176. package/dist/api/routing/schema/jwt.d.ts +1 -1
  177. package/dist/api/routing/schema/jwt.d.ts.map +1 -1
  178. package/dist/api/routing/schema/jwt.js +3 -2
  179. package/dist/api/routing/tsort.d.ts +1 -1
  180. package/dist/api/routing/tsort.d.ts.map +1 -1
  181. package/dist/api/routing/utils.d.ts +4 -4
  182. package/dist/api/routing/utils.d.ts.map +1 -1
  183. package/dist/api/routing/utils.js +3 -2
  184. package/dist/api/routing.d.ts +84 -37
  185. package/dist/api/routing.d.ts.map +1 -1
  186. package/dist/api/routing.js +115 -45
  187. package/dist/api/setupRequest.d.ts +10 -6
  188. package/dist/api/setupRequest.d.ts.map +1 -1
  189. package/dist/api/setupRequest.js +15 -7
  190. package/dist/api/util.d.ts +1 -1
  191. package/dist/arbs.d.ts +2 -2
  192. package/dist/arbs.d.ts.map +1 -1
  193. package/dist/arbs.js +5 -3
  194. package/dist/errorReporter.d.ts +7 -5
  195. package/dist/errorReporter.d.ts.map +1 -1
  196. package/dist/errorReporter.js +22 -26
  197. package/dist/errors.d.ts +1 -1
  198. package/dist/fileUtil.d.ts +2 -2
  199. package/dist/fileUtil.d.ts.map +1 -1
  200. package/dist/fileUtil.js +2 -2
  201. package/dist/index.d.ts +1 -1
  202. package/dist/logger/jsonLogger.d.ts +2 -2
  203. package/dist/logger/jsonLogger.d.ts.map +1 -1
  204. package/dist/logger/jsonLogger.js +4 -2
  205. package/dist/logger/logFmtLogger.d.ts +2 -2
  206. package/dist/logger/logFmtLogger.d.ts.map +1 -1
  207. package/dist/logger/logFmtLogger.js +2 -2
  208. package/dist/logger/shared.d.ts +2 -2
  209. package/dist/logger/shared.d.ts.map +1 -1
  210. package/dist/logger/shared.js +3 -3
  211. package/dist/logger.d.ts +1 -1
  212. package/dist/logger.d.ts.map +1 -1
  213. package/dist/otel.d.ts +75 -0
  214. package/dist/otel.d.ts.map +1 -0
  215. package/dist/otel.js +65 -0
  216. package/dist/rateLimit.d.ts +12 -4
  217. package/dist/rateLimit.d.ts.map +1 -1
  218. package/dist/rateLimit.js +7 -12
  219. package/dist/test.d.ts +3 -3
  220. package/dist/test.d.ts.map +1 -1
  221. package/dist/test.js +2 -2
  222. package/dist/vitest.d.ts +1 -1
  223. package/examples/query.ts +46 -38
  224. package/package.json +46 -37
  225. package/src/CUPS.ts +15 -11
  226. package/src/Emailer/Sendgrid.ts +21 -15
  227. package/src/Emailer/fake.ts +1 -1
  228. package/src/Emailer/service.ts +13 -3
  229. package/src/MainFiberSet.ts +9 -6
  230. package/src/Model/Repository/Registry.ts +34 -0
  231. package/src/Model/Repository/ext.ts +103 -11
  232. package/src/Model/Repository/internal/internal.ts +231 -149
  233. package/src/Model/Repository/legacy.ts +3 -1
  234. package/src/Model/Repository/makeRepo.ts +15 -10
  235. package/src/Model/Repository/service.ts +35 -23
  236. package/src/Model/Repository/validation.ts +5 -5
  237. package/src/Model/Repository.ts +1 -0
  238. package/src/Model/dsl.ts +5 -4
  239. package/src/Model/filter/types/path/eager.ts +1 -2
  240. package/src/Model/query/dsl.ts +353 -19
  241. package/src/Model/query/new-kid-interpreter.ts +211 -6
  242. package/src/Model.ts +1 -0
  243. package/src/QueueMaker/SQLQueue.ts +150 -153
  244. package/src/QueueMaker/errors.ts +3 -1
  245. package/src/QueueMaker/memQueue.ts +111 -105
  246. package/src/QueueMaker/sbqueue.ts +76 -88
  247. package/src/QueueMaker/service.ts +3 -1
  248. package/src/RequestContext.ts +15 -16
  249. package/src/RequestFiberSet.ts +8 -2
  250. package/src/Store/ContextMapContainer.ts +45 -2
  251. package/src/Store/Cosmos/query.ts +143 -44
  252. package/src/Store/Cosmos.ts +491 -350
  253. package/src/Store/Disk.ts +106 -66
  254. package/src/Store/Memory.ts +285 -87
  255. package/src/Store/SQL/Pg.ts +364 -0
  256. package/src/Store/SQL/query.ts +540 -0
  257. package/src/Store/SQL.ts +736 -0
  258. package/src/Store/codeFilter.ts +5 -2
  259. package/src/Store/index.ts +20 -3
  260. package/src/Store/service.ts +45 -10
  261. package/src/Store/utils.ts +25 -23
  262. package/src/adapters/SQL/Model.ts +42 -41
  263. package/src/adapters/ServiceBus.ts +131 -121
  264. package/src/adapters/cosmos-client.ts +4 -2
  265. package/src/adapters/index.ts +7 -0
  266. package/src/adapters/memQueue.ts +5 -4
  267. package/src/adapters/mongo-client.ts +4 -2
  268. package/src/adapters/redis-client.ts +6 -2
  269. package/src/api/ContextProvider.ts +17 -13
  270. package/src/api/internal/RequestContextMiddleware.ts +16 -5
  271. package/src/api/internal/auth.ts +248 -44
  272. package/src/api/internal/events.ts +19 -10
  273. package/src/api/layerUtils.ts +12 -8
  274. package/src/api/reportError.ts +2 -1
  275. package/src/api/routing/middleware/RouterMiddleware.ts +5 -4
  276. package/src/api/routing/middleware/middleware.ts +60 -15
  277. package/src/api/routing/middleware.ts +0 -2
  278. package/src/api/routing/schema/jwt.ts +2 -1
  279. package/src/api/routing/utils.ts +2 -1
  280. package/src/api/routing.ts +304 -131
  281. package/src/api/setupRequest.ts +31 -8
  282. package/src/arbs.ts +5 -3
  283. package/src/errorReporter.ts +65 -75
  284. package/src/fileUtil.ts +1 -1
  285. package/src/logger/jsonLogger.ts +3 -1
  286. package/src/logger/logFmtLogger.ts +1 -1
  287. package/src/logger/shared.ts +3 -2
  288. package/src/otel.ts +152 -0
  289. package/src/rateLimit.ts +34 -23
  290. package/src/test.ts +2 -2
  291. package/test/auth.test.ts +101 -0
  292. package/test/contextProvider.test.ts +14 -11
  293. package/test/controller.test.ts +25 -29
  294. package/test/dist/auth.test.d.ts.map +1 -0
  295. package/test/dist/contextProvider.test.d.ts.map +1 -1
  296. package/test/dist/controller.test.d.ts.map +1 -1
  297. package/test/dist/date-query.test.d.ts.map +1 -0
  298. package/test/dist/fixtures.d.ts +30 -12
  299. package/test/dist/fixtures.d.ts.map +1 -1
  300. package/test/dist/fixtures.js +17 -10
  301. package/test/dist/query.test.d.ts.map +1 -1
  302. package/test/dist/rawQuery.test.d.ts.map +1 -1
  303. package/test/dist/repository-ext.test.d.ts.map +1 -0
  304. package/test/dist/requires.test.d.ts.map +1 -1
  305. package/test/dist/router-generator.test.d.ts.map +1 -0
  306. package/test/dist/routing-interruptibility.test.d.ts.map +1 -0
  307. package/test/dist/rpc-e2e-invalidation.test.d.ts.map +1 -0
  308. package/test/dist/rpc-multi-middleware.test.d.ts.map +1 -1
  309. package/test/dist/rpc-stream-fullstack.test.d.ts.map +1 -0
  310. package/test/dist/sql-store.test.d.ts.map +1 -0
  311. package/test/fixtures.ts +16 -9
  312. package/test/layerUtils.test.ts +1 -1
  313. package/test/query.test.ts +819 -38
  314. package/test/rawQuery.test.ts +312 -20
  315. package/test/repository-ext.test.ts +62 -0
  316. package/test/requires.test.ts +10 -5
  317. package/test/router-generator.test.ts +187 -0
  318. package/test/routing-interruptibility.test.ts +66 -0
  319. package/test/rpc-e2e-invalidation.test.ts +256 -0
  320. package/test/rpc-multi-middleware.test.ts +84 -9
  321. package/test/rpc-stream-fullstack.test.ts +304 -0
  322. package/test/sql-store.test.ts +1592 -0
  323. package/test/validateSample.test.ts +17 -12
  324. package/tsconfig.examples.json +1 -1
  325. package/tsconfig.json +0 -1
  326. package/tsconfig.json.bak +2 -2
  327. package/tsconfig.src.json +35 -35
  328. package/tsconfig.test.json +2 -2
  329. package/dist/Operations.d.ts +0 -55
  330. package/dist/Operations.d.ts.map +0 -1
  331. package/dist/Operations.js +0 -102
  332. package/dist/OperationsRepo.d.ts +0 -41
  333. package/dist/OperationsRepo.d.ts.map +0 -1
  334. package/dist/OperationsRepo.js +0 -14
  335. package/eslint.config.mjs +0 -24
  336. package/src/Operations.ts +0 -235
  337. package/src/OperationsRepo.ts +0 -16
package/package.json CHANGED
@@ -1,54 +1,52 @@
1
1
  {
2
2
  "name": "@effect-app/infra",
3
- "version": "4.0.0-beta.22",
3
+ "version": "4.0.0-beta.221",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "dependencies": {
7
7
  "@faker-js/faker": "^8.4.1",
8
8
  "change-case": "^5.4.4",
9
9
  "cross-fetch": "^4.1.0",
10
- "express-oauth2-jwt-bearer": "^1.7.4",
11
- "fast-check": "~4.5.3",
10
+ "fast-check": "~4.7.0",
11
+ "jose": "^6.2.3",
12
12
  "path-parser": "^6.1.0",
13
13
  "proper-lockfile": "^4.1.2",
14
- "pure-rand": "7.0.1",
14
+ "pure-rand": "8.4.0",
15
15
  "query-string": "^9.3.1",
16
- "effect-app": "4.0.0-beta.22"
16
+ "effect-app": "4.0.0-beta.221"
17
17
  },
18
18
  "devDependencies": {
19
- "@azure/cosmos": "^4.9.1",
19
+ "@azure/cosmos": "^4.9.3",
20
20
  "@azure/service-bus": "^7.9.5",
21
- "@sentry/node": "10.42.0",
22
- "@sentry/opentelemetry": "10.42.0",
23
- "@types/express": "^5.0.6",
24
- "@types/node": "25.3.3",
21
+ "@effect/sql-sqlite-node": "4.0.0-beta.62",
22
+ "@sentry/node": "10.51.0",
23
+ "@sentry/opentelemetry": "10.51.0",
24
+ "@types/better-sqlite3": "^7.6.13",
25
+ "@types/node": "25.6.0",
25
26
  "@types/proper-lockfile": "^4.1.4",
26
27
  "@types/redis": "^2.8.32",
27
28
  "@types/redlock": "^4.0.8",
28
- "express": "^5.2.1",
29
- "jwks-rsa": "2.1.4",
29
+ "better-sqlite3": "^12.9.0",
30
30
  "jwt-decode": "^4.0.0",
31
- "mongodb": "7.1.0",
31
+ "mongodb": "7.2.0",
32
32
  "redis": "^3.1.2",
33
33
  "redlock": "^4.2.0",
34
34
  "strip-ansi": "^7.2.0",
35
- "typescript": "~5.9.3",
36
- "vitest": "^4.0.18",
37
- "@effect-app/eslint-shared-config": "0.5.7-beta.2"
35
+ "typescript": "~6.0.3",
36
+ "vitest": "^4.1.5"
38
37
  },
39
38
  "peerDependencies": {
40
- "@azure/cosmos": "^4.9.1",
39
+ "@azure/cosmos": "^4.9.3",
41
40
  "@azure/service-bus": "^7.9.5",
42
- "@effect/vitest": "^4.0.0-beta.36",
41
+ "@effect/vitest": "^4.0.0-beta.62",
43
42
  "@sendgrid/helpers": "^8.0.0",
44
43
  "@sendgrid/mail": "^8.1.6",
45
- "@sentry/node": "10.42.0",
46
- "@sentry/opentelemetry": "10.42.0",
44
+ "@sentry/node": "10.51.0",
45
+ "@sentry/opentelemetry": "10.51.0",
46
+ "effect": "^4.0.0-beta.62",
47
47
  "jwt-decode": "^4.0.0",
48
48
  "redis": "^3.1.2",
49
- "redlock": "^4.2.0",
50
- "effect": "^4.0.0-beta.36",
51
- "express": "^5.2.1"
49
+ "redlock": "^4.2.0"
52
50
  },
53
51
  "typesVersions": {
54
52
  "*": {
@@ -94,6 +92,10 @@
94
92
  "types": "./dist/Model/Repository.d.ts",
95
93
  "default": "./dist/Model/Repository.js"
96
94
  },
95
+ "./Model/Repository/Registry": {
96
+ "types": "./dist/Model/Repository/Registry.d.ts",
97
+ "default": "./dist/Model/Repository/Registry.js"
98
+ },
97
99
  "./Model/Repository/ext": {
98
100
  "types": "./dist/Model/Repository/ext.d.ts",
99
101
  "default": "./dist/Model/Repository/ext.js"
@@ -166,14 +168,6 @@
166
168
  "types": "./dist/Model/query/new-kid-interpreter.d.ts",
167
169
  "default": "./dist/Model/query/new-kid-interpreter.js"
168
170
  },
169
- "./Operations": {
170
- "types": "./dist/Operations.d.ts",
171
- "default": "./dist/Operations.js"
172
- },
173
- "./OperationsRepo": {
174
- "types": "./dist/OperationsRepo.d.ts",
175
- "default": "./dist/OperationsRepo.js"
176
- },
177
171
  "./QueueMaker/SQLQueue": {
178
172
  "types": "./dist/QueueMaker/SQLQueue.d.ts",
179
173
  "default": "./dist/QueueMaker/SQLQueue.js"
@@ -226,6 +220,18 @@
226
220
  "types": "./dist/Store/Memory.d.ts",
227
221
  "default": "./dist/Store/Memory.js"
228
222
  },
223
+ "./Store/SQL": {
224
+ "types": "./dist/Store/SQL.d.ts",
225
+ "default": "./dist/Store/SQL.js"
226
+ },
227
+ "./Store/SQL/Pg": {
228
+ "types": "./dist/Store/SQL/Pg.d.ts",
229
+ "default": "./dist/Store/SQL/Pg.js"
230
+ },
231
+ "./Store/SQL/query": {
232
+ "types": "./dist/Store/SQL/query.d.ts",
233
+ "default": "./dist/Store/SQL/query.js"
234
+ },
229
235
  "./Store/codeFilter": {
230
236
  "types": "./dist/Store/codeFilter.d.ts",
231
237
  "default": "./dist/Store/codeFilter.js"
@@ -366,6 +372,10 @@
366
372
  "types": "./dist/logger/shared.d.ts",
367
373
  "default": "./dist/logger/shared.js"
368
374
  },
375
+ "./otel": {
376
+ "types": "./dist/otel.d.ts",
377
+ "default": "./dist/otel.js"
378
+ },
369
379
  "./rateLimit": {
370
380
  "types": "./dist/rateLimit.d.ts",
371
381
  "default": "./dist/rateLimit.js"
@@ -384,18 +394,17 @@
384
394
  "scripts": {
385
395
  "watch": "pnpm build:tsc -w",
386
396
  "build:tsc": "pnpm clean-dist && effect-app-cli packagejson pnpm check",
387
- "check": "tsc --build",
397
+ "check": "tsgo --build",
388
398
  "build": "pnpm build:tsc",
389
- "watch2": "pnpm clean-dist && NODE_OPTIONS=--max-old-space-size=6144 tsc -w",
399
+ "watch2": "pnpm clean-dist && NODE_OPTIONS=--max-old-space-size=6144 tsgo -w",
390
400
  "clean": "rm -rf dist",
391
401
  "clean-dist": "sh ../../scripts/clean-dist.sh",
392
402
  "circular": "pnpm circular:src && pnpm circular:dist",
393
403
  "circular:src": "madge --circular --ts-config ./tsconfig.json --extensions ts ./src",
394
404
  "circular:dist": "madge --circular --extensions js ./dist",
395
- "compile": "NODE_OPTIONS=--max-old-space-size=6144 tsc --noEmit",
396
- "lint": "NODE_OPTIONS=--max-old-space-size=6144 ESLINT_TS=1 eslint ./src",
397
- "lint:watch": "ESLINT_TS=1 esw -w --changed --clear --ext ts,tsx .",
398
- "lint-fix": "pnpm lint --fix",
405
+ "compile": "NODE_OPTIONS=--max-old-space-size=6144 tsgo --noEmit",
406
+ "lint": "oxlint --quiet --type-aware ./src && pnpm exec dprint check --config ../../dprint.jsonc .",
407
+ "lint-fix": "oxlint --quiet --type-aware --fix ./src && pnpm exec dprint fmt --config ../../dprint.jsonc .",
399
408
  "test": "vitest",
400
409
  "test:run": "pnpm run test run --passWithNoTests",
401
410
  "testsuite": "pnpm lint && pnpm circular && pnpm run test:run",
package/src/CUPS.ts CHANGED
@@ -1,7 +1,13 @@
1
1
  import { type FileOptions, tempFile } from "@effect-app/infra/fileUtil"
2
2
  import cp from "child_process"
3
- import { Config, Effect, Layer, Option, Predicate, S, ServiceMap } from "effect-app"
3
+ import * as Config from "effect-app/Config"
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 * as Option from "effect-app/Option"
8
+ import * as S from "effect-app/Schema"
4
9
  import { pretty } from "effect-app/utils"
10
+ import * as Predicate from "effect/Predicate"
5
11
  import fs from "fs"
6
12
  import os from "os"
7
13
  import path from "path"
@@ -74,15 +80,13 @@ function printBuffer(printer: PrinterConfig, options: string[]) {
74
80
  )
75
81
  }
76
82
 
77
- function getAvailablePrinters(host?: string) {
78
- return Effect.gen(function*() {
79
- const { stdout } = yield* exec(["lpstat", ...buildListArgs({ host }), "-s"].join(" "))
80
- return [...stdout.matchAll(/device for (\w+):/g)]
81
- .map((_) => _[1])
82
- .filter(Predicate.isNotNullish)
83
- .map((_) => S.NonEmptyString255(_))
84
- })
85
- }
83
+ const getAvailablePrinters = Effect.fnUntraced(function*(host?: string) {
84
+ const { stdout } = yield* exec(["lpstat", ...buildListArgs({ host }), "-s"].join(" "))
85
+ return [...stdout.matchAll(/device for (\w+):/g)]
86
+ .map((_) => _[1])
87
+ .filter(Predicate.isNotNullish)
88
+ .map((_) => S.NonEmptyString255(_))
89
+ })
86
90
 
87
91
  function* buildListArgs(config?: { host?: string | undefined }) {
88
92
  if (config?.host) {
@@ -100,7 +104,7 @@ export const CUPSConfig = Config.all({
100
104
  )
101
105
  })
102
106
 
103
- export class CUPS extends ServiceMap.Service<CUPS>()("effect-app/CUPS", {
107
+ export class CUPS extends Context.Service<CUPS>()("effect-app/CUPS", {
104
108
  make: Effect.gen(function*() {
105
109
  const config = yield* CUPSConfig
106
110
  const serverUrl = Option.getOrUndefined(config.server)
@@ -1,13 +1,18 @@
1
1
  import type { EmailData } from "@sendgrid/helpers/classes/email-address.js"
2
2
  import type { MailContent } from "@sendgrid/helpers/classes/mail.js"
3
3
  import sgMail from "@sendgrid/mail"
4
- import { Array, Effect, Equivalence, Redacted } from "effect-app"
4
+ import * as Array from "effect-app/Array"
5
+ import * as Effect from "effect-app/Effect"
5
6
  import { dropUndefinedT } from "effect-app/utils"
7
+ import * as Equivalence from "effect/Equivalence"
8
+ import * as Redacted from "effect/Redacted"
6
9
  import { inspect } from "util"
7
10
  import { InfraLogger } from "../logger.js"
8
11
  import { Emailer, type EmailMsg, type EmailMsgOptionalFrom, type SendgridConfig, SendMailError } from "./service.js"
9
12
 
10
- const makeSendgrid = ({ apiKey, defaultFrom, defaultReplyTo, realMail, subjectPrefix }: SendgridConfig) =>
13
+ const makeSendgrid = (
14
+ { apiKey, defaultFrom, defaultReplyTo, fakeMailAddress, realMail, subjectPrefix }: SendgridConfig
15
+ ) =>
11
16
  Effect.sync(() => {
12
17
  sgMail.setApiKey(Redacted.value(apiKey))
13
18
 
@@ -18,7 +23,7 @@ const makeSendgrid = ({ apiKey, defaultFrom, defaultReplyTo, realMail, subjectPr
18
23
  from: msg_.from ?? defaultFrom,
19
24
  replyTo: msg_.replyTo ?? (msg_.from ? undefined : defaultReplyTo)
20
25
  })
21
- const render = renderMessage(!realMail)
26
+ const render = renderMessage(!realMail, fakeMailAddress)
22
27
 
23
28
  const renderedMsg_ = render(msg)
24
29
  const renderedMsg = {
@@ -68,23 +73,24 @@ export function Sendgrid(config: SendgridConfig) {
68
73
  /**
69
74
  * @hidden
70
75
  */
71
- export function renderMessage(forceFake: boolean) {
76
+ export function renderMessage(forceFake: boolean, fakeMailAddress: string) {
72
77
  let i = 0
73
78
  const makeId = () => i++
79
+ const makeFakeEmail = () => fakeMailAddress.replace("{i}", String(makeId()))
74
80
  return forceFake
75
81
  ? (msg: EmailMsg) =>
76
82
  dropUndefinedT({
77
83
  ...msg,
78
- to: msg.to && renderFake(msg.to, makeId),
79
- cc: msg.cc && renderFake(msg.cc, makeId),
80
- bcc: msg.bcc && renderFake(msg.bcc, makeId)
84
+ to: msg.to && renderFake(msg.to, makeFakeEmail),
85
+ cc: msg.cc && renderFake(msg.cc, makeFakeEmail),
86
+ bcc: msg.bcc && renderFake(msg.bcc, makeFakeEmail)
81
87
  })
82
88
  : (msg: EmailMsg) =>
83
89
  dropUndefinedT({
84
90
  ...msg,
85
- to: msg.to && renderFakeIfTest(msg.to, makeId),
86
- cc: msg.cc && renderFakeIfTest(msg.cc, makeId),
87
- bcc: msg.bcc && renderFakeIfTest(msg.bcc, makeId)
91
+ to: msg.to && renderFakeIfTest(msg.to, makeFakeEmail),
92
+ cc: msg.cc && renderFakeIfTest(msg.cc, makeFakeEmail),
93
+ bcc: msg.bcc && renderFakeIfTest(msg.bcc, makeFakeEmail)
88
94
  })
89
95
  }
90
96
 
@@ -100,10 +106,10 @@ export function isTestAddress(to: EmailData) {
100
106
  )
101
107
  }
102
108
 
103
- function renderFake(addr: EmailData | readonly EmailData[], makeId: () => number) {
109
+ function renderFake(addr: EmailData | readonly EmailData[], makeEmail: () => string) {
104
110
  return {
105
111
  name: renderMailData(addr),
106
- email: `test+${makeId()}@nomizz.com`
112
+ email: makeEmail()
107
113
  }
108
114
  }
109
115
  const eq = Equivalence.mapInput(
@@ -117,14 +123,14 @@ function isEmailDataArray(md: EmailData | readonly EmailData[]): md is readonly
117
123
 
118
124
  // TODO: should just not add any already added email address
119
125
  // https://stackoverflow.com/a/53603076/11595834
120
- function renderFakeIfTest(addr: EmailData | readonly EmailData[], makeId: () => number) {
126
+ function renderFakeIfTest(addr: EmailData | readonly EmailData[], makeEmail: () => string) {
121
127
  if (isEmailDataArray(addr)) {
122
128
  return Array.dedupeWith(
123
- addr.map((x) => (isTestAddress(x) ? renderFake(x, makeId) : x)),
129
+ addr.map((x) => (isTestAddress(x) ? renderFake(x, makeEmail) : x)),
124
130
  eq
125
131
  )
126
132
  }
127
- return isTestAddress(addr) ? renderFake(addr, makeId) : addr
133
+ return isTestAddress(addr) ? renderFake(addr, makeEmail) : addr
128
134
  }
129
135
 
130
136
  function renderMailData(md: EmailData | readonly EmailData[]): string {
@@ -1,4 +1,4 @@
1
- import { Effect } from "effect-app"
1
+ import * as Effect from "effect-app/Effect"
2
2
  import { pretty } from "effect-app/utils"
3
3
  import { InfraLogger } from "../logger.js"
4
4
  import { Emailer } from "./service.js"
@@ -1,13 +1,17 @@
1
1
  import type { MailContent, MailData } from "@sendgrid/helpers/classes/mail.js"
2
2
  import type { ResponseError } from "@sendgrid/mail"
3
- import { Data, type Effect, type NonEmptyReadonlyArray, type Redacted, ServiceMap } from "effect-app"
3
+ import type { NonEmptyReadonlyArray } from "effect-app/Array"
4
+ import * as Context from "effect-app/Context"
5
+ import type * as Effect from "effect-app/Effect"
4
6
  import type { Email } from "effect-app/Schema"
7
+ import * as Data from "effect/Data"
8
+ import type * as Redacted from "effect/Redacted"
5
9
 
6
10
  export class SendMailError extends Data.TaggedError("SendMailError")<{
7
11
  readonly raw: Error | ResponseError
8
12
  }> {}
9
13
 
10
- export class Emailer extends ServiceMap.Opaque<Emailer, {
14
+ export class Emailer extends Context.Opaque<Emailer, {
11
15
  sendMail: (msg: EmailMsgOptionalFrom) => Effect.Effect<void, SendMailError>
12
16
  }>()("effect-app/Emailer") {}
13
17
 
@@ -21,7 +25,13 @@ export interface SendgridConfig {
21
25
  subjectPrefix: string
22
26
  realMail: boolean
23
27
  defaultFrom: EmailData
24
- apiKey: Redacted.Redacted<string>
28
+ apiKey: Redacted.Redacted
29
+ /**
30
+ * Email address used for fake/test recipients. Use `{i}` as a placeholder for an auto-incrementing index to ensure uniqueness.
31
+ *
32
+ * @example "test+{i}@example.com"
33
+ */
34
+ fakeMailAddress: string
25
35
  }
26
36
  export type EmailTemplateMsg = MailData & { templateId: string }
27
37
 
@@ -1,14 +1,17 @@
1
- import { Effect, Fiber, FiberSet, Layer, ServiceMap } from "effect-app"
2
- import type {} from "effect/Scope"
1
+ import * as Context from "effect-app/Context"
2
+ import * as Effect from "effect-app/Effect"
3
+ import * as Layer from "effect-app/Layer"
4
+ import * as Fiber from "effect/Fiber"
5
+ import * as FiberSet from "effect/FiberSet"
6
+
3
7
  import { InfraLogger } from "./logger.js"
4
8
  import { reportNonInterruptedFailureCause } from "./QueueMaker/errors.js"
5
9
  import { setRootParentSpan } from "./RequestFiberSet.js"
6
10
 
7
11
  const make = Effect.gen(function*() {
8
12
  const set = yield* FiberSet.make<unknown, never>()
9
- const add = (...fibers: Fiber.Fiber<never, never>[]) =>
10
- Effect.sync(() => fibers.forEach((_) => FiberSet.addUnsafe(set, _)))
11
- const addAll = (fibers: readonly Fiber.Fiber<never, never>[]) =>
13
+ const add = (...fibers: Fiber.Fiber<never>[]) => Effect.sync(() => fibers.forEach((_) => FiberSet.addUnsafe(set, _)))
14
+ const addAll = (fibers: readonly Fiber.Fiber<never>[]) =>
12
15
  Effect.sync(() => fibers.forEach((_) => FiberSet.addUnsafe(set, _)))
13
16
  const join = FiberSet.size(set).pipe(
14
17
  Effect.andThen((count) => InfraLogger.logDebug(`Joining ${count} current fibers on the MainFiberSet`)),
@@ -62,7 +65,7 @@ const make = Effect.gen(function*() {
62
65
  * you should register these long running fibers in a FiberSet, and join them at the end of your main program.
63
66
  * This way any errors will blow up the main program instead of fibers dying unknowingly.
64
67
  */
65
- export class MainFiberSet extends ServiceMap.Service<MainFiberSet>()("MainFiberSet", { make }) {
68
+ export class MainFiberSet extends Context.Service<MainFiberSet>()("MainFiberSet", { make }) {
66
69
  static readonly Live = Layer.effect(this, this.make)
67
70
  static readonly JoinLive = this.asEffect().pipe(
68
71
  Effect.andThen((_) => _.join),
@@ -0,0 +1,34 @@
1
+ import * as Context from "effect-app/Context"
2
+ import * as Effect from "effect-app/Effect"
3
+
4
+ export interface RegisteredRepository {
5
+ readonly seedNamespace: (namespace: string) => Effect.Effect<void>
6
+ }
7
+
8
+ const make = Effect.sync(() => {
9
+ const repos = new Map<string, RegisteredRepository>()
10
+ return {
11
+ register(modelName: string, repo: RegisteredRepository) {
12
+ repos.set(modelName, repo)
13
+ },
14
+ seedNamespace: (namespace: string) =>
15
+ Effect.suspend(() =>
16
+ Effect.forEach(
17
+ repos.values(),
18
+ (r) => r.seedNamespace(namespace),
19
+ { concurrency: "unbounded", discard: true }
20
+ )
21
+ ),
22
+ get entries(): ReadonlyMap<string, RegisteredRepository> {
23
+ return repos
24
+ }
25
+ }
26
+ })
27
+
28
+ export class RepositoryRegistry extends Context.Opaque<RepositoryRegistry, {
29
+ readonly register: (modelName: string, repo: RegisteredRepository) => void
30
+ readonly seedNamespace: (namespace: string) => Effect.Effect<void>
31
+ readonly entries: ReadonlyMap<string, RegisteredRepository>
32
+ }>()("effect-app/RepositoryRegistry", { make }) {}
33
+
34
+ export const RepositoryRegistryLive = RepositoryRegistry.toLayer(RepositoryRegistry.make)
@@ -1,14 +1,36 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
2
  /* eslint-disable @typescript-eslint/no-unsafe-return */
3
- import { Array, Effect, Exit, type NonEmptyArray, Option, Request, RequestResolver } from "effect-app"
3
+ import * as Array from "effect-app/Array"
4
+ import type { NonEmptyArray } from "effect-app/Array"
4
5
  import { type InvalidStateError, NotFoundError, type OptimisticConcurrencyException } from "effect-app/client/errors"
6
+ import * as Effect from "effect-app/Effect"
7
+ import * as Option from "effect-app/Option"
5
8
  import { type FixEnv, type PureEnv, runTerm } from "effect-app/Pure"
9
+ import * as Exit from "effect/Exit"
10
+ import * as Request from "effect/Request"
11
+ import * as RequestResolver from "effect/RequestResolver"
6
12
  import { AnyPureDSL } from "../dsl.js"
7
13
  import type { FieldValues } from "../filter/types.js"
8
14
  import type { Query, QueryEnd, QueryWhere } from "../query.js"
9
15
  import * as Q from "../query.js"
10
16
  import type { Repository } from "./service.js"
11
17
 
18
+ interface BatchOptions {
19
+ readonly batch?: true | number
20
+ }
21
+
22
+ const asReadonlyArray = <T>(itemOrItems: T | ReadonlyArray<T>): ReadonlyArray<T> =>
23
+ globalThis.Array.isArray(itemOrItems)
24
+ ? itemOrItems as ReadonlyArray<T>
25
+ : [itemOrItems as T]
26
+
27
+ const getBatchSize = (batch?: true | number) =>
28
+ batch === true
29
+ ? 100
30
+ : typeof batch === "number" && Number.isFinite(batch) && batch > 0
31
+ ? Math.floor(batch)
32
+ : undefined
33
+
12
34
  export const extendRepo = <
13
35
  T,
14
36
  Encoded extends FieldValues,
@@ -16,9 +38,10 @@ export const extendRepo = <
16
38
  ItemType extends string,
17
39
  IdKey extends keyof T & keyof Encoded,
18
40
  RSchema,
19
- RPublish
41
+ RPublish,
42
+ RProvided = never
20
43
  >(
21
- repo: Repository<T, Encoded, Evt, ItemType, IdKey, RSchema, RPublish>
44
+ repo: Repository<T, Encoded, Evt, ItemType, IdKey, RSchema, RPublish, RProvided>
22
45
  ) => {
23
46
  const get = (id: T[IdKey]) =>
24
47
  repo.find(id).pipe(
@@ -109,7 +132,7 @@ export const extendRepo = <
109
132
  ) =>
110
133
  | Query<Encoded>
111
134
  | QueryWhere<Encoded>
112
- | QueryEnd<Encoded, "many">,
135
+ | QueryEnd<Encoded>,
113
136
  pure: Effect.Effect<A, E2, FixEnv<R2, Evt, readonly T[], readonly T2[]>>
114
137
  ): Effect.Effect<
115
138
  A,
@@ -126,7 +149,7 @@ export const extendRepo = <
126
149
  ) =>
127
150
  | Query<Encoded>
128
151
  | QueryWhere<Encoded>
129
- | QueryEnd<Encoded, "many">,
152
+ | QueryEnd<Encoded>,
130
153
  pure: Effect.Effect<A, E2, FixEnv<R2, Evt, readonly T[], readonly T2[]>>,
131
154
  batch: "batched" | number
132
155
  ): Effect.Effect<
@@ -214,8 +237,7 @@ export const extendRepo = <
214
237
  _key: unknown
215
238
  ) =>
216
239
  (repo.query(Q.where(repo.idKey as any, "in" as any, entries.map((_) => _.request.id)) as any) as Effect.Effect<
217
- readonly T[],
218
- never
240
+ readonly T[]
219
241
  >)
220
242
  // TODO
221
243
  .pipe(
@@ -244,8 +266,77 @@ export const extendRepo = <
244
266
  request: (id: T[IdKey]) => Effect.request(_request({ id }), requestResolver),
245
267
  get,
246
268
  log: (evt: Evt) => AnyPureDSL.log(evt),
247
- save: (...items: NonEmptyArray<T>) => repo.saveAndPublish(items),
269
+ /**
270
+ * Enables chunked writes for large batches via `options.batch`.
271
+ * Note: batching breaks transactional properties because chunks are saved independently.
272
+ */
273
+ save: ((itemOrItems: T | ReadonlyArray<T>, options?: BatchOptions) => {
274
+ const items = asReadonlyArray(itemOrItems)
275
+ if (!Array.isReadonlyArrayNonEmpty(items)) {
276
+ return Effect.void
277
+ }
278
+ const batchSize = getBatchSize(options?.batch)
279
+ if (batchSize === undefined) {
280
+ return repo.saveAndPublish(items)
281
+ }
282
+ return Effect.forEach(
283
+ Array.chunksOf(items, batchSize),
284
+ (batch) => repo.saveAndPublish(batch),
285
+ { discard: true }
286
+ )
287
+ }) as (
288
+ itemOrItems: T | ReadonlyArray<T>,
289
+ options?: BatchOptions
290
+ ) => Effect.Effect<
291
+ void,
292
+ InvalidStateError | OptimisticConcurrencyException,
293
+ RSchema | RPublish
294
+ >,
248
295
  saveWithEvents: (events: Iterable<Evt>) => (...items: NonEmptyArray<T>) => repo.saveAndPublish(items, events),
296
+ /**
297
+ * Enables chunked deletes for large batches via `options.batch`.
298
+ * Note: batching breaks transactional properties because chunks are removed independently.
299
+ */
300
+ remove: ((itemOrItems: T | ReadonlyArray<T>, options?: BatchOptions) => {
301
+ const items = asReadonlyArray(itemOrItems)
302
+ if (!Array.isReadonlyArrayNonEmpty(items)) {
303
+ return Effect.void
304
+ }
305
+ const batchSize = getBatchSize(options?.batch)
306
+ if (batchSize === undefined) {
307
+ return repo.removeAndPublish(items)
308
+ }
309
+ return Effect.forEach(
310
+ Array.chunksOf(items, batchSize),
311
+ (batch) => repo.removeAndPublish(batch),
312
+ { discard: true }
313
+ )
314
+ }) as (
315
+ itemOrItems: T | ReadonlyArray<T>,
316
+ options?: BatchOptions
317
+ ) => Effect.Effect<void, never, RSchema | RPublish>,
318
+ /**
319
+ * Enables chunked deletes for large batches via `options.batch`.
320
+ * Note: batching breaks transactional properties because chunks are removed independently.
321
+ */
322
+ removeById: ((idOrIds: T[IdKey] | ReadonlyArray<T[IdKey]>, options?: BatchOptions) => {
323
+ const ids = asReadonlyArray(idOrIds)
324
+ if (!Array.isReadonlyArrayNonEmpty(ids)) {
325
+ return Effect.void
326
+ }
327
+ const batchSize = getBatchSize(options?.batch)
328
+ if (batchSize === undefined) {
329
+ return repo.removeById(ids)
330
+ }
331
+ return Effect.forEach(
332
+ Array.chunksOf(ids, batchSize),
333
+ (batch) => repo.removeById(batch),
334
+ { discard: true }
335
+ )
336
+ }) as (
337
+ idOrIds: T[IdKey] | ReadonlyArray<T[IdKey]>,
338
+ options?: BatchOptions
339
+ ) => Effect.Effect<void, never, RSchema>,
249
340
  queryAndSavePure,
250
341
  saveManyWithPure,
251
342
  byIdAndSaveWithPure,
@@ -268,7 +359,7 @@ export const extendRepo = <
268
359
  return {
269
360
  ...repo,
270
361
  ...exts
271
- } as Repository<T, Encoded, Evt, ItemType, IdKey, RSchema, RPublish> & typeof exts
362
+ } as Repository<T, Encoded, Evt, ItemType, IdKey, RSchema, RPublish, RProvided> & typeof exts
272
363
  }
273
364
 
274
365
  // eslint-disable-next-line @typescript-eslint/no-empty-object-type
@@ -279,5 +370,6 @@ export interface ExtendedRepository<
279
370
  ItemType extends string,
280
371
  IdKey extends keyof T & keyof Encoded,
281
372
  RSchema,
282
- RPublish
283
- > extends ReturnType<typeof extendRepo<T, Encoded, Evt, ItemType, IdKey, RSchema, RPublish>> {}
373
+ RPublish,
374
+ RProvided = never
375
+ > extends ReturnType<typeof extendRepo<T, Encoded, Evt, ItemType, IdKey, RSchema, RPublish, RProvided>> {}