effect-app 4.0.0-beta.99 → 4.0.1

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 (391) hide show
  1. package/CHANGELOG.md +2042 -0
  2. package/dist/Array.d.ts +1 -17
  3. package/dist/Array.d.ts.map +1 -1
  4. package/dist/Array.js +3 -27
  5. package/dist/Chunk.d.ts +3 -27
  6. package/dist/Chunk.d.ts.map +1 -1
  7. package/dist/Chunk.js +4 -39
  8. package/dist/Config/SecretURL.d.ts +3 -1
  9. package/dist/Config/SecretURL.d.ts.map +1 -1
  10. package/dist/Config/SecretURL.js +3 -6
  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 +0 -5
  14. package/dist/Config.d.ts.map +1 -1
  15. package/dist/Config.js +7 -5
  16. package/dist/ConfigProvider.d.ts +0 -37
  17. package/dist/ConfigProvider.d.ts.map +1 -1
  18. package/dist/ConfigProvider.js +5 -41
  19. package/dist/Context.d.ts +6 -4
  20. package/dist/Context.d.ts.map +1 -1
  21. package/dist/Context.js +4 -3
  22. package/dist/DataDependencies.d.ts +136 -0
  23. package/dist/DataDependencies.d.ts.map +1 -0
  24. package/dist/DataDependencies.js +112 -0
  25. package/dist/DateTime.d.ts +33 -0
  26. package/dist/DateTime.d.ts.map +1 -0
  27. package/dist/DateTime.js +18 -0
  28. package/dist/Effect.d.ts +3 -14
  29. package/dist/Effect.d.ts.map +1 -1
  30. package/dist/Effect.js +8 -26
  31. package/dist/Emailer.d.ts +51 -0
  32. package/dist/Emailer.d.ts.map +1 -0
  33. package/dist/Emailer.js +7 -0
  34. package/dist/Function.d.ts +0 -4
  35. package/dist/Function.d.ts.map +1 -1
  36. package/dist/Function.js +1 -7
  37. package/dist/Layer.d.ts +6 -3
  38. package/dist/Layer.d.ts.map +1 -1
  39. package/dist/Layer.js +3 -2
  40. package/dist/Model/Repository/Registry.d.ts +22 -0
  41. package/dist/Model/Repository/Registry.d.ts.map +1 -0
  42. package/dist/Model/Repository/Registry.js +18 -0
  43. package/dist/Model/Repository/dependency.d.ts +6 -0
  44. package/dist/Model/Repository/dependency.d.ts.map +1 -0
  45. package/dist/Model/Repository/dependency.js +29 -0
  46. package/dist/Model/Repository/ext.d.ts +60 -0
  47. package/dist/Model/Repository/ext.d.ts.map +1 -0
  48. package/dist/Model/Repository/ext.js +124 -0
  49. package/dist/Model/Repository/internal/internal.d.ts +68 -0
  50. package/dist/Model/Repository/internal/internal.d.ts.map +1 -0
  51. package/dist/Model/Repository/internal/internal.js +610 -0
  52. package/dist/Model/Repository/legacy.d.ts +21 -0
  53. package/dist/Model/Repository/legacy.d.ts.map +1 -0
  54. package/dist/Model/Repository/legacy.js +2 -0
  55. package/dist/Model/Repository/makeRepo.d.ts +71 -0
  56. package/dist/Model/Repository/makeRepo.d.ts.map +1 -0
  57. package/dist/Model/Repository/makeRepo.js +30 -0
  58. package/dist/Model/Repository/service.d.ts +121 -0
  59. package/dist/Model/Repository/service.d.ts.map +1 -0
  60. package/dist/Model/Repository/service.js +2 -0
  61. package/dist/Model/Repository/validation.d.ts +72 -0
  62. package/dist/Model/Repository/validation.d.ts.map +1 -0
  63. package/dist/Model/Repository/validation.js +39 -0
  64. package/dist/Model/Repository.d.ts +8 -0
  65. package/dist/Model/Repository.d.ts.map +1 -0
  66. package/dist/Model/Repository.js +8 -0
  67. package/dist/Model/dsl.d.ts +34 -0
  68. package/dist/Model/dsl.d.ts.map +1 -0
  69. package/dist/Model/dsl.js +45 -0
  70. package/dist/Model/filter/filterApi.d.ts +30 -0
  71. package/dist/Model/filter/filterApi.d.ts.map +1 -0
  72. package/dist/Model/filter/filterApi.js +2 -0
  73. package/dist/Model/filter/types/errors.d.ts +29 -0
  74. package/dist/Model/filter/types/errors.d.ts.map +1 -0
  75. package/dist/Model/filter/types/errors.js +2 -0
  76. package/dist/Model/filter/types/fields.d.ts +15 -0
  77. package/dist/Model/filter/types/fields.d.ts.map +1 -0
  78. package/dist/Model/filter/types/fields.js +2 -0
  79. package/dist/Model/filter/types/path/common.d.ts +316 -0
  80. package/dist/Model/filter/types/path/common.d.ts.map +1 -0
  81. package/dist/Model/filter/types/path/common.js +2 -0
  82. package/dist/Model/filter/types/path/eager.d.ts +94 -0
  83. package/dist/Model/filter/types/path/eager.d.ts.map +1 -0
  84. package/dist/Model/filter/types/path/eager.js +36 -0
  85. package/dist/Model/filter/types/path/index.d.ts +4 -0
  86. package/dist/Model/filter/types/path/index.d.ts.map +1 -0
  87. package/dist/Model/filter/types/path/index.js +3 -0
  88. package/dist/Model/filter/types/utils.d.ts +79 -0
  89. package/dist/Model/filter/types/utils.d.ts.map +1 -0
  90. package/dist/Model/filter/types/utils.js +2 -0
  91. package/dist/Model/filter/types/validator.d.ts +30 -0
  92. package/dist/Model/filter/types/validator.d.ts.map +1 -0
  93. package/dist/Model/filter/types/validator.js +2 -0
  94. package/dist/Model/filter/types.d.ts +5 -0
  95. package/dist/Model/filter/types.d.ts.map +1 -0
  96. package/dist/Model/filter/types.js +7 -0
  97. package/dist/Model/query/dsl.d.ts +630 -0
  98. package/dist/Model/query/dsl.d.ts.map +1 -0
  99. package/dist/Model/query/dsl.js +376 -0
  100. package/dist/Model/query/new-kid-interpreter.d.ts +132 -0
  101. package/dist/Model/query/new-kid-interpreter.d.ts.map +1 -0
  102. package/dist/Model/query/new-kid-interpreter.js +369 -0
  103. package/dist/Model/query.d.ts +15 -0
  104. package/dist/Model/query.d.ts.map +1 -0
  105. package/dist/Model/query.js +3 -0
  106. package/dist/Model.d.ts +6 -0
  107. package/dist/Model.d.ts.map +1 -0
  108. package/dist/Model.js +6 -0
  109. package/dist/NonEmptySet.d.ts +3 -1
  110. package/dist/NonEmptySet.d.ts.map +1 -1
  111. package/dist/NonEmptySet.js +2 -2
  112. package/dist/Option.d.ts +1 -2
  113. package/dist/Option.d.ts.map +1 -1
  114. package/dist/Option.js +3 -7
  115. package/dist/Pure.d.ts +9 -7
  116. package/dist/Pure.d.ts.map +1 -1
  117. package/dist/Pure.js +20 -17
  118. package/dist/QueueMaker.d.ts +11 -0
  119. package/dist/QueueMaker.d.ts.map +1 -0
  120. package/dist/QueueMaker.js +11 -0
  121. package/dist/RequestContext.d.ts +87 -0
  122. package/dist/RequestContext.d.ts.map +1 -0
  123. package/dist/RequestContext.js +45 -0
  124. package/dist/RequestScopedDependencies.d.ts +21 -0
  125. package/dist/RequestScopedDependencies.d.ts.map +1 -0
  126. package/dist/RequestScopedDependencies.js +16 -0
  127. package/dist/Schema/Class.d.ts +163 -16
  128. package/dist/Schema/Class.d.ts.map +1 -1
  129. package/dist/Schema/Class.js +193 -21
  130. package/dist/Schema/FastCheck.d.ts.map +1 -1
  131. package/dist/Schema/SchemaParser.d.ts +5 -0
  132. package/dist/Schema/SchemaParser.d.ts.map +1 -0
  133. package/dist/Schema/SchemaParser.js +6 -0
  134. package/dist/Schema/SpecialJsonSchema.d.ts +15 -2
  135. package/dist/Schema/SpecialJsonSchema.d.ts.map +1 -1
  136. package/dist/Schema/SpecialJsonSchema.js +70 -12
  137. package/dist/Schema/SpecialOpenApi.d.ts +1 -1
  138. package/dist/Schema/SpecialOpenApi.js +3 -3
  139. package/dist/Schema/brand.d.ts +5 -5
  140. package/dist/Schema/brand.d.ts.map +1 -1
  141. package/dist/Schema/brand.js +6 -4
  142. package/dist/Schema/email.d.ts.map +1 -1
  143. package/dist/Schema/email.js +8 -5
  144. package/dist/Schema/ext.d.ts +279 -75
  145. package/dist/Schema/ext.d.ts.map +1 -1
  146. package/dist/Schema/ext.js +330 -72
  147. package/dist/Schema/moreStrings.d.ts +82 -48
  148. package/dist/Schema/moreStrings.d.ts.map +1 -1
  149. package/dist/Schema/moreStrings.js +85 -51
  150. package/dist/Schema/numbers.d.ts +33 -21
  151. package/dist/Schema/numbers.d.ts.map +1 -1
  152. package/dist/Schema/numbers.js +64 -12
  153. package/dist/Schema/phoneNumber.d.ts.map +1 -1
  154. package/dist/Schema/phoneNumber.js +6 -6
  155. package/dist/Schema/schema.d.ts +1 -1
  156. package/dist/Schema/schema.d.ts.map +1 -1
  157. package/dist/Schema/schema.js +2 -2
  158. package/dist/Schema/strings.d.ts +18 -4
  159. package/dist/Schema/strings.d.ts.map +1 -1
  160. package/dist/Schema/strings.js +1 -5
  161. package/dist/Schema.d.ts +224 -7
  162. package/dist/Schema.d.ts.map +1 -1
  163. package/dist/Schema.js +190 -24
  164. package/dist/SchemaAST.d.ts +2 -0
  165. package/dist/SchemaAST.d.ts.map +1 -0
  166. package/dist/SchemaAST.js +2 -0
  167. package/dist/Set.d.ts +4 -1
  168. package/dist/Set.d.ts.map +1 -1
  169. package/dist/Set.js +8 -6
  170. package/dist/Store.d.ts +215 -0
  171. package/dist/Store.d.ts.map +1 -0
  172. package/dist/Store.js +113 -0
  173. package/dist/_ext/Array.d.ts +1 -1
  174. package/dist/_ext/Array.d.ts.map +1 -1
  175. package/dist/_ext/Array.js +4 -2
  176. package/dist/_ext/ord.ext.d.ts +2 -1
  177. package/dist/_ext/ord.ext.d.ts.map +1 -1
  178. package/dist/_ext/ord.ext.js +2 -2
  179. package/dist/builtin.d.ts +2 -14
  180. package/dist/builtin.d.ts.map +1 -1
  181. package/dist/builtin.js +1 -1
  182. package/dist/client/InvalidationKeys.d.ts +30 -0
  183. package/dist/client/InvalidationKeys.d.ts.map +1 -0
  184. package/dist/client/InvalidationKeys.js +37 -0
  185. package/dist/client/apiClientFactory.d.ts +13 -8
  186. package/dist/client/apiClientFactory.d.ts.map +1 -1
  187. package/dist/client/apiClientFactory.js +154 -34
  188. package/dist/client/clientFor.d.ts +48 -13
  189. package/dist/client/clientFor.d.ts.map +1 -1
  190. package/dist/client/clientFor.js +9 -1
  191. package/dist/client/errors.d.ts +74 -28
  192. package/dist/client/errors.d.ts.map +1 -1
  193. package/dist/client/errors.js +41 -10
  194. package/dist/client/makeClient.d.ts +487 -32
  195. package/dist/client/makeClient.d.ts.map +1 -1
  196. package/dist/client/makeClient.js +47 -21
  197. package/dist/client.d.ts +2 -0
  198. package/dist/client.d.ts.map +1 -1
  199. package/dist/client.js +3 -1
  200. package/dist/faker.d.ts.map +1 -1
  201. package/dist/http/Request.d.ts +2 -2
  202. package/dist/http/Request.d.ts.map +1 -1
  203. package/dist/http/Request.js +2 -2
  204. package/dist/http/internal/lib.d.ts +12 -12
  205. package/dist/http/internal/lib.d.ts.map +1 -1
  206. package/dist/http/internal/lib.js +13 -13
  207. package/dist/ids.d.ts +32 -14
  208. package/dist/ids.d.ts.map +1 -1
  209. package/dist/ids.js +38 -7
  210. package/dist/index.d.ts +3 -0
  211. package/dist/index.d.ts.map +1 -1
  212. package/dist/index.js +5 -1
  213. package/dist/middleware.d.ts +12 -6
  214. package/dist/middleware.d.ts.map +1 -1
  215. package/dist/middleware.js +13 -7
  216. package/dist/migration/nativeEffect.d.ts +21 -0
  217. package/dist/migration/nativeEffect.d.ts.map +1 -0
  218. package/dist/migration/nativeEffect.js +598 -0
  219. package/dist/rpc/Invalidation.d.ts +1124 -0
  220. package/dist/rpc/Invalidation.d.ts.map +1 -0
  221. package/dist/rpc/Invalidation.js +178 -0
  222. package/dist/rpc/MiddlewareMaker.d.ts +10 -7
  223. package/dist/rpc/MiddlewareMaker.d.ts.map +1 -1
  224. package/dist/rpc/MiddlewareMaker.js +57 -37
  225. package/dist/rpc/RpcContextMap.d.ts +2 -2
  226. package/dist/rpc/RpcContextMap.d.ts.map +1 -1
  227. package/dist/rpc/RpcMiddleware.d.ts +13 -10
  228. package/dist/rpc/RpcMiddleware.d.ts.map +1 -1
  229. package/dist/rpc/RpcMiddleware.js +2 -2
  230. package/dist/rpc.d.ts +1 -1
  231. package/dist/rpc.d.ts.map +1 -1
  232. package/dist/rpc.js +2 -2
  233. package/dist/runtime.d.ts +19 -0
  234. package/dist/runtime.d.ts.map +1 -0
  235. package/dist/runtime.js +40 -0
  236. package/dist/setupRequest.d.ts +20 -0
  237. package/dist/setupRequest.d.ts.map +1 -0
  238. package/dist/setupRequest.js +72 -0
  239. package/dist/toast.d.ts +51 -0
  240. package/dist/toast.d.ts.map +1 -0
  241. package/dist/toast.js +34 -0
  242. package/dist/transform.d.ts +1 -1
  243. package/dist/transform.d.ts.map +1 -1
  244. package/dist/transform.js +4 -5
  245. package/dist/utils/effectify.d.ts +1 -1
  246. package/dist/utils/effectify.d.ts.map +1 -1
  247. package/dist/utils/effectify.js +2 -2
  248. package/dist/utils/extend.d.ts +6 -1
  249. package/dist/utils/extend.d.ts.map +1 -1
  250. package/dist/utils/extend.js +24 -6
  251. package/dist/utils/gen.d.ts +4 -4
  252. package/dist/utils/gen.d.ts.map +1 -1
  253. package/dist/utils/logLevel.d.ts +2 -2
  254. package/dist/utils/logLevel.d.ts.map +1 -1
  255. package/dist/utils/logger.d.ts +2 -1
  256. package/dist/utils/logger.d.ts.map +1 -1
  257. package/dist/utils/logger.js +2 -2
  258. package/dist/utils.d.ts +34 -45
  259. package/dist/utils.d.ts.map +1 -1
  260. package/dist/utils.js +33 -49
  261. package/dist/validation/validators.d.ts.map +1 -1
  262. package/dist/validation.d.ts.map +1 -1
  263. package/dist/withToast.d.ts +30 -0
  264. package/dist/withToast.d.ts.map +1 -0
  265. package/dist/withToast.js +64 -0
  266. package/package.json +25 -266
  267. package/src/Array.ts +7 -39
  268. package/src/Chunk.ts +6 -55
  269. package/src/Config/SecretURL.ts +6 -3
  270. package/src/Config/internal/configSecretURL.ts +2 -2
  271. package/src/Config.ts +6 -13
  272. package/src/ConfigProvider.ts +4 -47
  273. package/src/Context.ts +9 -8
  274. package/src/DataDependencies.ts +171 -0
  275. package/src/DateTime.ts +473 -0
  276. package/src/Effect.ts +10 -32
  277. package/src/Emailer.ts +51 -0
  278. package/src/Function.ts +0 -7
  279. package/src/Inputify.type.ts +1 -1
  280. package/src/Layer.ts +8 -5
  281. package/src/Model/Repository/Registry.ts +35 -0
  282. package/src/Model/Repository/dependency.ts +32 -0
  283. package/src/Model/Repository/ext.ts +374 -0
  284. package/src/Model/Repository/internal/internal.ts +987 -0
  285. package/src/Model/Repository/legacy.ts +29 -0
  286. package/src/Model/Repository/makeRepo.ts +168 -0
  287. package/src/Model/Repository/service.ts +676 -0
  288. package/src/Model/Repository/validation.ts +38 -0
  289. package/src/Model/Repository.ts +7 -0
  290. package/src/Model/dsl.ts +130 -0
  291. package/src/Model/filter/filterApi.ts +78 -0
  292. package/src/Model/filter/types/errors.ts +47 -0
  293. package/src/Model/filter/types/fields.ts +50 -0
  294. package/src/Model/filter/types/path/common.ts +404 -0
  295. package/src/Model/filter/types/path/eager.ts +329 -0
  296. package/src/Model/filter/types/path/index.ts +4 -0
  297. package/src/Model/filter/types/utils.ts +128 -0
  298. package/src/Model/filter/types/validator.ts +46 -0
  299. package/src/Model/filter/types.ts +6 -0
  300. package/src/Model/query/dsl.ts +3092 -0
  301. package/src/Model/query/new-kid-interpreter.ts +531 -0
  302. package/src/Model/query.ts +13 -0
  303. package/src/Model.ts +5 -0
  304. package/src/NonEmptySet.ts +6 -4
  305. package/src/Option.ts +3 -8
  306. package/src/Pure.ts +20 -17
  307. package/src/QueueMaker.ts +11 -0
  308. package/src/RequestContext.ts +48 -0
  309. package/src/RequestScopedDependencies.ts +45 -0
  310. package/src/Schema/Class.ts +550 -56
  311. package/src/Schema/SchemaParser.ts +12 -0
  312. package/src/Schema/SpecialJsonSchema.ts +75 -7
  313. package/src/Schema/SpecialOpenApi.ts +5 -5
  314. package/src/Schema/brand.ts +27 -12
  315. package/src/Schema/email.ts +9 -7
  316. package/src/Schema/ext.ts +405 -95
  317. package/src/Schema/moreStrings.ts +213 -88
  318. package/src/Schema/numbers.ts +107 -29
  319. package/src/Schema/phoneNumber.ts +8 -9
  320. package/src/Schema/schema.ts +1 -1
  321. package/src/Schema/strings.ts +23 -14
  322. package/src/Schema.ts +403 -46
  323. package/src/SchemaAST.ts +1 -0
  324. package/src/Set.ts +10 -5
  325. package/src/Store.ts +325 -0
  326. package/src/_ext/Array.ts +4 -2
  327. package/src/_ext/ord.ext.ts +2 -1
  328. package/src/builtin-json.d.ts +24 -0
  329. package/src/builtin.ts +16 -21
  330. package/src/client/InvalidationKeys.ts +55 -0
  331. package/src/client/apiClientFactory.ts +295 -129
  332. package/src/client/clientFor.ts +101 -33
  333. package/src/client/errors.ts +66 -20
  334. package/src/client/makeClient.ts +519 -60
  335. package/src/client.ts +6 -4
  336. package/src/http/Request.ts +4 -4
  337. package/src/http/internal/lib.ts +12 -12
  338. package/src/http.ts +1 -1
  339. package/src/ids.ts +45 -8
  340. package/src/index.ts +20 -16
  341. package/src/middleware.ts +12 -8
  342. package/src/migration/nativeEffect.ts +645 -0
  343. package/src/rpc/Invalidation.ts +278 -0
  344. package/src/rpc/MiddlewareMaker.ts +86 -79
  345. package/src/rpc/README.md +2 -2
  346. package/src/rpc/RpcContextMap.ts +4 -4
  347. package/src/rpc/RpcMiddleware.ts +18 -13
  348. package/src/rpc.ts +4 -4
  349. package/src/runtime.ts +57 -0
  350. package/src/setupRequest.ts +138 -0
  351. package/src/toast.ts +54 -0
  352. package/src/transform.ts +4 -4
  353. package/src/utils/effectify.ts +1 -1
  354. package/src/utils/extend.ts +24 -5
  355. package/src/utils/gen.ts +7 -7
  356. package/src/utils/logLevel.ts +1 -1
  357. package/src/utils/logger.ts +3 -2
  358. package/src/utils.ts +85 -175
  359. package/src/validation.ts +2 -2
  360. package/src/withToast.ts +133 -0
  361. package/test/dateTimeLocal.test.ts +55 -0
  362. package/test/dist/dateTimeLocal.test.d.ts.map +1 -0
  363. package/test/dist/nativeEffectMigration.test.d.ts.map +1 -0
  364. package/test/dist/rpc.test.d.ts.map +1 -1
  365. package/test/dist/rpcMiddlewareContext.test.d.ts.map +1 -0
  366. package/test/moreStrings.test.ts +55 -10
  367. package/test/nativeEffectMigration.test.ts +77 -0
  368. package/test/rpc.test.ts +28 -11
  369. package/test/rpcMiddlewareContext.test.ts +63 -0
  370. package/test/schema.test.ts +318 -55
  371. package/test/secretURL.test.ts +4 -1
  372. package/test/special.test.ts +663 -131
  373. package/test/utils.test.ts +5 -5
  374. package/tsconfig.base.json +6 -4
  375. package/tsconfig.json +9 -1
  376. package/tsconfig.src.json +29 -29
  377. package/tsconfig.test.json +2 -2
  378. package/dist/Operations.d.ts +0 -124
  379. package/dist/Operations.d.ts.map +0 -1
  380. package/dist/Operations.js +0 -29
  381. package/dist/_ext/date.d.ts +0 -15
  382. package/dist/_ext/date.d.ts.map +0 -1
  383. package/dist/_ext/date.js +0 -16
  384. package/dist/_ext/misc.d.ts +0 -14
  385. package/dist/_ext/misc.d.ts.map +0 -1
  386. package/dist/_ext/misc.js +0 -17
  387. package/eslint.config.mjs +0 -26
  388. package/src/Operations.ts +0 -55
  389. package/src/_ext/date.ts +0 -27
  390. package/src/_ext/misc.ts +0 -46
  391. package/tsconfig.json.bak +0 -12
