@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
@@ -1,11 +1,23 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
- import type {} from "effect/Equal"
3
- import type {} from "effect/Hash"
4
- import { Array, Chunk, Effect, Equivalence, flow, type NonEmptyReadonlyArray, Option, pipe, Pipeable, PubSub, Result, S, SchemaAST, ServiceMap, Unify } from "effect-app"
2
+
3
+ import * as Array from "effect-app/Array"
4
+ import type { NonEmptyReadonlyArray } from "effect-app/Array"
5
5
  import { toNonEmptyArray } from "effect-app/Array"
6
+ import * as Chunk from "effect-app/Chunk"
6
7
  import { NotFoundError } from "effect-app/client/errors"
8
+ import * as Context from "effect-app/Context"
9
+ import * as Effect from "effect-app/Effect"
7
10
  import { flatMapOption } from "effect-app/Effect"
11
+ import * as Option from "effect-app/Option"
12
+ import * as S from "effect-app/Schema"
8
13
  import { type Codec, NonNegativeInt } from "effect-app/Schema"
14
+ import * as Equivalence from "effect/Equivalence"
15
+ import { flow, pipe } from "effect/Function"
16
+ import * as Pipeable from "effect/Pipeable"
17
+ import * as PubSub from "effect/PubSub"
18
+ import * as Result from "effect/Result"
19
+ import * as SchemaAST from "effect/SchemaAST"
20
+ import * as Unify from "effect/Unify"
9
21
  import { setupRequestContextFromCurrent } from "../../../api/setupRequest.js"
10
22
  import { type FilterArgs, type PersistenceModelType, type StoreConfig, StoreMaker } from "../../../Store.js"
11
23
  import { getContextMap } from "../../../Store/ContextMapContainer.js"
@@ -55,14 +67,14 @@ export function makeRepoInternal<
55
67
 
