effect-app 3.15.1 → 4.0.0-beta.0
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 +12 -0
- package/dist/Array.js +1 -1
- package/dist/Chunk.d.ts +2 -4
- package/dist/Chunk.d.ts.map +1 -1
- package/dist/Chunk.js +2 -2
- package/dist/Config/SecretURL.d.ts +2 -12
- package/dist/Config/SecretURL.d.ts.map +1 -1
- package/dist/Config/SecretURL.js +2 -4
- package/dist/Config/internal/configSecretURL.d.ts.map +1 -1
- package/dist/Config/internal/configSecretURL.js +3 -4
- package/dist/Effect.d.ts +12 -10
- package/dist/Effect.d.ts.map +1 -1
- package/dist/Effect.js +6 -15
- package/dist/Layer.d.ts +15 -9
- package/dist/Layer.d.ts.map +1 -1
- package/dist/Layer.js +2 -2
- package/dist/Operations.d.ts +37 -47
- package/dist/Operations.d.ts.map +1 -1
- package/dist/Option.js +3 -3
- package/dist/Pure.d.ts +17 -6
- package/dist/Pure.d.ts.map +1 -1
- package/dist/Pure.js +35 -17
- package/dist/Schema/Class.d.ts +13 -16
- package/dist/Schema/Class.d.ts.map +1 -1
- package/dist/Schema/Class.js +5 -27
- package/dist/Schema/brand.d.ts +7 -10
- package/dist/Schema/brand.d.ts.map +1 -1
- package/dist/Schema/brand.js +3 -2
- package/dist/Schema/email.d.ts +1 -1
- package/dist/Schema/email.d.ts.map +1 -1
- package/dist/Schema/email.js +2 -2
- package/dist/Schema/ext.d.ts +42 -45
- package/dist/Schema/ext.d.ts.map +1 -1
- package/dist/Schema/ext.js +49 -63
- package/dist/Schema/moreStrings.d.ts +17 -17
- package/dist/Schema/moreStrings.d.ts.map +1 -1
- package/dist/Schema/moreStrings.js +10 -10
- package/dist/Schema/numbers.d.ts +14 -14
- package/dist/Schema/numbers.js +5 -5
- package/dist/Schema/phoneNumber.d.ts +1 -1
- package/dist/Schema/phoneNumber.d.ts.map +1 -1
- package/dist/Schema/phoneNumber.js +2 -2
- package/dist/Schema/schema.d.ts +2 -3
- package/dist/Schema/schema.d.ts.map +1 -1
- package/dist/Schema/schema.js +3 -4
- package/dist/Schema/strings.d.ts +4 -4
- package/dist/Schema/strings.d.ts.map +1 -1
- package/dist/Schema/strings.js +4 -4
- package/dist/Schema.d.ts +27 -25
- package/dist/Schema.d.ts.map +1 -1
- package/dist/Schema.js +22 -21
- package/dist/ServiceMap.d.ts +44 -0
- package/dist/ServiceMap.d.ts.map +1 -0
- package/dist/ServiceMap.js +91 -0
- package/dist/Set.d.ts +4 -4
- package/dist/Set.d.ts.map +1 -1
- package/dist/Set.js +14 -14
- package/dist/Struct.d.ts +4 -4
- package/dist/Struct.d.ts.map +1 -1
- package/dist/_ext/Array.d.ts.map +1 -1
- package/dist/_ext/Array.js +4 -4
- package/dist/_ext/misc.d.ts +2 -2
- package/dist/_ext/misc.js +4 -4
- package/dist/_ext/ord.ext.js +2 -2
- package/dist/builtin.d.ts +0 -8
- package/dist/builtin.d.ts.map +1 -1
- package/dist/builtin.js +3 -1
- package/dist/client/apiClientFactory.d.ts +14 -16
- package/dist/client/apiClientFactory.d.ts.map +1 -1
- package/dist/client/apiClientFactory.js +38 -23
- package/dist/client/clientFor.d.ts +7 -4
- package/dist/client/clientFor.d.ts.map +1 -1
- package/dist/client/errors.d.ts +36 -48
- package/dist/client/errors.d.ts.map +1 -1
- package/dist/client/errors.js +19 -9
- package/dist/client/makeClient.d.ts +34 -50
- package/dist/client/makeClient.d.ts.map +1 -1
- package/dist/client/makeClient.js +28 -18
- package/dist/http/Request.d.ts +3 -3
- package/dist/http/Request.d.ts.map +1 -1
- package/dist/http/Request.js +5 -8
- package/dist/http/internal/lib.d.ts +12 -13
- package/dist/http/internal/lib.d.ts.map +1 -1
- package/dist/http/internal/lib.js +14 -14
- package/dist/ids.d.ts +9 -9
- package/dist/ids.d.ts.map +1 -1
- package/dist/ids.js +1 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -2
- package/dist/logger.d.ts +1 -1
- package/dist/middleware.d.ts +2 -2
- package/dist/middleware.d.ts.map +1 -1
- package/dist/middleware.js +3 -3
- package/dist/rpc/MiddlewareMaker.d.ts +17 -16
- package/dist/rpc/MiddlewareMaker.d.ts.map +1 -1
- package/dist/rpc/MiddlewareMaker.js +27 -18
- package/dist/rpc/RpcContextMap.d.ts +4 -4
- package/dist/rpc/RpcContextMap.d.ts.map +1 -1
- package/dist/rpc/RpcContextMap.js +4 -4
- package/dist/rpc/RpcMiddleware.d.ts +24 -40
- package/dist/rpc/RpcMiddleware.d.ts.map +1 -1
- package/dist/rpc/RpcMiddleware.js +3 -10
- package/dist/utils/effectify.js +2 -2
- package/dist/utils/gen.d.ts +4 -5
- package/dist/utils/gen.d.ts.map +1 -1
- package/dist/utils/logLevel.d.ts +1 -1
- package/dist/utils/logLevel.d.ts.map +1 -1
- package/dist/utils/logLevel.js +6 -7
- package/dist/utils/logger.d.ts +4 -3
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +10 -9
- package/dist/utils.d.ts +4 -5
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +10 -9
- package/package.json +16 -25
- package/src/Array.ts +1 -1
- package/src/Chunk.ts +2 -2
- package/src/Config/SecretURL.ts +3 -18
- package/src/Config/internal/configSecretURL.ts +2 -3
- package/src/Effect.ts +17 -37
- package/src/Layer.ts +16 -11
- package/src/Option.ts +2 -2
- package/src/Pure.ts +60 -26
- package/src/Schema/Class.ts +17 -73
- package/src/Schema/brand.ts +11 -12
- package/src/Schema/email.ts +2 -2
- package/src/Schema/ext.ts +114 -167
- package/src/Schema/moreStrings.ts +20 -23
- package/src/Schema/numbers.ts +4 -4
- package/src/Schema/phoneNumber.ts +2 -2
- package/src/Schema/schema.ts +2 -3
- package/src/Schema/strings.ts +3 -3
- package/src/Schema.ts +49 -47
- package/src/ServiceMap.ts +187 -0
- package/src/Set.ts +19 -19
- package/src/Struct.ts +4 -4
- package/src/_ext/Array.ts +4 -5
- package/src/_ext/misc.ts +4 -4
- package/src/_ext/ord.ext.ts +2 -2
- package/src/builtin.ts +2 -8
- package/src/client/apiClientFactory.ts +74 -59
- package/src/client/clientFor.ts +10 -7
- package/src/client/errors.ts +28 -22
- package/src/client/makeClient.ts +75 -100
- package/src/http/Request.ts +5 -8
- package/src/http/internal/lib.ts +13 -13
- package/src/ids.ts +1 -1
- package/src/index.ts +10 -1
- package/src/middleware.ts +2 -2
- package/src/rpc/MiddlewareMaker.ts +76 -47
- package/src/rpc/RpcContextMap.ts +7 -7
- package/src/rpc/RpcMiddleware.ts +28 -54
- package/src/utils/effectify.ts +1 -1
- package/src/utils/gen.ts +8 -6
- package/src/utils/logLevel.ts +6 -6
- package/src/utils/logger.ts +15 -20
- package/src/utils.ts +12 -12
- package/test/dist/rpc.test.d.ts.map +1 -1
- package/test/schema.test.ts +8 -8
- package/test/utils.test.ts +2 -2
- package/tsconfig.json +1 -25
- package/dist/Context.d.ts +0 -67
- package/dist/Context.d.ts.map +0 -1
- package/dist/Context.js +0 -207
- package/dist/Tag.d.ts +0 -6
- package/dist/Tag.d.ts.map +0 -1
- package/dist/Tag.js +0 -9
- package/dist/Unify.d.ts +0 -27
- package/dist/Unify.d.ts.map +0 -1
- package/dist/Unify.js +0 -15
- package/src/Context.ts +0 -351
- package/src/Tag.ts +0 -11
- package/src/Unify.ts +0 -40
package/src/http/Request.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import type { HttpClientResponse } from "
|
|
1
|
+
import type { HttpClientResponse } from "effect/unstable/http/HttpClientResponse"
|
|
2
2
|
import * as Effect from "../Effect.js"
|
|
3
|
-
import * as Option from "../Option.js"
|
|
4
3
|
import { HttpClient, HttpClientError, HttpClientRequest, HttpHeaders } from "./internal/lib.js"
|
|
5
4
|
|
|
6
5
|
export interface ResponseWithBody<A> extends Pick<HttpClientResponse, "headers" | "status" | "remoteAddress"> {
|
|
@@ -25,18 +24,16 @@ export const demandJson = (client: HttpClient.HttpClient) =>
|
|
|
25
24
|
.mapRequest(client, (_) => HttpClientRequest.acceptJson(_))
|
|
26
25
|
.pipe(HttpClient.transform((r, request) =>
|
|
27
26
|
Effect.tap(r, (response) =>
|
|
28
|
-
|
|
29
|
-
.
|
|
30
|
-
.get(response.headers, "Content-Type"))
|
|
27
|
+
HttpHeaders
|
|
28
|
+
.get(response.headers, "Content-Type")
|
|
31
29
|
?.startsWith("application/json")
|
|
32
30
|
? Effect.void
|
|
33
31
|
: Effect.fail(
|
|
34
|
-
new HttpClientError.
|
|
32
|
+
new HttpClientError.DecodeError({
|
|
35
33
|
request,
|
|
36
34
|
response,
|
|
37
|
-
reason: "Decode",
|
|
38
35
|
description: "not json response: "
|
|
39
|
-
+
|
|
36
|
+
+ HttpHeaders.get(response.headers, "Content-Type")
|
|
40
37
|
})
|
|
41
38
|
))
|
|
42
39
|
))
|
package/src/http/internal/lib.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
export * as HttpHeaders from "
|
|
2
|
-
export * as HttpBody from "
|
|
3
|
-
export * as HttpClient from "
|
|
4
|
-
export * as HttpClientError from "
|
|
5
|
-
export * as HttpClientRequest from "
|
|
6
|
-
export * as HttpClientResponse from "
|
|
7
|
-
|
|
8
|
-
export * as HttpMiddleware from "
|
|
9
|
-
export * as HttpRouter from "
|
|
10
|
-
export * as HttpServer from "
|
|
11
|
-
export * as HttpServerError from "
|
|
12
|
-
export * as HttpServerRequest from "
|
|
13
|
-
export * as HttpServerResponse from "
|
|
1
|
+
export * as HttpHeaders from "effect/unstable/http/Headers"
|
|
2
|
+
export * as HttpBody from "effect/unstable/http/HttpBody"
|
|
3
|
+
export * as HttpClient from "effect/unstable/http/HttpClient"
|
|
4
|
+
export * as HttpClientError from "effect/unstable/http/HttpClientError"
|
|
5
|
+
export * as HttpClientRequest from "effect/unstable/http/HttpClientRequest"
|
|
6
|
+
export * as HttpClientResponse from "effect/unstable/http/HttpClientResponse"
|
|
7
|
+
// HttpLayerRouter removed in v4 — use HttpRouter instead
|
|
8
|
+
export * as HttpMiddleware from "effect/unstable/http/HttpMiddleware"
|
|
9
|
+
export * as HttpRouter from "effect/unstable/http/HttpRouter"
|
|
10
|
+
export * as HttpServer from "effect/unstable/http/HttpServer"
|
|
11
|
+
export * as HttpServerError from "effect/unstable/http/HttpServerError"
|
|
12
|
+
export * as HttpServerRequest from "effect/unstable/http/HttpServerRequest"
|
|
13
|
+
export * as HttpServerResponse from "effect/unstable/http/HttpServerResponse"
|
package/src/ids.ts
CHANGED
|
@@ -12,7 +12,7 @@ export type RequestId = NonEmptyString255
|
|
|
12
12
|
// a request id may be made from a span id, which does not comply with StringId schema.
|
|
13
13
|
export const RequestId = extendM(
|
|
14
14
|
Object
|
|
15
|
-
.assign(Object.create(NonEmptyString255) as {}, NonEmptyString255 as Schema<NonEmptyString255
|
|
15
|
+
.assign(Object.create(NonEmptyString255) as {}, NonEmptyString255 as unknown as Schema<NonEmptyString255>),
|
|
16
16
|
(s) => {
|
|
17
17
|
const make = StringId.make as () => NonEmptyString255
|
|
18
18
|
return ({
|
package/src/index.ts
CHANGED
|
@@ -1,15 +1,24 @@
|
|
|
1
1
|
import "./builtin.js"
|
|
2
2
|
|
|
3
|
+
import * as ServiceMap from "./ServiceMap.js"
|
|
4
|
+
|
|
3
5
|
export * as Fnc from "./Function.js"
|
|
4
6
|
export * as Utils from "./utils.js"
|
|
5
7
|
|
|
6
8
|
export * as Array from "./Array.js"
|
|
7
|
-
export * as Context from "./Context.js"
|
|
8
9
|
export * as Effect from "./Effect.js"
|
|
9
10
|
export * as Layer from "./Layer.js"
|
|
10
11
|
export * as NonEmptySet from "./NonEmptySet.js"
|
|
12
|
+
export * as ServiceMap from "./ServiceMap.js"
|
|
11
13
|
export * as Set from "./Set.js"
|
|
12
14
|
|
|
15
|
+
export {
|
|
16
|
+
/**
|
|
17
|
+
* @deprecated use ServiceMap directly instead
|
|
18
|
+
*/
|
|
19
|
+
ServiceMap as Context
|
|
20
|
+
}
|
|
21
|
+
|
|
13
22
|
export { type NonEmptyArray, type NonEmptyReadonlyArray } from "./Array.js"
|
|
14
23
|
|
|
15
24
|
export * from "effect"
|
package/src/middleware.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
-
import {
|
|
2
|
+
import { ServiceMap } from "effect-app"
|
|
3
3
|
import { RpcX } from "./rpc.js"
|
|
4
4
|
|
|
5
|
-
export class DevMode extends
|
|
5
|
+
export class DevMode extends ServiceMap.Reference("DevMode", { defaultValue: () => false }) {}
|
|
6
6
|
|
|
7
7
|
export class RequestCacheMiddleware
|
|
8
8
|
extends RpcX.RpcMiddleware.Tag<RequestCacheMiddleware>()("RequestCacheMiddleware")
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
-
import {
|
|
3
|
-
import { type HandlersFrom } from "@effect/rpc/RpcGroup"
|
|
4
|
-
import { Context, Effect, Layer, type Schema, Schema as S, type Scope } from "effect"
|
|
2
|
+
import { Effect, Layer, type Schema, Schema as S, type Scope, ServiceMap } from "effect"
|
|
5
3
|
import { type NonEmptyArray, type NonEmptyReadonlyArray } from "effect/Array"
|
|
6
4
|
import { type Simplify } from "effect/Types"
|
|
5
|
+
import { Rpc, type RpcGroup, type RpcSchema } from "effect/unstable/rpc"
|
|
6
|
+
import { type HandlersFrom } from "effect/unstable/rpc/RpcGroup"
|
|
7
|
+
import { type RequestId } from "effect/unstable/rpc/RpcMessage"
|
|
8
|
+
import { type HttpHeaders } from "../http.js"
|
|
7
9
|
import { PreludeLogger } from "../logger.js"
|
|
8
10
|
import { type TypeTestId } from "../TypeTest.js"
|
|
9
11
|
import { typedValuesOf } from "../utils.js"
|
|
@@ -11,8 +13,8 @@ import { type GetContextConfig, type RequestContextMapTagAny, type RpcContextMap
|
|
|
11
13
|
import { type AddMiddleware, type AnyDynamic, type RpcDynamic, type RpcMiddlewareV4, type TagClassAny } from "./RpcMiddleware.js"
|
|
12
14
|
import * as RpcMiddlewareX from "./RpcMiddleware.js"
|
|
13
15
|
|
|
14
|
-
// adapter for effect/rpc v3 middleware provides. (in effect-smol (v4), it's
|
|
15
|
-
type MakeTags<A> =
|
|
16
|
+
// adapter for effect/rpc v3 middleware provides. (in effect-smol (v4), it's just a Service Identifier, no tags.)
|
|
17
|
+
type MakeTags<A> = ServiceMap.Service<A, A>
|
|
16
18
|
|
|
17
19
|
export interface MiddlewareMaker<
|
|
18
20
|
Self,
|
|
@@ -20,11 +22,10 @@ export interface MiddlewareMaker<
|
|
|
20
22
|
RequestContextMap extends Record<string, RpcContextMap.Any>,
|
|
21
23
|
MiddlewareProviders extends ReadonlyArray<MiddlewareMaker.Any>
|
|
22
24
|
> extends
|
|
23
|
-
|
|
25
|
+
RpcMiddlewareX.TagClass<
|
|
24
26
|
Self,
|
|
25
27
|
Id,
|
|
26
28
|
Simplify<
|
|
27
|
-
& { readonly wrap: true }
|
|
28
29
|
& (Exclude<
|
|
29
30
|
MiddlewareMaker.ManyRequired<MiddlewareProviders>,
|
|
30
31
|
MiddlewareMaker.ManyProvided<MiddlewareProviders>
|
|
@@ -38,20 +39,34 @@ export interface MiddlewareMaker<
|
|
|
38
39
|
})
|
|
39
40
|
& (MiddlewareMaker.ManyErrors<MiddlewareProviders> extends never ? {}
|
|
40
41
|
: {
|
|
41
|
-
readonly
|
|
42
|
+
readonly error: S.Schema<MiddlewareMaker.ManyErrors<MiddlewareProviders>>
|
|
42
43
|
})
|
|
43
44
|
& (MiddlewareMaker.ManyProvided<MiddlewareProviders> extends never ? {}
|
|
44
45
|
: { readonly provides: MakeTags<MiddlewareMaker.ManyProvided<MiddlewareProviders>> })
|
|
45
|
-
|
|
46
|
+
>,
|
|
47
|
+
{
|
|
48
|
+
provides: MiddlewareMaker.ManyProvided<MiddlewareProviders> extends never ? never
|
|
49
|
+
: MakeTags<MiddlewareMaker.ManyProvided<MiddlewareProviders>>
|
|
50
|
+
requires: Exclude<
|
|
51
|
+
MiddlewareMaker.ManyRequired<MiddlewareProviders>,
|
|
52
|
+
MiddlewareMaker.ManyProvided<MiddlewareProviders>
|
|
53
|
+
> extends never ? never
|
|
54
|
+
: MakeTags<
|
|
55
|
+
Exclude<
|
|
56
|
+
MiddlewareMaker.ManyRequired<MiddlewareProviders>,
|
|
57
|
+
MiddlewareMaker.ManyProvided<MiddlewareProviders>
|
|
58
|
+
>
|
|
59
|
+
>
|
|
60
|
+
}
|
|
46
61
|
>
|
|
47
62
|
{
|
|
48
|
-
readonly layer: Layer.Layer<Self, never,
|
|
63
|
+
readonly layer: Layer.Layer<Self, never, ServiceMap.Service.Identifier<MiddlewareProviders[number]>>
|
|
49
64
|
readonly requestContext: RequestContextTag<RequestContextMap>
|
|
50
65
|
readonly requestContextMap: RequestContextMap
|
|
51
66
|
}
|
|
52
67
|
|
|
53
68
|
export interface RequestContextTag<RequestContextMap extends Record<string, RpcContextMap.Any>>
|
|
54
|
-
extends
|
|
69
|
+
extends ServiceMap.Service<"RequestContextConfig", GetContextConfig<RequestContextMap>>
|
|
55
70
|
{}
|
|
56
71
|
|
|
57
72
|
export namespace MiddlewareMaker {
|
|
@@ -77,7 +92,7 @@ export namespace MiddlewareMaker {
|
|
|
77
92
|
: never
|
|
78
93
|
: never
|
|
79
94
|
|
|
80
|
-
export type Errors<T> = T extends TagClassAny ? T extends {
|
|
95
|
+
export type Errors<T> = T extends TagClassAny ? T extends { error: S.Top } ? S.Schema.Type<T["error"]>
|
|
81
96
|
: never
|
|
82
97
|
: never
|
|
83
98
|
|
|
@@ -153,9 +168,9 @@ export interface BuildingMiddleware<
|
|
|
153
168
|
> {
|
|
154
169
|
rpc: <
|
|
155
170
|
const Tag extends string,
|
|
156
|
-
Payload extends Schema.
|
|
157
|
-
Success extends Schema.
|
|
158
|
-
Error extends Schema.
|
|
171
|
+
Payload extends Schema.Top | Schema.Struct.Fields = typeof Schema.Void,
|
|
172
|
+
Success extends Schema.Top = typeof Schema.Void,
|
|
173
|
+
Error extends Schema.Top = typeof Schema.Never,
|
|
159
174
|
const Stream extends boolean = false,
|
|
160
175
|
Config extends GetContextConfig<RequestContextMap> = {}
|
|
161
176
|
>(tag: Tag, options?: {
|
|
@@ -164,8 +179,9 @@ export interface BuildingMiddleware<
|
|
|
164
179
|
readonly error?: Error
|
|
165
180
|
readonly stream?: Stream
|
|
166
181
|
readonly config?: Config
|
|
167
|
-
readonly primaryKey?: [Payload] extends [Schema.Struct.Fields]
|
|
168
|
-
|
|
182
|
+
readonly primaryKey?: [Payload] extends [Schema.Struct.Fields] ? ((
|
|
183
|
+
payload: Payload extends Schema.Struct.Fields ? Simplify<Schema.Struct<Payload>["Type"]> : Payload["Type"]
|
|
184
|
+
) => string)
|
|
169
185
|
: never
|
|
170
186
|
}) =>
|
|
171
187
|
& Rpc.Rpc<
|
|
@@ -258,29 +274,31 @@ const middlewareMaker = <
|
|
|
258
274
|
middlewares = middlewares.toReversed() as any
|
|
259
275
|
|
|
260
276
|
return Effect.gen(function*() {
|
|
261
|
-
const context = yield* Effect.
|
|
277
|
+
const context = yield* Effect.services()
|
|
262
278
|
|
|
263
279
|
// returns a Effect/RpcMiddlewareV4 with Scope.Scope in requirements
|
|
280
|
+
// v4: wrap middleware takes (effect, options) as two params instead of a single options bag
|
|
264
281
|
return (
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
282
|
+
next: Effect.Effect<any, any, any>,
|
|
283
|
+
options: {
|
|
284
|
+
readonly clientId: number
|
|
285
|
+
readonly requestId: RequestId
|
|
286
|
+
readonly rpc: Rpc.AnyWithProps
|
|
287
|
+
readonly payload: unknown
|
|
288
|
+
readonly headers: HttpHeaders.Headers
|
|
289
|
+
}
|
|
271
290
|
) => {
|
|
272
|
-
const { next, ...options } = _options
|
|
273
291
|
// we start with the actual handler
|
|
274
292
|
let handler = next
|
|
275
293
|
|
|
276
294
|
// inspired from Effect/RpcMiddleware
|
|
277
295
|
for (const tag of middlewares) {
|
|
278
296
|
// use the tag to get the middleware from context
|
|
279
|
-
const middleware =
|
|
297
|
+
const middleware = ServiceMap.getUnsafe(context, tag)
|
|
280
298
|
|
|
281
299
|
// wrap the current handler, allowing the middleware to run before and after it
|
|
282
300
|
handler = PreludeLogger.logDebug("Applying middleware wrap " + tag.key).pipe(
|
|
283
|
-
Effect.
|
|
301
|
+
Effect.andThen(middleware(handler, options))
|
|
284
302
|
) as any
|
|
285
303
|
}
|
|
286
304
|
return handler
|
|
@@ -302,15 +320,17 @@ const makeMiddlewareBasic = <Self>() =>
|
|
|
302
320
|
// reverse middlewares and wrap one after the other
|
|
303
321
|
const middleware = middlewareMaker(make)
|
|
304
322
|
|
|
305
|
-
const failures = make.map((_) => _.
|
|
323
|
+
const failures = make.map((_) => _.error).filter(Boolean)
|
|
306
324
|
const provides = make.flatMap((_) => !_.provides ? [] : Array.isArray(_.provides) ? _.provides : [_.provides])
|
|
307
325
|
const requires = make
|
|
308
326
|
.flatMap((_) => !_.requires ? [] : Array.isArray(_.requires) ? _.requires : [_.requires])
|
|
309
327
|
.filter((_) => !provides.includes(_))
|
|
310
328
|
|
|
329
|
+
const [firstFailure, ...restFailures] = failures
|
|
330
|
+
|
|
311
331
|
const MiddlewareMaker = RpcMiddlewareX.Tag<Self>()(id, {
|
|
312
|
-
|
|
313
|
-
? S.Union(...
|
|
332
|
+
error: (firstFailure
|
|
333
|
+
? S.Union([firstFailure, ...restFailures])
|
|
314
334
|
: S.Never) as unknown as MiddlewareMaker.ManyErrors<MiddlewareProviders> extends never ? never
|
|
315
335
|
: S.Schema<MiddlewareMaker.ManyErrors<MiddlewareProviders>>,
|
|
316
336
|
requires: (requires.length > 0
|
|
@@ -329,17 +349,16 @@ const makeMiddlewareBasic = <Self>() =>
|
|
|
329
349
|
provides: (provides.length > 0
|
|
330
350
|
? provides
|
|
331
351
|
: undefined) as unknown as MiddlewareMaker.ManyProvided<MiddlewareProviders> extends never ? never
|
|
332
|
-
: MakeTags<MiddlewareMaker.ManyProvided<MiddlewareProviders
|
|
333
|
-
wrap: true
|
|
352
|
+
: MakeTags<MiddlewareMaker.ManyProvided<MiddlewareProviders>>
|
|
334
353
|
})
|
|
335
354
|
|
|
336
355
|
const layer = Layer
|
|
337
|
-
.
|
|
356
|
+
.effect(
|
|
338
357
|
MiddlewareMaker,
|
|
339
358
|
middleware as Effect.Effect<
|
|
340
|
-
any,
|
|
341
|
-
Effect.
|
|
342
|
-
Effect.
|
|
359
|
+
any,
|
|
360
|
+
Effect.Error<typeof middleware>,
|
|
361
|
+
Effect.Services<typeof middleware>
|
|
343
362
|
>
|
|
344
363
|
)
|
|
345
364
|
|
|
@@ -347,7 +366,7 @@ const makeMiddlewareBasic = <Self>() =>
|
|
|
347
366
|
return Object.assign(MiddlewareMaker, {
|
|
348
367
|
layer,
|
|
349
368
|
// tag to be used to retrieve the RequestContextConfig from Rpc annotations
|
|
350
|
-
requestContext:
|
|
369
|
+
requestContext: ServiceMap.Service<"RequestContextConfig", GetContextConfig<RequestContextMap>>(
|
|
351
370
|
"RequestContextConfig"
|
|
352
371
|
),
|
|
353
372
|
requestContextMap: rcm
|
|
@@ -360,7 +379,7 @@ export const Tag = <Self>() =>
|
|
|
360
379
|
RequestContextMap extends RequestContextMapTagAny
|
|
361
380
|
>(id: Id, rcm: RequestContextMap): MiddlewaresBuilder<Self, Id, RequestContextMap["config"]> => {
|
|
362
381
|
let allMiddleware: MiddlewareMaker.Any[] = []
|
|
363
|
-
const requestContext =
|
|
382
|
+
const requestContext = ServiceMap.Service<"RequestContextConfig", GetContextConfig<RequestContextMap["config"]>>(
|
|
364
383
|
"RequestContextConfig"
|
|
365
384
|
)
|
|
366
385
|
const it = {
|
|
@@ -368,9 +387,9 @@ export const Tag = <Self>() =>
|
|
|
368
387
|
// rpc with config
|
|
369
388
|
rpc: <
|
|
370
389
|
const Tag extends string,
|
|
371
|
-
Payload extends Schema.
|
|
372
|
-
Success extends Schema.
|
|
373
|
-
Error extends Schema.
|
|
390
|
+
Payload extends Schema.Top | Schema.Struct.Fields = typeof Schema.Void,
|
|
391
|
+
Success extends Schema.Top = typeof Schema.Void,
|
|
392
|
+
Error extends Schema.Top = typeof Schema.Never,
|
|
374
393
|
const Stream extends boolean = false,
|
|
375
394
|
Config extends GetContextConfig<RequestContextMap["config"]> = {}
|
|
376
395
|
>(tag: Tag, options?: {
|
|
@@ -379,8 +398,9 @@ export const Tag = <Self>() =>
|
|
|
379
398
|
readonly error?: Error
|
|
380
399
|
readonly stream?: Stream
|
|
381
400
|
readonly config?: Config
|
|
382
|
-
readonly primaryKey?: [Payload] extends [Schema.Struct.Fields]
|
|
383
|
-
|
|
401
|
+
readonly primaryKey?: [Payload] extends [Schema.Struct.Fields] ? ((
|
|
402
|
+
payload: Payload extends Schema.Struct.Fields ? Simplify<Schema.Struct<Payload>["Type"]> : Payload["Type"]
|
|
403
|
+
) => string)
|
|
384
404
|
: never
|
|
385
405
|
}):
|
|
386
406
|
& Rpc.Rpc<
|
|
@@ -398,9 +418,18 @@ export const Tag = <Self>() =>
|
|
|
398
418
|
// TODO: we should only include errors that are relevant based on the middleware config.ks
|
|
399
419
|
const error = options?.error
|
|
400
420
|
const errors = typedValuesOf(rcm.config).map((_) => _.error).filter((_) => _ && _ !== S.Never) // TODO: only the errors relevant based on config
|
|
401
|
-
const
|
|
402
|
-
|
|
403
|
-
const
|
|
421
|
+
const allErrors = error ? [error, ...errors] : errors
|
|
422
|
+
const [firstError, ...restErrors] = allErrors
|
|
423
|
+
const newError = firstError ? S.Union([firstError, ...restErrors]) : S.Never
|
|
424
|
+
|
|
425
|
+
// @ts-expect-error — TypeScript can't prove Simplify<T> ≡ { [K in keyof T]: T[K] } for unresolved generics (primaryKey)
|
|
426
|
+
const rpc = Rpc.make(tag, {
|
|
427
|
+
...options?.payload !== undefined ? { payload: options.payload } : {},
|
|
428
|
+
...options?.success !== undefined ? { success: options.success } : {},
|
|
429
|
+
error: newError,
|
|
430
|
+
...options?.stream !== undefined ? { stream: options.stream } : {},
|
|
431
|
+
...options?.primaryKey !== undefined ? { primaryKey: options.primaryKey } : {}
|
|
432
|
+
}) as any
|
|
404
433
|
|
|
405
434
|
return Object.assign(rpc.annotate(requestContext, config), { config })
|
|
406
435
|
},
|
|
@@ -422,7 +451,7 @@ export const Tag = <Self>() =>
|
|
|
422
451
|
// alternatively consider group.serverMiddleware? hmmm
|
|
423
452
|
export const middlewareGroup = <
|
|
424
453
|
RequestContextMap extends Record<string, RpcContextMap.Any>,
|
|
425
|
-
Middleware extends
|
|
454
|
+
Middleware extends RpcMiddlewareX.TagClassAny & {
|
|
426
455
|
readonly requestContext: RequestContextTag<RequestContextMap>
|
|
427
456
|
readonly requestContextMap: RequestContextMap
|
|
428
457
|
}
|
package/src/rpc/RpcContextMap.ts
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
|
3
3
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
4
4
|
|
|
5
|
-
import { type
|
|
6
|
-
import {
|
|
5
|
+
import { type Schema as S, ServiceMap } from "effect"
|
|
6
|
+
import { type AnyWithProps } from "effect/unstable/rpc/Rpc"
|
|
7
7
|
import { type RpcDynamic } from "./RpcMiddleware.js"
|
|
8
8
|
|
|
9
9
|
type Values<T extends Record<any, any>> = T[keyof T]
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
|
-
* Middleware is inactivate by default, the Key is optional in route context, and the service is optionally provided as Effect
|
|
12
|
+
* Middleware is inactivate by default, the Key is optional in route context, and the service is optionally provided as Effect ServiceMap.
|
|
13
13
|
* Unless explicitly configured as `true`.
|
|
14
14
|
*/
|
|
15
15
|
export type RpcContextMap<Service, E> = {
|
|
@@ -22,7 +22,7 @@ export type RpcContextMap<Service, E> = {
|
|
|
22
22
|
|
|
23
23
|
export declare namespace RpcContextMap {
|
|
24
24
|
/**
|
|
25
|
-
* Middleware is active by default, and provides the Service at Key in route context, and the Service is provided as Effect
|
|
25
|
+
* Middleware is active by default, and provides the Service at Key in route context, and the Service is provided as Effect ServiceMap.
|
|
26
26
|
* Unless explicitly omitted.
|
|
27
27
|
*/
|
|
28
28
|
export type Inverted<Service, E> = {
|
|
@@ -41,7 +41,7 @@ export declare namespace RpcContextMap {
|
|
|
41
41
|
|
|
42
42
|
export type Any = {
|
|
43
43
|
service: any
|
|
44
|
-
error: S.
|
|
44
|
+
error: S.Top
|
|
45
45
|
contextActivation: any
|
|
46
46
|
inverted: boolean
|
|
47
47
|
}
|
|
@@ -97,7 +97,7 @@ export type GetEffectError<RequestContextMap extends Record<string, RpcContextMa
|
|
|
97
97
|
}
|
|
98
98
|
>
|
|
99
99
|
|
|
100
|
-
const tag =
|
|
100
|
+
const tag = ServiceMap.Service("RequestContextConfig")
|
|
101
101
|
|
|
102
102
|
export const makeMap = <const Config extends Record<string, RpcContextMap.Any>>(config: Config) => {
|
|
103
103
|
const cls = class {
|
|
@@ -109,7 +109,7 @@ export const makeMap = <const Config extends Record<string, RpcContextMap.Any>>(
|
|
|
109
109
|
return Object.assign(cls, {
|
|
110
110
|
config, /** Retrieves RequestContextConfig out of the Rpc annotations */
|
|
111
111
|
getConfig: (rpc: AnyWithProps): GetContextConfig<Config> => {
|
|
112
|
-
return
|
|
112
|
+
return ServiceMap.getOrElse(rpc.annotations, tag as any, () => ({}))
|
|
113
113
|
},
|
|
114
114
|
/** Adapter used when setting the dynamic prop on a middleware implementation */
|
|
115
115
|
get: <
|
package/src/rpc/RpcMiddleware.ts
CHANGED
|
@@ -1,28 +1,17 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
|
3
3
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
4
|
-
import { type
|
|
5
|
-
import { type SuccessValue, type TypeId } from "@effect/rpc/RpcMiddleware"
|
|
6
|
-
import { type Context, type Effect, type Schema, type Schema as S, type Scope, type Stream, Unify } from "effect"
|
|
7
|
-
import { type HttpHeaders } from "effect-app/http"
|
|
4
|
+
import { type Effect, type Schema, type Schema as S, type Scope, type ServiceMap, type Stream } from "effect"
|
|
8
5
|
import { type NonEmptyReadonlyArray } from "effect/Array"
|
|
9
|
-
import { type
|
|
10
|
-
import { type
|
|
6
|
+
import { type Rpc, RpcMiddleware } from "effect/unstable/rpc"
|
|
7
|
+
import { type TypeId } from "effect/unstable/rpc/RpcMiddleware"
|
|
11
8
|
import { type GetEffectContext, type RpcContextMap } from "./RpcContextMap.js"
|
|
12
9
|
|
|
13
|
-
|
|
14
|
-
export interface RpcMiddlewareV4<Provides, E, Requires> {
|
|
15
|
-
(effect: Effect.Effect<SuccessValue, E, Provides | Scope.Scope | Requires>, options: {
|
|
16
|
-
readonly clientId: number
|
|
17
|
-
readonly rpc: Rpc.AnyWithProps
|
|
18
|
-
readonly payload: unknown
|
|
19
|
-
readonly headers: HttpHeaders.Headers
|
|
20
|
-
}): Effect.Effect<SuccessValue, E, Scope.Scope | Requires>
|
|
21
|
-
}
|
|
10
|
+
export type RpcMiddlewareV4<Provides, E, Requires> = RpcMiddleware.RpcMiddleware<Provides, E, Requires>
|
|
22
11
|
|
|
23
12
|
export type RpcOptionsOriginal = {
|
|
24
13
|
readonly optional?: boolean
|
|
25
|
-
readonly
|
|
14
|
+
readonly error?: Schema.Top
|
|
26
15
|
readonly requiredForClient?: boolean
|
|
27
16
|
}
|
|
28
17
|
|
|
@@ -44,27 +33,13 @@ export interface RpcOptionsDynamic<Key extends string, A extends RpcContextMap.A
|
|
|
44
33
|
|
|
45
34
|
export type Dynamic<Options> = Options extends RpcOptionsDynamic<any, any> ? true : false
|
|
46
35
|
|
|
47
|
-
export interface RpcMiddlewareDynamic<E, R, _Config> {
|
|
48
|
-
(effect: Effect.Effect<SuccessValue, E, Scope.Scope | R>, options: {
|
|
49
|
-
readonly clientId: number
|
|
50
|
-
readonly rpc: Rpc.AnyWithProps
|
|
51
|
-
readonly payload: unknown
|
|
52
|
-
readonly headers: HttpHeaders.Headers
|
|
53
|
-
}): Effect.Effect<
|
|
54
|
-
SuccessValue,
|
|
55
|
-
E,
|
|
56
|
-
Scope.Scope | R
|
|
57
|
-
>
|
|
58
|
-
}
|
|
36
|
+
export interface RpcMiddlewareDynamic<E, R, _Config> extends RpcMiddleware.RpcMiddleware<never, E, R> {}
|
|
59
37
|
|
|
60
|
-
export interface TagClassAny extends
|
|
61
|
-
readonly [TypeId]: TypeId
|
|
38
|
+
export interface TagClassAny extends RpcMiddleware.AnyService {
|
|
62
39
|
readonly optional: boolean
|
|
63
40
|
readonly provides: any
|
|
64
41
|
readonly requires: any
|
|
65
|
-
readonly
|
|
66
|
-
readonly requiredForClient: boolean
|
|
67
|
-
readonly wrap: true
|
|
42
|
+
readonly error: Schema.Top
|
|
68
43
|
readonly dynamic?: RpcDynamic<any, any> | undefined
|
|
69
44
|
readonly dependsOn?: NonEmptyReadonlyArray<AnyDynamic> | undefined
|
|
70
45
|
}
|
|
@@ -74,8 +49,8 @@ export declare namespace TagClass {
|
|
|
74
49
|
* @since 1.0.0
|
|
75
50
|
* @category models
|
|
76
51
|
*/
|
|
77
|
-
export type FailureSchema<Options> = Options extends
|
|
78
|
-
|
|
52
|
+
export type FailureSchema<Options> = Options extends { readonly error: Schema.Top; readonly optional?: false }
|
|
53
|
+
? Options["error"]
|
|
79
54
|
// actually not, the Failure depends on Dynamic Middleware Configuration!
|
|
80
55
|
// : Options extends { readonly dynamic: RpcDynamic<any, infer A> } ? A["error"]
|
|
81
56
|
: typeof Schema.Never
|
|
@@ -84,8 +59,8 @@ export declare namespace TagClass {
|
|
|
84
59
|
* @since 1.0.0
|
|
85
60
|
* @category models
|
|
86
61
|
*/
|
|
87
|
-
export type Failure<Options> = Options extends
|
|
88
|
-
|
|
62
|
+
export type Failure<Options> = Options extends { readonly error: Schema.Schema<infer _A>; readonly optional?: false }
|
|
63
|
+
? _A
|
|
89
64
|
// actually not, the Failure depends on Dynamic Middleware Configuration!
|
|
90
65
|
: Options extends { readonly dynamic: RpcDynamic<any, infer A> } ? S.Schema.Type<A["error"]>
|
|
91
66
|
: never
|
|
@@ -94,7 +69,7 @@ export declare namespace TagClass {
|
|
|
94
69
|
* @since 1.0.0
|
|
95
70
|
* @category models
|
|
96
71
|
*/
|
|
97
|
-
export type FailureContext<Options> = Schema.
|
|
72
|
+
export type FailureContext<Options> = Schema.Codec.DecodingServices<FailureSchema<Options>>
|
|
98
73
|
|
|
99
74
|
/**
|
|
100
75
|
* @since 1.0.0
|
|
@@ -127,18 +102,18 @@ export declare namespace TagClass {
|
|
|
127
102
|
requires?: any
|
|
128
103
|
provides?: any
|
|
129
104
|
}
|
|
130
|
-
> extends
|
|
131
|
-
new(_: never):
|
|
105
|
+
> extends ServiceMap.Service<Self, Service> {
|
|
106
|
+
new(_: never): ServiceMap.ServiceClass.Shape<Name, Service>
|
|
132
107
|
readonly [TypeId]: TypeId
|
|
133
108
|
readonly optional: Optional<Options>
|
|
134
|
-
readonly
|
|
109
|
+
readonly error: FailureSchema<Options>
|
|
110
|
+
readonly "~ClientError": Options extends { readonly clientError: infer CE } ? CE : never
|
|
135
111
|
readonly provides: "provides" extends keyof Config ? Config["provides"] : never
|
|
136
112
|
readonly requires: "requires" extends keyof Config ? Config["requires"] : never
|
|
137
113
|
readonly dynamic: Options extends RpcOptionsDynamic<any, any> ? Options["dynamic"]
|
|
138
114
|
: undefined
|
|
139
115
|
readonly dependsOn: Options extends DependsOn ? Options["dependsOn"] : undefined
|
|
140
116
|
readonly requiredForClient: RequiredForClient<Options>
|
|
141
|
-
readonly wrap: true
|
|
142
117
|
}
|
|
143
118
|
}
|
|
144
119
|
|
|
@@ -183,18 +158,15 @@ export const Tag = <
|
|
|
183
158
|
id: Name,
|
|
184
159
|
options?: Options
|
|
185
160
|
): TagClass<Self, Name, Options, Config> =>
|
|
186
|
-
class extends RpcMiddleware.
|
|
161
|
+
class extends RpcMiddleware.Service<Self>()(id, options as any) {
|
|
187
162
|
static readonly requires: "requires" extends keyof Config ? Config["requires"] : never
|
|
188
|
-
static
|
|
163
|
+
static readonly provides: "provides" extends keyof Config ? Config["provides"] : never
|
|
189
164
|
static readonly dynamic = options && "dynamic" in options ? options.dynamic : undefined
|
|
190
165
|
static readonly dependsOn = options && "dependsOn" in options ? options.dependsOn : undefined
|
|
191
|
-
static override [Unify.typeSymbol]?: unknown
|
|
192
|
-
static override [Unify.unifySymbol]?: TagUnify<typeof this>
|
|
193
|
-
static override [Unify.ignoreSymbol]?: TagUnifyIgnore
|
|
194
166
|
} as any
|
|
195
167
|
|
|
196
168
|
// not needed if there's official support in Rpc.Rpc.
|
|
197
|
-
export type AddMiddleware<R extends Rpc.Any, Middleware extends RpcMiddleware.
|
|
169
|
+
export type AddMiddleware<R extends Rpc.Any, Middleware extends RpcMiddleware.AnyServiceWithProps> = R extends Rpc.Rpc<
|
|
198
170
|
infer _Tag,
|
|
199
171
|
infer _Payload,
|
|
200
172
|
infer _Success,
|
|
@@ -221,13 +193,13 @@ export type HandlerContext<Rpcs extends Rpc.Any, K extends Rpcs["_tag"], Handler
|
|
|
221
193
|
| Stream.Stream<infer _A, infer _E, infer _R>
|
|
222
194
|
| Rpc.Wrapper<Stream.Stream<infer _A, infer _E, infer _R>>
|
|
223
195
|
| Effect.Effect<
|
|
224
|
-
|
|
196
|
+
infer _A,
|
|
225
197
|
infer _EX,
|
|
226
198
|
infer _R
|
|
227
199
|
>
|
|
228
200
|
| Rpc.Wrapper<
|
|
229
201
|
Effect.Effect<
|
|
230
|
-
|
|
202
|
+
infer _A,
|
|
231
203
|
infer _EX,
|
|
232
204
|
infer _R
|
|
233
205
|
>
|
|
@@ -241,7 +213,7 @@ export type HandlerContext<Rpcs extends Rpc.Any, K extends Rpcs["_tag"], Handler
|
|
|
241
213
|
|
|
242
214
|
// new
|
|
243
215
|
export type ExtractDynamicallyProvides<R extends Rpc.Any, Tag extends string> = R extends
|
|
244
|
-
Rpc.Rpc<Tag, infer _Payload, infer _Success, infer _Error, infer _Middleware> ? _Middleware extends {
|
|
216
|
+
Rpc.Rpc<Tag, infer _Payload, infer _Success, infer _Error, infer _Middleware, infer _Requires> ? _Middleware extends {
|
|
245
217
|
readonly requestContextMap: infer _RC
|
|
246
218
|
} ? _RC extends Record<string, RpcContextMap.Any> // ? GetEffectContext<_RC, { allowAnonymous: false }>
|
|
247
219
|
? R extends { readonly config: infer _C } ? GetEffectContext<_RC, _C>
|
|
@@ -251,9 +223,11 @@ export type ExtractDynamicallyProvides<R extends Rpc.Any, Tag extends string> =
|
|
|
251
223
|
: never
|
|
252
224
|
|
|
253
225
|
export type ExtractProvides<R extends Rpc.Any, Tag extends string> = R extends
|
|
254
|
-
Rpc.Rpc<Tag, infer _Payload, infer _Success, infer _Error, infer _Middleware> ? _Middleware extends {
|
|
255
|
-
readonly provides:
|
|
256
|
-
} ?
|
|
226
|
+
Rpc.Rpc<Tag, infer _Payload, infer _Success, infer _Error, infer _Middleware, infer _Requires> ? _Middleware extends {
|
|
227
|
+
readonly provides: infer _P
|
|
228
|
+
} ? [_P] extends [never] ? never
|
|
229
|
+
: _P extends ServiceMap.Service<infer _I, infer _S> ? _I
|
|
230
|
+
: never
|
|
257
231
|
: never
|
|
258
232
|
: never
|
|
259
233
|
|
package/src/utils/effectify.ts
CHANGED
|
@@ -245,7 +245,7 @@ export const effectify: {
|
|
|
245
245
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
246
246
|
(<A>(fn: Function, onError?: (e: any, args: any) => any, onSyncError?: (e: any, args: any) => any) =>
|
|
247
247
|
(...args: Array<any>) =>
|
|
248
|
-
Effect.
|
|
248
|
+
Effect.callback<A, Error>((resume) => {
|
|
249
249
|
try {
|
|
250
250
|
fn(...args, (err: Error | null, result: A) => {
|
|
251
251
|
if (err) {
|
package/src/utils/gen.ts
CHANGED
|
@@ -1,22 +1,24 @@
|
|
|
1
|
-
import { type Effect } from "effect/Effect"
|
|
2
|
-
import { type YieldWrap } from "effect/Utils"
|
|
1
|
+
import { type Effect, type Yieldable } from "effect/Effect"
|
|
3
2
|
|
|
4
3
|
export namespace EffectGenUtils {
|
|
5
4
|
export type Success<EG> = EG extends Effect<infer A, infer _E, infer _R> ? A
|
|
6
5
|
// there could be a case where the generator function does not yield anything, so we need to handle that
|
|
7
6
|
: EG extends (..._: infer _3) => Generator<never, infer A, infer _2> ? A
|
|
8
|
-
:
|
|
7
|
+
// v4: generators can yield Yieldable (Effect, Service, etc.), all have asEffect()
|
|
8
|
+
: EG extends (..._: infer _3) => Generator<Yieldable<any, infer _, infer _E, infer _R>, infer A, infer _2> ? A
|
|
9
9
|
: never
|
|
10
10
|
|
|
11
11
|
export type Error<EG> = EG extends Effect<infer _A, infer E, infer _R> ? E
|
|
12
12
|
// there could be a case where the generator function does not yield anything, so we need to handle that
|
|
13
13
|
: EG extends (..._: infer _3) => Generator<never, infer _A, infer _2> ? never
|
|
14
|
-
:
|
|
14
|
+
// v4: generators can yield Yieldable (Effect, Service, etc.), all have asEffect()
|
|
15
|
+
: EG extends (..._: infer _3) => Generator<Yieldable<any, infer _, infer E, infer _R>, infer _A, infer _2> ? E
|
|
15
16
|
: never
|
|
16
17
|
|
|
17
|
-
export type
|
|
18
|
+
export type ServiceMap<EG> = EG extends Effect<infer _A, infer _E, infer R> ? R
|
|
18
19
|
// there could be a case where the generator function does not yield anything, so we need to handle that
|
|
19
20
|
: EG extends (..._: infer _3) => Generator<never, infer _A, infer _2> ? never
|
|
20
|
-
:
|
|
21
|
+
// v4: generators can yield Yieldable (Effect, Service, etc.), all have asEffect()
|
|
22
|
+
: EG extends (..._: infer _3) => Generator<Yieldable<any, infer _, infer _E, infer R>, infer _A, infer _2> ? R
|
|
21
23
|
: never
|
|
22
24
|
}
|