package/src/Effect.ts CHANGED
@@ -2,14 +2,13 @@
2
2
  /* eslint-disable prefer-destructuring */
3
3
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
4
4
 
5
- import { Effect, Option, Ref } from "effect"
6
- import * as Def from "effect/Deferred"
7
- import * as Fiber from "effect/Fiber"
8
- import type { Scope } from "effect/Scope"
5
+ import * as Effect from "effect/Effect"
6
+ import * as Option from "effect/Option"
7
+ import * as Ref from "effect/Ref"
9
8
  import type { Semaphore } from "effect/Semaphore"
10
- import type * as Context from "./Context.js"
11
- import { curry } from "./Function.js"
12
- import { typedKeysOf } from "./utils.js"
9
+ import * as Struct from "effect/Struct"
10
+ import type * as Context from "./Context.ts"
11
+ import { curry } from "./Function.ts"
13
12
 
14
13
  export * from "effect/Effect"
15
14
  // v4: Effect interface not re-exported by `export *` due to local binding collision
@@ -93,9 +92,6 @@ export function ifDiff<I, R, E, A>(n: I, orig: I) {
93
92
  return (f: (i: I) => Effect.Effect<A, E, R>) => ifDiff_(n, orig, f)
94
93
  }
95
94
 
96
- // NOTE: await extension doesnt work via tsplus somehow
97
- export const await_ = Def.await
98
-
99
95
  /**
100
96
  * Ref has atomic modify support if synchronous, for Effect we need a Semaphore.
101
97
  */
