effect-app 4.0.0-beta.26 → 4.0.0-beta.260

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 (365) hide show
  1. package/CHANGELOG.md +1192 -0
  2. package/dist/Array.d.ts +3 -2
  3. package/dist/Array.d.ts.map +1 -1
  4. package/dist/Array.js +4 -4
  5. package/dist/Chunk.d.ts +1 -1
  6. package/dist/Chunk.d.ts.map +1 -1
  7. package/dist/Config/SecretURL.d.ts +4 -2
  8. package/dist/Config/SecretURL.d.ts.map +1 -1
  9. package/dist/Config/SecretURL.js +3 -6
  10. package/dist/Config/internal/configSecretURL.d.ts +1 -1
  11. package/dist/Config/internal/configSecretURL.d.ts.map +1 -1
  12. package/dist/Config/internal/configSecretURL.js +2 -2
  13. package/dist/Config.d.ts +7 -0
  14. package/dist/Config.d.ts.map +1 -0
  15. package/dist/Config.js +6 -0
  16. package/dist/ConfigProvider.d.ts +39 -0
  17. package/dist/ConfigProvider.d.ts.map +1 -0
  18. package/dist/ConfigProvider.js +42 -0
  19. package/dist/Context.d.ts +42 -0
  20. package/dist/Context.d.ts.map +1 -0
  21. package/dist/Context.js +67 -0
  22. package/dist/Effect.d.ts +13 -12
  23. package/dist/Effect.d.ts.map +1 -1
  24. package/dist/Effect.js +5 -8
  25. package/dist/Emailer.d.ts +51 -0
  26. package/dist/Emailer.d.ts.map +1 -0
  27. package/dist/Emailer.js +7 -0
  28. package/dist/Function.d.ts +1 -1
  29. package/dist/Function.d.ts.map +1 -1
  30. package/dist/Inputify.type.d.ts +1 -1
  31. package/dist/Layer.d.ts +11 -7
  32. package/dist/Layer.d.ts.map +1 -1
  33. package/dist/Layer.js +3 -2
  34. package/dist/Model/Repository/Registry.d.ts +21 -0
  35. package/dist/Model/Repository/Registry.d.ts.map +1 -0
  36. package/dist/Model/Repository/Registry.js +18 -0
  37. package/dist/Model/Repository/ext.d.ts +60 -0
  38. package/dist/Model/Repository/ext.d.ts.map +1 -0
  39. package/dist/Model/Repository/ext.js +122 -0
  40. package/dist/Model/Repository/internal/internal.d.ts +63 -0
  41. package/dist/Model/Repository/internal/internal.d.ts.map +1 -0
  42. package/dist/Model/Repository/internal/internal.js +430 -0
  43. package/dist/Model/Repository/legacy.d.ts +21 -0
  44. package/dist/Model/Repository/legacy.d.ts.map +1 -0
  45. package/dist/Model/Repository/legacy.js +2 -0
  46. package/dist/Model/Repository/makeRepo.d.ts +54 -0
  47. package/dist/Model/Repository/makeRepo.d.ts.map +1 -0
  48. package/dist/Model/Repository/makeRepo.js +27 -0
  49. package/dist/Model/Repository/service.d.ts +121 -0
  50. package/dist/Model/Repository/service.d.ts.map +1 -0
  51. package/dist/Model/Repository/service.js +2 -0
  52. package/dist/Model/Repository/validation.d.ts +58 -0
  53. package/dist/Model/Repository/validation.d.ts.map +1 -0
  54. package/dist/Model/Repository/validation.js +32 -0
  55. package/dist/Model/Repository.d.ts +7 -0
  56. package/dist/Model/Repository.d.ts.map +1 -0
  57. package/dist/Model/Repository.js +7 -0
  58. package/dist/Model/dsl.d.ts +33 -0
  59. package/dist/Model/dsl.d.ts.map +1 -0
  60. package/dist/Model/dsl.js +43 -0
  61. package/dist/Model/filter/filterApi.d.ts +30 -0
  62. package/dist/Model/filter/filterApi.d.ts.map +1 -0
  63. package/dist/Model/filter/filterApi.js +2 -0
  64. package/dist/Model/filter/types/errors.d.ts +29 -0
  65. package/dist/Model/filter/types/errors.d.ts.map +1 -0
  66. package/dist/Model/filter/types/errors.js +2 -0
  67. package/dist/Model/filter/types/fields.d.ts +15 -0
  68. package/dist/Model/filter/types/fields.d.ts.map +1 -0
  69. package/dist/Model/filter/types/fields.js +2 -0
  70. package/dist/Model/filter/types/path/common.d.ts +316 -0
  71. package/dist/Model/filter/types/path/common.d.ts.map +1 -0
  72. package/dist/Model/filter/types/path/common.js +2 -0
  73. package/dist/Model/filter/types/path/eager.d.ts +95 -0
  74. package/dist/Model/filter/types/path/eager.d.ts.map +1 -0
  75. package/dist/Model/filter/types/path/eager.js +31 -0
  76. package/dist/Model/filter/types/path/index.d.ts +4 -0
  77. package/dist/Model/filter/types/path/index.d.ts.map +1 -0
  78. package/dist/Model/filter/types/path/index.js +3 -0
  79. package/dist/Model/filter/types/utils.d.ts +79 -0
  80. package/dist/Model/filter/types/utils.d.ts.map +1 -0
  81. package/dist/Model/filter/types/utils.js +2 -0
  82. package/dist/Model/filter/types/validator.d.ts +30 -0
  83. package/dist/Model/filter/types/validator.d.ts.map +1 -0
  84. package/dist/Model/filter/types/validator.js +2 -0
  85. package/dist/Model/filter/types.d.ts +5 -0
  86. package/dist/Model/filter/types.d.ts.map +1 -0
  87. package/dist/Model/filter/types.js +7 -0
  88. package/dist/Model/query/dsl.d.ts +493 -0
  89. package/dist/Model/query/dsl.d.ts.map +1 -0
  90. package/dist/Model/query/dsl.js +376 -0
  91. package/dist/Model/query/new-kid-interpreter.d.ts +136 -0
  92. package/dist/Model/query/new-kid-interpreter.d.ts.map +1 -0
  93. package/dist/Model/query/new-kid-interpreter.js +336 -0
  94. package/dist/Model/query.d.ts +15 -0
  95. package/dist/Model/query.d.ts.map +1 -0
  96. package/dist/Model/query.js +3 -0
  97. package/dist/Model.d.ts +5 -0
  98. package/dist/Model.d.ts.map +1 -0
  99. package/dist/Model.js +5 -0
  100. package/dist/NonEmptySet.d.ts +4 -2
  101. package/dist/NonEmptySet.d.ts.map +1 -1
  102. package/dist/NonEmptySet.js +2 -2
  103. package/dist/Option.d.ts +2 -1
  104. package/dist/Option.d.ts.map +1 -1
  105. package/dist/Option.js +3 -1
  106. package/dist/Pure.d.ts +8 -6
  107. package/dist/Pure.d.ts.map +1 -1
  108. package/dist/Pure.js +17 -14
  109. package/dist/QueueMaker.d.ts +13 -0
  110. package/dist/QueueMaker.d.ts.map +1 -0
  111. package/dist/QueueMaker.js +4 -0
  112. package/dist/RequestContext.d.ts +91 -0
  113. package/dist/RequestContext.d.ts.map +1 -0
  114. package/dist/RequestContext.js +49 -0
  115. package/dist/Schema/Class.d.ts +66 -20
  116. package/dist/Schema/Class.d.ts.map +1 -1
  117. package/dist/Schema/Class.js +192 -27
  118. package/dist/Schema/FastCheck.d.ts +1 -1
  119. package/dist/Schema/FastCheck.d.ts.map +1 -1
  120. package/dist/Schema/Methods.d.ts +1 -1
  121. package/dist/Schema/SchemaParser.d.ts +5 -0
  122. package/dist/Schema/SchemaParser.d.ts.map +1 -0
  123. package/dist/Schema/SchemaParser.js +6 -0
  124. package/dist/Schema/SpecialJsonSchema.d.ts +34 -0
  125. package/dist/Schema/SpecialJsonSchema.d.ts.map +1 -0
  126. package/dist/Schema/SpecialJsonSchema.js +118 -0
  127. package/dist/Schema/SpecialOpenApi.d.ts +32 -0
  128. package/dist/Schema/SpecialOpenApi.d.ts.map +1 -0
  129. package/dist/Schema/SpecialOpenApi.js +123 -0
  130. package/dist/Schema/brand.d.ts +5 -3
  131. package/dist/Schema/brand.d.ts.map +1 -1
  132. package/dist/Schema/brand.js +3 -1
  133. package/dist/Schema/email.d.ts +1 -1
  134. package/dist/Schema/email.d.ts.map +1 -1
  135. package/dist/Schema/email.js +7 -4
  136. package/dist/Schema/ext.d.ts +339 -56
  137. package/dist/Schema/ext.d.ts.map +1 -1
  138. package/dist/Schema/ext.js +358 -53
  139. package/dist/Schema/moreStrings.d.ts +83 -37
  140. package/dist/Schema/moreStrings.d.ts.map +1 -1
  141. package/dist/Schema/moreStrings.js +49 -42
  142. package/dist/Schema/numbers.d.ts +35 -22
  143. package/dist/Schema/numbers.d.ts.map +1 -1
  144. package/dist/Schema/numbers.js +55 -12
  145. package/dist/Schema/phoneNumber.d.ts +1 -1
  146. package/dist/Schema/phoneNumber.d.ts.map +1 -1
  147. package/dist/Schema/phoneNumber.js +6 -3
  148. package/dist/Schema/schema.d.ts +1 -1
  149. package/dist/Schema/strings.d.ts +19 -5
  150. package/dist/Schema/strings.d.ts.map +1 -1
  151. package/dist/Schema/strings.js +1 -5
  152. package/dist/Schema.d.ts +214 -8
  153. package/dist/Schema.d.ts.map +1 -1
  154. package/dist/Schema.js +190 -11
  155. package/dist/Set.d.ts +5 -2
  156. package/dist/Set.d.ts.map +1 -1
  157. package/dist/Set.js +3 -2
  158. package/dist/Store.d.ts +170 -0
  159. package/dist/Store.d.ts.map +1 -0
  160. package/dist/Store.js +121 -0
  161. package/dist/TypeTest.d.ts +1 -1
  162. package/dist/Types.d.ts +1 -1
  163. package/dist/Widen.type.d.ts +1 -1
  164. package/dist/_ext/Array.d.ts +2 -2
  165. package/dist/_ext/Array.d.ts.map +1 -1
  166. package/dist/_ext/Array.js +4 -2
  167. package/dist/_ext/date.d.ts +1 -1
  168. package/dist/_ext/misc.d.ts +5 -2
  169. package/dist/_ext/misc.d.ts.map +1 -1
  170. package/dist/_ext/misc.js +4 -2
  171. package/dist/_ext/ord.ext.d.ts +3 -2
  172. package/dist/_ext/ord.ext.d.ts.map +1 -1
  173. package/dist/_ext/ord.ext.js +2 -2
  174. package/dist/builtin.d.ts +1 -1
  175. package/dist/builtin.d.ts.map +1 -1
  176. package/dist/client/InvalidationKeys.d.ts +29 -0
  177. package/dist/client/InvalidationKeys.d.ts.map +1 -0
  178. package/dist/client/InvalidationKeys.js +33 -0
  179. package/dist/client/apiClientFactory.d.ts +20 -32
  180. package/dist/client/apiClientFactory.d.ts.map +1 -1
  181. package/dist/client/apiClientFactory.js +104 -34
  182. package/dist/client/clientFor.d.ts +53 -19
  183. package/dist/client/clientFor.d.ts.map +1 -1
  184. package/dist/client/clientFor.js +9 -1
  185. package/dist/client/errors.d.ts +49 -25
  186. package/dist/client/errors.d.ts.map +1 -1
  187. package/dist/client/errors.js +43 -17
  188. package/dist/client/makeClient.d.ts +495 -33
  189. package/dist/client/makeClient.d.ts.map +1 -1
  190. package/dist/client/makeClient.js +66 -24
  191. package/dist/client.d.ts +6 -5
  192. package/dist/client.d.ts.map +1 -1
  193. package/dist/client.js +2 -1
  194. package/dist/faker.d.ts +1 -1
  195. package/dist/faker.d.ts.map +1 -1
  196. package/dist/http/Request.d.ts +2 -2
  197. package/dist/http/Request.d.ts.map +1 -1
  198. package/dist/http/Request.js +2 -2
  199. package/dist/http/internal/lib.d.ts +1 -1
  200. package/dist/http.d.ts +1 -1
  201. package/dist/ids.d.ts +43 -15
  202. package/dist/ids.d.ts.map +1 -1
  203. package/dist/ids.js +30 -5
  204. package/dist/index.d.ts +7 -8
  205. package/dist/index.d.ts.map +1 -1
  206. package/dist/index.js +8 -8
  207. package/dist/logger.d.ts +1 -1
  208. package/dist/middleware.d.ts +14 -8
  209. package/dist/middleware.d.ts.map +1 -1
  210. package/dist/middleware.js +14 -8
  211. package/dist/rpc/Invalidation.d.ts +420 -0
  212. package/dist/rpc/Invalidation.d.ts.map +1 -0
  213. package/dist/rpc/Invalidation.js +168 -0
  214. package/dist/rpc/MiddlewareMaker.d.ts +12 -8
  215. package/dist/rpc/MiddlewareMaker.d.ts.map +1 -1
  216. package/dist/rpc/MiddlewareMaker.js +59 -38
  217. package/dist/rpc/RpcContextMap.d.ts +4 -4
  218. package/dist/rpc/RpcContextMap.d.ts.map +1 -1
  219. package/dist/rpc/RpcContextMap.js +4 -4
  220. package/dist/rpc/RpcMiddleware.d.ts +15 -11
  221. package/dist/rpc/RpcMiddleware.d.ts.map +1 -1
  222. package/dist/rpc/RpcMiddleware.js +1 -1
  223. package/dist/rpc.d.ts +2 -2
  224. package/dist/rpc.d.ts.map +1 -1
  225. package/dist/rpc.js +2 -2
  226. package/dist/runtime.d.ts +19 -0
  227. package/dist/runtime.d.ts.map +1 -0
  228. package/dist/runtime.js +40 -0
  229. package/dist/setupRequest.d.ts +19 -0
  230. package/dist/setupRequest.d.ts.map +1 -0
  231. package/dist/setupRequest.js +69 -0
  232. package/dist/toast.d.ts +51 -0
  233. package/dist/toast.d.ts.map +1 -0
  234. package/dist/toast.js +34 -0
  235. package/dist/transform.d.ts +2 -2
  236. package/dist/transform.d.ts.map +1 -1
  237. package/dist/transform.js +4 -5
  238. package/dist/utils/effectify.d.ts +2 -2
  239. package/dist/utils/effectify.d.ts.map +1 -1
  240. package/dist/utils/effectify.js +2 -2
  241. package/dist/utils/extend.d.ts +1 -1
  242. package/dist/utils/extend.d.ts.map +1 -1
  243. package/dist/utils/gen.d.ts +5 -5
  244. package/dist/utils/gen.d.ts.map +1 -1
  245. package/dist/utils/logLevel.d.ts +3 -3
  246. package/dist/utils/logLevel.d.ts.map +1 -1
  247. package/dist/utils/logger.d.ts +5 -4
  248. package/dist/utils/logger.d.ts.map +1 -1
  249. package/dist/utils/logger.js +4 -4
  250. package/dist/utils.d.ts +40 -45
  251. package/dist/utils.d.ts.map +1 -1
  252. package/dist/utils.js +19 -27
  253. package/dist/validation/validators.d.ts +1 -1
  254. package/dist/validation/validators.d.ts.map +1 -1
  255. package/dist/validation.d.ts +1 -1
  256. package/dist/validation.d.ts.map +1 -1
  257. package/dist/withToast.d.ts +30 -0
  258. package/dist/withToast.d.ts.map +1 -0
  259. package/dist/withToast.js +64 -0
  260. package/package.json +20 -245
  261. package/src/Array.ts +3 -3
  262. package/src/Config/SecretURL.ts +5 -2
  263. package/src/Config/internal/configSecretURL.ts +1 -1
  264. package/src/Config.ts +14 -0
  265. package/src/ConfigProvider.ts +48 -0
  266. package/src/{ServiceMap.ts → Context.ts} +56 -63
  267. package/src/Effect.ts +12 -14
  268. package/src/Emailer.ts +51 -0
  269. package/src/Layer.ts +10 -6
  270. package/src/Model/Repository/Registry.ts +34 -0
  271. package/src/Model/Repository/ext.ts +375 -0
  272. package/src/Model/Repository/internal/internal.ts +741 -0
  273. package/src/Model/Repository/legacy.ts +29 -0
  274. package/src/Model/Repository/makeRepo.ts +145 -0
  275. package/src/Model/Repository/service.ts +666 -0
  276. package/src/Model/Repository/validation.ts +31 -0
  277. package/src/Model/Repository.ts +6 -0
  278. package/src/Model/dsl.ts +129 -0
  279. package/src/Model/filter/filterApi.ts +60 -0
  280. package/src/Model/filter/types/errors.ts +47 -0
  281. package/src/Model/filter/types/fields.ts +50 -0
  282. package/src/Model/filter/types/path/common.ts +404 -0
  283. package/src/Model/filter/types/path/eager.ts +297 -0
  284. package/src/Model/filter/types/path/index.ts +4 -0
  285. package/src/Model/filter/types/utils.ts +128 -0
  286. package/src/Model/filter/types/validator.ts +46 -0
  287. package/src/Model/filter/types.ts +6 -0
  288. package/src/Model/query/dsl.ts +2694 -0
  289. package/src/Model/query/new-kid-interpreter.ts +484 -0
  290. package/src/Model/query.ts +13 -0
  291. package/src/Model.ts +4 -0
  292. package/src/NonEmptySet.ts +3 -1
  293. package/src/Option.ts +2 -0
  294. package/src/Pure.ts +21 -19
  295. package/src/QueueMaker.ts +19 -0
  296. package/src/RequestContext.ts +62 -0
  297. package/src/Schema/Class.ts +274 -68
  298. package/src/Schema/SchemaParser.ts +12 -0
  299. package/src/Schema/SpecialJsonSchema.ts +139 -0
  300. package/src/Schema/SpecialOpenApi.ts +130 -0
  301. package/src/Schema/brand.ts +22 -2
  302. package/src/Schema/email.ts +7 -2
  303. package/src/Schema/ext.ts +443 -88
  304. package/src/Schema/moreStrings.ts +146 -67
  305. package/src/Schema/numbers.ts +96 -27
  306. package/src/Schema/phoneNumber.ts +5 -1
  307. package/src/Schema/strings.ts +22 -13
  308. package/src/Schema.ts +374 -10
  309. package/src/Set.ts +5 -1
  310. package/src/Store.ts +277 -0
  311. package/src/_ext/Array.ts +3 -1
  312. package/src/_ext/misc.ts +4 -1
  313. package/src/_ext/ord.ext.ts +2 -1
  314. package/src/client/InvalidationKeys.ts +50 -0
  315. package/src/client/apiClientFactory.ts +230 -131
  316. package/src/client/clientFor.ts +102 -31
  317. package/src/client/errors.ts +52 -26
  318. package/src/client/makeClient.ts +592 -71
  319. package/src/client.ts +5 -4
  320. package/src/http/Request.ts +1 -1
  321. package/src/ids.ts +32 -5
  322. package/src/index.ts +7 -10
  323. package/src/middleware.ts +13 -9
  324. package/src/rpc/Invalidation.ts +261 -0
  325. package/src/rpc/MiddlewareMaker.ts +83 -75
  326. package/src/rpc/README.md +2 -2
  327. package/src/rpc/RpcContextMap.ts +6 -5
  328. package/src/rpc/RpcMiddleware.ts +18 -12
  329. package/src/rpc.ts +1 -1
  330. package/src/runtime.ts +56 -0
  331. package/src/setupRequest.ts +134 -0
  332. package/src/toast.ts +54 -0
  333. package/src/transform.ts +3 -3
  334. package/src/utils/effectify.ts +1 -1
  335. package/src/utils/gen.ts +8 -8
  336. package/src/utils/logLevel.ts +1 -1
  337. package/src/utils/logger.ts +4 -3
  338. package/src/utils.ts +62 -139
  339. package/src/withToast.ts +133 -0
  340. package/test/dist/rpc-dynamic-middleware.test.d.ts.map +1 -0
  341. package/test/dist/rpc.test.d.ts.map +1 -1
  342. package/test/dist/secretURL.test.d.ts.map +1 -0
  343. package/test/dist/special.test.d.ts.map +1 -0
  344. package/test/dist/stream-error.types.d.ts +2 -0
  345. package/test/dist/stream-error.types.d.ts.map +1 -0
  346. package/test/dist/stream-error.types.js +27 -0
  347. package/test/moreStrings.test.ts +1 -1
  348. package/test/rpc.test.ts +46 -6
  349. package/test/schema.test.ts +459 -30
  350. package/test/secretURL.test.ts +160 -0
  351. package/test/special.test.ts +1026 -0
  352. package/test/utils.test.ts +7 -7
  353. package/tsconfig.base.json +6 -5
  354. package/tsconfig.json +2 -1
  355. package/tsconfig.json.bak +2 -2
  356. package/tsconfig.src.json +29 -29
  357. package/tsconfig.test.json +2 -2
  358. package/dist/Operations.d.ts +0 -123
  359. package/dist/Operations.d.ts.map +0 -1
  360. package/dist/Operations.js +0 -29
  361. package/dist/ServiceMap.d.ts +0 -44
  362. package/dist/ServiceMap.d.ts.map +0 -1
  363. package/dist/ServiceMap.js +0 -91
  364. package/eslint.config.mjs +0 -26
  365. package/src/Operations.ts +0 -55