56
68
  function make<RInitial = never, E = never, RPublish = never, RCtx = never>(
57
69
  args: [Evt] extends [never] ? {
58
- schemaContext?: ServiceMap.ServiceMap<RCtx>
70
+ schemaContext?: Context.Context<RCtx>
59
71
  makeInitial?: Effect.Effect<readonly T[], E, RInitial> | undefined
60
72
  config?: Omit<StoreConfig<Encoded>, "partitionValue"> & {
61
73
  partitionValue?: (e?: Encoded) => string
62
74
  }
63
75
  }
64
76
  : {
65
- schemaContext?: ServiceMap.ServiceMap<RCtx>
77
+ schemaContext?: Context.Context<RCtx>
66
78
  publishEvents: (evt: NonEmptyReadonlyArray<Evt>) => Effect.Effect<void, never, RPublish>
67
79
  makeInitial?: Effect.Effect<readonly T[], E, RInitial> | undefined
68
80
  config?: Omit<StoreConfig<Encoded>, "partitionValue"> & {
@@ -72,16 +84,16 @@ export function makeRepoInternal<
72
84
  ) {
73
85
  return Effect
74
86
  .gen(function*() {
75
- const rctx: ServiceMap.ServiceMap<RCtx> = args.schemaContext ?? ServiceMap.empty() as any
87
+ const rctx: Context.Context<RCtx> = args.schemaContext ?? Context.empty() as any
76
88
  const provideRctx = Effect.provide(rctx)
77
89
  const encodeMany = flow(
78
90
  S.encodeEffect(S.Array(schema)),
79
91
  provideRctx,
80
- Effect.withSpan("encodeMany", {}, { captureStackTrace: false })
92
+ Effect.withSpan("encodeMany", { attributes: { "app.entity": name } }, { captureStackTrace: false })
81
93
  )
82
- const decode = flow(S.decodeEffect(schema), provideRctx)
94
+ const decode = flow(S.decodeEffectConcurrently(schema), provideRctx)
83
95
  const decodeMany = flow(
84
- S.decodeEffect(S.Array(schema)),
96
+ S.decodeEffectConcurrently(S.Array(schema)),
85
97
  provideRctx
86
98
  )
87
99
 
@@ -104,7 +116,13 @@ export function makeRepoInternal<
104
116
  allE,
105
117
  (_) => decodeMany(_).pipe(Effect.orDie)
106
118
  )
107
- .pipe(Effect.map((_) => _ as T[]))
119
+ .pipe(
120
+ Effect.map((_) => _ as T[]),
121
+ Effect.withSpan("Repository.all", {
122
+ kind: "client",
123
+ attributes: { "app.entity": name }
124
+ }, { captureStackTrace: false })
125
+ )
108
126
 
109
127
  const fieldsSchema = schema as unknown as { fields: any }
110
128
  // assumes the id field never needs a service...
@@ -113,11 +131,14 @@ export function makeRepoInternal<
113
131
  let ast = _.ast
114
132
  if (ast._tag === "Declaration") ast = ast.typeParameters[0]!
115
133
 
116
- // In v4, to get the encoded (from) side of a schema, use SchemaAST.toEncoded
117
134
  const pickIdFromAst = (a: SchemaAST.AST) => {
118
- const encoded = SchemaAST.toEncoded(a)
119
- if (SchemaAST.isObjects(encoded)) {
120
- const field = encoded.propertySignatures.find((_) => _.name === idKey)
135
+ // Unwrap Declaration (e.g. TaggedClass) to get the underlying Objects AST
136
+ let inner = a
137
+ if (inner._tag === "Declaration") inner = inner.typeParameters[0]!
138
+ // Pick from the original AST to preserve the full encoding chain (e.g. decodeTo transformations).
139
+ // Using toEncoded would lose transformation info needed to encode Type -> Encoded.
140
+ if (SchemaAST.isObjects(inner)) {
141
+ const field = inner.propertySignatures.find((_) => _.name === idKey)
121
142
  if (field) {
122
143
  return S.Struct({ [idKey]: S.make(field.type) }) as unknown as Codec<T, Encoded>
123
144
  }
@@ -138,7 +159,7 @@ export function makeRepoInternal<
138
159
  Effect.map((_: Record<string, unknown>) => _[idKey as string] as Encoded[IdKey])
139
160
  )
140
161
  const findEId = Effect.fnUntraced(function*(id: Encoded[IdKey]) {
141
- yield* Effect.annotateCurrentSpan({ itemId: id })
162
+ yield* Effect.annotateCurrentSpan({ "app.entity.id": id })
142
163
 
143
164
  return yield* Effect.flatMap(
144
165
  store.find(id),
@@ -151,7 +172,7 @@ export function makeRepoInternal<
151
172
  })
152
173
  // TODO: select the particular field, instead of as struct
153
174
  const findE = Effect.fnUntraced(function*(id: T[IdKey]) {
154
- yield* Effect.annotateCurrentSpan({ itemId: id })
175
+ yield* Effect.annotateCurrentSpan({ "app.entity.id": id })
155
176
 
156
177
  return yield* pipe(
157
178
  encodeId({ [idKey]: id } as any),
@@ -161,9 +182,11 @@ export function makeRepoInternal<
161
182
  )
162
183
  })
163
184
 
164
- const find = Effect.fn("find")(function*(id: T[IdKey]) {
165
- yield* Effect.annotateCurrentSpan({ itemId: id })
166
-
185
+ const find = Effect.fn("Repository.find", {
186
+ kind: "client",
187
+ attributes: { "app.entity": name }
188
+ })(function*(id: T[IdKey]) {
189
+ yield* Effect.annotateCurrentSpan({ "app.entity.id": id })
167
190
  return yield* flatMapOption(findE(id), (_) => Effect.orDie(decode(_)))
168
191
  })
169
192
 
@@ -188,73 +211,96 @@ export function makeRepoInternal<
188
211
  Effect.andThen(saveAllE)
189
212
  )
190
213
 
191
- const saveAndPublish = Effect.fn("saveAndPublish")(function*(items: Iterable<T>, events: Iterable<Evt> = []) {
192
- const it = Chunk.fromIterable(items)
193
- const evts = [...events]
194
- yield* Effect.annotateCurrentSpan({ itemIds: [...Chunk.map(it, (_) => _[idKey])], events: evts.length })
195
- return yield* saveAll(it)
196
- .pipe(
197
- Effect.andThen(Effect.sync(() => toNonEmptyArray(evts))),
198
- // TODO: for full consistency the events should be stored within the same database transaction, and then picked up.
199
- (_) => flatMapOption(_, pub),
200
- Effect.andThen(PubSub.publish(changeFeed, [Chunk.toArray(it), "save"] as [T[], "save" | "remove"])),
201
- Effect.asVoid
202
- )
203
- })
214
+ const saveAndPublish = Effect.fn("Repository.saveAndPublish", { attributes: { "app.entity": name } })(
215
+ function*(items: Iterable<T>, events: Iterable<Evt> = []) {
216
+ const it = Chunk.fromIterable(items)
217
+ const evts = [...events]
218
+ yield* Effect.annotateCurrentSpan({
219
+ "app.entity.ids": Chunk.map(it, (_) => _[idKey]),
220
+ "app.event.count": evts.length
221
+ })
222
+ return yield* saveAll(it)
223
+ .pipe(
224
+ Effect.andThen(Effect.sync(() => toNonEmptyArray(evts))),
225
+ // TODO: for full consistency the events should be stored within the same database transaction, and then picked up.
226
+ (_) => flatMapOption(_, pub),
227
+ Effect.andThen(PubSub.publish(changeFeed, [Chunk.toArray(it), "save"] as [T[], "save" | "remove"])),
228
+ Effect.asVoid
229
+ )
230
+ }
231
+ )
204
232
 
205
- const removeAndPublish = Effect.fn("removeAndPublish")(function*(a: Iterable<T>, events: Iterable<Evt> = []) {
206
- const { set } = yield* cms
207
- const it = [...a]
208
- const evts = [...events]
209
- yield* Effect.annotateCurrentSpan({ itemIds: it.map((_) => _[idKey]), eventCount: evts.length })
210
- const items = yield* encodeMany(it).pipe(Effect.orDie)
211
- if (Array.isReadonlyArrayNonEmpty(items)) {
212
- yield* store.batchRemove(
213
- items.map((_) => (_[idKey])),
214
- args.config?.partitionValue?.(items[0])
215
- )
216
- for (const e of items) {
217
- set(e[idKey], undefined)
233
+ const removeAndPublish = Effect.fn("Repository.removeAndPublish", { attributes: { "app.entity": name } })(
234
+ function*(a: Iterable<T>, events: Iterable<Evt> = []) {
235
+ const { set } = yield* cms
236
+ const it = [...a]
237
+ const evts = [...events]
238
+ yield* Effect.annotateCurrentSpan({
239
+ "app.entity.ids": it.map((_) => _[idKey]),
240
+ "app.event.count": evts.length
241
+ })
242
+ const items = yield* encodeMany(it).pipe(Effect.orDie)
243
+ if (Array.isReadonlyArrayNonEmpty(items)) {
244
+ yield* store.batchRemove(
245
+ items.map((_) => (_[idKey])),
246
+ args.config?.partitionValue?.(items[0])
247
+ )
248
+ for (const e of items) {
249
+ set(e[idKey], undefined)
250
+ }
251
+ yield* Effect
252
+ .sync(() => toNonEmptyArray(evts))
253
+ // TODO: for full consistency the events should be stored within the same database transaction, and then picked up.
254
+ .pipe((_) => flatMapOption(_, pub))
255
+
256
+ yield* PubSub.publish(changeFeed, [it, "remove"] as [T[], "save" | "remove"])
218
257
  }
219
- yield* Effect
220
- .sync(() => toNonEmptyArray(evts))
221
- // TODO: for full consistency the events should be stored within the same database transaction, and then picked up.
222
- .pipe((_) => flatMapOption(_, pub))
258
+ }
259
+ )
223
260
 
224
- yield* PubSub.publish(changeFeed, [it, "remove"] as [T[], "save" | "remove"])
261
+ const removeById = Effect.fn("Repository.removeById", { attributes: { "app.entity": name } })(
262
+ function*(idOrIds: T[IdKey] | ReadonlyArray<T[IdKey]>) {
263
+ const ids = globalThis.Array.isArray(idOrIds)
264
+ ? idOrIds as readonly T[IdKey][]
265
+ : [idOrIds as T[IdKey]]
266
+ if (!Array.isReadonlyArrayNonEmpty(ids)) {
267
+ return
268
+ }
269
+ const { set } = yield* cms
270
+ const eids = yield* Effect.forEach(ids, (_) => encodeIdOnly(_ as any)).pipe(Effect.orDie)
271
+ yield* Effect.annotateCurrentSpan({ "app.entity.ids": eids })
272
+ yield* store.batchRemove(eids)
273
+ for (const id of eids) {
274
+ set(id, undefined)
275
+ }
276
+ yield* PubSub.publish(changeFeed, [[], "remove"] as [T[], "save" | "remove"])
225
277
  }
226
- })
278
+ )
227
279
 
228
- const removeById = Effect.fn("removeById")(function*(...ids: readonly T[IdKey][]) {
229
- if (!Array.isReadonlyArrayNonEmpty(ids)) {
230
- return
280
+ const parseMany = Effect.fn("parseMany", { attributes: { "app.entity": name } })(
281
+ function*(items: readonly PM[]) {
282
+ const cm = yield* cms
283
+ return yield* decodeMany(items.map((_) => mapReverse(_, cm.set))).pipe(Effect.orDie)
231
284
  }
232
- const { set } = yield* cms
233
- const eids = yield* Effect.forEach(ids, (_) => encodeIdOnly(_ as any)).pipe(Effect.orDie)
234
- yield* Effect.annotateCurrentSpan({ itemIds: eids })
235
- yield* store.batchRemove(eids)
236
- for (const id of eids) {
237
- set(id, undefined)
285
+ )
286
+ const decodeManyCache = new WeakMap<
287
+ S.Codec<any, any, any>,
288
+ (i: readonly any[]) => Effect.Effect<any, any, any>
289
+ >()
290
+ const getDecodeMany = (s: S.Codec<any, Encoded, any>) => {
291
+ let dec = decodeManyCache.get(s)
292
+ if (!dec) {
293
+ dec = S.decodeEffectConcurrently(S.Array(s))
294
+ decodeManyCache.set(s, dec)
238
295
  }
239
- yield* PubSub.publish(changeFeed, [[], "remove"] as [T[], "save" | "remove"])
240
- })
241
-
242
- const parseMany = (items: readonly PM[]) =>
243
- Effect
244
- .flatMap(cms, (cm) =>
245
- decodeMany(items.map((_) => mapReverse(_, cm.set)))
246
- .pipe(Effect.orDie, Effect.withSpan("parseMany", {}, { captureStackTrace: false })))
247
- const parseMany2 = <A, R>(
248
- items: readonly PM[],
249
- schema: S.Codec<A, Encoded, R>
250
- ) =>
251
- Effect
252
- .flatMap(cms, (cm) =>
253
- S
254
- .decodeEffect(S.Array(schema))(
255
- items.map((_) => mapReverse(_, cm.set))
256
- )
257
- .pipe(Effect.orDie, Effect.withSpan("parseMany2", {}, { captureStackTrace: false })))
296
+ return dec
297
+ }
298
+ const parseMany2 = Effect.fn("parseMany2", { attributes: { "app.entity": name } })(
299
+ function*<A, R>(items: readonly PM[], schema: S.Codec<A, Encoded, R>) {
300
+ const cm = yield* cms
301
+ return yield* getDecodeMany(schema)(items.map((_) => mapReverse(_, cm.set))).pipe(Effect.orDie)
302
+ }
303
+ )
258
304
  const filter = <U extends keyof Encoded = keyof Encoded>(args: FilterArgs<Encoded, U>) =>
259
305
  store
260
306
  .filter(
@@ -276,24 +322,28 @@ export function makeRepoInternal<
276
322
  const query: {
277
323
  <A, R, From extends FieldValues>(
278
324
  q: Q.QueryProjection<Encoded extends From ? From : never, A, R>
279
- ): Effect.Effect<readonly A[], S.SchemaError, R>
325
+ ): Effect.Effect<readonly A[], S.SchemaError, Exclude<R, RCtx>>
280
326
  <A, R, EncodedRefined extends Encoded = Encoded>(
281
327
  q: Q.QAll<NoInfer<Encoded>, NoInfer<EncodedRefined>, A, R>
282
- ): Effect.Effect<readonly A[], never, R>
328
+ ): Effect.Effect<readonly A[], never, Exclude<R, RCtx>>
283
329
  } = (<A, R, EncodedRefined extends Encoded = Encoded>(q: Q.QAll<Encoded, EncodedRefined, A, R>) => {
284
- const a = Q.toFilter(q)
330
+ const a = Q.toFilter(q, schema)
331
+ // Mode dispatch — see `Q.project` JSDoc for the contract:
332
+ // project : decode raw encoded rows with schema; no PM reverse-mapping; SchemaError surfaces.
333
+ // collect : same as project, but schema yields Option and None rows are dropped.
334
+ // transform: PM reverse-map (re-inject _etag/PM state from cms cache) then decode; orDie.
285
335
  const eff = a.mode === "project"
286
336
  ? filter(a)
287
337
  // TODO: mapFrom but need to support per field and dependencies
288
338
  .pipe(
289
- Effect.andThen(flow(S.decodeEffect(S.Array(a.schema ?? schema)), provideRctx))
339
+ Effect.andThen(flow(S.decodeEffectConcurrently(S.Array(a.schema ?? schema)), provideRctx))
290
340
  )
291
341
  : a.mode === "collect"
292
342
  ? filter(a)
293
343
  // TODO: mapFrom but need to support per field and dependencies
294
344
  .pipe(
295
345
  Effect.flatMap(flow(
296
- S.decodeEffect(S.Array(a.schema)),
346
+ S.decodeEffectConcurrently(S.Array(a.schema)),
297
347
  Effect.map(Array.getSomes),
298
348
  provideRctx
299
349
  ))
@@ -325,72 +375,89 @@ export function makeRepoInternal<
325
375
  .map(eff, (_) => NonNegativeInt(_.length))
326
376
  .pipe(Effect.catchTag("SchemaError", (e) => Effect.die(e)))
327
377
  : eff,
328
- Effect.withSpan("Repository.query [effect-app/infra]", {
329
- attributes: {
330
- "repository.model_name": name,
331
- query: { ...a, schema: a.schema ? "__SCHEMA__" : a.schema, filter: a.filter }
332
- }
378
+ Effect.tap((r) =>
379
+ Effect.annotateCurrentSpan({
380
+ "app.query.ttype": a.ttype,
381
+ "app.query.mode": a.mode,
382
+ "db.response.returned_rows": Array.isArray(r) ? r.length : 1
383
+ })
384
+ ),
385
+ Effect.withSpan("Repository.query", {
386
+ kind: "client",
387
+ attributes: { "app.entity": name }
333
388
  }, { captureStackTrace: false })
334
389
  )
335
390
  }) as any
336
391
 
337
- const validateSample = Effect.fn("validateSample")(function*(options?: {
338
- percentage?: number
339
- maxItems?: number
340
- }) {
341
- const percentage = options?.percentage ?? 0.1 // default 10%
342
- const maxItems = options?.maxItems
343
-
344
- // 1. get all IDs with projection (bypasses main schema decode)
345
- const allIds = yield* store.filter({
346
- t: null as unknown as Encoded,
347
- select: [idKey as keyof Encoded]
348
- })
349
-
350
- // 2. random subset
351
- const shuffled = [...allIds].sort(() => Math.random() - 0.5)
352
- const sampleSize = Math.min(
353
- maxItems ?? Infinity,
354
- Math.ceil(allIds.length * percentage)
355
- )
356
- const sample = shuffled.slice(0, sampleSize)
357
-
358
- // 3. validate each item
359
- const errors: ValidationError[] = []
360
-
361
- for (const item of sample) {
362
- const id = item[idKey]
363
- const rawResult = yield* store.find(id)
364
-
365
- if (Option.isNone(rawResult)) continue
392
+ const validateSample = Effect.fn("Repository.validateSample", { attributes: { "app.entity": name } })(
393
+ function*(options?: {
394
+ percentage?: number
395
+ maxItems?: number
396
+ }) {
397
+ const percentage = options?.percentage ?? 0.1 // default 10%
398
+ const maxItems = options?.maxItems
399
+
400
+ // 1. get all IDs with projection (bypasses main schema decode)
401
+ const allIds = yield* store
402
+ .filter({
403
+ t: null as unknown as Encoded,
404
+ select: [idKey as keyof Encoded]
405
+ })
406
+ .pipe(Effect.withSpan("Repository.filter", {
407
+ kind: "client",
408
+ attributes: { "app.entity": name }
409
+ }, { captureStackTrace: false }))
410
+
411
+ // 2. random subset
412
+ const shuffled = [...allIds].sort(() => Math.random() - 0.5)
413
+ const sampleSize = Math.min(
414
+ maxItems ?? Infinity,
415
+ Math.ceil(allIds.length * percentage)
416
+ )
417
+ const sample = shuffled.slice(0, sampleSize)
418
+
419
+ // 3. validate each item
420
+ const errors: ValidationError[] = []
421
+
422
+ for (const item of sample) {
423
+ const id = item[idKey]
424
+ const rawResult = yield* store.find(id).pipe(
425
+ Effect.withSpan("Repository.find", {
426
+ kind: "client",
427
+ attributes: { "app.entity": name, "app.entity.id": id }
428
+ }, { captureStackTrace: false })
429
+ )
366
430
 
367
- const rawData = rawResult.value as Encoded
368
- const jitMResult = mapFrom(rawData) // apply jitM
431
+ if (Option.isNone(rawResult)) continue
369
432
 
370
- const decodeResult = yield* S.decodeEffect(schema)(jitMResult).pipe(
371
- Effect.result,
372
- provideRctx
373
- )
433
+ const rawData = rawResult.value as Encoded
434
+ const jitMResult = mapFrom(rawData) // apply jitM
374
435
 
375
- if (Result.isFailure(decodeResult)) {
376
- errors.push(
377
- new ValidationError({
378
- id,
379
- rawData,
380
- jitMResult,
381
- error: decodeResult.failure
382
- })
436
+ const decodeResult = yield* S.decodeEffectConcurrently(schema)(jitMResult).pipe(
437
+ Effect.result,
438
+ provideRctx
383
439
  )
440
+
441
+ if (Result.isFailure(decodeResult)) {
442
+ errors.push(
443
+ ValidationError.make({
444
+ id,
445
+ rawData,
446
+ jitMResult,
447
+ error: decodeResult.failure
448
+ })
449
+ )
450
+ }
384
451
  }
385
- }
386
452
 
387
- return new ValidationResult({
388
- total: NonNegativeInt(allIds.length),
389
- sampled: NonNegativeInt(sample.length),
390
- valid: NonNegativeInt(sample.length - errors.length),
391
- errors
392
- })
393
- })
453
+ return ValidationResult.make({
454
+ total: NonNegativeInt(allIds.length),
455
+ sampled: NonNegativeInt(sample.length),
456
+ valid: NonNegativeInt(sample.length - errors.length),
457
+ errors
458
+ })
459
+ }
460
+ )
394
461
 
395
462
  const r = {
396
463
  changeFeed,
@@ -401,10 +468,17 @@ export function makeRepoInternal<
401
468
  saveAndPublish,
402
469
  removeAndPublish,
403
470
  removeById,
471
+ seedNamespace: (namespace: string) => store.seedNamespace(namespace),
404
472
  validateSample,
405
473
  queryRaw<A, Out, QR>(schema: S.Codec<A, Out, QR>, q: Q.RawQuery<Encoded, Out>) {
406
- const dec = S.decodeEffect(S.Array(schema))
407
- return store.queryRaw(q).pipe(Effect.flatMap(dec))
474
+ const dec = S.decodeEffectConcurrently(S.Array(schema))
475
+ return store.queryRaw(q).pipe(
476
+ Effect.flatMap(dec),
477
+ Effect.withSpan("Repository.queryRaw", {
478
+ kind: "client",
479
+ attributes: { "app.entity": name }
480
+ }, { captureStackTrace: false })
481
+ )
408
482
  },
409
483
  query(q: any) {
410
484
  // eslint-disable-next-line prefer-rest-params
@@ -414,15 +488,23 @@ export function makeRepoInternal<
414
488
  * @internal
415
489
  */
416
490
  mapped: <A, R>(schema: S.Codec<A, any, R>) => {
417
- const dec = S.decodeEffect(schema)
491
+ const dec = S.decodeEffectConcurrently(schema)
418
492
  const encMany = S.encodeEffect(S.Array(schema))
419
- const decMany = S.decodeEffect(S.Array(schema))
493
+ const decMany = S.decodeEffectConcurrently(S.Array(schema))
494
+ const spanAttrs = { kind: "client" as const, attributes: { "app.entity": name } }
420
495
  return {
421
496
  all: allE.pipe(
422
497
  Effect.flatMap(decMany),
423
- Effect.map((_) => _ as any[])
498
+ Effect.map((_) => _ as any[]),
499
+ Effect.withSpan("Repository.mapped.all", spanAttrs, { captureStackTrace: false })
424
500
  ),
425
- find: (id: T[IdKey]) => flatMapOption(findE(id), dec),
501
+ find: (id: T[IdKey]) =>
502
+ flatMapOption(findE(id), dec).pipe(
503
+ Effect.withSpan("Repository.mapped.find", {
504
+ ...spanAttrs,
505
+ attributes: { ...spanAttrs.attributes, "app.entity.id": id }
506
+ }, { captureStackTrace: false })
507
+ ),
426
508
  // query: (q: any) => {
427
509
  // const a = Q.toFilter(q)
428
510
 
@@ -441,12 +523,12 @@ export function makeRepoInternal<
441
523
  // },
442
524
  save: (...xes: any[]) =>
443
525
  Effect.flatMap(encMany(xes), (_) => saveAllE(_)).pipe(
444
- Effect.withSpan("mapped.save", {}, { captureStackTrace: false })
526
+ Effect.withSpan("Repository.mapped.save", spanAttrs, { captureStackTrace: false })
445
527
  )
446
528
  }
447
529
  }
448
530
  }
449
- return r as Repository<T, Encoded, Evt, ItemType, IdKey, Exclude<R, RCtx>, RPublish>
531
+ return r as Repository<T, Encoded, Evt, ItemType, IdKey, Exclude<R, RCtx>, RPublish, RCtx>
450
532
  })
451
533
  .pipe(Effect
452
534
  // .withSpan("Repository.make [effect-app/infra]", { attributes: { "repository.model_name": name } })
@@ -513,7 +595,7 @@ export function makeStore<Encoded extends FieldValues>() {
513
595
  .pipe(
514
596
  Effect.flatMap(Effect.forEach(encodeToEncoded())),
515
597
  setupRequestContextFromCurrent("Repository.makeInitial [effect-app/infra]", {
516
- attributes: { "repository.model_name": name }
598
+ attributes: { "app.entity": name }
517
599
  })
518
600
  )
519
601
  : undefined,
@@ -1,7 +1,9 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
2
  /* eslint-disable @typescript-eslint/no-unsafe-assignment */
3
- import type { Effect, Option, S } from "effect-app"
4
3
  import type { OptimisticConcurrencyException } from "effect-app/client/errors"
4
+ import type * as Effect from "effect-app/Effect"
5
+ import type * as Option from "effect-app/Option"
6
+ import type * as S from "effect-app/Schema"
5
7
 
6
8
  export interface Mapped1<A, IdKey extends keyof A, R> {
7
9
  all: Effect.Effect<A[], S.SchemaError, R>
@@ -5,13 +5,16 @@
5
5
  /* eslint-disable @typescript-eslint/no-explicit-any */
6
6
 
7
7
  // import type { ParserEnv } from "effect-app/Schema/custom/Parser"
8
- import type {} from "effect/Equal"
9
- import type {} from "effect/Hash"
10
- import { Effect, type NonEmptyReadonlyArray, type S, type ServiceMap } from "effect-app"
8
+
9
+ import type { NonEmptyReadonlyArray } from "effect-app/Array"
10
+ import type * as Context from "effect-app/Context"
11
+ import * as Effect from "effect-app/Effect"
12
+ import type * as S from "effect-app/Schema"
11
13
  import type { StoreConfig, StoreMaker } from "../../Store.js"
12
14
  import type { FieldValues } from "../filter/types.js"
13
15
  import { type ExtendedRepository, extendRepo } from "./ext.js"
14
16
  import { makeRepoInternal } from "./internal/internal.js"
17
+ import { RepositoryRegistry } from "./Registry.js"
15
18
  import type { Repository } from "./service.js"
16
19
 
17
20
  export interface RepositoryOptions<
@@ -52,11 +55,11 @@ export interface RepositoryOptions<
52
55
  * Optional context to be provided to Schema decode/encode.
53
56
  * Useful for effectful transformations like XWithItems, where items is a transformation retrieving elements from another database table or other source.
54
57
  */
55
- schemaContext?: ServiceMap.ServiceMap<RCtx>
58
+ schemaContext?: Context.Context<RCtx>
56
59
 
57
60
  overrides?: (
58
- repo: Repository<T, Encoded, Evt, ItemType, IdKey, Exclude<RSchema, RCtx>, RPublish>
59
- ) => Repository<T, Encoded, Evt, ItemType, IdKey, Exclude<RSchema, RCtx>, RPublish>
61
+ repo: Repository<T, Encoded, Evt, ItemType, IdKey, Exclude<RSchema, RCtx>, RPublish, RCtx>
62
+ ) => Repository<T, Encoded, Evt, ItemType, IdKey, Exclude<RSchema, RCtx>, RPublish, RCtx>
60
63
  }
61
64
 
62
65
  /**
@@ -83,9 +86,9 @@ export const makeRepo: {
83
86
  schema: S.Codec<T, Encoded, RSchema>,
84
87
  options: RepositoryOptions<IdKey, Encoded, T, ItemType, Evt, RPublish, E, RInitial, RCtx, RSchema>
85
88
  ): Effect.Effect<
86
- ExtendedRepository<T, Encoded, Evt, ItemType, IdKey, Exclude<RSchema, RCtx>, RPublish>,
89
+ ExtendedRepository<T, Encoded, Evt, ItemType, IdKey, Exclude<RSchema, RCtx>, RPublish, RCtx>,
87
90
  E,
88
- RInitial | StoreMaker
91
+ RInitial | StoreMaker | RepositoryRegistry
89
92
  >
90
93
  <
91
94
  ItemType extends string,
@@ -102,9 +105,9 @@ export const makeRepo: {
102
105
  schema: S.Codec<T, Encoded, RSchema>,
103
106
  options: Omit<RepositoryOptions<"id", Encoded, T, ItemType, Evt, RPublish, E, RInitial, RCtx, RSchema>, "idKey">
104
107
  ): Effect.Effect<
105
- ExtendedRepository<T, Encoded, Evt, ItemType, "id", Exclude<RSchema, RCtx>, RPublish>,
108
+ ExtendedRepository<T, Encoded, Evt, ItemType, "id", Exclude<RSchema, RCtx>, RPublish, RCtx>,
106
109
  E,
107
- RInitial | StoreMaker
110
+ RInitial | StoreMaker | RepositoryRegistry
108
111
  >
109
112
  } = <
110
113
  ItemType extends string,
@@ -135,5 +138,7 @@ export const makeRepo: {
135
138
  let r = yield* mkRepo.make<RInitial, E, RPublish, RCtx>(options as any)
136
139
  if (options.overrides) r = options.overrides(r)
137
140
  const repo = extendRepo(r)
141
+ const registry = yield* RepositoryRegistry
142
+ registry.register(itemType, repo)
138
143
  return repo
139
144
  })