@@ -112,10 +108,6 @@ export function modifyWithPermitWithEffect<A>(ref: Ref.Ref<A>, semaphore: Semaph
112
108
  )
113
109
  }
114
110
 
115
- export function joinAll<E, A>(fibers: Iterable<Fiber.Fiber<A, E>>): Effect.Effect<readonly A[], E> {
116
- return Fiber.joinAll(fibers) as any
117
- }
118
-
119
111
  type ServiceA<T> = T extends Effect.Effect<infer S, any, any> ? S
120
112
  : T extends Context.Service<any, infer S> ? S
121
113
  : never
@@ -141,6 +133,7 @@ type ValuesE<T> = T extends { [s: string]: infer S } ? ServiceE<S> : never
141
133
  * const b = a({ str: "" }) // valid, but shouldn't be!
142
134
  * ```
143
135
  */
136
+ // eslint-disable-next-line import/namespace
144
137
  export interface EffectUnunified<R, E, A> extends Effect.Effect<R, E, A> {}
145
138
 
146
139
  export type LowerFirst<S extends PropertyKey> = S extends `${infer First}${infer Rest}` ? `${Lowercase<First>}${Rest}`
@@ -153,13 +146,12 @@ export function allLower<T extends Record<string, Context.Service<any, any> | Ef
153
146
  services: T
154
147
  ) {
155
148
  return Effect.all(
156
- typedKeysOf(services).reduce((prev, cur) => {
149
+ Struct.keys(services).reduce((prev, cur) => {
157
150
  const svc = services[cur]!
158
- prev[((cur as string)[0]!.toLowerCase() + (cur as string).slice(1)) as unknown as LowerFirst<typeof cur>] =
159
- "asEffect" in svc ? svc.asEffect() : svc
151
+ prev[(cur[0]!.toLowerCase() + cur.slice(1)) as unknown as LowerFirst<typeof cur>] = svc
160
152
  return prev
161
153
  }, {} as any),
162
- { concurrency: "inherit" }
154
+ { concurrency: "unbounded" }
163
155
  ) as any as Effect.Effect<LowerServices<T>, ValuesE<T>, ValuesR<T>>
164
156
  }
165
157
 
@@ -189,17 +181,3 @@ export function catchAllMap<E, A2>(f: (e: E) => A2) {
189
181
  return <R, A>(self: Effect.Effect<A, E, R>): Effect.Effect<A2 | A, never, R> =>
190
182
  Effect.catch(self, (err: E) => Effect.sync(() => f(err)))
191
183
  }
192
-
193
- /**
194
- * Annotates each log in this scope with the specified log annotation.
195
- */
196
- export function annotateLogscoped(key: string, value: string): Effect.Effect<void, never, Scope> {
197
- return Effect.annotateLogsScoped(key, value)
198
- }
199
-
200
- /**
201
- * Annotates each log in this scope with the specified log annotations.
202
- */
203
- export function annotateLogsScoped(kvps: Record<string, string>): Effect.Effect<void, never, Scope> {
204
- return Effect.annotateLogsScoped(kvps)
205
- }
package/src/Emailer.ts ADDED
@@ -0,0 +1,51 @@
1
+ import * as Data from "effect/Data"
2
+ import type { NonEmptyReadonlyArray } from "./Array.ts"
3
+ import * as Context from "./Context.ts"
4
+ import type * as Effect from "./Effect.ts"
5
+ import type { Email } from "./Schema.ts"
6
+
7
+ export class SendMailError extends Data.TaggedError("SendMailError")<{
8
+ readonly raw: Error
9
+ }> {}
10
+
11
+ export class Emailer extends Context.Opaque<Emailer, {
12
+ sendMail: (msg: EmailMsgOptionalFrom) => Effect.Effect<void, SendMailError>
13
+ }>()("effect-app/Emailer") {}
14
+
15
+ export type EmailData = Email | {
16
+ name?: string
17
+ email: Email
18
+ }
19
+
20
+ export interface EmailContentPart {
21
+ type: string
22
+ value: string
23
+ }
24
+
25
+ export type EmailRecipients = EmailData | NonEmptyReadonlyArray<EmailData>
26
+
27
+ export interface EmailMsgBase {
28
+ readonly to: EmailRecipients
29
+ readonly cc?: EmailRecipients
30
+ readonly bcc?: EmailRecipients
31
+ readonly from: EmailData
32
+ readonly replyTo?: EmailData
33
+ readonly subject?: string
34
+ /**
35
+ * should multiple `to` addresess be considered multiple emails?
36
+ * defaults to `true`, not to leak email addresses
37
+ */
38
+ readonly isMultiple?: boolean
39
+ }
40
+
41
+ export type EmailContent =
42
+ | { text: string }
43
+ | { html: string }
44
+ | { templateId: string }
45
+ | { content: NonEmptyReadonlyArray<EmailContentPart> }
46
+
47
+ export type EmailMsg =
48
+ & EmailMsgBase
49
+ & EmailContent
50
+
51
+ export type EmailMsgOptionalFrom = Omit<EmailMsgBase, "from"> & Partial<Pick<EmailMsg, "from">> & EmailContent
package/src/Function.ts CHANGED
@@ -1,13 +1,6 @@
1
1
  export * from "effect/Function"
2
2
  export type { Predicate, Refinement } from "effect/Predicate"
3
3
 
4
- /**
5
- * Construct tuples
6
- */
7
- export function tuple<T extends ReadonlyArray<any>>(...t: T): Readonly<T> {
8
- return t
9
- }
10
-
11
4
  /* eslint-disable @typescript-eslint/no-explicit-any */
12
5
 
13
6
  export function tupledCurry<A, B, C>(f: (b: B) => (a: A) => C) {
@@ -1,6 +1,6 @@
1
1
  import type { BuiltInObject } from "effect-app/utils"
2
2
 
3
- import type { Primitive } from "./Widen.type.js"
3
+ import type { Primitive } from "./Widen.type.ts"
4
4
 
5
5
  // Get rid of Date | string, and replace with Date | null
6
6
  export type Inputify<T> = Date extends T ? string extends T ? Date | null
package/src/Layer.ts CHANGED
@@ -1,8 +1,11 @@
1
- import { type Array, Effect, Layer, type Scope, type Types } from "effect"
2
- import { type Yieldable } from "effect/Effect"
1
+ import type * as Array from "effect/Array"
2
+ import * as Effect from "effect/Effect"
3
3
  import { dual } from "effect/Function"
4
- import type * as Context from "./Context.js"
5
- import { type EffectGenUtils } from "./utils/gen.js"
4
+ import * as Layer from "effect/Layer"
5
+ import type * as Scope from "effect/Scope"
6
+ import type * as Types from "effect/Types"
7
+ import type * as Context from "./Context.ts"
8
+ import { type EffectGenUtils } from "./utils/gen.ts"
6
9
 
7
10
  export * from "effect/Layer"
8
11
 
@@ -12,7 +15,7 @@ type MakeEff<S, E, R> = {
12
15
  readonly make: Effect.Effect<S, E, R>
13
16
  }
14
17
  type MakeGen<S, E = never, R = never> = {
15
- readonly make: () => Generator<Yieldable<any, any, E, R>, S, any>
18
+ readonly make: () => Generator<Effect.Effect<any, E, R>, S>
16
19
  }
17
20
  type MakeGenNo<S> = {
18
21
  readonly make: () => Generator<unknown, S>
@@ -0,0 +1,35 @@
1
+ import type { DatabaseError } from "../../client/errors.ts"
2
+ import * as Context from "../../Context.ts"
3
+ import * as Effect from "../../Effect.ts"
4
+
5
+ export interface RegisteredRepository {
6
+ readonly seedNamespace: (namespace: string) => Effect.Effect<void, DatabaseError>
7
+ }
8
+
9
+ const make = Effect.sync(() => {
10
+ const repos = new Map<string, RegisteredRepository>()
11
+ return {
12
+ register(modelName: string, repo: RegisteredRepository) {
13
+ repos.set(modelName, repo)
14
+ },
15
+ seedNamespace: (namespace: string) =>
16
+ Effect.suspend(() =>
17
+ Effect.forEach(
18
+ repos.values(),
19
+ (r) => r.seedNamespace(namespace),
20
+ { concurrency: "unbounded", discard: true }
21
+ )
22
+ ),
23
+ get entries(): ReadonlyMap<string, RegisteredRepository> {
24
+ return repos
25
+ }
26
+ }
27
+ })
28
+
29
+ export class RepositoryRegistry extends Context.Opaque<RepositoryRegistry, {
30
+ readonly register: (modelName: string, repo: RegisteredRepository) => void
31
+ readonly seedNamespace: (namespace: string) => Effect.Effect<void, DatabaseError>
32
+ readonly entries: ReadonlyMap<string, RegisteredRepository>
33
+ }>()("effect-app/RepositoryRegistry", { make }) {}
34
+
35
+ export const RepositoryRegistryLive = RepositoryRegistry.toLayer(RepositoryRegistry.make)
@@ -0,0 +1,32 @@
1
+ import * as S from "../../Schema.ts"
2
+ import * as SchemaAST from "../../SchemaAST.ts"
3
+
4
+ const RepositoryDependencyAnnotation = "effect-app/Repository/dependency"
5
+
6
+ /** Marks an encoded model field as an identity alias for repository invalidation. */
7
+ export const repositoryDependency = <Schema extends S.Top>(schema: Schema): Schema["Rebuild"] =>
8
+ S.annotateEncoded({ [RepositoryDependencyAnnotation]: true })(schema)
9
+
10
+ /** @internal */
11
+ export const repositoryDependencyPaths = (schema: S.Schema<unknown>): readonly string[] => {
12
+ const visit = (ast: SchemaAST.AST, path: readonly string[]): readonly string[] => {
13
+ const annotations = ast.checks?.at(-1)?.annotations ?? ast.annotations
14
+ if (annotations?.[RepositoryDependencyAnnotation] === true) return [path.join(".")]
15
+ if (SchemaAST.isDeclaration(ast)) return ast.typeParameters.flatMap((parameter) => visit(parameter, path))
16
+ if (SchemaAST.isUnion(ast)) return ast.types.flatMap((member) => visit(member, path))
17
+ if (SchemaAST.isObjects(ast)) {
18
+ return ast.propertySignatures.flatMap((property) =>
19
+ typeof property.name === "string" ? visit(property.type, [...path, property.name]) : []
20
+ )
21
+ }
22
+ if (SchemaAST.isArrays(ast)) {
23
+ return [
24
+ ...ast.elements.flatMap((element, index) => visit(element, [...path, String(index)])),
25
+ ...ast.rest.flatMap((element) => visit(element, [...path, "-1"]))
26
+ ]
27
+ }
28
+ return []
29
+ }
30
+
31
+ return [...new Set(visit(SchemaAST.toEncoded(schema.ast), []))]
32
+ }
@@ -0,0 +1,374 @@
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.ts"
7
+ import type { NonEmptyArray } from "../../Array.ts"
8
+ import { type DatabaseError, type InvalidStateError, NotFoundError, type OptimisticConcurrencyException } from "../../client/errors.ts"
9
+ import * as Effect from "../../Effect.ts"
10
+ import * as Option from "../../Option.ts"
11
+ import { type FixEnv, type PureEnv, runTerm } from "../../Pure.ts"
12
+ import { AnyPureDSL } from "../dsl.ts"
13
+ import type { FieldValues } from "../filter/types.ts"
14
+ import type { Query, QueryEnd, QueryWhere } from "../query.ts"
15
+ import * as Q from "../query.ts"
16
+ import type { Repository } from "./service.ts"
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
+ ): Effect.Effect<
93
+ A,
94
+ E | InvalidStateError | OptimisticConcurrencyException | DatabaseError,
95
+ R | RSchema | RPublish
96
+ > {
97
+ return Effect.flatMap(gen, ([items, events, a]) => repo.saveAndPublish(items, events).pipe(Effect.map(() => a)))
98
+ }
99
+
100
+ function saveManyWithPureBatched_<
101
+ R,
102
+ A,
103
+ E,
104
+ S1 extends T,
105
+ S2 extends T
106
+ >(
107
+ items: Iterable<S1>,
108
+ pure: Effect.Effect<A, E, FixEnv<R, Evt, readonly S1[], readonly S2[]>>,
109
+ batchSize = 100
110
+ ) {
111
+ return Effect.forEach(
112
+ Array.chunksOf(items, batchSize),
113
+ (batch) =>
114
+ saveAllWithEffectInt(
115
+ runTerm(pure, batch)
116
+ )
117
+ )
118
+ }
119
+
120
+ type PureStoreError = InvalidStateError | OptimisticConcurrencyException | DatabaseError
121
+
122
+ const queryAndSavePure: {
123
+ <A, E2, R2, T2 extends T>(
124
+ q: (
125
+ q: Query<Encoded>
126
+ ) => QueryEnd<Encoded, "one">,
127
+ pure: Effect.Effect<A, E2, FixEnv<R2, Evt, T, T2>>
128
+ ): Effect.Effect<
129
+ A,
130
+ PureStoreError | NotFoundError<ItemType> | E2,
131
+ | RSchema
132
+ | RPublish
133
+ | Exclude<R2, {
134
+ env: PureEnv<Evt, T, T2>
135
+ }>
136
+ >
137
+ <A, E2, R2, T2 extends T>(
138
+ q: (
139
+ q: Query<Encoded>
140
+ ) =>
141
+ | Query<Encoded>
142
+ | QueryWhere<Encoded>
143
+ | QueryEnd<Encoded>,
144
+ pure: Effect.Effect<A, E2, FixEnv<R2, Evt, readonly T[], readonly T2[]>>
145
+ ): Effect.Effect<
146
+ A,
147
+ PureStoreError | E2,
148
+ | RSchema
149
+ | RPublish
150
+ | Exclude<R2, {
151
+ env: PureEnv<Evt, readonly T[], readonly T2[]>
152
+ }>
153
+ >
154
+ <A, E2, R2, T2 extends T>(
155
+ q: (
156
+ q: Query<Encoded>
157
+ ) =>
158
+ | Query<Encoded>
159
+ | QueryWhere<Encoded>
160
+ | QueryEnd<Encoded>,
161
+ pure: Effect.Effect<A, E2, FixEnv<R2, Evt, readonly T[], readonly T2[]>>,
162
+ batch: "batched" | number
163
+ ): Effect.Effect<
164
+ A[],
165
+ PureStoreError | E2,
166
+ | RSchema
167
+ | RPublish
168
+ | Exclude<R2, {
169
+ env: PureEnv<Evt, readonly T[], readonly T2[]>
170
+ }>
171
+ >
172
+ } = ((q: any, pure: any, batch?: "batched" | number) =>
173
+ // Overload dispatch: query returns T | T[]; pure helpers are generic on item shape.
174
+ // Runtime path is query → pure term → saveAndPublish (which raises DatabaseError).
175
+ repo.query(q).pipe(
176
+ Effect.andThen((_) =>
177
+ Array.isArray(_)
178
+ ? batch === undefined
179
+ ? saveManyWithPure_(_ as T[], pure)
180
+ : saveManyWithPureBatched_(_ as T[], pure, batch === "batched" ? 100 : batch)
181
+ : saveWithPure_(_ as T, pure)
182
+ )
183
+ )) as typeof queryAndSavePure
184
+
185
+ const saveManyWithPure: {
186
+ <R, A, E, S1 extends T, S2 extends T>(
187
+ items: Iterable<S1>,
188
+ pure: Effect.Effect<A, E, FixEnv<R, Evt, readonly S1[], readonly S2[]>>
189
+ ): Effect.Effect<
190
+ A,
191
+ PureStoreError | E,
192
+ | RSchema
193
+ | RPublish
194
+ | Exclude<R, {
195
+ env: PureEnv<Evt, readonly S1[], readonly S2[]>
196
+ }>
197
+ >
198
+ <R, A, E, S1 extends T, S2 extends T>(
199
+ items: Iterable<S1>,
200
+ pure: Effect.Effect<A, E, FixEnv<R, Evt, readonly S1[], readonly S2[]>>,
201
+ batch: "batched" | number
202
+ ): Effect.Effect<
203
+ A[],
204
+ PureStoreError | E,
205
+ | RSchema
206
+ | RPublish
207
+ | Exclude<R, {
208
+ env: PureEnv<Evt, readonly S1[], readonly S2[]>
209
+ }>
210
+ >
211
+ } = ((items: Iterable<T>, pure: any, batch?: "batched" | number) =>
212
+ batch
213
+ ? Effect.forEach(
214
+ Array.chunksOf([...items], batch === "batched" ? 100 : batch),
215
+ (batchItems) =>
216
+ saveAllWithEffectInt(
217
+ runTerm(pure, batchItems as any)
218
+ )
219
+ )
220
+ : saveAllWithEffectInt(
221
+ runTerm(pure, [...items] as any)
222
+ )) as typeof saveManyWithPure
223
+
224
+ const byIdAndSaveWithPure: {
225
+ <R, A, E, S2 extends T>(
226
+ id: T[IdKey],
227
+ pure: Effect.Effect<A, E, FixEnv<R, Evt, T, S2>>
228
+ ): Effect.Effect<
229
+ A,
230
+ PureStoreError | NotFoundError<ItemType> | E,
231
+ | RSchema
232
+ | RPublish
233
+ | Exclude<R, {
234
+ env: PureEnv<Evt, T, S2>
235
+ }>
236
+ >
237
+ } = (id, pure) => get(id).pipe(Effect.flatMap((item) => saveWithPure_(item, pure)))
238
+
239
+ // query can raise DatabaseError; NotFound is completed per-entry. Dual package
240
+ // round-trips may still surface other store errors via failCause — keep channel honest.
241
+ type Req =
242
+ & Request.Request<T, NotFoundError<ItemType> | DatabaseError>
243
+ & { _tag: `Get${ItemType}`; id: T[IdKey] }
244
+ const _request = Request.tagged<Req>(`Get${repo.itemType}`)
245
+
246
+ const requestResolver = RequestResolver
247
+ .make((
248
+ entries: NonEmptyArray<Request.Entry<Req>>,
249
+ _key: unknown
250
+ ) =>
251
+ (repo.query(Q.where(repo.idKey as any, "in" as any, entries.map((_) => _.request.id)) as any) as Effect.Effect<
252
+ readonly T[],
253
+ DatabaseError
254
+ >)
255
+ .pipe(
256
+ Effect.andThen((items) =>
257
+ Effect.forEach(entries, (entry) =>
258
+ Request.complete(
259
+ Array
260
+ .findFirst(items, (_) => _[repo.idKey] === entry.request.id)
261
+ .pipe(Option.match({
262
+ onNone: () => Exit.fail(new NotFoundError({ type: repo.itemType, id: entry.request.id })),
263
+ onSome: Exit.succeed
264
+ }))
265
+ )(entry), { discard: true })
266
+ ),
267
+ Effect
268
+ .catchCause((cause) =>
269
+ Effect.forEach(entries, (entry) => Request.complete(Exit.failCause(cause))(entry), { discard: true })
270
+ )
271
+ )
272
+ )
273
+ .pipe(
274
+ RequestResolver.batchN(20)
275
+ )
276
+
277
+ const exts = {
278
+ request: (id: T[IdKey]) => Effect.request(_request({ id }), requestResolver),
279
+ get,
280
+ log: (evt: Evt) => AnyPureDSL.log(evt),
281
+ /**
282
+ * Enables chunked writes for large batches via `options.batch`.
283
+ * Note: batching breaks transactional properties because chunks are saved independently.
284
+ */
285
+ save: (itemOrItems: T | ReadonlyArray<T>, options?: BatchOptions) => {
286
+ const items = asReadonlyArray(itemOrItems)
287
+ if (!Array.isReadonlyArrayNonEmpty(items)) {
288
+ return Effect.void
289
+ }
290
+ const batchSize = getBatchSize(options?.batch)
291
+ if (batchSize === undefined) {
292
+ return repo.saveAndPublish(items)
293
+ }
294
+ return Effect.forEach(
295
+ Array.chunksOf(items, batchSize),
296
+ (batch) => repo.saveAndPublish(batch),
297
+ { discard: true }
298
+ )
299
+ },
300
+ saveWithEvents: (events: Iterable<Evt>) => (...items: NonEmptyArray<T>) => repo.saveAndPublish(items, events),
301
+ /**
302
+ * Enables chunked deletes for large batches via `options.batch`.
303
+ * Note: batching breaks transactional properties because chunks are removed independently.
304
+ */
305
+ remove: (itemOrItems: T | ReadonlyArray<T>, options?: BatchOptions) => {
306
+ const items = asReadonlyArray(itemOrItems)
307
+ if (!Array.isReadonlyArrayNonEmpty(items)) {
308
+ return Effect.void as Effect.Effect<void, DatabaseError, RSchema | RPublish>
309
+ }
310
+ const batchSize = getBatchSize(options?.batch)
311
+ if (batchSize === undefined) {
312
+ return repo.removeAndPublish(items)
313
+ }
314
+ return Effect.forEach(
315
+ Array.chunksOf(items, batchSize),
316
+ (batch) => repo.removeAndPublish(batch),
317
+ { discard: true }
318
+ )
319
+ },
320
+ /**
321
+ * Enables chunked deletes for large batches via `options.batch`.
322
+ * Note: batching breaks transactional properties because chunks are removed independently.
323
+ */
324
+ removeById: (idOrIds: T[IdKey] | ReadonlyArray<T[IdKey]>, options?: BatchOptions) => {
325
+ const ids = asReadonlyArray(idOrIds)
326
+ if (!Array.isReadonlyArrayNonEmpty(ids)) {
327
+ return Effect.void as Effect.Effect<void, DatabaseError, RSchema>
328
+ }
329
+ const batchSize = getBatchSize(options?.batch)
330
+ if (batchSize === undefined) {
331
+ return repo.removeById(ids)
332
+ }
333
+ return Effect.forEach(
334
+ Array.chunksOf(ids, batchSize),
335
+ (batch) => repo.removeById(batch),
336
+ { discard: true }
337
+ )
338
+ },
339
+ queryAndSavePure,
340
+ saveManyWithPure,
341
+ byIdAndSaveWithPure,
342
+ saveWithPure: <
343
+ R,
344
+ A,
345
+ E,
346
+ S1 extends T,
347
+ S2 extends T
348
+ >(
349
+ item: S1,
350
+ pure: Effect.Effect<A, E, FixEnv<R, Evt, S1, S2>>
351
+ ) =>
352
+ saveAllWithEffectInt(
353
+ runTerm(pure, item)
354
+ .pipe(Effect.map(([item, events, a]) => [[item], events, a]))
355
+ )
356
+ }
357
+
358
+ return {
359
+ ...repo,
360
+ ...exts
361
+ } as Repository<T, Encoded, Evt, ItemType, IdKey, RSchema, RPublish, RProvided> & typeof exts
362
+ }
363
+
364
+ // eslint-disable-next-line @typescript-eslint/no-empty-object-type
365
+ export interface ExtendedRepository<
366
+ T,
367
+ Encoded extends FieldValues,
368
+ Evt,
369
+ ItemType extends string,
370
+ IdKey extends keyof T & keyof Encoded,
371
+ RSchema,
372
+ RPublish,
373
+ RProvided = never
374
+ > extends ReturnType<typeof extendRepo<T, Encoded, Evt, ItemType, IdKey, RSchema, RPublish, RProvided>> {}