@@ -0,0 +1,375 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ /* eslint-disable @typescript-eslint/no-unsafe-return */
3
+ import * as Exit from "effect/Exit"
4
+ import * as Request from "effect/Request"
5
+ import * as RequestResolver from "effect/RequestResolver"
6
+ import * as Array from "../../Array.js"
7
+ import type { NonEmptyArray } from "../../Array.js"
8
+ import { type InvalidStateError, NotFoundError, type OptimisticConcurrencyException } from "../../client/errors.js"
9
+ import * as Effect from "../../Effect.js"
10
+ import * as Option from "../../Option.js"
11
+ import { type FixEnv, type PureEnv, runTerm } from "../../Pure.js"
12
+ import { AnyPureDSL } from "../dsl.js"
13
+ import type { FieldValues } from "../filter/types.js"
14
+ import type { Query, QueryEnd, QueryWhere } from "../query.js"
15
+ import * as Q from "../query.js"
16
+ import type { Repository } from "./service.js"
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
+
34
+ export const extendRepo = <
35
+ T,
36
+ Encoded extends FieldValues,
37
+ Evt,
38
+ ItemType extends string,
39
+ IdKey extends keyof T & keyof Encoded,
40
+ RSchema,
41
+ RPublish,
42
+ RProvided = never
43
+ >(
44
+ repo: Repository<T, Encoded, Evt, ItemType, IdKey, RSchema, RPublish, RProvided>
45
+ ) => {
46
+ const get = (id: T[IdKey]) =>
47
+ repo.find(id).pipe(
48
+ Effect.flatMap(Option.match({
49
+ onNone: () => Effect.fail(new NotFoundError<ItemType>({ type: repo.itemType, id })),
50
+ onSome: Effect.succeed
51
+ }))
52
+ )
53
+ function saveManyWithPure_<
54
+ R,
55
+ A,
56
+ E,
57
+ S1 extends T,
58
+ S2 extends T
59
+ >(
60
+ items: Iterable<S1>,
61
+ pure: Effect.Effect<A, E, FixEnv<R, Evt, readonly S1[], readonly S2[]>>
62
+ ) {
63
+ return saveAllWithEffectInt(
64
+ runTerm(pure, [...items])
65
+ )
66
+ }
67
+
68
+ function saveWithPure_<
69
+ R,
70
+ A,
71
+ E,
72
+ S1 extends T,
73
+ S2 extends T
74
+ >(
75
+ item: S1,
76
+ pure: Effect.Effect<A, E, FixEnv<R, Evt, S1, S2>>
77
+ ) {
78
+ return saveAllWithEffectInt(
79
+ runTerm(pure, item)
80
+ .pipe(Effect
81
+ .map(([item, events, a]) => [[item], events, a]))
82
+ )
83
+ }
84
+
85
+ function saveAllWithEffectInt<
86
+ P extends T,
87
+ R,
88
+ E,
89
+ A
90
+ >(
91
+ gen: Effect.Effect<readonly [Iterable<P>, Iterable<Evt>, A], E, R>
92
+ ) {
93
+ return Effect.flatMap(gen, ([items, events, a]) => repo.saveAndPublish(items, events).pipe(Effect.map(() => a)))
94
+ }
95
+
96
+ function saveManyWithPureBatched_<
97
+ R,
98
+ A,
99
+ E,
100
+ S1 extends T,
101
+ S2 extends T
102
+ >(
103
+ items: Iterable<S1>,
104
+ pure: Effect.Effect<A, E, FixEnv<R, Evt, readonly S1[], readonly S2[]>>,
105
+ batchSize = 100
106
+ ) {
107
+ return Effect.forEach(
108
+ Array.chunksOf(items, batchSize),
109
+ (batch) =>
110
+ saveAllWithEffectInt(
111
+ runTerm(pure, batch)
112
+ )
113
+ )
114
+ }
115
+
116
+ const queryAndSavePure: {
117
+ <A, E2, R2, T2 extends T>(
118
+ q: (
119
+ q: Query<Encoded>
120
+ ) => QueryEnd<Encoded, "one">,
121
+ pure: Effect.Effect<A, E2, FixEnv<R2, Evt, T, T2>>
122
+ ): Effect.Effect<
123
+ A,
124
+ InvalidStateError | OptimisticConcurrencyException | NotFoundError<ItemType> | E2,
125
+ Exclude<R2, {
126
+ env: PureEnv<Evt, T, T2>
127
+ }>
128
+ >
129
+ <A, E2, R2, T2 extends T>(
130
+ q: (
131
+ q: Query<Encoded>
132
+ ) =>
133
+ | Query<Encoded>
134
+ | QueryWhere<Encoded>
135
+ | QueryEnd<Encoded>,
136
+ pure: Effect.Effect<A, E2, FixEnv<R2, Evt, readonly T[], readonly T2[]>>
137
+ ): Effect.Effect<
138
+ A,
139
+ InvalidStateError | OptimisticConcurrencyException | E2,
140
+ | RSchema
141
+ | RPublish
142
+ | Exclude<R2, {
143
+ env: PureEnv<Evt, readonly T[], readonly T2[]>
144
+ }>
145
+ >
146
+ <A, E2, R2, T2 extends T>(
147
+ q: (
148
+ q: Query<Encoded>
149
+ ) =>
150
+ | Query<Encoded>
151
+ | QueryWhere<Encoded>
152
+ | QueryEnd<Encoded>,
153
+ pure: Effect.Effect<A, E2, FixEnv<R2, Evt, readonly T[], readonly T2[]>>,
154
+ batch: "batched" | number
155
+ ): Effect.Effect<
156
+ A[],
157
+ InvalidStateError | OptimisticConcurrencyException | E2,
158
+ | RSchema
159
+ | RPublish
160
+ | Exclude<R2, {
161
+ env: PureEnv<Evt, readonly T[], readonly T2[]>
162
+ }>
163
+ >
164
+ } = (q, pure, batch?: "batched" | number) =>
165
+ repo.query(q).pipe(
166
+ Effect.andThen((_) =>
167
+ Array.isArray(_)
168
+ ? batch === undefined
169
+ ? saveManyWithPure_(_ as any, pure as any)
170
+ : saveManyWithPureBatched_(_ as any, pure as any, batch === "batched" ? 100 : batch)
171
+ : saveWithPure_(_ as any, pure as any)
172
+ )
173
+ ) as any
174
+
175
+ const saveManyWithPure: {
176
+ <R, A, E, S1 extends T, S2 extends T>(
177
+ items: Iterable<S1>,
178
+ pure: Effect.Effect<A, E, FixEnv<R, Evt, readonly S1[], readonly S2[]>>
179
+ ): Effect.Effect<
180
+ A,
181
+ InvalidStateError | OptimisticConcurrencyException | E,
182
+ | RSchema
183
+ | RPublish
184
+ | Exclude<R, {
185
+ env: PureEnv<Evt, readonly S1[], readonly S2[]>
186
+ }>
187
+ >
188
+ <R, A, E, S1 extends T, S2 extends T>(
189
+ items: Iterable<S1>,
190
+ pure: Effect.Effect<A, E, FixEnv<R, Evt, readonly S1[], readonly S2[]>>,
191
+ batch: "batched" | number
192
+ ): Effect.Effect<
193
+ A[],
194
+ InvalidStateError | OptimisticConcurrencyException | E,
195
+ | RSchema
196
+ | RPublish
197
+ | Exclude<R, {
198
+ env: PureEnv<Evt, readonly S1[], readonly S2[]>
199
+ }>
200
+ >
201
+ } = (items, pure, batch?: "batched" | number) =>
202
+ batch
203
+ ? Effect.forEach(
204
+ Array.chunksOf(items, batch === "batched" ? 100 : batch),
205
+ (batch) =>
206
+ saveAllWithEffectInt(
207
+ runTerm(pure, batch)
208
+ )
209
+ )
210
+ : saveAllWithEffectInt(
211
+ runTerm(pure, [...items])
212
+ )
213
+
214
+ const byIdAndSaveWithPure: {
215
+ <R, A, E, S2 extends T>(
216
+ id: T[IdKey],
217
+ pure: Effect.Effect<A, E, FixEnv<R, Evt, T, S2>>
218
+ ): Effect.Effect<
219
+ A,
220
+ InvalidStateError | OptimisticConcurrencyException | NotFoundError<ItemType> | E,
221
+ | RSchema
222
+ | RPublish
223
+ | Exclude<R, {
224
+ env: PureEnv<Evt, T, S2>
225
+ }>
226
+ >
227
+ } = (id, pure): any => get(id).pipe(Effect.flatMap((item) => saveWithPure_(item, pure)))
228
+
229
+ type Req =
230
+ & Request.Request<T, NotFoundError<ItemType>>
231
+ & { _tag: `Get${ItemType}`; id: T[IdKey] }
232
+ const _request = Request.tagged<Req>(`Get${repo.itemType}`)
233
+
234
+ const requestResolver = RequestResolver
235
+ .make((
236
+ entries: NonEmptyArray<Request.Entry<Req>>,
237
+ _key: unknown
238
+ ) =>
239
+ (repo.query(Q.where(repo.idKey as any, "in" as any, entries.map((_) => _.request.id)) as any) as Effect.Effect<
240
+ readonly T[]
241
+ >)
242
+ // TODO
243
+ .pipe(
244
+ Effect.andThen((items) =>
245
+ Effect.forEach(entries, (entry) =>
246
+ Request.complete(
247
+ Array
248
+ .findFirst(items, (_) => _[repo.idKey] === entry.request.id)
249
+ .pipe(Option.match({
250
+ onNone: () => Exit.fail(new NotFoundError({ type: repo.itemType, id: entry.request.id })),
251
+ onSome: Exit.succeed
252
+ }))
253
+ )(entry), { discard: true })
254
+ ),
255
+ Effect
256
+ .catchCause((cause) =>
257
+ Effect.forEach(entries, (entry) => Request.complete(Exit.failCause(cause))(entry), { discard: true })
258
+ )
259
+ )
260
+ )
261
+ .pipe(
262
+ RequestResolver.batchN(20)
263
+ )
264
+
265
+ const exts = {
266
+ request: (id: T[IdKey]) => Effect.request(_request({ id }), requestResolver),
267
+ get,
268
+ log: (evt: Evt) => AnyPureDSL.log(evt),
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
+ >,
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>,
340
+ queryAndSavePure,
341
+ saveManyWithPure,
342
+ byIdAndSaveWithPure,
343
+ saveWithPure: <
344
+ R,
345
+ A,
346
+ E,
347
+ S1 extends T,
348
+ S2 extends T
349
+ >(
350
+ item: S1,
351
+ pure: Effect.Effect<A, E, FixEnv<R, Evt, S1, S2>>
352
+ ) =>
353
+ saveAllWithEffectInt(
354
+ runTerm(pure, item)
355
+ .pipe(Effect.map(([item, events, a]) => [[item], events, a]))
356
+ )
357
+ }
358
+
359
+ return {
360
+ ...repo,
361
+ ...exts
362
+ } as Repository<T, Encoded, Evt, ItemType, IdKey, RSchema, RPublish, RProvided> & typeof exts
363
+ }
364
+
365
+ // eslint-disable-next-line @typescript-eslint/no-empty-object-type
366
+ export interface ExtendedRepository<
367
+ T,
368
+ Encoded extends FieldValues,
369
+ Evt,
370
+ ItemType extends string,
371
+ IdKey extends keyof T & keyof Encoded,
372
+ RSchema,
373
+ RPublish,
374
+ RProvided = never
375
+ > extends ReturnType<typeof extendRepo<T, Encoded, Evt, ItemType, IdKey, RSchema, RPublish, RProvided>> {}