@effect-app/infra 4.0.0-beta.24 → 4.0.0-beta.240
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 +1811 -0
- package/_check.sh +1 -1
- package/dist/CUPS.d.ts +12 -7
- package/dist/CUPS.d.ts.map +1 -1
- package/dist/CUPS.js +16 -12
- package/dist/Emailer/Sendgrid.d.ts +15 -15
- package/dist/Emailer/Sendgrid.d.ts.map +1 -1
- package/dist/Emailer/Sendgrid.js +21 -17
- package/dist/Emailer/fake.d.ts +1 -1
- package/dist/Emailer/fake.js +3 -3
- package/dist/Emailer/service.d.ts +13 -4
- package/dist/Emailer/service.d.ts.map +1 -1
- package/dist/Emailer/service.js +4 -3
- package/dist/Emailer.d.ts +1 -1
- package/dist/MainFiberSet.d.ts +12 -9
- package/dist/MainFiberSet.d.ts.map +1 -1
- package/dist/MainFiberSet.js +10 -6
- package/dist/Model/Repository/Registry.d.ts +21 -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 +35 -16
- package/dist/Model/Repository/ext.d.ts.map +1 -1
- package/dist/Model/Repository/ext.js +60 -3
- package/dist/Model/Repository/internal/internal.d.ts +9 -6
- package/dist/Model/Repository/internal/internal.d.ts.map +1 -1
- package/dist/Model/Repository/internal/internal.js +141 -59
- package/dist/Model/Repository/legacy.d.ts +4 -2
- package/dist/Model/Repository/legacy.d.ts.map +1 -1
- package/dist/Model/Repository/makeRepo.d.ts +10 -6
- package/dist/Model/Repository/makeRepo.d.ts.map +1 -1
- package/dist/Model/Repository/makeRepo.js +5 -2
- package/dist/Model/Repository/service.d.ts +32 -24
- package/dist/Model/Repository/service.d.ts.map +1 -1
- package/dist/Model/Repository/validation.d.ts +47 -18
- package/dist/Model/Repository/validation.d.ts.map +1 -1
- package/dist/Model/Repository/validation.js +6 -6
- package/dist/Model/Repository.d.ts +2 -1
- package/dist/Model/Repository.d.ts.map +1 -1
- package/dist/Model/Repository.js +2 -1
- package/dist/Model/dsl.d.ts +6 -5
- package/dist/Model/dsl.d.ts.map +1 -1
- package/dist/Model/dsl.js +2 -3
- package/dist/Model/filter/filterApi.d.ts +5 -5
- package/dist/Model/filter/filterApi.d.ts.map +1 -1
- package/dist/Model/filter/types/errors.d.ts +1 -1
- package/dist/Model/filter/types/fields.d.ts +1 -1
- package/dist/Model/filter/types/path/common.d.ts +1 -1
- package/dist/Model/filter/types/path/eager.d.ts +1 -1
- package/dist/Model/filter/types/path/eager.d.ts.map +1 -1
- package/dist/Model/filter/types/path/eager.js +1 -1
- package/dist/Model/filter/types/path/index.d.ts +1 -1
- package/dist/Model/filter/types/utils.d.ts +1 -1
- package/dist/Model/filter/types/validator.d.ts +1 -1
- package/dist/Model/filter/types.d.ts +5 -5
- package/dist/Model/query/dsl.d.ts +216 -18
- package/dist/Model/query/dsl.d.ts.map +1 -1
- package/dist/Model/query/dsl.js +240 -5
- package/dist/Model/query/new-kid-interpreter.d.ts +116 -8
- package/dist/Model/query/new-kid-interpreter.d.ts.map +1 -1
- package/dist/Model/query/new-kid-interpreter.js +177 -6
- package/dist/Model/query.d.ts +1 -1
- package/dist/Model.d.ts +2 -1
- package/dist/Model.d.ts.map +1 -1
- package/dist/Model.js +2 -1
- package/dist/QueueMaker/SQLQueue.d.ts +7 -8
- package/dist/QueueMaker/SQLQueue.d.ts.map +1 -1
- package/dist/QueueMaker/SQLQueue.js +135 -117
- package/dist/QueueMaker/errors.d.ts +5 -3
- package/dist/QueueMaker/errors.d.ts.map +1 -1
- package/dist/QueueMaker/errors.js +4 -2
- package/dist/QueueMaker/memQueue.d.ts +9 -5
- package/dist/QueueMaker/memQueue.d.ts.map +1 -1
- package/dist/QueueMaker/memQueue.js +81 -65
- package/dist/QueueMaker/sbqueue.d.ts +8 -4
- package/dist/QueueMaker/sbqueue.d.ts.map +1 -1
- package/dist/QueueMaker/sbqueue.js +57 -55
- package/dist/QueueMaker/service.d.ts +4 -2
- package/dist/QueueMaker/service.d.ts.map +1 -1
- package/dist/QueueMaker/service.js +1 -1
- package/dist/RequestContext.d.ts +75 -35
- package/dist/RequestContext.d.ts.map +1 -1
- package/dist/RequestContext.js +14 -14
- package/dist/RequestFiberSet.d.ts +10 -7
- package/dist/RequestFiberSet.d.ts.map +1 -1
- package/dist/RequestFiberSet.js +12 -7
- package/dist/Store/ContextMapContainer.d.ts +22 -3
- package/dist/Store/ContextMapContainer.d.ts.map +1 -1
- package/dist/Store/ContextMapContainer.js +18 -4
- package/dist/Store/Cosmos/query.d.ts +13 -2
- package/dist/Store/Cosmos/query.d.ts.map +1 -1
- package/dist/Store/Cosmos/query.js +179 -41
- package/dist/Store/Cosmos.d.ts +2 -2
- package/dist/Store/Cosmos.d.ts.map +1 -1
- package/dist/Store/Cosmos.js +343 -244
- package/dist/Store/Disk.d.ts +3 -3
- package/dist/Store/Disk.d.ts.map +1 -1
- package/dist/Store/Disk.js +76 -36
- package/dist/Store/Memory.d.ts +7 -4
- package/dist/Store/Memory.d.ts.map +1 -1
- package/dist/Store/Memory.js +327 -62
- package/dist/Store/SQL/Pg.d.ts +4 -0
- package/dist/Store/SQL/Pg.d.ts.map +1 -0
- package/dist/Store/SQL/Pg.js +233 -0
- package/dist/Store/SQL/query.d.ts +49 -0
- package/dist/Store/SQL/query.d.ts.map +1 -0
- package/dist/Store/SQL/query.js +527 -0
- package/dist/Store/SQL.d.ts +21 -0
- package/dist/Store/SQL.d.ts.map +1 -0
- package/dist/Store/SQL.js +450 -0
- package/dist/Store/codeFilter.d.ts +2 -2
- package/dist/Store/codeFilter.d.ts.map +1 -1
- package/dist/Store/codeFilter.js +6 -3
- package/dist/Store/index.d.ts +6 -3
- package/dist/Store/index.d.ts.map +1 -1
- package/dist/Store/index.js +18 -4
- package/dist/Store/service.d.ts +39 -9
- package/dist/Store/service.d.ts.map +1 -1
- package/dist/Store/service.js +31 -7
- package/dist/Store/utils.d.ts +3 -2
- package/dist/Store/utils.d.ts.map +1 -1
- package/dist/Store/utils.js +5 -5
- package/dist/Store.d.ts +1 -1
- package/dist/adapters/SQL/Model.d.ts +32 -43
- package/dist/adapters/SQL/Model.d.ts.map +1 -1
- package/dist/adapters/SQL/Model.js +30 -39
- package/dist/adapters/SQL.d.ts +1 -1
- package/dist/adapters/ServiceBus.d.ts +14 -11
- package/dist/adapters/ServiceBus.d.ts.map +1 -1
- package/dist/adapters/ServiceBus.js +30 -21
- package/dist/adapters/cosmos-client.d.ts +5 -3
- package/dist/adapters/cosmos-client.d.ts.map +1 -1
- package/dist/adapters/cosmos-client.js +6 -4
- package/dist/adapters/index.d.ts +8 -2
- package/dist/adapters/index.d.ts.map +1 -1
- package/dist/adapters/index.js +8 -2
- package/dist/adapters/logger.d.ts +1 -1
- package/dist/adapters/logger.d.ts.map +1 -1
- package/dist/adapters/memQueue.d.ts +5 -3
- package/dist/adapters/memQueue.d.ts.map +1 -1
- package/dist/adapters/memQueue.js +6 -5
- package/dist/adapters/mongo-client.d.ts +4 -3
- package/dist/adapters/mongo-client.d.ts.map +1 -1
- package/dist/adapters/mongo-client.js +5 -3
- package/dist/adapters/redis-client.d.ts +6 -3
- package/dist/adapters/redis-client.d.ts.map +1 -1
- package/dist/adapters/redis-client.js +7 -3
- package/dist/api/ContextProvider.d.ts +12 -9
- package/dist/api/ContextProvider.d.ts.map +1 -1
- package/dist/api/ContextProvider.js +9 -7
- package/dist/api/codec.d.ts +1 -1
- package/dist/api/internal/RequestContextMiddleware.d.ts +3 -3
- package/dist/api/internal/RequestContextMiddleware.d.ts.map +1 -1
- package/dist/api/internal/RequestContextMiddleware.js +18 -7
- package/dist/api/internal/auth.d.ts +45 -7
- package/dist/api/internal/auth.d.ts.map +1 -1
- package/dist/api/internal/auth.js +162 -29
- package/dist/api/internal/events.d.ts +6 -4
- package/dist/api/internal/events.d.ts.map +1 -1
- package/dist/api/internal/events.js +18 -11
- package/dist/api/internal/health.d.ts +1 -1
- package/dist/api/layerUtils.d.ts +15 -7
- package/dist/api/layerUtils.d.ts.map +1 -1
- package/dist/api/layerUtils.js +7 -6
- package/dist/api/middlewares.d.ts +1 -1
- package/dist/api/reportError.d.ts +2 -2
- package/dist/api/reportError.d.ts.map +1 -1
- package/dist/api/reportError.js +3 -2
- package/dist/api/routing/middleware/RouterMiddleware.d.ts +5 -4
- package/dist/api/routing/middleware/RouterMiddleware.d.ts.map +1 -1
- package/dist/api/routing/middleware/middleware.d.ts +42 -3
- package/dist/api/routing/middleware/middleware.d.ts.map +1 -1
- package/dist/api/routing/middleware/middleware.js +53 -17
- package/dist/api/routing/middleware.d.ts +3 -4
- package/dist/api/routing/middleware.d.ts.map +1 -1
- package/dist/api/routing/middleware.js +1 -2
- package/dist/api/routing/schema/jwt.d.ts +1 -1
- package/dist/api/routing/schema/jwt.d.ts.map +1 -1
- package/dist/api/routing/schema/jwt.js +3 -2
- package/dist/api/routing/tsort.d.ts +1 -1
- package/dist/api/routing/tsort.d.ts.map +1 -1
- package/dist/api/routing/utils.d.ts +4 -4
- package/dist/api/routing/utils.d.ts.map +1 -1
- package/dist/api/routing/utils.js +3 -2
- package/dist/api/routing.d.ts +84 -38
- package/dist/api/routing.d.ts.map +1 -1
- package/dist/api/routing.js +115 -45
- package/dist/api/setupRequest.d.ts +13 -6
- package/dist/api/setupRequest.d.ts.map +1 -1
- package/dist/api/setupRequest.js +37 -11
- package/dist/api/util.d.ts +1 -1
- package/dist/arbs.d.ts +2 -2
- package/dist/arbs.d.ts.map +1 -1
- package/dist/arbs.js +5 -3
- package/dist/errorReporter.d.ts +7 -5
- package/dist/errorReporter.d.ts.map +1 -1
- package/dist/errorReporter.js +22 -26
- package/dist/errors.d.ts +1 -1
- package/dist/fileUtil.d.ts +2 -2
- package/dist/fileUtil.d.ts.map +1 -1
- package/dist/fileUtil.js +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/logger/jsonLogger.d.ts +2 -2
- package/dist/logger/jsonLogger.d.ts.map +1 -1
- package/dist/logger/jsonLogger.js +4 -2
- package/dist/logger/logFmtLogger.d.ts +2 -2
- package/dist/logger/logFmtLogger.d.ts.map +1 -1
- package/dist/logger/logFmtLogger.js +2 -2
- package/dist/logger/shared.d.ts +2 -2
- package/dist/logger/shared.d.ts.map +1 -1
- package/dist/logger/shared.js +3 -3
- package/dist/logger.d.ts +2 -2
- package/dist/logger.d.ts.map +1 -1
- package/dist/otel.d.ts +75 -0
- package/dist/otel.d.ts.map +1 -0
- package/dist/otel.js +65 -0
- package/dist/rateLimit.d.ts +12 -4
- package/dist/rateLimit.d.ts.map +1 -1
- package/dist/rateLimit.js +7 -12
- package/dist/test.d.ts +3 -3
- package/dist/test.d.ts.map +1 -1
- package/dist/test.js +2 -2
- package/dist/vitest.d.ts +1 -1
- package/examples/query.ts +46 -38
- package/package.json +46 -37
- package/src/CUPS.ts +15 -11
- package/src/Emailer/Sendgrid.ts +65 -57
- package/src/Emailer/fake.ts +2 -2
- package/src/Emailer/service.ts +13 -3
- package/src/MainFiberSet.ts +12 -10
- package/src/Model/Repository/Registry.ts +34 -0
- package/src/Model/Repository/ext.ts +103 -11
- package/src/Model/Repository/internal/internal.ts +266 -151
- package/src/Model/Repository/legacy.ts +3 -1
- package/src/Model/Repository/makeRepo.ts +15 -10
- package/src/Model/Repository/service.ts +35 -23
- package/src/Model/Repository/validation.ts +5 -5
- package/src/Model/Repository.ts +1 -0
- package/src/Model/dsl.ts +5 -4
- package/src/Model/filter/types/path/eager.ts +1 -2
- package/src/Model/filter/types.ts +4 -4
- package/src/Model/query/dsl.ts +456 -20
- package/src/Model/query/new-kid-interpreter.ts +281 -7
- package/src/Model.ts +1 -0
- package/src/QueueMaker/SQLQueue.ts +150 -153
- package/src/QueueMaker/errors.ts +3 -1
- package/src/QueueMaker/memQueue.ts +111 -105
- package/src/QueueMaker/sbqueue.ts +76 -88
- package/src/QueueMaker/service.ts +3 -1
- package/src/RequestContext.ts +15 -16
- package/src/RequestFiberSet.ts +12 -7
- package/src/Store/ContextMapContainer.ts +46 -3
- package/src/Store/Cosmos/query.ts +214 -50
- package/src/Store/Cosmos.ts +491 -350
- package/src/Store/Disk.ts +106 -66
- package/src/Store/Memory.ts +365 -91
- package/src/Store/SQL/Pg.ts +364 -0
- package/src/Store/SQL/query.ts +603 -0
- package/src/Store/SQL.ts +736 -0
- package/src/Store/codeFilter.ts +5 -2
- package/src/Store/index.ts +20 -3
- package/src/Store/service.ts +60 -11
- package/src/Store/utils.ts +25 -23
- package/src/adapters/SQL/Model.ts +42 -41
- package/src/adapters/ServiceBus.ts +131 -121
- package/src/adapters/cosmos-client.ts +5 -3
- package/src/adapters/index.ts +7 -0
- package/src/adapters/memQueue.ts +5 -4
- package/src/adapters/mongo-client.ts +4 -2
- package/src/adapters/redis-client.ts +6 -2
- package/src/api/ContextProvider.ts +19 -16
- package/src/api/internal/RequestContextMiddleware.ts +24 -6
- package/src/api/internal/auth.ts +248 -44
- package/src/api/internal/events.ts +21 -12
- package/src/api/layerUtils.ts +13 -9
- package/src/api/reportError.ts +2 -1
- package/src/api/routing/middleware/RouterMiddleware.ts +5 -4
- package/src/api/routing/middleware/middleware.ts +60 -15
- package/src/api/routing/middleware.ts +2 -4
- package/src/api/routing/schema/jwt.ts +2 -1
- package/src/api/routing/utils.ts +2 -1
- package/src/api/routing.ts +309 -139
- package/src/api/setupRequest.ts +63 -12
- package/src/arbs.ts +5 -3
- package/src/errorReporter.ts +65 -75
- package/src/fileUtil.ts +1 -1
- package/src/logger/jsonLogger.ts +3 -1
- package/src/logger/logFmtLogger.ts +1 -1
- package/src/logger/shared.ts +3 -2
- package/src/otel.ts +152 -0
- package/src/rateLimit.ts +34 -23
- package/src/test.ts +2 -2
- package/test/auth.test.ts +101 -0
- package/test/contextProvider.test.ts +14 -11
- package/test/controller.test.ts +25 -29
- package/test/cosmos-query.test.ts +159 -0
- package/test/dist/auth.test.d.ts.map +1 -0
- package/test/dist/contextProvider.test.d.ts.map +1 -1
- package/test/dist/controller.test.d.ts.map +1 -1
- package/test/dist/cosmos-query.test.d.ts.map +1 -0
- package/test/dist/date-query.test.d.ts.map +1 -0
- package/test/dist/fixtures.d.ts +30 -12
- package/test/dist/fixtures.d.ts.map +1 -1
- package/test/dist/fixtures.js +17 -10
- package/test/dist/query.test.d.ts.map +1 -1
- package/test/dist/rawQuery.test.d.ts.map +1 -1
- package/test/dist/repository-ext.test.d.ts.map +1 -0
- package/test/dist/requires.test.d.ts.map +1 -1
- package/test/dist/router-generator.test.d.ts.map +1 -0
- package/test/dist/routing-interruptibility.test.d.ts.map +1 -0
- package/test/dist/rpc-context-map-streaming.test.d.ts.map +1 -0
- package/test/dist/rpc-e2e-invalidation.test.d.ts.map +1 -0
- package/test/dist/rpc-multi-middleware.test.d.ts.map +1 -1
- package/test/dist/rpc-stream-fullstack.test.d.ts.map +1 -0
- package/test/dist/sql-store.test.d.ts.map +1 -0
- package/test/fixtures.ts +16 -9
- package/test/layerUtils.test.ts +1 -1
- package/test/query.test.ts +901 -38
- package/test/rawQuery.test.ts +338 -20
- package/test/repository-ext.test.ts +62 -0
- package/test/requires.test.ts +10 -5
- package/test/router-generator.test.ts +187 -0
- package/test/routing-interruptibility.test.ts +66 -0
- package/test/rpc-context-map-streaming.test.ts +262 -0
- package/test/rpc-e2e-invalidation.test.ts +256 -0
- package/test/rpc-multi-middleware.test.ts +84 -9
- package/test/rpc-stream-fullstack.test.ts +304 -0
- package/test/sql-store.test.ts +1711 -0
- package/test/validateSample.test.ts +17 -12
- package/tsconfig.examples.json +1 -1
- package/tsconfig.json +2 -1
- package/tsconfig.json.bak +2 -2
- package/tsconfig.src.json +35 -35
- package/tsconfig.test.json +2 -2
- package/dist/Operations.d.ts +0 -55
- package/dist/Operations.d.ts.map +0 -1
- package/dist/Operations.js +0 -102
- package/dist/OperationsRepo.d.ts +0 -41
- package/dist/OperationsRepo.d.ts.map +0 -1
- package/dist/OperationsRepo.js +0 -14
- package/eslint.config.mjs +0 -24
- package/src/Operations.ts +0 -235
- package/src/OperationsRepo.ts +0 -16
package/src/api/routing.ts
CHANGED
|
@@ -2,22 +2,38 @@
|
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
3
3
|
/* eslint-disable @typescript-eslint/no-empty-object-type */
|
|
4
4
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
5
|
-
import {
|
|
5
|
+
import type { NonEmptyReadonlyArray } from "effect-app/Array"
|
|
6
|
+
import { getMeta } from "effect-app/client"
|
|
7
|
+
import * as Config from "effect-app/Config"
|
|
8
|
+
import * as Effect from "effect-app/Effect"
|
|
6
9
|
import { type HttpHeaders } from "effect-app/http"
|
|
10
|
+
import * as Layer from "effect-app/Layer"
|
|
11
|
+
import { Invalidation } from "effect-app/rpc"
|
|
7
12
|
import { type GetEffectContext, type GetEffectError, type RpcContextMap } from "effect-app/rpc/RpcContextMap"
|
|
13
|
+
import * as S from "effect-app/Schema"
|
|
8
14
|
import { type TypeTestId } from "effect-app/TypeTest"
|
|
9
15
|
import { typedKeysOf, typedValuesOf } from "effect-app/utils"
|
|
10
|
-
import
|
|
16
|
+
import * as Predicate from "effect/Predicate"
|
|
17
|
+
import * as Ref from "effect/Ref"
|
|
18
|
+
import type * as Scope from "effect/Scope"
|
|
19
|
+
import * as Stream from "effect/Stream"
|
|
11
20
|
import { Rpc, RpcGroup, type RpcSerialization, RpcServer } from "effect/unstable/rpc"
|
|
12
21
|
import { type LayerUtils } from "./layerUtils.js"
|
|
13
|
-
import {
|
|
22
|
+
import { RequestType as RequestTypeAnnotation } from "./routing/middleware.js"
|
|
14
23
|
|
|
15
24
|
export * from "./routing/middleware.js"
|
|
16
25
|
|
|
26
|
+
export const applyRequestTypeInterruptibility = <A, E, R>(
|
|
27
|
+
requestType: "command" | "query",
|
|
28
|
+
effect: Effect.Effect<A, E, R>
|
|
29
|
+
) => requestType === "command" ? Rpc.uninterruptible(effect) : effect
|
|
30
|
+
|
|
17
31
|
// it's the result of extending S.Req setting success, config
|
|
18
32
|
// it's a schema plus some metadata
|
|
19
33
|
export type AnyRequestModule = S.Top & {
|
|
20
34
|
_tag: string // unique identifier for the request module
|
|
35
|
+
type: "command" | "query"
|
|
36
|
+
stream: boolean
|
|
21
37
|
config: any // ?
|
|
22
38
|
success: S.Top // validates the success response
|
|
23
39
|
error: S.Top // validates the failure response
|
|
@@ -65,7 +81,10 @@ interface HandlerBase<Action extends AnyRequestModule, RT extends RequestType, A
|
|
|
65
81
|
new(): {}
|
|
66
82
|
_tag: RT
|
|
67
83
|
stack: string
|
|
68
|
-
handler: (
|
|
84
|
+
handler: (
|
|
85
|
+
req: S.Schema.Type<Action>,
|
|
86
|
+
headers: HttpHeaders.Headers
|
|
87
|
+
) => Effect.Effect<A, E, R> | Stream.Stream<A, E, R>
|
|
69
88
|
}
|
|
70
89
|
|
|
71
90
|
export interface Handler<Action extends AnyRequestModule, RT extends RequestType, R> extends
|
|
@@ -98,35 +117,47 @@ type RpcRouteR<
|
|
|
98
117
|
] ? R
|
|
99
118
|
: never
|
|
100
119
|
|
|
101
|
-
type
|
|
120
|
+
type EffectMatch<
|
|
102
121
|
Resource extends Record<string, any>,
|
|
103
122
|
RequestContextMap extends Record<string, any>,
|
|
104
123
|
RT extends RequestType,
|
|
105
124
|
Key extends keyof Resource
|
|
106
|
-
> =
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
Exclude<R2, GetEffectContext<RequestContextMap, Resource[Key]["config"]>>,
|
|
115
|
-
Scope.Scope
|
|
116
|
-
>
|
|
125
|
+
> = <A extends GetSuccessShape<Resource[Key], RT>, R2 = never, E = never>(
|
|
126
|
+
f: (req: S.Schema.Type<Resource[Key]>) => Effect.Effect<A, E, R2>
|
|
127
|
+
) => Handler<
|
|
128
|
+
Resource[Key],
|
|
129
|
+
RT,
|
|
130
|
+
Exclude<
|
|
131
|
+
Exclude<R2, GetEffectContext<RequestContextMap, Resource[Key]["config"]>>,
|
|
132
|
+
Scope.Scope
|
|
117
133
|
>
|
|
134
|
+
>
|
|
118
135
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
136
|
+
type StreamMatch<
|
|
137
|
+
Resource extends Record<string, any>,
|
|
138
|
+
RequestContextMap extends Record<string, any>,
|
|
139
|
+
RT extends RequestType,
|
|
140
|
+
Key extends keyof Resource
|
|
141
|
+
> = <A extends GetSuccessShape<Resource[Key], RT>, R2 = never, E = never>(
|
|
142
|
+
f: (req: S.Schema.Type<Resource[Key]>) => Stream.Stream<A, E, R2>
|
|
143
|
+
) => Handler<
|
|
144
|
+
Resource[Key],
|
|
145
|
+
RT,
|
|
146
|
+
Exclude<
|
|
147
|
+
Exclude<R2, GetEffectContext<RequestContextMap, Resource[Key]["config"]>>,
|
|
148
|
+
Scope.Scope
|
|
128
149
|
>
|
|
129
|
-
|
|
150
|
+
>
|
|
151
|
+
|
|
152
|
+
// Stream resources only accept Stream / Effect<Stream> handlers; non-stream resources
|
|
153
|
+
// only accept Effect handlers. Discriminated by the request module's `stream` flag.
|
|
154
|
+
type Match<
|
|
155
|
+
Resource extends Record<string, any>,
|
|
156
|
+
RequestContextMap extends Record<string, any>,
|
|
157
|
+
RT extends RequestType,
|
|
158
|
+
Key extends keyof Resource
|
|
159
|
+
> = Resource[Key] extends { stream: true } ? StreamMatch<Resource, RequestContextMap, RT, Key>
|
|
160
|
+
: EffectMatch<Resource, RequestContextMap, RT, Key>
|
|
130
161
|
|
|
131
162
|
export type RouteMatcher<
|
|
132
163
|
RequestContextMap extends Record<string, any>,
|
|
@@ -156,51 +187,93 @@ export const skipOnProd = Effect
|
|
|
156
187
|
})
|
|
157
188
|
.pipe(Effect.orDie)
|
|
158
189
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
>
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
190
|
+
// Type helpers to extract middleware information from a resource's request classes.
|
|
191
|
+
type MiddlewareOf<M extends Record<string, any>> = Exclude<
|
|
192
|
+
{ [K in keyof M]: M[K] extends { readonly middleware?: infer MW } ? NonNullable<MW> : never }[keyof M],
|
|
193
|
+
never
|
|
194
|
+
>
|
|
195
|
+
type ProvidesOf<MW> = MW extends { readonly provides: infer P } ? P : never
|
|
196
|
+
type RequestContextMapOf<MW> = MW extends {
|
|
197
|
+
requestContextMap: infer RCM extends Record<string, RpcContextMap.Any>
|
|
198
|
+
} ? RCM
|
|
199
|
+
: Record<string, never>
|
|
200
|
+
type LayerNormalize<L> = L extends Layer.Layer<any, infer E, infer R> ? Layer.Layer<never, E, R>
|
|
201
|
+
: Layer.Layer<never, never, never>
|
|
202
|
+
type LayerSuccess<L> = L extends Layer.Layer<infer A, any, any> ? A : never
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Middleware tags are typically passed to `makeRpcClient` as the class value, so
|
|
206
|
+
* the captured `MW` is a constructor type. Layers carry the *instance* type as
|
|
207
|
+
* their success channel. Bridge the two so the constraint compares like-with-like.
|
|
208
|
+
*
|
|
209
|
+
* Effect middleware classes declare `new(_: never): Shape` which the standard
|
|
210
|
+
* `T extends abstract new (...args: any) => infer I` form sometimes fails to
|
|
211
|
+
* narrow. Use the `prototype` member instead — it is always the instance type.
|
|
212
|
+
*/
|
|
213
|
+
type MWService<MW> = MW extends { readonly prototype: infer P } ? P : MW
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Type-level guard: emits a structural mismatch on `Resource` when the middleware
|
|
217
|
+
* service identifier extracted from the resource's request classes is not provided
|
|
218
|
+
* by the layer passed to `makeRouter`. When `MW` is `never` (no middleware on the
|
|
219
|
+
* resource) or already a subtype of the layer's success, this resolves to `unknown`
|
|
220
|
+
* and intersects harmlessly with `Resource`.
|
|
221
|
+
*/
|
|
222
|
+
type EnsureMiddlewareProvided<Live, MW> = [MW] extends [never] ? unknown
|
|
223
|
+
: [MWService<MW>] extends [LayerSuccess<Live>] ? unknown
|
|
224
|
+
: {
|
|
225
|
+
readonly __middlewareNotProvidedByRouterLayer: {
|
|
226
|
+
readonly expected: MWService<MW>
|
|
227
|
+
readonly providedByLayer: LayerSuccess<Live>
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// Safe wrappers that check the constraint before calling GetEffectContext/GetEffectError.
|
|
232
|
+
// These avoid TypeScript constraint errors when the RC map type is deferred (generic).
|
|
233
|
+
type SafeGetEffectContext<RCM, Config> = RCM extends Record<string, RpcContextMap.Any> ? GetEffectContext<RCM, Config>
|
|
234
|
+
: never
|
|
235
|
+
type SafeGetEffectError<RCM, Config> = RCM extends Record<string, RpcContextMap.Any> ? GetEffectError<RCM, Config>
|
|
236
|
+
: never
|
|
237
|
+
|
|
238
|
+
export const makeRouter = <Live extends Layer.Layer<any, any, any> = Layer.Layer<any, never, never>>(
|
|
239
|
+
middlewareLive?: Live
|
|
179
240
|
) => {
|
|
241
|
+
type ResourceMWDefault = LayerNormalize<Live>
|
|
242
|
+
|
|
180
243
|
/**
|
|
181
|
-
* Create a Router for specified resource
|
|
182
|
-
*
|
|
244
|
+
* Create a Router for specified resource.
|
|
245
|
+
* Middleware schema/tag is read from the request classes (stored via `makeRpcClient`).
|
|
246
|
+
* The middleware **Live** layer is the one passed to `makeRouter`.
|
|
247
|
+
* If `check` is provided, the router will only be created if the effect succeeds with true.
|
|
183
248
|
*/
|
|
184
249
|
function matchFor<
|
|
185
|
-
const
|
|
186
|
-
|
|
250
|
+
const Resource extends Record<string, any>,
|
|
251
|
+
MW = MiddlewareOf<Resource>
|
|
187
252
|
>(
|
|
188
|
-
rsc: Resource &
|
|
253
|
+
rsc: Resource & EnsureMiddlewareProvided<Live, MW>,
|
|
189
254
|
options?: { check?: Effect.Effect<boolean> }
|
|
190
255
|
) {
|
|
256
|
+
// MW is a defaulted type parameter so TypeScript evaluates MiddlewareOf<Resource>
|
|
257
|
+
// eagerly at each call site, producing a concrete type instead of a deferred conditional.
|
|
258
|
+
type ResourceRequestContextMap = RequestContextMapOf<MW>
|
|
259
|
+
type ResourceContextProviderA = ProvidesOf<MW>
|
|
260
|
+
|
|
261
|
+
type HandlerContext<Action extends AnyRequestModule> =
|
|
262
|
+
| SafeGetEffectContext<ResourceRequestContextMap, Action["config"]>
|
|
263
|
+
| ResourceContextProviderA
|
|
264
|
+
|
|
191
265
|
type HandlerWithInputGen<
|
|
192
266
|
Action extends AnyRequestModule,
|
|
193
267
|
RT extends RequestType
|
|
194
268
|
> = (
|
|
195
269
|
req: S.Schema.Type<Action>
|
|
196
270
|
) => Generator<
|
|
197
|
-
|
|
198
|
-
any,
|
|
271
|
+
Effect.Effect<
|
|
199
272
|
any,
|
|
200
273
|
S.Schema.Type<GetFailure<Action>> | S.SchemaError,
|
|
201
274
|
// the actual implementation of the handler may just require the dynamic context provided by the middleware
|
|
202
275
|
// and the per request context provided by the context provider
|
|
203
|
-
|
|
276
|
+
HandlerContext<Action>
|
|
204
277
|
>,
|
|
205
278
|
GetSuccessShape<Action, RT>,
|
|
206
279
|
never
|
|
@@ -216,40 +289,41 @@ export const makeRouter = <
|
|
|
216
289
|
S.Schema.Type<GetFailure<Action>> | S.SchemaError,
|
|
217
290
|
// the actual implementation of the handler may just require the dynamic context provided by the middleware
|
|
218
291
|
// and the per request context provided by the context provider
|
|
219
|
-
|
|
292
|
+
HandlerContext<Action>
|
|
220
293
|
>
|
|
221
294
|
|
|
222
|
-
type
|
|
295
|
+
type HandlerWithInputStream<
|
|
223
296
|
Action extends AnyRequestModule,
|
|
224
297
|
RT extends RequestType
|
|
225
|
-
> =
|
|
298
|
+
> = (
|
|
299
|
+
req: S.Schema.Type<Action>
|
|
300
|
+
) => Stream.Stream<
|
|
226
301
|
GetSuccessShape<Action, RT>,
|
|
227
302
|
S.Schema.Type<GetFailure<Action>> | S.SchemaError,
|
|
228
|
-
|
|
229
|
-
// and the per request context provided by the context provider
|
|
230
|
-
GetEffectContext<RequestContextMap, Action["config"]> | ContextProviderA
|
|
303
|
+
HandlerContext<Action>
|
|
231
304
|
>
|
|
232
305
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
|
306
|
+
// Stream resources only accept `(req) => Stream`; non-stream only Effect / Generator.
|
|
307
|
+
type Handlers<Action extends AnyRequestModule, RT extends RequestType> = Action extends { stream: true }
|
|
308
|
+
? HandlerWithInputStream<Action, RT>
|
|
309
|
+
: HandlerWithInputGen<Action, RT> | HandlerWithInputEff<Action, RT>
|
|
237
310
|
|
|
238
311
|
type HandlersDecoded<Action extends AnyRequestModule> = Handlers<Action, RequestTypes.DECODED>
|
|
239
312
|
|
|
240
|
-
type HandlersRaw<Action extends AnyRequestModule> =
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
313
|
+
type HandlersRaw<Action extends AnyRequestModule> = Action extends { stream: true }
|
|
314
|
+
? { raw: HandlerWithInputStream<Action, RequestTypes.RAW> }
|
|
315
|
+
:
|
|
316
|
+
| { raw: HandlerWithInputGen<Action, RequestTypes.RAW> }
|
|
317
|
+
| { raw: HandlerWithInputEff<Action, RequestTypes.RAW> }
|
|
244
318
|
|
|
245
319
|
type AnyHandlers<Action extends AnyRequestModule> = HandlersRaw<Action> | HandlersDecoded<Action>
|
|
246
320
|
|
|
247
|
-
const
|
|
321
|
+
const meta = getMeta(rsc)
|
|
248
322
|
|
|
249
323
|
type RequestModules = FilterRequestModules<Resource>
|
|
250
324
|
const requestModules = typedKeysOf(rsc).reduce((acc, cur) => {
|
|
251
325
|
if (Predicate.isObjectKeyword(rsc[cur]) && rsc[cur]["success"]) {
|
|
252
|
-
acc[cur as keyof RequestModules] = rsc[cur]
|
|
326
|
+
acc[cur as keyof RequestModules] = rsc[cur]
|
|
253
327
|
}
|
|
254
328
|
return acc
|
|
255
329
|
}, {} as RequestModules)
|
|
@@ -260,19 +334,13 @@ export const makeRouter = <
|
|
|
260
334
|
// handlerImpl is the actual handler implementation
|
|
261
335
|
if (handlerImpl[Symbol.toStringTag] === "GeneratorFunction") handlerImpl = Effect.fnUntraced(handlerImpl)
|
|
262
336
|
const stack = new Error().stack?.split("\n").slice(2).join("\n")
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
: class {
|
|
271
|
-
static request = rsc[cur]
|
|
272
|
-
static stack = stack
|
|
273
|
-
static _tag = RequestTypes.DECODED
|
|
274
|
-
static handler = handlerImpl
|
|
275
|
-
}
|
|
337
|
+
// oxlint-disable-next-line typescript/no-extraneous-class
|
|
338
|
+
return class {
|
|
339
|
+
static request = rsc[cur]
|
|
340
|
+
static stack = stack
|
|
341
|
+
static _tag = RequestTypes.DECODED
|
|
342
|
+
static handler = handlerImpl
|
|
343
|
+
}
|
|
276
344
|
}, {
|
|
277
345
|
success: rsc[cur].success,
|
|
278
346
|
successRaw: S.toEncoded(rsc[cur].success),
|
|
@@ -283,24 +351,18 @@ export const makeRouter = <
|
|
|
283
351
|
(handlerImpl: any) => {
|
|
284
352
|
if (handlerImpl[Symbol.toStringTag] === "GeneratorFunction") handlerImpl = Effect.fnUntraced(handlerImpl)
|
|
285
353
|
const stack = new Error().stack?.split("\n").slice(2).join("\n")
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
: class {
|
|
294
|
-
static request = rsc[cur]
|
|
295
|
-
static stack = stack
|
|
296
|
-
static _tag = RequestTypes.RAW
|
|
297
|
-
static handler = handlerImpl
|
|
298
|
-
}
|
|
354
|
+
// oxlint-disable-next-line typescript/no-extraneous-class
|
|
355
|
+
return class {
|
|
356
|
+
static request = rsc[cur]
|
|
357
|
+
static stack = stack
|
|
358
|
+
static _tag = RequestTypes.RAW
|
|
359
|
+
static handler = handlerImpl
|
|
360
|
+
}
|
|
299
361
|
}
|
|
300
362
|
})
|
|
301
363
|
return prev
|
|
302
364
|
},
|
|
303
|
-
{} as RouteMatcher<
|
|
365
|
+
{} as RouteMatcher<ResourceRequestContextMap, Resource>
|
|
304
366
|
)
|
|
305
367
|
|
|
306
368
|
const router3: <
|
|
@@ -318,23 +380,19 @@ export const makeRouter = <
|
|
|
318
380
|
// retrieves context R from the actual implementation of the handler
|
|
319
381
|
Impl[K] extends { raw: any }
|
|
320
382
|
? Impl[K]["raw"] extends (...args: any[]) => Effect.Effect<any, any, infer R> ? R
|
|
321
|
-
: Impl[K]["raw"] extends
|
|
383
|
+
: Impl[K]["raw"] extends (...args: any[]) => Stream.Stream<any, any, infer R> ? R
|
|
322
384
|
: Impl[K]["raw"] extends (...args: any[]) => Generator<
|
|
323
|
-
|
|
324
|
-
any,
|
|
325
|
-
any
|
|
385
|
+
Effect.Effect<any, any, infer R>
|
|
326
386
|
> ? R
|
|
327
387
|
: never
|
|
328
388
|
: Impl[K] extends (...args: any[]) => Effect.Effect<any, any, infer R> ? R
|
|
329
|
-
: Impl[K] extends
|
|
389
|
+
: Impl[K] extends (...args: any[]) => Stream.Stream<any, any, infer R> ? R
|
|
330
390
|
: Impl[K] extends (...args: any[]) => Generator<
|
|
331
|
-
|
|
332
|
-
any,
|
|
333
|
-
any
|
|
391
|
+
Effect.Effect<any, any, infer R>
|
|
334
392
|
> ? R
|
|
335
393
|
: never,
|
|
336
|
-
|
|
|
337
|
-
|
|
|
394
|
+
| SafeGetEffectContext<ResourceRequestContextMap, Resource[K]["config"]>
|
|
395
|
+
| ResourceContextProviderA
|
|
338
396
|
>,
|
|
339
397
|
Scope.Scope
|
|
340
398
|
>
|
|
@@ -359,7 +417,7 @@ export const makeRouter = <
|
|
|
359
417
|
match: any
|
|
360
418
|
) =>
|
|
361
419
|
| Effect.Effect<THandlers, MakeE, MakeR>
|
|
362
|
-
| Generator<
|
|
420
|
+
| Generator<Effect.Effect<any, MakeE, MakeR>, THandlers>
|
|
363
421
|
) => {
|
|
364
422
|
const dependenciesL = (dependencies ? Layer.mergeAll(...dependencies as any) : Layer.empty) as Layer.Layer<
|
|
365
423
|
LayerUtils.GetLayersSuccess<MakeDependencies>,
|
|
@@ -375,6 +433,9 @@ export const makeRouter = <
|
|
|
375
433
|
|
|
376
434
|
const controllers = yield* finalMake
|
|
377
435
|
|
|
436
|
+
// Read the middleware from the resource's request classes at runtime
|
|
437
|
+
const mw = meta.middleware as any
|
|
438
|
+
|
|
378
439
|
// return make.pipe(Effect.map((c) => controllers(c, dependencies)))
|
|
379
440
|
const mapped = typedKeysOf(requestModules).reduce((acc, cur) => {
|
|
380
441
|
const handler = controllers[cur as keyof typeof controllers]
|
|
@@ -386,12 +447,105 @@ export const makeRouter = <
|
|
|
386
447
|
static success = S.toEncoded(resource.success)
|
|
387
448
|
} as any
|
|
388
449
|
: resource,
|
|
389
|
-
(payload: any, headers: any) =>
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
450
|
+
(payload: any, headers: any) => {
|
|
451
|
+
const result: any = handler.handler(payload, headers)
|
|
452
|
+
if (resource.stream) {
|
|
453
|
+
// Wrap stream items as { _tag: "value", value } and append a final
|
|
454
|
+
// { _tag: "done", metadata } chunk carrying accumulated invalidation keys.
|
|
455
|
+
// V2: on failure, convert to { _tag: "error", error, metadata } chunk so
|
|
456
|
+
// clients can invalidate queries even when the stream fails.
|
|
457
|
+
const keysRef = Ref.makeUnsafe<ReadonlyArray<Invalidation.InvalidationKey>>([])
|
|
458
|
+
const invalidationSet = Invalidation.makeInvalidationSet(keysRef)
|
|
459
|
+
return Stream.concat(
|
|
460
|
+
(result as Stream.Stream<any, any, any>).pipe(
|
|
461
|
+
Stream.map((item: any) => ({ _tag: "value" as const, value: item })),
|
|
462
|
+
Stream.provideService(Invalidation.InvalidationSet, invalidationSet),
|
|
463
|
+
// V3: after each value chunk, drain accumulated keys and emit a "metadata"
|
|
464
|
+
// chunk if any keys were collected since the last drain. This lets clients
|
|
465
|
+
// invalidate queries mid-stream without waiting for the "done" chunk.
|
|
466
|
+
Stream.flatMap((valueChunk: any) =>
|
|
467
|
+
Stream
|
|
468
|
+
.fromEffect(
|
|
469
|
+
Ref.getAndSet(keysRef, []).pipe(
|
|
470
|
+
Effect.map((keys) =>
|
|
471
|
+
keys.length > 0
|
|
472
|
+
? [
|
|
473
|
+
valueChunk,
|
|
474
|
+
{ _tag: "metadata" as const, metadata: { invalidateQueries: keys } }
|
|
475
|
+
]
|
|
476
|
+
: [valueChunk]
|
|
477
|
+
)
|
|
478
|
+
)
|
|
479
|
+
)
|
|
480
|
+
.pipe(Stream.flatMap(Stream.fromIterable))
|
|
481
|
+
),
|
|
482
|
+
// V2: catch stream failures and embed them in the stream as an error chunk
|
|
483
|
+
Stream.catch((err: any) =>
|
|
484
|
+
Stream.fromEffect(
|
|
485
|
+
Ref.get(keysRef).pipe(
|
|
486
|
+
Effect.flatMap((keys) =>
|
|
487
|
+
Effect.fail({
|
|
488
|
+
_tag: "error" as const,
|
|
489
|
+
error: err,
|
|
490
|
+
metadata: { invalidateQueries: keys }
|
|
491
|
+
})
|
|
492
|
+
)
|
|
493
|
+
)
|
|
494
|
+
)
|
|
495
|
+
)
|
|
496
|
+
),
|
|
497
|
+
Stream.fromEffect(
|
|
498
|
+
Ref.get(keysRef).pipe(
|
|
499
|
+
Effect.map((keys) => ({ _tag: "done" as const, metadata: { invalidateQueries: keys } }))
|
|
500
|
+
)
|
|
501
|
+
)
|
|
502
|
+
)
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
let effect = Effect
|
|
506
|
+
.annotateCurrentSpan({
|
|
507
|
+
"rpc.system": "effect-app",
|
|
508
|
+
"rpc.service": meta.moduleName,
|
|
509
|
+
"rpc.method": resource._tag,
|
|
510
|
+
"code.function.name": resource._tag,
|
|
511
|
+
"code.namespace": meta.moduleName,
|
|
512
|
+
"app.rpc.type": resource.type
|
|
393
513
|
})
|
|
394
|
-
|
|
514
|
+
.pipe(Effect.andThen(result as Effect.Effect<unknown, unknown, unknown>))
|
|
515
|
+
|
|
516
|
+
// Commands: provide a request-scoped `InvalidationSet` and wrap both
|
|
517
|
+
// success (`CommandResponseWithMetaData`) and handler-thrown failure
|
|
518
|
+
// (`CommandFailureWithMetaData`) so the client receives accumulated
|
|
519
|
+
// invalidation keys on either path. Middleware-thrown errors bypass the
|
|
520
|
+
// wrap (they fail the outer effect before reaching this `.catch`) and
|
|
521
|
+
// flow raw on the Cause; client decodes them via the rpc's
|
|
522
|
+
// `middlewares[*].error` failure-union channel.
|
|
523
|
+
if (resource.type === "command") {
|
|
524
|
+
const keysRef = Ref.makeUnsafe<ReadonlyArray<Invalidation.InvalidationKey>>([])
|
|
525
|
+
const invalidationSet = Invalidation.makeInvalidationSet(keysRef)
|
|
526
|
+
effect = effect.pipe(
|
|
527
|
+
Effect.provideService(Invalidation.InvalidationSet, invalidationSet),
|
|
528
|
+
Effect.flatMap((value) =>
|
|
529
|
+
Ref.get(keysRef).pipe(
|
|
530
|
+
Effect.map((keys) => ({ payload: value, metadata: { invalidateQueries: keys } }) as any)
|
|
531
|
+
)
|
|
532
|
+
),
|
|
533
|
+
Effect.catch((err: any) =>
|
|
534
|
+
Ref.get(keysRef).pipe(
|
|
535
|
+
Effect.flatMap((keys) =>
|
|
536
|
+
Effect.fail({
|
|
537
|
+
_tag: "CommandFailureWithMetaData" as const,
|
|
538
|
+
error: err,
|
|
539
|
+
metadata: { invalidateQueries: keys }
|
|
540
|
+
})
|
|
541
|
+
)
|
|
542
|
+
)
|
|
543
|
+
)
|
|
544
|
+
)
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
return applyRequestTypeInterruptibility(resource.type, effect)
|
|
548
|
+
}
|
|
395
549
|
] as const
|
|
396
550
|
return acc
|
|
397
551
|
}, {} as any) as {
|
|
@@ -403,10 +557,10 @@ export const makeRouter = <
|
|
|
403
557
|
) => Effect.Effect<
|
|
404
558
|
Effect.Success<ReturnType<THandlers[K]["handler"]>>,
|
|
405
559
|
| Effect.Error<ReturnType<THandlers[K]["handler"]>>
|
|
406
|
-
|
|
|
560
|
+
| SafeGetEffectError<ResourceRequestContextMap, Resource[K]["config"]>,
|
|
407
561
|
Exclude<
|
|
408
562
|
Effect.Services<ReturnType<THandlers[K]["handler"]>>,
|
|
409
|
-
|
|
563
|
+
ResourceContextProviderA | SafeGetEffectContext<ResourceRequestContextMap, Resource[K]["config"]>
|
|
410
564
|
>
|
|
411
565
|
>
|
|
412
566
|
]
|
|
@@ -415,13 +569,33 @@ export const makeRouter = <
|
|
|
415
569
|
const rpcs = RpcGroup
|
|
416
570
|
.make(
|
|
417
571
|
...typedValuesOf(mapped).map(([resource]) => {
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
572
|
+
const isStream = resource.stream
|
|
573
|
+
const isCommand = resource.type === "command"
|
|
574
|
+
return (isCommand
|
|
575
|
+
? isStream
|
|
576
|
+
? Invalidation.makeStreamRpc(resource._tag, {
|
|
577
|
+
payload: resource,
|
|
578
|
+
success: resource.success,
|
|
579
|
+
error: resource.error,
|
|
580
|
+
stream: true as const
|
|
581
|
+
})
|
|
582
|
+
: Invalidation.makeCommandRpc(resource._tag, {
|
|
583
|
+
payload: resource,
|
|
584
|
+
success: resource.success,
|
|
585
|
+
error: resource.error
|
|
586
|
+
})
|
|
587
|
+
: Rpc.make(resource._tag, {
|
|
588
|
+
payload: resource,
|
|
589
|
+
success: resource.success,
|
|
590
|
+
error: resource.error,
|
|
591
|
+
stream: isStream
|
|
592
|
+
}))
|
|
593
|
+
.annotate(mw.requestContext, resource.config ?? {})
|
|
594
|
+
.annotate(RequestTypeAnnotation, resource.type)
|
|
421
595
|
})
|
|
422
596
|
)
|
|
423
597
|
.prefix(`${meta.moduleName}.`)
|
|
424
|
-
.middleware(
|
|
598
|
+
.middleware(mw)
|
|
425
599
|
|
|
426
600
|
const rpc = rpcs
|
|
427
601
|
.toLayer(Effect.gen(function*() {
|
|
@@ -437,7 +611,6 @@ export const makeRouter = <
|
|
|
437
611
|
|
|
438
612
|
return RpcServer
|
|
439
613
|
.layerHttp({
|
|
440
|
-
spanPrefix: "RpcServer." + meta.moduleName,
|
|
441
614
|
group: rpcs,
|
|
442
615
|
path: ("/rpc/" + meta.moduleName) as `/${typeof meta.moduleName}`,
|
|
443
616
|
protocol: "http"
|
|
@@ -449,7 +622,7 @@ export const makeRouter = <
|
|
|
449
622
|
const routes = layer.pipe(
|
|
450
623
|
Layer.provide([
|
|
451
624
|
dependenciesL,
|
|
452
|
-
|
|
625
|
+
(middlewareLive ?? Layer.empty) as Layer.Layer<any, any, any>
|
|
453
626
|
])
|
|
454
627
|
)
|
|
455
628
|
|
|
@@ -473,14 +646,12 @@ export const makeRouter = <
|
|
|
473
646
|
const Make extends {
|
|
474
647
|
dependencies?: ReadonlyArray<Layer.Any>
|
|
475
648
|
effect: (match: typeof router3) => Generator<
|
|
476
|
-
|
|
477
|
-
any,
|
|
649
|
+
Effect.Effect<
|
|
478
650
|
any,
|
|
479
651
|
any,
|
|
480
652
|
any
|
|
481
653
|
>,
|
|
482
|
-
{ [K in keyof FilterRequestModules<Resource>]: AnyHandler<Resource[K]> }
|
|
483
|
-
any
|
|
654
|
+
{ [K in keyof FilterRequestModules<Resource>]: AnyHandler<Resource[K]> }
|
|
484
655
|
>
|
|
485
656
|
/** @deprecated */
|
|
486
657
|
readonly ಠ_ಠ: never
|
|
@@ -492,9 +663,9 @@ export const makeRouter = <
|
|
|
492
663
|
never,
|
|
493
664
|
| MakeErrors<Make>
|
|
494
665
|
| MakeDepsE<Make>
|
|
495
|
-
| Layer.Error<
|
|
666
|
+
| Layer.Error<ResourceMWDefault>,
|
|
496
667
|
| MakeDepsIn<Make>
|
|
497
|
-
| Layer.Services<
|
|
668
|
+
| Layer.Services<ResourceMWDefault>
|
|
498
669
|
| Exclude<
|
|
499
670
|
MakeContext<Make>,
|
|
500
671
|
MakeDepsOut<Make>
|
|
@@ -510,9 +681,8 @@ export const makeRouter = <
|
|
|
510
681
|
dependencies?: ReadonlyArray<Layer.Any>
|
|
511
682
|
// v4: generators yield Yieldable with asEffect()
|
|
512
683
|
effect: (match: typeof router3) => Generator<
|
|
513
|
-
|
|
514
|
-
{ [K in keyof FilterRequestModules<Resource>]: AnyHandler<Resource[K]> }
|
|
515
|
-
any
|
|
684
|
+
Effect.Effect<any, any, any>,
|
|
685
|
+
{ [K in keyof FilterRequestModules<Resource>]: AnyHandler<Resource[K]> }
|
|
516
686
|
>
|
|
517
687
|
}
|
|
518
688
|
>(
|
|
@@ -522,9 +692,9 @@ export const makeRouter = <
|
|
|
522
692
|
never,
|
|
523
693
|
| MakeErrors<Make>
|
|
524
694
|
| MakeDepsE<Make>
|
|
525
|
-
| Layer.Error<
|
|
695
|
+
| Layer.Error<ResourceMWDefault>,
|
|
526
696
|
| MakeDepsIn<Make>
|
|
527
|
-
| Layer.Services<
|
|
697
|
+
| Layer.Services<ResourceMWDefault>
|
|
528
698
|
| Exclude<
|
|
529
699
|
MakeContext<Make>,
|
|
530
700
|
MakeDepsOut<Make>
|
|
@@ -571,24 +741,24 @@ export type MakeDeps<Make> = Make extends { readonly dependencies: ReadonlyArray
|
|
|
571
741
|
export type MakeErrors<Make> = /*Make extends { readonly effect: (_: any) => Effect.Effect<any, infer E, any> } ? E
|
|
572
742
|
: Make extends { readonly effect: (_: any) => Effect.Effect<any, never, any> } ? never
|
|
573
743
|
: */
|
|
574
|
-
// v4: generators yield
|
|
575
|
-
Make extends { readonly effect: (_: any) => Generator<
|
|
576
|
-
: Make extends { readonly effect: (_: any) => Generator<
|
|
744
|
+
// v4: generators yield Effect values
|
|
745
|
+
Make extends { readonly effect: (_: any) => Generator<Effect.Effect<any, never, any>, any> } ? never
|
|
746
|
+
: Make extends { readonly effect: (_: any) => Generator<Effect.Effect<any, infer E, any>, any> } ? E
|
|
577
747
|
: never
|
|
578
748
|
|
|
579
749
|
export type MakeContext<Make> = /*Make extends { readonly effect: (_: any) => Effect.Effect<any, any, infer R> } ? R
|
|
580
750
|
: Make extends { readonly effect: (_: any) => Effect.Effect<any, any, never> } ? never
|
|
581
751
|
: */
|
|
582
|
-
// v4: generators yield
|
|
583
|
-
Make extends { readonly effect: (_: any) => Generator<
|
|
584
|
-
: Make extends { readonly effect: (_: any) => Generator<
|
|
752
|
+
// v4: generators yield Effect values
|
|
753
|
+
Make extends { readonly effect: (_: any) => Generator<Effect.Effect<any, any, never>, any> } ? never
|
|
754
|
+
: Make extends { readonly effect: (_: any) => Generator<Effect.Effect<any, any, infer R>, any> } ? R
|
|
585
755
|
: never
|
|
586
756
|
|
|
587
757
|
export type MakeHandlers<Make, _Handlers extends Record<string, any>> = /*Make extends
|
|
588
758
|
{ readonly effect: (_: any) => Effect.Effect<{ [K in keyof Handlers]: AnyHandler<Handlers[K]> }, any, any> }
|
|
589
759
|
? Effect.Success<ReturnType<Make["effect"]>>
|
|
590
760
|
: */
|
|
591
|
-
Make extends { readonly effect: (_: any) => Generator<any, infer S
|
|
761
|
+
Make extends { readonly effect: (_: any) => Generator<any, infer S> } ? S
|
|
592
762
|
: never
|
|
593
763
|
|
|
594
764
|
export type MakeDepsE<Make> = Layer.Error<MakeDeps<Make>>
|