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