effect-app 4.0.0-beta.3 → 4.0.0-beta.300
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.
- package/CHANGELOG.md +1592 -0
- package/dist/Array.d.ts +2 -1
- package/dist/Array.d.ts.map +1 -1
- package/dist/Array.js +4 -4
- package/dist/Chunk.d.ts.map +1 -1
- package/dist/Config/SecretURL.d.ts +3 -1
- package/dist/Config/SecretURL.d.ts.map +1 -1
- package/dist/Config/SecretURL.js +3 -6
- package/dist/Config/internal/configSecretURL.d.ts.map +1 -1
- package/dist/Config/internal/configSecretURL.js +2 -2
- package/dist/Config.d.ts +2 -0
- package/dist/Config.d.ts.map +1 -0
- package/dist/Config.js +8 -0
- package/dist/ConfigProvider.d.ts +2 -0
- package/dist/ConfigProvider.d.ts.map +1 -0
- package/dist/ConfigProvider.js +6 -0
- package/dist/Context.d.ts +42 -0
- package/dist/Context.d.ts.map +1 -0
- package/dist/Context.js +67 -0
- package/dist/DataDependencies.d.ts +388 -0
- package/dist/DataDependencies.d.ts.map +1 -0
- package/dist/DataDependencies.js +64 -0
- package/dist/Effect.d.ts +10 -9
- package/dist/Effect.d.ts.map +1 -1
- package/dist/Effect.js +5 -7
- package/dist/Emailer.d.ts +51 -0
- package/dist/Emailer.d.ts.map +1 -0
- package/dist/Emailer.js +7 -0
- package/dist/Function.d.ts.map +1 -1
- package/dist/Layer.d.ts +10 -6
- package/dist/Layer.d.ts.map +1 -1
- package/dist/Layer.js +3 -2
- package/dist/Model/Repository/Registry.d.ts +22 -0
- package/dist/Model/Repository/Registry.d.ts.map +1 -0
- package/dist/Model/Repository/Registry.js +18 -0
- package/dist/Model/Repository/ext.d.ts +60 -0
- package/dist/Model/Repository/ext.d.ts.map +1 -0
- package/dist/Model/Repository/ext.js +122 -0
- package/dist/Model/Repository/internal/internal.d.ts +63 -0
- package/dist/Model/Repository/internal/internal.d.ts.map +1 -0
- package/dist/Model/Repository/internal/internal.js +438 -0
- package/dist/Model/Repository/legacy.d.ts +21 -0
- package/dist/Model/Repository/legacy.d.ts.map +1 -0
- package/dist/Model/Repository/legacy.js +2 -0
- package/dist/Model/Repository/makeRepo.d.ts +54 -0
- package/dist/Model/Repository/makeRepo.d.ts.map +1 -0
- package/dist/Model/Repository/makeRepo.js +27 -0
- package/dist/Model/Repository/service.d.ts +121 -0
- package/dist/Model/Repository/service.d.ts.map +1 -0
- package/dist/Model/Repository/service.js +2 -0
- package/dist/Model/Repository/validation.d.ts +58 -0
- package/dist/Model/Repository/validation.d.ts.map +1 -0
- package/dist/Model/Repository/validation.js +32 -0
- package/dist/Model/Repository.d.ts +7 -0
- package/dist/Model/Repository.d.ts.map +1 -0
- package/dist/Model/Repository.js +7 -0
- package/dist/Model/dsl.d.ts +33 -0
- package/dist/Model/dsl.d.ts.map +1 -0
- package/dist/Model/dsl.js +43 -0
- package/dist/Model/filter/filterApi.d.ts +30 -0
- package/dist/Model/filter/filterApi.d.ts.map +1 -0
- package/dist/Model/filter/filterApi.js +2 -0
- package/dist/Model/filter/types/errors.d.ts +29 -0
- package/dist/Model/filter/types/errors.d.ts.map +1 -0
- package/dist/Model/filter/types/errors.js +2 -0
- package/dist/Model/filter/types/fields.d.ts +15 -0
- package/dist/Model/filter/types/fields.d.ts.map +1 -0
- package/dist/Model/filter/types/fields.js +2 -0
- package/dist/Model/filter/types/path/common.d.ts +316 -0
- package/dist/Model/filter/types/path/common.d.ts.map +1 -0
- package/dist/Model/filter/types/path/common.js +2 -0
- package/dist/Model/filter/types/path/eager.d.ts +94 -0
- package/dist/Model/filter/types/path/eager.d.ts.map +1 -0
- package/dist/Model/filter/types/path/eager.js +36 -0
- package/dist/Model/filter/types/path/index.d.ts +4 -0
- package/dist/Model/filter/types/path/index.d.ts.map +1 -0
- package/dist/Model/filter/types/path/index.js +3 -0
- package/dist/Model/filter/types/utils.d.ts +79 -0
- package/dist/Model/filter/types/utils.d.ts.map +1 -0
- package/dist/Model/filter/types/utils.js +2 -0
- package/dist/Model/filter/types/validator.d.ts +30 -0
- package/dist/Model/filter/types/validator.d.ts.map +1 -0
- package/dist/Model/filter/types/validator.js +2 -0
- package/dist/Model/filter/types.d.ts +5 -0
- package/dist/Model/filter/types.d.ts.map +1 -0
- package/dist/Model/filter/types.js +7 -0
- package/dist/Model/query/dsl.d.ts +514 -0
- package/dist/Model/query/dsl.d.ts.map +1 -0
- package/dist/Model/query/dsl.js +376 -0
- package/dist/Model/query/new-kid-interpreter.d.ts +132 -0
- package/dist/Model/query/new-kid-interpreter.d.ts.map +1 -0
- package/dist/Model/query/new-kid-interpreter.js +361 -0
- package/dist/Model/query.d.ts +15 -0
- package/dist/Model/query.d.ts.map +1 -0
- package/dist/Model/query.js +3 -0
- package/dist/Model.d.ts +5 -0
- package/dist/Model.d.ts.map +1 -0
- package/dist/Model.js +5 -0
- package/dist/NonEmptySet.d.ts +3 -1
- package/dist/NonEmptySet.d.ts.map +1 -1
- package/dist/NonEmptySet.js +2 -2
- package/dist/Option.d.ts +1 -0
- package/dist/Option.d.ts.map +1 -1
- package/dist/Option.js +3 -1
- package/dist/Pure.d.ts +7 -5
- package/dist/Pure.d.ts.map +1 -1
- package/dist/Pure.js +17 -14
- package/dist/QueueMaker.d.ts +11 -0
- package/dist/QueueMaker.d.ts.map +1 -0
- package/dist/QueueMaker.js +11 -0
- package/dist/RequestContext.d.ts +87 -0
- package/dist/RequestContext.d.ts.map +1 -0
- package/dist/RequestContext.js +45 -0
- package/dist/RequestScopedDependencies.d.ts +21 -0
- package/dist/RequestScopedDependencies.d.ts.map +1 -0
- package/dist/RequestScopedDependencies.js +16 -0
- package/dist/Schema/Class.d.ts +188 -19
- package/dist/Schema/Class.d.ts.map +1 -1
- package/dist/Schema/Class.js +259 -22
- package/dist/Schema/FastCheck.d.ts.map +1 -1
- package/dist/Schema/SchemaParser.d.ts +5 -0
- package/dist/Schema/SchemaParser.d.ts.map +1 -0
- package/dist/Schema/SchemaParser.js +6 -0
- package/dist/Schema/SpecialJsonSchema.d.ts +34 -0
- package/dist/Schema/SpecialJsonSchema.d.ts.map +1 -0
- package/dist/Schema/SpecialJsonSchema.js +118 -0
- package/dist/Schema/SpecialOpenApi.d.ts +32 -0
- package/dist/Schema/SpecialOpenApi.d.ts.map +1 -0
- package/dist/Schema/SpecialOpenApi.js +123 -0
- package/dist/Schema/brand.d.ts +11 -6
- package/dist/Schema/brand.d.ts.map +1 -1
- package/dist/Schema/brand.js +3 -1
- package/dist/Schema/email.d.ts.map +1 -1
- package/dist/Schema/email.js +9 -5
- package/dist/Schema/ext.d.ts +340 -56
- package/dist/Schema/ext.d.ts.map +1 -1
- package/dist/Schema/ext.js +361 -63
- package/dist/Schema/moreStrings.d.ts +82 -36
- package/dist/Schema/moreStrings.d.ts.map +1 -1
- package/dist/Schema/moreStrings.js +53 -44
- package/dist/Schema/numbers.d.ts +34 -21
- package/dist/Schema/numbers.d.ts.map +1 -1
- package/dist/Schema/numbers.js +55 -12
- package/dist/Schema/phoneNumber.d.ts.map +1 -1
- package/dist/Schema/phoneNumber.js +8 -4
- package/dist/Schema/schema.d.ts +1 -1
- package/dist/Schema/schema.d.ts.map +1 -1
- package/dist/Schema/schema.js +2 -2
- package/dist/Schema/strings.d.ts +18 -4
- package/dist/Schema/strings.d.ts.map +1 -1
- package/dist/Schema/strings.js +1 -5
- package/dist/Schema.d.ts +238 -58
- package/dist/Schema.d.ts.map +1 -1
- package/dist/Schema.js +227 -69
- package/dist/SchemaAST.d.ts +2 -0
- package/dist/SchemaAST.d.ts.map +1 -0
- package/dist/SchemaAST.js +2 -0
- package/dist/Set.d.ts +4 -1
- package/dist/Set.d.ts.map +1 -1
- package/dist/Set.js +3 -2
- package/dist/Store.d.ts +163 -0
- package/dist/Store.d.ts.map +1 -0
- package/dist/Store.js +113 -0
- package/dist/_ext/Array.d.ts +1 -1
- package/dist/_ext/Array.d.ts.map +1 -1
- package/dist/_ext/Array.js +4 -2
- package/dist/_ext/misc.d.ts +4 -1
- package/dist/_ext/misc.d.ts.map +1 -1
- package/dist/_ext/misc.js +4 -2
- package/dist/_ext/ord.ext.d.ts +2 -1
- package/dist/_ext/ord.ext.d.ts.map +1 -1
- package/dist/_ext/ord.ext.js +2 -2
- package/dist/builtin.d.ts +2 -14
- package/dist/builtin.d.ts.map +1 -1
- package/dist/builtin.js +1 -1
- package/dist/client/InvalidationKeys.d.ts +30 -0
- package/dist/client/InvalidationKeys.d.ts.map +1 -0
- package/dist/client/InvalidationKeys.js +37 -0
- package/dist/client/apiClientFactory.d.ts +19 -31
- package/dist/client/apiClientFactory.d.ts.map +1 -1
- package/dist/client/apiClientFactory.js +160 -41
- package/dist/client/clientFor.d.ts +54 -18
- package/dist/client/clientFor.d.ts.map +1 -1
- package/dist/client/clientFor.js +9 -1
- package/dist/client/errors.d.ts +82 -27
- package/dist/client/errors.d.ts.map +1 -1
- package/dist/client/errors.js +75 -19
- package/dist/client/makeClient.d.ts +492 -32
- package/dist/client/makeClient.d.ts.map +1 -1
- package/dist/client/makeClient.js +62 -38
- package/dist/client.d.ts +2 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +3 -1
- package/dist/faker.d.ts.map +1 -1
- package/dist/http/Request.d.ts +1 -1
- package/dist/http/Request.d.ts.map +1 -1
- package/dist/http/Request.js +5 -5
- package/dist/ids.d.ts +42 -14
- package/dist/ids.d.ts.map +1 -1
- package/dist/ids.js +30 -5
- package/dist/index.d.ts +6 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -9
- package/dist/middleware.d.ts +13 -7
- package/dist/middleware.d.ts.map +1 -1
- package/dist/middleware.js +14 -8
- package/dist/rpc/Invalidation.d.ts +3140 -0
- package/dist/rpc/Invalidation.d.ts.map +1 -0
- package/dist/rpc/Invalidation.js +178 -0
- package/dist/rpc/MiddlewareMaker.d.ts +11 -7
- package/dist/rpc/MiddlewareMaker.d.ts.map +1 -1
- package/dist/rpc/MiddlewareMaker.js +59 -38
- package/dist/rpc/RpcContextMap.d.ts +3 -3
- package/dist/rpc/RpcContextMap.d.ts.map +1 -1
- package/dist/rpc/RpcContextMap.js +4 -4
- package/dist/rpc/RpcMiddleware.d.ts +14 -10
- package/dist/rpc/RpcMiddleware.d.ts.map +1 -1
- package/dist/rpc/RpcMiddleware.js +1 -1
- package/dist/rpc.d.ts +1 -1
- package/dist/rpc.d.ts.map +1 -1
- package/dist/rpc.js +2 -2
- package/dist/runtime.d.ts +19 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +40 -0
- package/dist/setupRequest.d.ts +20 -0
- package/dist/setupRequest.d.ts.map +1 -0
- package/dist/setupRequest.js +72 -0
- package/dist/toast.d.ts +51 -0
- package/dist/toast.d.ts.map +1 -0
- package/dist/toast.js +34 -0
- package/dist/transform.d.ts +1 -1
- package/dist/transform.d.ts.map +1 -1
- package/dist/transform.js +4 -5
- package/dist/utils/effectify.d.ts +1 -1
- package/dist/utils/effectify.d.ts.map +1 -1
- package/dist/utils/effectify.js +2 -2
- package/dist/utils/extend.d.ts.map +1 -1
- package/dist/utils/gen.d.ts +4 -4
- package/dist/utils/gen.d.ts.map +1 -1
- package/dist/utils/logLevel.d.ts +2 -2
- package/dist/utils/logLevel.d.ts.map +1 -1
- package/dist/utils/logger.d.ts +4 -3
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +4 -4
- package/dist/utils.d.ts +50 -37
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +51 -36
- package/dist/validation/validators.d.ts.map +1 -1
- package/dist/validation.d.ts.map +1 -1
- package/dist/withToast.d.ts +30 -0
- package/dist/withToast.d.ts.map +1 -0
- package/dist/withToast.js +64 -0
- package/package.json +27 -255
- package/src/Array.ts +5 -5
- package/src/Chunk.ts +3 -3
- package/src/Config/SecretURL.ts +6 -3
- package/src/Config/internal/configSecretURL.ts +2 -2
- package/src/Config.ts +7 -0
- package/src/ConfigProvider.ts +5 -0
- package/src/{ServiceMap.ts → Context.ts} +59 -65
- package/src/DataDependencies.ts +114 -0
- package/src/Effect.ts +15 -16
- package/src/Emailer.ts +51 -0
- package/src/Inputify.type.ts +1 -1
- package/src/Layer.ts +11 -7
- package/src/Model/Repository/Registry.ts +35 -0
- package/src/Model/Repository/ext.ts +375 -0
- package/src/Model/Repository/internal/internal.ts +755 -0
- package/src/Model/Repository/legacy.ts +29 -0
- package/src/Model/Repository/makeRepo.ts +145 -0
- package/src/Model/Repository/service.ts +676 -0
- package/src/Model/Repository/validation.ts +31 -0
- package/src/Model/Repository.ts +6 -0
- package/src/Model/dsl.ts +129 -0
- package/src/Model/filter/filterApi.ts +60 -0
- package/src/Model/filter/types/errors.ts +47 -0
- package/src/Model/filter/types/fields.ts +50 -0
- package/src/Model/filter/types/path/common.ts +404 -0
- package/src/Model/filter/types/path/eager.ts +329 -0
- package/src/Model/filter/types/path/index.ts +4 -0
- package/src/Model/filter/types/utils.ts +128 -0
- package/src/Model/filter/types/validator.ts +46 -0
- package/src/Model/filter/types.ts +6 -0
- package/src/Model/query/dsl.ts +2770 -0
- package/src/Model/query/new-kid-interpreter.ts +526 -0
- package/src/Model/query.ts +13 -0
- package/src/Model.ts +4 -0
- package/src/NonEmptySet.ts +6 -4
- package/src/Option.ts +2 -0
- package/src/Pure.ts +22 -20
- package/src/QueueMaker.ts +11 -0
- package/src/RequestContext.ts +48 -0
- package/src/RequestScopedDependencies.ts +45 -0
- package/src/Schema/Class.ts +631 -63
- package/src/Schema/SchemaParser.ts +12 -0
- package/src/Schema/SpecialJsonSchema.ts +139 -0
- package/src/Schema/SpecialOpenApi.ts +130 -0
- package/src/Schema/brand.ts +34 -8
- package/src/Schema/email.ts +12 -5
- package/src/Schema/ext.ts +469 -106
- package/src/Schema/moreStrings.ts +155 -73
- package/src/Schema/numbers.ts +97 -28
- package/src/Schema/phoneNumber.ts +12 -6
- package/src/Schema/schema.ts +1 -1
- package/src/Schema/strings.ts +23 -14
- package/src/Schema.ts +468 -121
- package/src/SchemaAST.ts +1 -0
- package/src/Set.ts +6 -2
- package/src/Store.ts +273 -0
- package/src/_ext/Array.ts +4 -2
- package/src/_ext/misc.ts +4 -1
- package/src/_ext/ord.ext.ts +2 -1
- package/src/builtin-json.d.ts +24 -0
- package/src/builtin.ts +16 -21
- package/src/client/InvalidationKeys.ts +55 -0
- package/src/client/apiClientFactory.ts +306 -144
- package/src/client/clientFor.ts +107 -34
- package/src/client/errors.ts +109 -29
- package/src/client/makeClient.ts +593 -87
- package/src/client.ts +6 -4
- package/src/http/Request.ts +9 -6
- package/src/http.ts +1 -1
- package/src/ids.ts +34 -7
- package/src/index.ts +20 -24
- package/src/middleware.ts +13 -9
- package/src/rpc/Invalidation.ts +278 -0
- package/src/rpc/MiddlewareMaker.ts +88 -80
- package/src/rpc/README.md +2 -2
- package/src/rpc/RpcContextMap.ts +7 -6
- package/src/rpc/RpcMiddleware.ts +19 -13
- package/src/rpc.ts +4 -4
- package/src/runtime.ts +56 -0
- package/src/setupRequest.ts +138 -0
- package/src/toast.ts +54 -0
- package/src/transform.ts +4 -4
- package/src/utils/effectify.ts +1 -1
- package/src/utils/gen.ts +8 -8
- package/src/utils/logLevel.ts +1 -1
- package/src/utils/logger.ts +4 -3
- package/src/utils.ts +105 -156
- package/src/validation.ts +2 -2
- package/src/withToast.ts +133 -0
- package/test/dist/moreStrings.test.d.ts.map +1 -0
- package/test/dist/rpc.test.d.ts.map +1 -1
- package/test/dist/rpcMiddlewareContext.test.d.ts.map +1 -0
- package/test/dist/secretURL.test.d.ts.map +1 -0
- package/test/dist/special.test.d.ts.map +1 -0
- package/test/moreStrings.test.ts +17 -0
- package/test/rpc.test.ts +45 -6
- package/test/rpcMiddlewareContext.test.ts +63 -0
- package/test/schema.test.ts +613 -7
- package/test/secretURL.test.ts +160 -0
- package/test/special.test.ts +1258 -0
- package/test/utils.test.ts +7 -7
- package/tsconfig.base.json +6 -5
- package/tsconfig.json +3 -1
- package/tsconfig.src.json +29 -29
- package/tsconfig.test.json +2 -2
- package/dist/Operations.d.ts +0 -87
- package/dist/Operations.d.ts.map +0 -1
- package/dist/Operations.js +0 -29
- package/dist/ServiceMap.d.ts +0 -44
- package/dist/ServiceMap.d.ts.map +0 -1
- package/dist/ServiceMap.js +0 -91
- package/dist/Struct.d.ts +0 -44
- package/dist/Struct.d.ts.map +0 -1
- package/dist/Struct.js +0 -29
- package/eslint.config.mjs +0 -26
- package/src/Operations.ts +0 -55
- package/src/Struct.ts +0 -54
- package/tsconfig.json.bak +0 -12
|
@@ -1,20 +1,17 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
-
|
|
3
|
-
* We're doing the long way around here with assignTag, TagBase & TagBaseTagged,
|
|
4
|
-
* because there's a typescript compiler issue where it will complain about Equal.symbol, and Hash.symbol not being accessible.
|
|
5
|
-
* https://github.com/microsoft/TypeScript/issues/52644
|
|
6
|
-
*/
|
|
2
|
+
/* eslint-disable import/namespace */
|
|
7
3
|
|
|
8
|
-
import
|
|
9
|
-
import * as
|
|
10
|
-
import
|
|
4
|
+
import * as CTX from "effect/Context"
|
|
5
|
+
import type * as Effect from "effect/Effect"
|
|
6
|
+
import * as Layer from "effect/Layer"
|
|
7
|
+
import type * as Scope from "effect/Scope"
|
|
8
|
+
import type * as Types from "effect/Types"
|
|
11
9
|
|
|
12
|
-
export * from "effect/
|
|
10
|
+
export * from "effect/Context"
|
|
13
11
|
|
|
14
|
-
export interface Opaque<Self extends object, in out Shape extends object> extends
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
serviceMap(self: Shape): ServiceMap.ServiceMap<Self>
|
|
12
|
+
export interface Opaque<Self extends object, in out Shape extends object> extends CTX.Key<Self, Self> {
|
|
13
|
+
of(this: void, self: Shape): Self
|
|
14
|
+
context(self: Shape): CTX.Context<Self>
|
|
18
15
|
// a version that leverages the Shape -> Self conversion
|
|
19
16
|
toLayer: <E, R>(
|
|
20
17
|
eff: Effect.Effect<Shape, E, R>
|
|
@@ -24,11 +21,11 @@ export interface Opaque<Self extends object, in out Shape extends object> extend
|
|
|
24
21
|
}
|
|
25
22
|
|
|
26
23
|
// export interface OpaqueMake<Self extends object, in out Shape extends object, E, R>
|
|
27
|
-
// extends
|
|
24
|
+
// extends CTX.Service<Self, Self>
|
|
28
25
|
// {
|
|
29
26
|
// // temp while sorting out https://github.com/Effect-TS/effect-smol/pull/1534
|
|
30
27
|
// of(self: Shape): Self
|
|
31
|
-
//
|
|
28
|
+
// contextMap2(self: Shape): CTX.Context<Self>
|
|
32
29
|
// // a version that leverages the Shape -> Self conversion
|
|
33
30
|
// toLayer: {
|
|
34
31
|
// <E, R>(
|
|
@@ -43,7 +40,7 @@ export function assignTag<Identifier extends object, Shape extends object = Iden
|
|
|
43
40
|
creationError?: Error
|
|
44
41
|
) {
|
|
45
42
|
return <S extends object>(cls: S): S & Opaque<Identifier, Shape> => {
|
|
46
|
-
const tag =
|
|
43
|
+
const tag = CTX.Service<Identifier, Shape>(key)
|
|
47
44
|
let fields = tag
|
|
48
45
|
if (Reflect.ownKeys(cls).includes("key")) {
|
|
49
46
|
const { key, ...rest } = tag
|
|
@@ -66,54 +63,51 @@ export function assignTag<Identifier extends object, Shape extends object = Iden
|
|
|
66
63
|
}
|
|
67
64
|
}
|
|
68
65
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
: Effect.Effect<Type[k], never, Self>
|
|
80
|
-
}
|
|
81
|
-
: {}
|
|
66
|
+
/** Accessor for a service method that returns a plain value. Wraps via `useSync`. */
|
|
67
|
+
export const accessFn = <
|
|
68
|
+
Self extends object,
|
|
69
|
+
Shape extends Record<PropertyKey, any>,
|
|
70
|
+
K extends keyof Shape
|
|
71
|
+
>(
|
|
72
|
+
Tag: Opaque<Self, Shape>,
|
|
73
|
+
key: K
|
|
74
|
+
): Shape[K] extends (...args: [...infer Args]) => infer A ? (...args: Readonly<Args>) => Effect.Effect<A, never, Self>
|
|
75
|
+
: never => ((...args: Array<any>) => Tag.useSync((s: any) => s[key](...args))) as any
|
|
82
76
|
|
|
83
|
-
/**
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const fn = (...args: Array<any>) => (Tag as any).use((s: any) => s[prop](...args))
|
|
105
|
-
const cn = (Tag as any).use((s: any) => s[prop])
|
|
106
|
-
// @effect-diagnostics effect/floatingEffect:off
|
|
107
|
-
Object.assign(fn, cn)
|
|
108
|
-
Object.setPrototypeOf(fn, Object.getPrototypeOf(cn))
|
|
109
|
-
cache.set(prop, fn)
|
|
110
|
-
return fn
|
|
111
|
-
}
|
|
112
|
-
})
|
|
113
|
-
return done
|
|
114
|
-
}
|
|
77
|
+
/** Accessor for a service method that returns an Effect. Delegates via `use`. */
|
|
78
|
+
export const accessEffectFn = <
|
|
79
|
+
Self extends object,
|
|
80
|
+
Shape extends Record<PropertyKey, any>,
|
|
81
|
+
K extends keyof Shape
|
|
82
|
+
>(
|
|
83
|
+
Tag: Opaque<Self, Shape>,
|
|
84
|
+
key: K
|
|
85
|
+
): Shape[K] extends (...args: [...infer Args]) => Effect.Effect<infer A, infer E, infer R>
|
|
86
|
+
? (...args: Readonly<Args>) => Effect.Effect<A, E, Self | R>
|
|
87
|
+
: never => ((...args: Array<any>) => Tag.use((s: any) => s[key](...args))) as any
|
|
88
|
+
|
|
89
|
+
/** Accessor for a service property (constant). Wraps via `useSync`. */
|
|
90
|
+
export const accessCn = <
|
|
91
|
+
Self extends object,
|
|
92
|
+
Shape extends Record<PropertyKey, any>,
|
|
93
|
+
K extends keyof Shape
|
|
94
|
+
>(
|
|
95
|
+
Tag: Opaque<Self, Shape>,
|
|
96
|
+
key: K
|
|
97
|
+
): Effect.Effect<Shape[K], never, Self> => Tag.useSync((s) => s[key])
|
|
115
98
|
|
|
116
|
-
|
|
99
|
+
/** Accessor for a service property that is an Effect. Delegates via `use`. */
|
|
100
|
+
export const accessEffectCn = <
|
|
101
|
+
Self extends object,
|
|
102
|
+
Shape extends Record<PropertyKey, any>,
|
|
103
|
+
K extends keyof Shape
|
|
104
|
+
>(
|
|
105
|
+
Tag: Opaque<Self, Shape>,
|
|
106
|
+
key: K
|
|
107
|
+
): Shape[K] extends Effect.Effect<infer A, infer E, infer R> ? Effect.Effect<A, E, Self | R>
|
|
108
|
+
: never => Tag.use((s: any) => s[key]) as any
|
|
109
|
+
|
|
110
|
+
export const TypeId = "~Context.Opaque"
|
|
117
111
|
|
|
118
112
|
// export function Opaque<const Key extends string>(key: Key) {
|
|
119
113
|
// return <Identifier extends object, Shape extends object>() => {
|
|
@@ -151,7 +145,7 @@ export const Opaque: {
|
|
|
151
145
|
id: Identifier,
|
|
152
146
|
options?: {
|
|
153
147
|
readonly make: ((...args: Args) => Effect.Effect<Shape, E, R>) | Effect.Effect<Shape, E, R> | undefined
|
|
154
|
-
}
|
|
148
|
+
}
|
|
155
149
|
) =>
|
|
156
150
|
& OpaqueClass<Self, Identifier, Shape>
|
|
157
151
|
& ([Types.unassigned] extends [R] ? unknown
|
|
@@ -178,10 +172,10 @@ export const Opaque: {
|
|
|
178
172
|
>
|
|
179
173
|
& { readonly make: Make }
|
|
180
174
|
} = () => (id: string, options: any) => {
|
|
181
|
-
const svc =
|
|
175
|
+
const svc = CTX.Service()(id, options) as any
|
|
182
176
|
return Object.assign(svc, {
|
|
183
177
|
toLayer: (eff: Effect.Effect<any, any, any>) => {
|
|
184
|
-
return Layer.effect(svc
|
|
178
|
+
return Layer.effect(svc, eff)
|
|
185
179
|
}
|
|
186
180
|
})
|
|
187
181
|
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import * as Ref from "effect/Ref"
|
|
2
|
+
import * as Stream from "effect/Stream"
|
|
3
|
+
import * as Effect from "./Effect.ts"
|
|
4
|
+
import * as RequestScopedDependencies from "./RequestScopedDependencies.ts"
|
|
5
|
+
import * as S from "./Schema.ts"
|
|
6
|
+
|
|
7
|
+
export const DataDependency = S.Struct({
|
|
8
|
+
type: S.Literals(["repo", "signal"]),
|
|
9
|
+
name: S.String
|
|
10
|
+
})
|
|
11
|
+
export type DataDependency = S.Schema.Type<typeof DataDependency>
|
|
12
|
+
|
|
13
|
+
export const DataDependencies = S.ReadonlySet(DataDependency)
|
|
14
|
+
export type DataDependencies = S.Schema.Type<typeof DataDependencies>
|
|
15
|
+
|
|
16
|
+
export const empty = (): DataDependencies => new Set()
|
|
17
|
+
|
|
18
|
+
export const DataDependencySet = S.Struct({
|
|
19
|
+
reads: DataDependencies,
|
|
20
|
+
writes: DataDependencies
|
|
21
|
+
})
|
|
22
|
+
export type DataDependencySet = S.Schema.Type<typeof DataDependencySet>
|
|
23
|
+
|
|
24
|
+
export interface DataDependencyRecorderService {
|
|
25
|
+
readonly read: (dependency: DataDependency) => Effect.Effect<void>
|
|
26
|
+
readonly write: (dependency: DataDependency) => Effect.Effect<void>
|
|
27
|
+
readonly get: Effect.Effect<DataDependencySet>
|
|
28
|
+
readonly drain: Effect.Effect<DataDependencySet>
|
|
29
|
+
readonly drainWrites: Effect.Effect<DataDependencies>
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const containsDependency = (dependencies: ReadonlySet<DataDependency>, dependency: DataDependency) => {
|
|
33
|
+
for (const _ of dependencies) {
|
|
34
|
+
if (_.type === dependency.type && _.name === dependency.name) return true
|
|
35
|
+
}
|
|
36
|
+
return false
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const appendDependency = (dependency: DataDependency) => (dependencies: DataDependencies): DataDependencies =>
|
|
40
|
+
containsDependency(dependencies, dependency) ? dependencies : new Set([...dependencies, dependency])
|
|
41
|
+
|
|
42
|
+
export const DataDependencyRecorder = RequestScopedDependencies.make(
|
|
43
|
+
"effect-app/DataDependencyRecorder",
|
|
44
|
+
Effect.gen(function*() {
|
|
45
|
+
const readsRef = yield* Ref.make(empty())
|
|
46
|
+
const writesRef = yield* Ref.make(empty())
|
|
47
|
+
return makeDataDependencyRecorder(readsRef, writesRef)
|
|
48
|
+
})
|
|
49
|
+
)
|
|
50
|
+
export type DataDependencyRecorder = typeof DataDependencyRecorder
|
|
51
|
+
|
|
52
|
+
export type DataDependencyRecorderNotStartedError = RequestScopedDependencies.RequestScopedDependencyNotStartedError
|
|
53
|
+
|
|
54
|
+
export const getDataDependencyRecorder = DataDependencyRecorder.current
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Guarantee a recorder is in scope for `self`, providing a fresh one per request when none is
|
|
58
|
+
* (e.g. a top-level client call with no parent query/command tracking its dependencies). An
|
|
59
|
+
* existing recorder is inherited, so nested calls forward into their parent rather than shadow it.
|
|
60
|
+
*/
|
|
61
|
+
export const ensureDataDependencyRecorder = <A, E, R>(self: Effect.Effect<A, E, R>): Effect.Effect<A, E, R> =>
|
|
62
|
+
Effect.flatMap(
|
|
63
|
+
DataDependencyRecorder,
|
|
64
|
+
(current) => current === "root" ? Effect.provide(self, DataDependencyRecorder.layer) : self
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
/** Stream variant of {@link ensureDataDependencyRecorder}. */
|
|
68
|
+
export const ensureDataDependencyRecorderStream = <A, E, R>(self: Stream.Stream<A, E, R>): Stream.Stream<A, E, R> =>
|
|
69
|
+
Stream.unwrap(
|
|
70
|
+
Effect.map(
|
|
71
|
+
DataDependencyRecorder,
|
|
72
|
+
(current) => current === "root" ? Stream.provide(self, DataDependencyRecorder.layer) : self
|
|
73
|
+
)
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
export const makeDataDependencyRecorder = (
|
|
77
|
+
readsRef: Ref.Ref<DataDependencies>,
|
|
78
|
+
writesRef: Ref.Ref<DataDependencies>
|
|
79
|
+
): DataDependencyRecorderService => ({
|
|
80
|
+
read: (dependency) => Ref.update(readsRef, appendDependency(dependency)),
|
|
81
|
+
write: (dependency) => Ref.update(writesRef, appendDependency(dependency)),
|
|
82
|
+
get: Effect.all({
|
|
83
|
+
reads: Ref.get(readsRef),
|
|
84
|
+
writes: Ref.get(writesRef)
|
|
85
|
+
}),
|
|
86
|
+
drain: Effect.all({
|
|
87
|
+
reads: Ref.getAndSet(readsRef, empty()),
|
|
88
|
+
writes: Ref.getAndSet(writesRef, empty())
|
|
89
|
+
}),
|
|
90
|
+
drainWrites: Ref.getAndSet(writesRef, empty())
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
export const repo = (name: string): DataDependency => ({ type: "repo", name })
|
|
94
|
+
export const signal = (name: string): DataDependency => ({ type: "signal", name })
|
|
95
|
+
|
|
96
|
+
export const QueryReadDependenciesMetaKey = "effect-app.query.readDependencies"
|
|
97
|
+
|
|
98
|
+
export const read = (dependency: DataDependency) =>
|
|
99
|
+
getDataDependencyRecorder.pipe(Effect.flatMap((_) => _.read(dependency)))
|
|
100
|
+
|
|
101
|
+
export const write = (dependency: DataDependency) =>
|
|
102
|
+
getDataDependencyRecorder.pipe(Effect.flatMap((_) => _.write(dependency)))
|
|
103
|
+
|
|
104
|
+
export const intersects = (
|
|
105
|
+
a: ReadonlySet<DataDependency>,
|
|
106
|
+
b: ReadonlySet<DataDependency>
|
|
107
|
+
) => {
|
|
108
|
+
for (const dependency of a) {
|
|
109
|
+
if (containsDependency(b, dependency)) return true
|
|
110
|
+
}
|
|
111
|
+
return false
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export const isNonEmpty = (dependencies: DataDependencies) => dependencies.size > 0
|
package/src/Effect.ts
CHANGED
|
@@ -2,13 +2,15 @@
|
|
|
2
2
|
/* eslint-disable prefer-destructuring */
|
|
3
3
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
4
4
|
|
|
5
|
-
import { Effect, Option, Ref, type ServiceMap } from "effect"
|
|
6
5
|
import * as Def from "effect/Deferred"
|
|
7
|
-
import * as
|
|
6
|
+
import * as Effect from "effect/Effect"
|
|
7
|
+
import * as Option from "effect/Option"
|
|
8
|
+
import * as Ref from "effect/Ref"
|
|
8
9
|
import type { Scope } from "effect/Scope"
|
|
9
10
|
import type { Semaphore } from "effect/Semaphore"
|
|
10
|
-
import
|
|
11
|
-
import {
|
|
11
|
+
import type * as Context from "./Context.ts"
|
|
12
|
+
import { curry } from "./Function.ts"
|
|
13
|
+
import { typedKeysOf } from "./utils.ts"
|
|
12
14
|
|
|
13
15
|
export * from "effect/Effect"
|
|
14
16
|
// v4: Effect interface not re-exported by `export *` due to local binding collision
|
|
@@ -111,15 +113,11 @@ export function modifyWithPermitWithEffect<A>(ref: Ref.Ref<A>, semaphore: Semaph
|
|
|
111
113
|
)
|
|
112
114
|
}
|
|
113
115
|
|
|
114
|
-
export function joinAll<E, A>(fibers: Iterable<Fiber.Fiber<A, E>>): Effect.Effect<readonly A[], E> {
|
|
115
|
-
return Fiber.joinAll(fibers) as any
|
|
116
|
-
}
|
|
117
|
-
|
|
118
116
|
type ServiceA<T> = T extends Effect.Effect<infer S, any, any> ? S
|
|
119
|
-
: T extends
|
|
117
|
+
: T extends Context.Service<any, infer S> ? S
|
|
120
118
|
: never
|
|
121
119
|
type ServiceR<T> = T extends Effect.Effect<any, any, infer R> ? R
|
|
122
|
-
: T extends
|
|
120
|
+
: T extends Context.Service<infer I, any> ? I
|
|
123
121
|
: never
|
|
124
122
|
type ServiceE<T> = T extends Effect.Effect<any, infer E, any> ? E : never
|
|
125
123
|
// type Values<T> = T extends { [s: string]: infer S } ? ServiceA<S> : never
|
|
@@ -140,28 +138,29 @@ type ValuesE<T> = T extends { [s: string]: infer S } ? ServiceE<S> : never
|
|
|
140
138
|
* const b = a({ str: "" }) // valid, but shouldn't be!
|
|
141
139
|
* ```
|
|
142
140
|
*/
|
|
141
|
+
// eslint-disable-next-line import/namespace
|
|
143
142
|
export interface EffectUnunified<R, E, A> extends Effect.Effect<R, E, A> {}
|
|
144
143
|
|
|
145
144
|
export type LowerFirst<S extends PropertyKey> = S extends `${infer First}${infer Rest}` ? `${Lowercase<First>}${Rest}`
|
|
146
145
|
: S
|
|
147
|
-
export type LowerServices<T extends Record<string,
|
|
146
|
+
export type LowerServices<T extends Record<string, Context.Service<any, any> | Effect.Effect<any, any, any>>> = {
|
|
148
147
|
[key in keyof T as LowerFirst<key>]: ServiceA<T[key]>
|
|
149
148
|
}
|
|
150
149
|
|
|
151
|
-
export function allLower<T extends Record<string,
|
|
150
|
+
export function allLower<T extends Record<string, Context.Service<any, any> | Effect.Effect<any, any, any>>>(
|
|
152
151
|
services: T
|
|
153
152
|
) {
|
|
154
153
|
return Effect.all(
|
|
155
154
|
typedKeysOf(services).reduce((prev, cur) => {
|
|
156
|
-
const svc = services[cur]
|
|
157
|
-
prev[((cur as string)[0]!.toLowerCase() + (cur as string).slice(1)) as unknown as LowerFirst<typeof cur>] = svc
|
|
155
|
+
const svc = services[cur]!
|
|
156
|
+
prev[((cur as string)[0]!.toLowerCase() + (cur as string).slice(1)) as unknown as LowerFirst<typeof cur>] = svc
|
|
158
157
|
return prev
|
|
159
158
|
}, {} as any),
|
|
160
159
|
{ concurrency: "inherit" }
|
|
161
160
|
) as any as Effect.Effect<LowerServices<T>, ValuesE<T>, ValuesR<T>>
|
|
162
161
|
}
|
|
163
162
|
|
|
164
|
-
export function allLowerWith<T extends Record<string,
|
|
163
|
+
export function allLowerWith<T extends Record<string, Context.Service<any, any> | Effect.Effect<any, any, any>>, A>(
|
|
165
164
|
services: T,
|
|
166
165
|
fn: (services: LowerServices<T>) => A
|
|
167
166
|
) {
|
|
@@ -169,7 +168,7 @@ export function allLowerWith<T extends Record<string, ServiceMap.Service<any, an
|
|
|
169
168
|
}
|
|
170
169
|
|
|
171
170
|
export function allLowerWithEffect<
|
|
172
|
-
T extends Record<string,
|
|
171
|
+
T extends Record<string, Context.Service<any, any> | Effect.Effect<any, any, any>>,
|
|
173
172
|
R,
|
|
174
173
|
E,
|
|
175
174
|
A
|
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/Inputify.type.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { BuiltInObject } from "effect-app/utils"
|
|
2
2
|
|
|
3
|
-
import type { Primitive } from "./Widen.type.
|
|
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,7 +1,11 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import type * as Array from "effect/Array"
|
|
2
|
+
import * as Effect from "effect/Effect"
|
|
3
3
|
import { dual } from "effect/Function"
|
|
4
|
-
import
|
|
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"
|
|
5
9
|
|
|
6
10
|
export * from "effect/Layer"
|
|
7
11
|
|
|
@@ -11,13 +15,13 @@ type MakeEff<S, E, R> = {
|
|
|
11
15
|
readonly make: Effect.Effect<S, E, R>
|
|
12
16
|
}
|
|
13
17
|
type MakeGen<S, E = never, R = never> = {
|
|
14
|
-
readonly make: () => Generator<
|
|
18
|
+
readonly make: () => Generator<Effect.Effect<any, E, R>, S>
|
|
15
19
|
}
|
|
16
20
|
type MakeGenNo<S> = {
|
|
17
21
|
readonly make: () => Generator<unknown, S>
|
|
18
22
|
}
|
|
19
23
|
type MakeErr<Opts> = Opts extends { make: () => any } ? EffectGenUtils.Error<Opts["make"]> : never
|
|
20
|
-
type MakeContext<Opts> = Opts extends { make: () => any } ? EffectGenUtils.
|
|
24
|
+
type MakeContext<Opts> = Opts extends { make: () => any } ? EffectGenUtils.Context<Opts["make"]> : never
|
|
21
25
|
|
|
22
26
|
type DependenciesOpt = { dependencies?: Array.NonEmptyReadonlyArray<Layer.Any> }
|
|
23
27
|
type Dependencies = { dependencies: Array.NonEmptyReadonlyArray<Layer.Any> }
|
|
@@ -41,12 +45,12 @@ type PackedOrUnpackedLayer<I, Opts> = Opts extends Dependencies ? PackedLayers<I
|
|
|
41
45
|
|
|
42
46
|
export const make: {
|
|
43
47
|
<I, S>(
|
|
44
|
-
tag:
|
|
48
|
+
tag: Context.Service<I, S>
|
|
45
49
|
): <Opts extends Make<Types.NoInfer<S>, any, any>>(
|
|
46
50
|
options: Opts
|
|
47
51
|
) => PackedOrUnpackedLayer<I, Opts>
|
|
48
52
|
<I, S, Opts extends Make<Types.NoInfer<S>, any, any>>(
|
|
49
|
-
tag:
|
|
53
|
+
tag: Context.Service<I, S>,
|
|
50
54
|
options: Opts
|
|
51
55
|
): PackedOrUnpackedLayer<I, Opts>
|
|
52
56
|
} = dual(2, (tag, options) => {
|
|
@@ -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)
|