effect-app 4.0.0-beta.0 → 4.0.0-beta.10
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 +60 -0
- package/dist/Pure.js +1 -1
- package/dist/Schema/brand.d.ts +4 -5
- package/dist/Schema/brand.d.ts.map +1 -1
- package/dist/Schema/brand.js +1 -1
- package/dist/Schema/moreStrings.d.ts +7 -7
- package/dist/Schema/moreStrings.d.ts.map +1 -1
- package/dist/Schema/moreStrings.js +1 -1
- package/dist/Schema.d.ts +4 -4
- package/dist/Schema.d.ts.map +1 -1
- package/dist/Schema.js +2 -3
- package/dist/ServiceMap.d.ts +3 -3
- package/dist/ServiceMap.d.ts.map +1 -1
- package/dist/ServiceMap.js +1 -1
- package/dist/client/apiClientFactory.d.ts.map +1 -1
- package/dist/client/apiClientFactory.js +8 -9
- package/dist/client/clientFor.d.ts +2 -2
- package/dist/client/clientFor.d.ts.map +1 -1
- package/dist/client/errors.d.ts.map +1 -1
- package/dist/client/errors.js +1 -1
- package/dist/client/makeClient.d.ts +8 -8
- package/dist/client/makeClient.d.ts.map +1 -1
- package/dist/client/makeClient.js +3 -14
- package/dist/ids.d.ts +10 -10
- package/dist/ids.d.ts.map +1 -1
- package/dist/ids.js +1 -1
- package/dist/rpc/MiddlewareMaker.d.ts +2 -2
- package/dist/rpc/MiddlewareMaker.d.ts.map +1 -1
- package/dist/rpc/MiddlewareMaker.js +1 -1
- package/dist/rpc/RpcMiddleware.d.ts +2 -2
- package/dist/rpc/RpcMiddleware.d.ts.map +1 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +3 -4
- package/package.json +3 -3
- package/src/Pure.ts +2 -2
- package/src/Schema/brand.ts +5 -6
- package/src/Schema/moreStrings.ts +10 -11
- package/src/Schema.ts +7 -7
- package/src/ServiceMap.ts +7 -5
- package/src/client/apiClientFactory.ts +12 -15
- package/src/client/clientFor.ts +2 -2
- package/src/client/errors.ts +12 -3
- package/src/client/makeClient.ts +9 -22
- package/src/ids.ts +2 -2
- package/src/rpc/MiddlewareMaker.ts +4 -3
- package/src/rpc/RpcMiddleware.ts +3 -3
- package/src/utils.ts +2 -3
- package/test/dist/rpc.test.d.ts.map +1 -1
package/src/Schema/brand.ts
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
|
3
3
|
import type { Option } from "effect"
|
|
4
4
|
import * as B from "effect/Brand"
|
|
5
|
-
import type * as Brand from "effect/Brand"
|
|
6
5
|
import type * as Result from "effect/Result"
|
|
7
6
|
import * as S from "effect/Schema"
|
|
8
7
|
|
|
@@ -21,7 +20,7 @@ export interface Constructor<in out A extends B.Brand<any>> {
|
|
|
21
20
|
* Constructs a branded type from a value of type `A`, returning `Result.succeed`
|
|
22
21
|
* if the provided `A` is valid, `Result.fail` otherwise.
|
|
23
22
|
*/
|
|
24
|
-
result(args: Unbranded<A>): Result.Result<A,
|
|
23
|
+
result(args: Unbranded<A>): Result.Result<A, B.BrandError>
|
|
25
24
|
/**
|
|
26
25
|
* Attempts to refine the provided value of type `A`, returning `true` if
|
|
27
26
|
* the provided `A` is valid, `false` otherwise.
|
|
@@ -29,19 +28,19 @@ export interface Constructor<in out A extends B.Brand<any>> {
|
|
|
29
28
|
is(a: Unbranded<A>): a is Unbranded<A> & A
|
|
30
29
|
}
|
|
31
30
|
|
|
32
|
-
export const fromBrand = <C extends
|
|
31
|
+
export const fromBrand = <C extends B.Brand<string>>(
|
|
33
32
|
constructor: Constructor<C>,
|
|
34
33
|
options?: S.Annotations.Filter
|
|
35
34
|
) =>
|
|
36
|
-
<Self extends S.Top>(self: Self): S.brand<Self["~rebuild.out"],
|
|
35
|
+
<Self extends S.Top>(self: Self): S.brand<Self["~rebuild.out"], B.Brand.Keys<C>> => {
|
|
37
36
|
const branded = S.fromBrand(options?.identifier ?? "Brand", constructor as any)(self as any)
|
|
38
37
|
return options ? (branded as any).pipe(S.annotate(options)) : branded as any
|
|
39
38
|
}
|
|
40
39
|
|
|
41
|
-
export type Brands<P> = P extends B.Brand<any> ?
|
|
40
|
+
export type Brands<P> = P extends B.Brand<any> ? B.Brand.Brands<P>
|
|
42
41
|
: never
|
|
43
42
|
|
|
44
|
-
export type Unbranded<P> = P extends B.Brand<any> ?
|
|
43
|
+
export type Unbranded<P> = P extends B.Brand<any> ? B.Brand.Unbranded<P> : P
|
|
45
44
|
|
|
46
45
|
export const nominal: <A extends B.Brand<any>>() => Constructor<A> = <
|
|
47
46
|
A extends B.Brand<any>
|
|
@@ -140,11 +140,10 @@ const minLength = 6
|
|
|
140
140
|
const maxLength = 50
|
|
141
141
|
const size = 21
|
|
142
142
|
const length = 10 * size
|
|
143
|
-
const StringIdArb = ():
|
|
143
|
+
const StringIdArb = (): S.LazyArbitrary<string> => (fc) =>
|
|
144
144
|
fc
|
|
145
145
|
.uint8Array({ minLength: length, maxLength: length })
|
|
146
|
-
.map((_
|
|
147
|
-
|
|
146
|
+
.map((_) => customRandom(urlAlphabet, size, (size) => _.subarray(0, size))())
|
|
148
147
|
/**
|
|
149
148
|
* A string that is at least 6 characters long and a maximum of 50.
|
|
150
149
|
*/
|
|
@@ -178,12 +177,12 @@ export function prefixedStringId<Brand extends StringId>() {
|
|
|
178
177
|
) => {
|
|
179
178
|
type FullPrefix = `${Prefix}${Separator}`
|
|
180
179
|
const pref = `${prefix}${separator ?? "-"}` as FullPrefix
|
|
181
|
-
const arb = ():
|
|
180
|
+
const arb = (): S.LazyArbitrary<string & Brand> => (fc) =>
|
|
182
181
|
StringIdArb()(fc).map(
|
|
183
|
-
(x
|
|
182
|
+
(x) => (pref + x.substring(0, 50 - pref.length)) as Brand
|
|
184
183
|
)
|
|
185
184
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
186
|
-
const s: S.
|
|
185
|
+
const s: S.Codec<string & Brand, string> = StringId
|
|
187
186
|
.pipe(
|
|
188
187
|
S.refine((x: string): x is string & Brand => x.startsWith(pref), {
|
|
189
188
|
arbitrary: arb,
|
|
@@ -217,10 +216,10 @@ export const brandedStringId = <
|
|
|
217
216
|
Brand extends StringIdBrand
|
|
218
217
|
>() =>
|
|
219
218
|
withDefaultMake(
|
|
220
|
-
Object.assign(Object.create(StringId), StringId) as S.
|
|
219
|
+
Object.assign(Object.create(StringId), StringId) as S.Codec<string & Brand, string> & {
|
|
221
220
|
make: () => string & Brand
|
|
222
|
-
withDefault:
|
|
223
|
-
} & WithDefaults<S.
|
|
221
|
+
withDefault: S.withConstructorDefault<S.Codec<string & Brand, string> & S.WithoutConstructorDefault>
|
|
222
|
+
} & WithDefaults<S.Codec<string & Brand, string>>
|
|
224
223
|
)
|
|
225
224
|
|
|
226
225
|
export interface PrefixedStringUtils<
|
|
@@ -232,7 +231,7 @@ export interface PrefixedStringUtils<
|
|
|
232
231
|
readonly unsafeFrom: (str: string) => Brand
|
|
233
232
|
prefixSafe: <REST extends string>(str: `${Prefix}${Separator}${REST}`) => Brand
|
|
234
233
|
readonly prefix: Prefix
|
|
235
|
-
readonly withDefault:
|
|
234
|
+
readonly withDefault: S.withConstructorDefault<S.Codec<Brand, string> & S.WithoutConstructorDefault>
|
|
236
235
|
}
|
|
237
236
|
|
|
238
237
|
export interface UrlBrand extends Simplify<B.Brand<"Url"> & NonEmptyStringBrand> {}
|
|
@@ -247,7 +246,7 @@ export const Url = S
|
|
|
247
246
|
.String
|
|
248
247
|
.pipe(
|
|
249
248
|
S.refine(isUrl, {
|
|
250
|
-
arbitrary: ():
|
|
249
|
+
arbitrary: (): S.LazyArbitrary<Url> => (fc) => fc.webUrl().map((_) => _ as Url),
|
|
251
250
|
identifier: "Url",
|
|
252
251
|
title: "Url",
|
|
253
252
|
jsonSchema: { format: "uri" }
|
package/src/Schema.ts
CHANGED
|
@@ -61,8 +61,8 @@ export const PhoneNumber = PhoneNumberT
|
|
|
61
61
|
withDefaultMake
|
|
62
62
|
)
|
|
63
63
|
|
|
64
|
-
export const makeIs = <A extends { _tag: string }>(
|
|
65
|
-
schema: S.
|
|
64
|
+
export const makeIs = <A extends { _tag: string }, I, R>(
|
|
65
|
+
schema: S.Codec<A, I, R>
|
|
66
66
|
) => {
|
|
67
67
|
// In v4, transformations are stored as encoding on nodes, not as wrapper nodes.
|
|
68
68
|
// Union member ASTs are directly Objects (TypeLiteral equivalent).
|
|
@@ -89,8 +89,8 @@ export const makeIs = <A extends { _tag: string }>(
|
|
|
89
89
|
throw new Error("Unsupported")
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
-
export const makeIsAnyOf = <A extends { _tag: string }>(
|
|
93
|
-
schema: S.
|
|
92
|
+
export const makeIsAnyOf = <A extends { _tag: string }, I, R>(
|
|
93
|
+
schema: S.Codec<A, I, R>
|
|
94
94
|
): IsAny<A> => {
|
|
95
95
|
if (SchemaAST.isUnion(schema.ast)) {
|
|
96
96
|
return <Keys extends A["_tag"][]>(...keys: Keys) => (a: A): a is ExtractUnion<A, ElemType<Keys>> =>
|
|
@@ -116,7 +116,7 @@ export const taggedUnionMap = <
|
|
|
116
116
|
// TODO: v4 migration — PropertySignatureDeclaration removed, need v4 AST traversal
|
|
117
117
|
const ast = key.fields._tag.ast as any
|
|
118
118
|
const tag = ((ast.type ?? ast) as SchemaAST.Literal).literal as string // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
|
|
119
|
-
|
|
119
|
+
acc[tag] = key as any
|
|
120
120
|
return acc
|
|
121
121
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
122
122
|
}, {} as any)
|
|
@@ -135,8 +135,8 @@ export const tags = <
|
|
|
135
135
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
136
136
|
})) as any
|
|
137
137
|
|
|
138
|
-
export const ExtendTaggedUnion = <A extends { _tag: string }>(
|
|
139
|
-
schema: S.
|
|
138
|
+
export const ExtendTaggedUnion = <A extends { _tag: string }, I, R>(
|
|
139
|
+
schema: S.Codec<A, I, R>
|
|
140
140
|
) =>
|
|
141
141
|
extendM(
|
|
142
142
|
schema,
|
package/src/ServiceMap.ts
CHANGED
|
@@ -7,13 +7,15 @@
|
|
|
7
7
|
|
|
8
8
|
import { type Effect, Layer, type Scope, type Types } from "effect"
|
|
9
9
|
import * as ServiceMap from "effect/ServiceMap"
|
|
10
|
-
import { Yieldable } from "./Effect.js"
|
|
10
|
+
import { type Yieldable } from "./Effect.js"
|
|
11
11
|
|
|
12
12
|
export * from "effect/ServiceMap"
|
|
13
13
|
|
|
14
|
-
export interface Opaque<Self extends object, in out Shape extends object>
|
|
14
|
+
export interface Opaque<Self extends object, in out Shape extends object>
|
|
15
|
+
extends ServiceMap.Key<Self, Self>, Yieldable<Opaque<Self, Shape>, Self, never, Self>
|
|
16
|
+
{
|
|
15
17
|
// temp while sorting out https://github.com/Effect-TS/effect-smol/pull/1534
|
|
16
|
-
of(self: Shape): Self
|
|
18
|
+
of(this: void, self: Shape): Self
|
|
17
19
|
serviceMap(self: Shape): ServiceMap.ServiceMap<Self>
|
|
18
20
|
// a version that leverages the Shape -> Self conversion
|
|
19
21
|
toLayer: <E, R>(
|
|
@@ -151,7 +153,7 @@ export const Opaque: {
|
|
|
151
153
|
id: Identifier,
|
|
152
154
|
options?: {
|
|
153
155
|
readonly make: ((...args: Args) => Effect.Effect<Shape, E, R>) | Effect.Effect<Shape, E, R> | undefined
|
|
154
|
-
}
|
|
156
|
+
}
|
|
155
157
|
) =>
|
|
156
158
|
& OpaqueClass<Self, Identifier, Shape>
|
|
157
159
|
& ([Types.unassigned] extends [R] ? unknown
|
|
@@ -181,7 +183,7 @@ export const Opaque: {
|
|
|
181
183
|
const svc = ServiceMap.Service()(id, options) as any
|
|
182
184
|
return Object.assign(svc, {
|
|
183
185
|
toLayer: (eff: Effect.Effect<any, any, any>) => {
|
|
184
|
-
return Layer.effect(svc
|
|
186
|
+
return Layer.effect(svc, eff)
|
|
185
187
|
}
|
|
186
188
|
})
|
|
187
189
|
}
|
|
@@ -50,17 +50,17 @@ export const HttpClientLayer = (config: ApiConfig) =>
|
|
|
50
50
|
Effect
|
|
51
51
|
.gen(function*() {
|
|
52
52
|
const baseClient = yield* HttpClient.HttpClient
|
|
53
|
-
const ctx = yield* RequestName
|
|
54
53
|
const client = baseClient.pipe(
|
|
55
54
|
HttpClient.mapRequest(HttpClientRequest.prependUrl(config.url + "/rpc")),
|
|
56
55
|
HttpClient.mapRequest(
|
|
57
56
|
HttpClientRequest.setHeaders(config.headers.pipe(Option.getOrElse(() => ({}))))
|
|
58
57
|
),
|
|
59
|
-
HttpClient.
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
58
|
+
HttpClient.mapRequestEffect((req) =>
|
|
59
|
+
Effect.map(RequestName.asEffect(), (ctx) =>
|
|
60
|
+
flow(
|
|
61
|
+
HttpClientRequest.appendUrlParam("action", ctx.requestName),
|
|
62
|
+
HttpClientRequest.appendUrl("/" + ctx.moduleName)
|
|
63
|
+
)(req))
|
|
64
64
|
)
|
|
65
65
|
)
|
|
66
66
|
return client
|
|
@@ -76,7 +76,7 @@ export const HttpClientFromConfigLayer = Layer.unwrap(
|
|
|
76
76
|
|
|
77
77
|
export const RpcSerializationLayer = (config: ApiConfig) =>
|
|
78
78
|
Layer.mergeAll(
|
|
79
|
-
RpcSerialization.
|
|
79
|
+
RpcSerialization.layerNdjson,
|
|
80
80
|
HttpClientLayer(config)
|
|
81
81
|
)
|
|
82
82
|
|
|
@@ -91,7 +91,7 @@ const getFiltered = <M extends Requests>(resource: M) => {
|
|
|
91
91
|
// TODO: Record.filter
|
|
92
92
|
const filtered = typedKeysOf(resource).reduce((acc, cur) => {
|
|
93
93
|
if (
|
|
94
|
-
Predicate.
|
|
94
|
+
Predicate.isObjectKeyword(resource[cur])
|
|
95
95
|
&& (resource[cur].success)
|
|
96
96
|
) {
|
|
97
97
|
acc[cur as keyof Filtered] = resource[cur] as any
|
|
@@ -146,10 +146,7 @@ const makeRpcTag = <M extends Requests>(resource: M) => {
|
|
|
146
146
|
// Use Layer.effect directly (not TheClient.toLayer) so TypeScript properly excludes Scope
|
|
147
147
|
const layer = Layer.effect(
|
|
148
148
|
TheClient,
|
|
149
|
-
|
|
150
|
-
RpcClient.make(rpcs, { spanPrefix: "RpcClient." + meta.moduleName }),
|
|
151
|
-
(cl) => (cl as any)[meta.moduleName]
|
|
152
|
-
)
|
|
149
|
+
RpcClient.make(rpcs, { spanPrefix: "RpcClient." + meta.moduleName })
|
|
153
150
|
)
|
|
154
151
|
return Object.assign(TheClient, { layer })
|
|
155
152
|
}
|
|
@@ -188,7 +185,7 @@ const makeApiClientFactory = Effect
|
|
|
188
185
|
const filtered = getFiltered(resource)
|
|
189
186
|
return {
|
|
190
187
|
mr,
|
|
191
|
-
client:
|
|
188
|
+
client: typedKeysOf(filtered)
|
|
192
189
|
.reduce((prev, cur) => {
|
|
193
190
|
const h = filtered[cur]!
|
|
194
191
|
|
|
@@ -211,7 +208,7 @@ const makeApiClientFactory = Effect
|
|
|
211
208
|
const layers = requestLevelLayers.pipe(Layer.provideMerge(requestNameLayer))
|
|
212
209
|
|
|
213
210
|
const fields = Struct.omit(Request.fields, ["_tag"] as const)
|
|
214
|
-
const requestAttr = h._tag
|
|
211
|
+
const requestAttr = `${meta.moduleName}.${h._tag}`
|
|
215
212
|
// @ts-expect-error doc
|
|
216
213
|
prev[cur] = Object.keys(fields).length === 0
|
|
217
214
|
? {
|
|
@@ -246,7 +243,7 @@ const makeApiClientFactory = Effect
|
|
|
246
243
|
}
|
|
247
244
|
|
|
248
245
|
return prev
|
|
249
|
-
}, {} as Client<M, M["meta"]["moduleName"]>)
|
|
246
|
+
}, {} as Client<M, M["meta"]["moduleName"]>)
|
|
250
247
|
}
|
|
251
248
|
})
|
|
252
249
|
|
package/src/client/clientFor.ts
CHANGED
|
@@ -58,11 +58,11 @@ export type Client<M extends RequestsAny, ModuleName extends string> = RequestHa
|
|
|
58
58
|
ModuleName
|
|
59
59
|
>
|
|
60
60
|
|
|
61
|
-
export type ExtractResponse<T> = T extends S.
|
|
61
|
+
export type ExtractResponse<T> = T extends S.Codec<any> ? S.Schema.Type<T>
|
|
62
62
|
: T extends unknown ? void
|
|
63
63
|
: never
|
|
64
64
|
|
|
65
|
-
export type ExtractEResponse<T> = T extends S.
|
|
65
|
+
export type ExtractEResponse<T> = T extends S.Codec<any> ? S.Codec.Encoded<T>
|
|
66
66
|
: T extends unknown ? void
|
|
67
67
|
: never
|
|
68
68
|
|
package/src/client/errors.ts
CHANGED
|
@@ -43,7 +43,10 @@ export class InvalidStateError extends TaggedError<InvalidStateError>()("Invalid
|
|
|
43
43
|
message: S.String
|
|
44
44
|
}) {
|
|
45
45
|
constructor(messageOrObject: string | { message: string; cause?: unknown }, disableValidation?: boolean) {
|
|
46
|
-
super(
|
|
46
|
+
super(
|
|
47
|
+
typeof messageOrObject === "object" ? messageOrObject : { message: messageOrObject } as any,
|
|
48
|
+
disableValidation as any
|
|
49
|
+
)
|
|
47
50
|
}
|
|
48
51
|
}
|
|
49
52
|
|
|
@@ -51,7 +54,10 @@ export class ServiceUnavailableError extends TaggedError<ServiceUnavailableError
|
|
|
51
54
|
message: S.String
|
|
52
55
|
}) {
|
|
53
56
|
constructor(messageOrObject: string | { message: string; cause?: unknown }, disableValidation?: boolean) {
|
|
54
|
-
super(
|
|
57
|
+
super(
|
|
58
|
+
typeof messageOrObject === "object" ? messageOrObject : { message: messageOrObject } as any,
|
|
59
|
+
disableValidation as any
|
|
60
|
+
)
|
|
55
61
|
}
|
|
56
62
|
}
|
|
57
63
|
|
|
@@ -116,7 +122,10 @@ export class OptimisticConcurrencyException extends TaggedError<OptimisticConcur
|
|
|
116
122
|
| ({ message: string; cause?: unknown; raw?: unknown }),
|
|
117
123
|
disableValidation?: boolean
|
|
118
124
|
) {
|
|
119
|
-
super(
|
|
125
|
+
super(
|
|
126
|
+
"message" in args ? args : { message: `Existing ${args.type} ${args.id} record changed` } as any,
|
|
127
|
+
disableValidation as any
|
|
128
|
+
)
|
|
120
129
|
if (!("message" in args)) {
|
|
121
130
|
this.details = args
|
|
122
131
|
}
|
package/src/client/makeClient.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type GetContextConfig, type RequestContextMapTagAny } from "../rpc/RpcContextMap.js"
|
|
1
|
+
import { type GetContextConfig, type GetEffectError, type RequestContextMapTagAny } from "../rpc/RpcContextMap.js"
|
|
2
2
|
import * as S from "../Schema.js"
|
|
3
3
|
import { AST } from "../Schema.js"
|
|
4
4
|
|
|
@@ -8,7 +8,7 @@ const merge = (a: any, b: Array<any>) =>
|
|
|
8
8
|
/**
|
|
9
9
|
* Whatever the input, we will only decode or encode to void
|
|
10
10
|
*/
|
|
11
|
-
const ForceVoid: S.
|
|
11
|
+
const ForceVoid: S.Codec<void> = S.Void as any
|
|
12
12
|
|
|
13
13
|
type SchemaOrFields<T> = T extends S.Top ? T : T extends S.Struct.Fields ? S.Struct<T> : S.Void
|
|
14
14
|
|
|
@@ -44,8 +44,8 @@ export const makeRpcClient = <
|
|
|
44
44
|
|
|
45
45
|
type MergeError<E> = [GeneralErrors] extends [never] ? SchemaOrFields<E> : S.Union<[SchemaOrFields<E>, GeneralErrors]>
|
|
46
46
|
type ErrorResult<C> = C extends { error: infer E } ? MergeError<E>
|
|
47
|
-
: [GeneralErrors] extends [never] ?
|
|
48
|
-
:
|
|
47
|
+
: [GeneralErrors] extends [never] ? GetEffectError<RequestContextMap["config"], C>
|
|
48
|
+
: MergeError<GetEffectError<RequestContextMap["config"], C>>
|
|
49
49
|
|
|
50
50
|
function TaggedRequest<_Self>(): {
|
|
51
51
|
<Tag extends string, Payload extends S.Struct.Fields, C extends ServiceMap>(
|
|
@@ -62,16 +62,16 @@ export const makeRpcClient = <
|
|
|
62
62
|
tag: Tag,
|
|
63
63
|
fields: Payload,
|
|
64
64
|
config: RequestConfig & C
|
|
65
|
-
): TaggedRequestResult<Tag, Payload, S.
|
|
65
|
+
): TaggedRequestResult<Tag, Payload, S.Codec<void>, ErrorResult<C>, Omit<C, "success" | "error">>
|
|
66
66
|
<Tag extends string, Payload extends S.Struct.Fields, C extends Record<string, any>>(
|
|
67
67
|
tag: Tag,
|
|
68
68
|
fields: Payload,
|
|
69
69
|
config: C & RequestConfig
|
|
70
|
-
): TaggedRequestResult<Tag, Payload, S.
|
|
70
|
+
): TaggedRequestResult<Tag, Payload, S.Codec<void>, ErrorResult<C>, Omit<C, "success" | "error">>
|
|
71
71
|
<Tag extends string, Payload extends S.Struct.Fields>(
|
|
72
72
|
tag: Tag,
|
|
73
73
|
fields: Payload
|
|
74
|
-
): TaggedRequestResult<Tag, Payload, S.
|
|
74
|
+
): TaggedRequestResult<Tag, Payload, S.Codec<void>, ErrorResult<never>, Record<string, never>>
|
|
75
75
|
} {
|
|
76
76
|
// TODO: filter errors based on config + take care of inversion
|
|
77
77
|
const errorSchemas = Object.values(rcs.config).map((_) => _.error)
|
|
@@ -92,22 +92,9 @@ export const makeRpcClient = <
|
|
|
92
92
|
: S.Struct(config.success)
|
|
93
93
|
: ForceVoid
|
|
94
94
|
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
const taggedFields = { _tag: S.tag(tag), ...fields }
|
|
98
|
-
|
|
99
|
-
const RequestClass = class {
|
|
100
|
-
constructor(payload?: any) {
|
|
101
|
-
if (payload) {
|
|
102
|
-
Object.assign(this, payload)
|
|
103
|
-
}
|
|
104
|
-
;(this as any)._tag = tag
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
Object.assign(RequestClass, payloadSchema, {
|
|
95
|
+
const RequestClass = S.TaggedClass<any>()(tag, fields)
|
|
96
|
+
Object.assign(RequestClass, {
|
|
109
97
|
_tag: tag,
|
|
110
|
-
fields: taggedFields,
|
|
111
98
|
success: successSchema,
|
|
112
99
|
error: failureSchema,
|
|
113
100
|
config
|
package/src/ids.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { brandedStringId,
|
|
1
|
+
import { brandedStringId, type Codec, NonEmptyString255, StringId, type StringIdBrand, withDefaultMake } from "effect-app/Schema"
|
|
2
2
|
import type { B } from "effect-app/Schema/schema"
|
|
3
3
|
import type { Simplify } from "effect/Types"
|
|
4
4
|
import { S } from "./index.js"
|
|
@@ -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 unknown as
|
|
15
|
+
.assign(Object.create(NonEmptyString255) as {}, NonEmptyString255 as unknown as Codec<NonEmptyString255, string>),
|
|
16
16
|
(s) => {
|
|
17
17
|
const make = StringId.make as () => NonEmptyString255
|
|
18
18
|
return ({
|
|
@@ -14,7 +14,8 @@ import { type AddMiddleware, type AnyDynamic, type RpcDynamic, type RpcMiddlewar
|
|
|
14
14
|
import * as RpcMiddlewareX from "./RpcMiddleware.js"
|
|
15
15
|
|
|
16
16
|
// adapter for effect/rpc v3 middleware provides. (in effect-smol (v4), it's just a Service Identifier, no tags.)
|
|
17
|
-
|
|
17
|
+
// hm?
|
|
18
|
+
type MakeTags<A> = A
|
|
18
19
|
|
|
19
20
|
export interface MiddlewareMaker<
|
|
20
21
|
Self,
|
|
@@ -39,7 +40,7 @@ export interface MiddlewareMaker<
|
|
|
39
40
|
})
|
|
40
41
|
& (MiddlewareMaker.ManyErrors<MiddlewareProviders> extends never ? {}
|
|
41
42
|
: {
|
|
42
|
-
readonly error: S.
|
|
43
|
+
readonly error: S.Codec<MiddlewareMaker.ManyErrors<MiddlewareProviders>>
|
|
43
44
|
})
|
|
44
45
|
& (MiddlewareMaker.ManyProvided<MiddlewareProviders> extends never ? {}
|
|
45
46
|
: { readonly provides: MakeTags<MiddlewareMaker.ManyProvided<MiddlewareProviders>> })
|
|
@@ -332,7 +333,7 @@ const makeMiddlewareBasic = <Self>() =>
|
|
|
332
333
|
error: (firstFailure
|
|
333
334
|
? S.Union([firstFailure, ...restFailures])
|
|
334
335
|
: S.Never) as unknown as MiddlewareMaker.ManyErrors<MiddlewareProviders> extends never ? never
|
|
335
|
-
: S.
|
|
336
|
+
: S.Codec<MiddlewareMaker.ManyErrors<MiddlewareProviders>>,
|
|
336
337
|
requires: (requires.length > 0
|
|
337
338
|
? requires
|
|
338
339
|
: undefined) as unknown as Exclude<
|
package/src/rpc/RpcMiddleware.ts
CHANGED
|
@@ -59,7 +59,7 @@ export declare namespace TagClass {
|
|
|
59
59
|
* @since 1.0.0
|
|
60
60
|
* @category models
|
|
61
61
|
*/
|
|
62
|
-
export type Failure<Options> = Options extends { readonly error: Schema.
|
|
62
|
+
export type Failure<Options> = Options extends { readonly error: Schema.Codec<infer _A>; readonly optional?: false }
|
|
63
63
|
? _A
|
|
64
64
|
// actually not, the Failure depends on Dynamic Middleware Configuration!
|
|
65
65
|
: Options extends { readonly dynamic: RpcDynamic<any, infer A> } ? S.Schema.Type<A["error"]>
|
|
@@ -226,8 +226,8 @@ export type ExtractProvides<R extends Rpc.Any, Tag extends string> = R extends
|
|
|
226
226
|
Rpc.Rpc<Tag, infer _Payload, infer _Success, infer _Error, infer _Middleware, infer _Requires> ? _Middleware extends {
|
|
227
227
|
readonly provides: infer _P
|
|
228
228
|
} ? [_P] extends [never] ? never
|
|
229
|
-
: _P extends ServiceMap.Service<infer _I, infer _S> ? _I
|
|
230
|
-
: never
|
|
229
|
+
: _P /*_P extends ServiceMap.Service<infer _I, infer _S> ? _I
|
|
230
|
+
: never */
|
|
231
231
|
: never
|
|
232
232
|
: never
|
|
233
233
|
|
package/src/utils.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-unsafe-function-type */
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
3
3
|
/* eslint-disable @typescript-eslint/no-redundant-type-constituents */
|
|
4
|
-
import { Effect, Exit, Fiber, Option, Record } from "effect"
|
|
4
|
+
import { Cause, Effect, Exit, Fiber, Option, Record } from "effect"
|
|
5
5
|
import { dual } from "effect/Function"
|
|
6
6
|
import { isFunction } from "effect/Predicate"
|
|
7
7
|
import * as Result from "effect/Result"
|
|
@@ -924,8 +924,7 @@ export const runtimeFiberAsPromise = <A, E>(fiber: Fiber.Fiber<A, E>, signal?: A
|
|
|
924
924
|
if (Exit.isSuccess(exit)) {
|
|
925
925
|
resolve(exit.value)
|
|
926
926
|
} else {
|
|
927
|
-
|
|
928
|
-
reject(exit.cause)
|
|
927
|
+
reject(Cause.squash(exit.cause))
|
|
929
928
|
}
|
|
930
929
|
})
|
|
931
930
|
)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rpc.test.d.ts","sourceRoot":"","sources":["../rpc.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AACrF,OAAO,EAAE,CAAC,EAAE,MAAM,iBAAiB,CAAA;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;;;;;;;;;;;;;;;;;;;;;;;;AAE7C,qBAAa,iBAAkB,SAAQ,sBAIrC;CAAG
|
|
1
|
+
{"version":3,"file":"rpc.test.d.ts","sourceRoot":"","sources":["../rpc.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AACrF,OAAO,EAAE,CAAC,EAAE,MAAM,iBAAiB,CAAA;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;;;;;;;;;;;;;;;;;;;;;;;;AAE7C,qBAAa,iBAAkB,SAAQ,sBAIrC;CAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIL,qBAAa,KAAM,SAAQ,UAQzB;CAAG"}
|