effect-app 4.0.0-beta.196 → 4.0.0-beta.198
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 +34 -0
- package/dist/Schema/Class.d.ts +7 -10
- package/dist/Schema/Class.d.ts.map +1 -1
- package/dist/Schema/Class.js +2 -3
- package/dist/Schema.d.ts +70 -18
- package/dist/Schema.d.ts.map +1 -1
- package/dist/Schema.js +4 -1
- package/dist/client/apiClientFactory.d.ts +3 -3
- package/dist/client/apiClientFactory.d.ts.map +1 -1
- package/dist/client/apiClientFactory.js +6 -6
- package/dist/client/clientFor.d.ts +2 -5
- package/dist/client/clientFor.d.ts.map +1 -1
- package/dist/client/makeClient.d.ts +137 -31
- package/dist/client/makeClient.d.ts.map +1 -1
- package/dist/client/makeClient.js +10 -12
- package/dist/rpc/Invalidation.d.ts +11 -459
- package/dist/rpc/Invalidation.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/Schema/Class.ts +8 -19
- package/src/Schema.ts +91 -24
- package/src/client/apiClientFactory.ts +13 -13
- package/src/client/clientFor.ts +3 -5
- package/src/client/makeClient.ts +211 -24
- package/test/dist/rpc.test.d.ts.map +1 -1
package/src/Schema.ts
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { SchemaAST, type Tracer } from "effect"
|
|
2
2
|
import * as S from "effect/Schema"
|
|
3
|
+
import { type Simplify } from "effect/Struct"
|
|
4
|
+
import type { RequiredKeys } from "effect/Types"
|
|
3
5
|
import type { NonEmptyReadonlyArray } from "./Array.js"
|
|
4
6
|
import { fakerArb } from "./faker.js"
|
|
5
7
|
import { Email as EmailT, type Email as EmailType } from "./Schema/email.js"
|
|
6
8
|
import { concurrencyUnbounded, withDefaultMake, withDefaultParseOptions } from "./Schema/ext.js"
|
|
7
9
|
import { PhoneNumber as PhoneNumberT, type PhoneNumber as PhoneNumberType } from "./Schema/phoneNumber.js"
|
|
10
|
+
import { type AST } from "./Schema/schema.js"
|
|
8
11
|
import { copy, extendM, type StructuralCopyOrigin } from "./utils.js"
|
|
9
12
|
|
|
10
13
|
export * from "effect/Schema"
|
|
@@ -41,18 +44,9 @@ export { Void as Void_ } from "effect/Schema"
|
|
|
41
44
|
// Struct / NonEmptyArray / Record
|
|
42
45
|
// ---------------------------------------------------------------------------
|
|
43
46
|
|
|
44
|
-
type WithSchemaCopy<Self extends S.Top & { readonly Type: object }> = Self & {
|
|
45
|
-
readonly copy: StructuralCopyOrigin<Self["Type"]>
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
type OptionalMakeInput<Fields extends S.Struct.Fields> = {} extends S.Struct.MakeIn<Fields> ? {
|
|
49
|
-
make(input?: S.Struct.MakeIn<Fields>, options?: S.MakeOptions): S.Struct.Type<Fields>
|
|
50
|
-
}
|
|
51
|
-
: {}
|
|
52
|
-
|
|
53
47
|
export function Struct<const Fields extends S.Struct.Fields>(
|
|
54
48
|
fields: Fields
|
|
55
|
-
): Struct<Fields>
|
|
49
|
+
): Struct<Fields> {
|
|
56
50
|
const result = S.Struct(fields).annotate(concurrencyUnbounded)
|
|
57
51
|
const allowVoidMake = (schema: any): any => {
|
|
58
52
|
// Normalize omitted input to an empty object so optional/default-only structs can be constructed with make().
|
|
@@ -107,27 +101,79 @@ export function Struct<const Fields extends S.Struct.Fields>(
|
|
|
107
101
|
}
|
|
108
102
|
;(result as any).copy = copy
|
|
109
103
|
allowVoidMake(result)
|
|
110
|
-
return result as Struct<Fields>
|
|
104
|
+
return result as Struct<Fields>
|
|
111
105
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
106
|
+
|
|
107
|
+
export interface Struct<Fields extends S.Struct.Fields> extends
|
|
108
|
+
S.Bottom<
|
|
109
|
+
Struct.Type<Fields>,
|
|
110
|
+
Struct.Encoded<Fields>,
|
|
111
|
+
Struct.DecodingServices<Fields>,
|
|
112
|
+
Struct.EncodingServices<Fields>,
|
|
113
|
+
AST.Objects,
|
|
114
|
+
// Rebuild is what's returned from annotate etc
|
|
115
|
+
Struct<Fields>,
|
|
116
|
+
Struct.MakeIn<Fields>,
|
|
117
|
+
Struct.Iso<Fields>
|
|
118
|
+
>
|
|
119
|
+
{
|
|
120
|
+
/**
|
|
121
|
+
* The field definitions of this struct. Spread them into a new struct to
|
|
122
|
+
* reuse fields across schemas.
|
|
123
|
+
*
|
|
124
|
+
* **Example** (Reusing fields across structs)
|
|
125
|
+
*
|
|
126
|
+
* ```ts
|
|
127
|
+
* import { Schema } from "effect"
|
|
128
|
+
*
|
|
129
|
+
* const Timestamped = Schema.Struct({
|
|
130
|
+
* createdAt: Schema.Date,
|
|
131
|
+
* updatedAt: Schema.Date
|
|
132
|
+
* })
|
|
133
|
+
*
|
|
134
|
+
* const User = Schema.Struct({
|
|
135
|
+
* ...Timestamped.fields,
|
|
136
|
+
* name: Schema.String,
|
|
137
|
+
* email: Schema.String
|
|
138
|
+
* })
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
141
|
+
readonly fields: Fields
|
|
142
|
+
/**
|
|
143
|
+
* Returns a new struct with the fields modified by the provided function.
|
|
144
|
+
*
|
|
145
|
+
* **Options**
|
|
146
|
+
*
|
|
147
|
+
* - `unsafePreserveChecks` - if `true`, keep any `.check(...)` constraints
|
|
148
|
+
* that were attached to the original union. Defaults to `false`.
|
|
149
|
+
*
|
|
150
|
+
* **Warning**: This is an unsafe operation. Since `mapFields`
|
|
151
|
+
* transformations change the schema type, the original refinement functions
|
|
152
|
+
* may no longer be valid or safe to apply to the transformed schema. Only
|
|
153
|
+
* use this option if you have verified that your refinements remain correct
|
|
154
|
+
* after the transformation.
|
|
155
|
+
*/
|
|
156
|
+
mapFields<To extends Struct.Fields>(
|
|
118
157
|
f: (fields: Fields) => To,
|
|
119
158
|
options?: {
|
|
120
159
|
readonly unsafePreserveChecks?: boolean | undefined
|
|
121
|
-
}
|
|
122
|
-
): Struct<Readonly<To
|
|
160
|
+
} | undefined
|
|
161
|
+
): Struct<Simplify<Readonly<To>>>
|
|
162
|
+
|
|
163
|
+
// added copy
|
|
164
|
+
readonly copy: StructuralCopyOrigin<Struct.Type<Fields>>
|
|
123
165
|
}
|
|
166
|
+
|
|
124
167
|
export declare namespace Struct {
|
|
125
168
|
export type Fields = S.Struct.Fields
|
|
126
169
|
export type Type<F extends S.Struct.Fields> = S.Struct.Type<F>
|
|
127
170
|
export type Encoded<F extends S.Struct.Fields> = S.Struct.Encoded<F>
|
|
128
171
|
export type DecodingServices<F extends S.Struct.Fields> = S.Struct.DecodingServices<F>
|
|
129
172
|
export type EncodingServices<F extends S.Struct.Fields> = S.Struct.EncodingServices<F>
|
|
130
|
-
|
|
173
|
+
// changed; all optional allows void
|
|
174
|
+
export type MakeIn<F extends S.Struct.Fields> = RequiredKeys<S.Struct.MakeIn<F>> extends never
|
|
175
|
+
? void | S.Struct.MakeIn<F>
|
|
176
|
+
: S.Struct.MakeIn<F>
|
|
131
177
|
export type Iso<F extends S.Struct.Fields> = S.Struct.Iso<F>
|
|
132
178
|
}
|
|
133
179
|
|
|
@@ -151,11 +197,32 @@ export function TaggedStruct<const Tag extends SchemaAST.LiteralValue, const Fie
|
|
|
151
197
|
): TaggedStruct<Tag, Fields> {
|
|
152
198
|
return Struct({ _tag: S.tag(value), ...fields }) as any
|
|
153
199
|
}
|
|
154
|
-
export
|
|
155
|
-
&
|
|
156
|
-
|
|
200
|
+
export interface TaggedStruct<Tag extends SchemaAST.LiteralValue, Fields extends S.Struct.Fields>
|
|
201
|
+
extends Struct<{ readonly _tag: S.tag<Tag> } & Fields>
|
|
202
|
+
{}
|
|
203
|
+
export declare namespace TaggedStruct {
|
|
204
|
+
export type Fields = S.Struct.Fields
|
|
205
|
+
export type Type<Tag extends SchemaAST.LiteralValue, F extends S.Struct.Fields> = S.Struct.Type<
|
|
206
|
+
{ readonly _tag: S.tag<Tag> } & F
|
|
207
|
+
>
|
|
208
|
+
export type Encoded<Tag extends SchemaAST.LiteralValue, F extends S.Struct.Fields> = S.Struct.Encoded<
|
|
209
|
+
{ readonly _tag: S.tag<Tag> } & F
|
|
157
210
|
>
|
|
158
|
-
|
|
211
|
+
export type DecodingServices<Tag extends SchemaAST.LiteralValue, F extends S.Struct.Fields> =
|
|
212
|
+
S.Struct.DecodingServices<
|
|
213
|
+
{ readonly _tag: S.tag<Tag> } & F
|
|
214
|
+
>
|
|
215
|
+
export type EncodingServices<Tag extends SchemaAST.LiteralValue, F extends S.Struct.Fields> =
|
|
216
|
+
S.Struct.EncodingServices<
|
|
217
|
+
{ readonly _tag: S.tag<Tag> } & F
|
|
218
|
+
>
|
|
219
|
+
export type MakeIn<Tag extends SchemaAST.LiteralValue, F extends S.Struct.Fields> = S.Struct.MakeIn<
|
|
220
|
+
{ readonly _tag: S.tag<Tag> } & F
|
|
221
|
+
>
|
|
222
|
+
export type Iso<Tag extends SchemaAST.LiteralValue, F extends S.Struct.Fields> = S.Struct.Iso<
|
|
223
|
+
{ readonly _tag: S.tag<Tag> } & F
|
|
224
|
+
>
|
|
225
|
+
}
|
|
159
226
|
|
|
160
227
|
export function Record<Key extends S.Record.Key, Value extends S.Top>(
|
|
161
228
|
key: Key,
|
|
@@ -44,8 +44,8 @@ export type Req = S.Top & {
|
|
|
44
44
|
config?: Record<string, any>
|
|
45
45
|
readonly id: string
|
|
46
46
|
readonly moduleName: string
|
|
47
|
-
readonly type: "command" | "query"
|
|
48
|
-
readonly
|
|
47
|
+
readonly type: "command" | "query"
|
|
48
|
+
readonly stream: boolean
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
class RequestName extends Context.Reference("RequestName", {
|
|
@@ -126,18 +126,18 @@ export const makeRpcGroupFromRequestsAndModuleName = <M extends RequestsAny, con
|
|
|
126
126
|
.make(
|
|
127
127
|
...typedValuesOf(filtered).map((_) => {
|
|
128
128
|
const r = _ as any
|
|
129
|
-
const isStream = r.
|
|
129
|
+
const isStream = r.stream
|
|
130
130
|
const isCommand = r.type === "command"
|
|
131
131
|
return (isCommand
|
|
132
|
-
?
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
: Rpc.make(r._tag, { payload: r, success: r.success, error: r.error })) as any
|
|
132
|
+
? isStream
|
|
133
|
+
? Invalidation.makeStreamRpc(r._tag, {
|
|
134
|
+
payload: r,
|
|
135
|
+
success: r.success,
|
|
136
|
+
error: r.error,
|
|
137
|
+
stream: true as const
|
|
138
|
+
})
|
|
139
|
+
: Invalidation.makeCommandRpc(r._tag, { payload: r, success: r.success, error: r.error })
|
|
140
|
+
: Rpc.make(r._tag, { payload: r, success: r.success, error: r.error, stream: isStream })) as any
|
|
141
141
|
})
|
|
142
142
|
)
|
|
143
143
|
.prefix(`${moduleName}.`) as unknown as RpcGroup.RpcGroup<
|
|
@@ -245,7 +245,7 @@ const makeApiClientFactory = Effect
|
|
|
245
245
|
const fields = Struct.omit(Request.fields, ["_tag"] as const)
|
|
246
246
|
const requestAttr = `${meta.moduleName}.${h._tag}`
|
|
247
247
|
const isCommand = h.type === "command"
|
|
248
|
-
const isStream = h.
|
|
248
|
+
const isStream = h.stream
|
|
249
249
|
|
|
250
250
|
const buildEffect = (input: any) =>
|
|
251
251
|
mr.contextEffect.pipe(
|
package/src/client/clientFor.ts
CHANGED
|
@@ -122,8 +122,6 @@ export type RequestStreamHandler<A, E, R, Request extends Req, Id extends string
|
|
|
122
122
|
RequestStreamHandlerWithInput<void, A, E, R, Request, Id, Final>
|
|
123
123
|
|
|
124
124
|
// make sure this is exported or d.ts of apiClientFactory breaks?!
|
|
125
|
-
type ReqDecodingServices<M> = M extends { readonly "~decodingServices": infer DS } ? DS : never
|
|
126
|
-
|
|
127
125
|
export type RequestInputFromMake<I extends { readonly make: (...args: any[]) => any }> = Parameters<I["make"]> extends
|
|
128
126
|
[] ? void : Parameters<I["make"]>[0]
|
|
129
127
|
|
|
@@ -146,12 +144,12 @@ export type HandlerInput<I extends { readonly make: (...args: any[]) => any }> =
|
|
|
146
144
|
type FinalTypeOf<T extends Req> = T extends { readonly final: infer F extends S.Top } ? S.Schema.Type<F>
|
|
147
145
|
: S.Schema.Type<T["success"]>
|
|
148
146
|
|
|
149
|
-
type RequestHandlerFor<R, E, T extends Req, Id extends string> = T["
|
|
147
|
+
type RequestHandlerFor<R, E, T extends Req, Id extends string> = T["stream"] extends true
|
|
150
148
|
? RequestStreamHandlerWithInput<
|
|
151
149
|
HandlerInput<T>,
|
|
152
150
|
S.Schema.Type<T["success"]>,
|
|
153
151
|
S.Schema.Type<T["error"]> | E,
|
|
154
|
-
R |
|
|
152
|
+
R | S.Codec.DecodingServices<T["success"]> | S.Codec.DecodingServices<T["error"]>,
|
|
155
153
|
T,
|
|
156
154
|
Id,
|
|
157
155
|
FinalTypeOf<T>
|
|
@@ -160,7 +158,7 @@ type RequestHandlerFor<R, E, T extends Req, Id extends string> = T["type"] exten
|
|
|
160
158
|
HandlerInput<T>,
|
|
161
159
|
S.Schema.Type<T["success"]>,
|
|
162
160
|
S.Schema.Type<T["error"]> | E,
|
|
163
|
-
R |
|
|
161
|
+
R | S.Codec.DecodingServices<T["success"]> | S.Codec.DecodingServices<T["error"]>,
|
|
164
162
|
T,
|
|
165
163
|
Id
|
|
166
164
|
>
|
package/src/client/makeClient.ts
CHANGED
|
@@ -87,21 +87,22 @@ type TaggedRequestForResult<
|
|
|
87
87
|
Error extends S.Top,
|
|
88
88
|
Config,
|
|
89
89
|
ModuleName extends string,
|
|
90
|
-
Type extends "command" | "query"
|
|
90
|
+
Type extends "command" | "query",
|
|
91
|
+
Stream extends boolean,
|
|
91
92
|
Resources = never,
|
|
92
93
|
Final extends S.Top = never
|
|
93
94
|
> =
|
|
94
|
-
& S.
|
|
95
|
+
& S.Opaque<Self, S.ExtendedSchemaNoEncoded, TaggedRequestSchema<Tag, Payload>, {}>
|
|
95
96
|
& {
|
|
97
|
+
readonly fields: TaggedRequestSchema<Tag, Payload>["fields"]
|
|
96
98
|
readonly _tag: Tag
|
|
97
99
|
readonly success: Success
|
|
98
100
|
readonly error: Error
|
|
99
101
|
readonly config: Config
|
|
100
|
-
readonly "~decodingServices": S.Codec.DecodingServices<Success> | S.Codec.DecodingServices<Error>
|
|
101
|
-
readonly "~encodingServices": S.Codec.EncodingServices<Success> | S.Codec.EncodingServices<Error>
|
|
102
102
|
readonly id: `${ModuleName}.${Tag}`
|
|
103
103
|
readonly moduleName: ModuleName
|
|
104
104
|
readonly type: Type
|
|
105
|
+
readonly stream: Stream
|
|
105
106
|
readonly "~invalidationResources"?: Resources
|
|
106
107
|
}
|
|
107
108
|
& ([Final] extends [never] ? {} : { readonly final: Final })
|
|
@@ -115,6 +116,7 @@ export const makeRpcClient = <
|
|
|
115
116
|
success: S.Top | S.Struct.Fields // SchemaOrFields will make a Schema type out of Struct.Fields
|
|
116
117
|
error: S.Top | S.Struct.Fields // SchemaOrFields will make a Schema type out of Struct.Fields
|
|
117
118
|
final?: S.Top | S.Struct.Fields // optional final-value schema for stream requests
|
|
119
|
+
stream?: boolean // request metadata — stripped from stored config
|
|
118
120
|
}
|
|
119
121
|
|
|
120
122
|
type RequestConfig = GetContextConfig<RequestContextMap["config"]>
|
|
@@ -145,23 +147,204 @@ export const makeRpcClient = <
|
|
|
145
147
|
const finalConfig = (config as any)?.final
|
|
146
148
|
const finalSchema = finalConfig && S.isSchema(finalConfig) ? finalConfig : undefined
|
|
147
149
|
|
|
148
|
-
|
|
150
|
+
// Strip stream from the stored config — it's request metadata, not handler config
|
|
151
|
+
const { stream: _stream, ...restConfig } = config ?? ({} as C)
|
|
152
|
+
|
|
153
|
+
const RequestClass = S.Opaque()(S.TaggedStruct(tag, fields))
|
|
149
154
|
Object.assign(RequestClass, {
|
|
150
155
|
_tag: tag,
|
|
151
156
|
success: successSchema,
|
|
152
157
|
error: failureSchema,
|
|
153
158
|
...(finalSchema !== undefined ? { final: finalSchema } : {}),
|
|
154
|
-
config
|
|
159
|
+
config: restConfig
|
|
155
160
|
})
|
|
156
161
|
|
|
157
162
|
return RequestClass
|
|
158
163
|
}
|
|
159
164
|
|
|
160
|
-
function makeTaggedRequestWithMeta<
|
|
165
|
+
function makeTaggedRequestWithMeta<
|
|
166
|
+
ModuleName extends string,
|
|
167
|
+
Type extends "command" | "query"
|
|
168
|
+
>(
|
|
161
169
|
moduleName: ModuleName,
|
|
162
170
|
type: Type
|
|
163
171
|
) {
|
|
164
172
|
function TaggedRequestWithMeta<Self, Resources extends InvalidationResources = never>(): {
|
|
173
|
+
// ─── stream: true overloads (must come before non-stream so TypeScript picks them) ───────────
|
|
174
|
+
<
|
|
175
|
+
Tag extends string,
|
|
176
|
+
Payload extends S.Struct.Fields,
|
|
177
|
+
Success extends S.Top | S.Struct.Fields,
|
|
178
|
+
Error extends S.Top | S.Struct.Fields,
|
|
179
|
+
Final extends S.Top | S.Struct.Fields = never,
|
|
180
|
+
C extends RequestConfig & Record<string, any> = RequestConfig & Record<string, any>
|
|
181
|
+
>(
|
|
182
|
+
tag: Tag,
|
|
183
|
+
fields: Payload,
|
|
184
|
+
config:
|
|
185
|
+
& Omit<C, "invalidatesQueries">
|
|
186
|
+
& { stream: true; success: Success; error: Error; final?: Final },
|
|
187
|
+
invalidatesQueries?: InvalidationCallback<
|
|
188
|
+
Resources,
|
|
189
|
+
InputFromPayload<Payload>,
|
|
190
|
+
OutputFromSuccess<SchemaOrFields<Success>>,
|
|
191
|
+
S.Schema.Type<ErrorResult<C & { success: Success; error: Error }>>
|
|
192
|
+
>
|
|
193
|
+
): TaggedRequestForResult<
|
|
194
|
+
Self,
|
|
195
|
+
Tag,
|
|
196
|
+
Payload,
|
|
197
|
+
SchemaOrFields<Success>,
|
|
198
|
+
ErrorResult<C & { success: Success; error: Error }>,
|
|
199
|
+
Omit<
|
|
200
|
+
& Omit<C, "invalidatesQueries">
|
|
201
|
+
& {
|
|
202
|
+
success: Success
|
|
203
|
+
error: Error
|
|
204
|
+
}
|
|
205
|
+
& Partial<
|
|
206
|
+
InvalidationConfigForCommand<
|
|
207
|
+
Resources,
|
|
208
|
+
Payload,
|
|
209
|
+
SchemaOrFields<Success>,
|
|
210
|
+
ErrorResult<C & { success: Success; error: Error }>
|
|
211
|
+
>
|
|
212
|
+
>,
|
|
213
|
+
"success" | "error" | "stream"
|
|
214
|
+
>,
|
|
215
|
+
ModuleName,
|
|
216
|
+
Type,
|
|
217
|
+
true,
|
|
218
|
+
Resources,
|
|
219
|
+
[Final] extends [never] ? never : SchemaOrFields<Final>
|
|
220
|
+
>
|
|
221
|
+
<
|
|
222
|
+
Tag extends string,
|
|
223
|
+
Payload extends S.Struct.Fields,
|
|
224
|
+
Success extends S.Top | S.Struct.Fields,
|
|
225
|
+
Final extends S.Top | S.Struct.Fields = never,
|
|
226
|
+
C extends RequestConfig & Record<string, any> & { error?: never } =
|
|
227
|
+
& RequestConfig
|
|
228
|
+
& Record<string, any>
|
|
229
|
+
& { error?: never }
|
|
230
|
+
>(
|
|
231
|
+
tag: Tag,
|
|
232
|
+
fields: Payload,
|
|
233
|
+
config:
|
|
234
|
+
& Omit<C, "invalidatesQueries">
|
|
235
|
+
& { stream: true; success: Success; final?: Final },
|
|
236
|
+
invalidatesQueries?: InvalidationCallback<
|
|
237
|
+
Resources,
|
|
238
|
+
InputFromPayload<Payload>,
|
|
239
|
+
OutputFromSuccess<SchemaOrFields<Success>>,
|
|
240
|
+
S.Schema.Type<ErrorResult<C & { success: Success }>>
|
|
241
|
+
>
|
|
242
|
+
): TaggedRequestForResult<
|
|
243
|
+
Self,
|
|
244
|
+
Tag,
|
|
245
|
+
Payload,
|
|
246
|
+
SchemaOrFields<Success>,
|
|
247
|
+
ErrorResult<C & { success: Success }>,
|
|
248
|
+
Omit<
|
|
249
|
+
& Omit<C, "invalidatesQueries">
|
|
250
|
+
& { success: Success }
|
|
251
|
+
& Partial<
|
|
252
|
+
InvalidationConfigForCommand<
|
|
253
|
+
Resources,
|
|
254
|
+
Payload,
|
|
255
|
+
SchemaOrFields<Success>,
|
|
256
|
+
ErrorResult<C & { success: Success }>
|
|
257
|
+
>
|
|
258
|
+
>,
|
|
259
|
+
"success" | "error" | "stream"
|
|
260
|
+
>,
|
|
261
|
+
ModuleName,
|
|
262
|
+
Type,
|
|
263
|
+
true,
|
|
264
|
+
Resources,
|
|
265
|
+
[Final] extends [never] ? never : SchemaOrFields<Final>
|
|
266
|
+
>
|
|
267
|
+
// ─── stream: true without `success` overloads ────────────────────────────────────────────────
|
|
268
|
+
<
|
|
269
|
+
Tag extends string,
|
|
270
|
+
Payload extends S.Struct.Fields,
|
|
271
|
+
Error extends S.Top | S.Struct.Fields,
|
|
272
|
+
C extends RequestConfig & Record<string, any> & { success?: never } =
|
|
273
|
+
& RequestConfig
|
|
274
|
+
& Record<string, any>
|
|
275
|
+
& { success?: never }
|
|
276
|
+
>(
|
|
277
|
+
tag: Tag,
|
|
278
|
+
fields: Payload,
|
|
279
|
+
config:
|
|
280
|
+
& Omit<C, "invalidatesQueries">
|
|
281
|
+
& { stream: true; error: Error },
|
|
282
|
+
invalidatesQueries?: InvalidationCallback<
|
|
283
|
+
Resources,
|
|
284
|
+
InputFromPayload<Payload>,
|
|
285
|
+
void,
|
|
286
|
+
S.Schema.Type<ErrorResult<C & { error: Error }>>
|
|
287
|
+
>
|
|
288
|
+
): TaggedRequestForResult<
|
|
289
|
+
Self,
|
|
290
|
+
Tag,
|
|
291
|
+
Payload,
|
|
292
|
+
typeof ForceVoid,
|
|
293
|
+
ErrorResult<C & { error: Error }>,
|
|
294
|
+
Omit<
|
|
295
|
+
& Omit<C, "invalidatesQueries">
|
|
296
|
+
& { error: Error }
|
|
297
|
+
& Partial<
|
|
298
|
+
InvalidationConfigForCommand<
|
|
299
|
+
Resources,
|
|
300
|
+
Payload,
|
|
301
|
+
typeof ForceVoid,
|
|
302
|
+
ErrorResult<C & { error: Error }>
|
|
303
|
+
>
|
|
304
|
+
>,
|
|
305
|
+
"success" | "error" | "stream"
|
|
306
|
+
>,
|
|
307
|
+
ModuleName,
|
|
308
|
+
Type,
|
|
309
|
+
true,
|
|
310
|
+
Resources
|
|
311
|
+
>
|
|
312
|
+
<
|
|
313
|
+
Tag extends string,
|
|
314
|
+
Payload extends S.Struct.Fields,
|
|
315
|
+
C extends RequestConfig & Record<string, any> & { success?: never; error?: never } =
|
|
316
|
+
& RequestConfig
|
|
317
|
+
& Record<string, any>
|
|
318
|
+
& { success?: never; error?: never }
|
|
319
|
+
>(
|
|
320
|
+
tag: Tag,
|
|
321
|
+
fields: Payload,
|
|
322
|
+
config:
|
|
323
|
+
& Omit<C, "invalidatesQueries">
|
|
324
|
+
& { stream: true },
|
|
325
|
+
invalidatesQueries?: InvalidationCallback<
|
|
326
|
+
Resources,
|
|
327
|
+
InputFromPayload<Payload>,
|
|
328
|
+
void,
|
|
329
|
+
S.Schema.Type<ErrorResult<C>>
|
|
330
|
+
>
|
|
331
|
+
): TaggedRequestForResult<
|
|
332
|
+
Self,
|
|
333
|
+
Tag,
|
|
334
|
+
Payload,
|
|
335
|
+
typeof ForceVoid,
|
|
336
|
+
ErrorResult<C>,
|
|
337
|
+
Omit<
|
|
338
|
+
& Omit<C, "invalidatesQueries">
|
|
339
|
+
& Partial<InvalidationConfigForCommand<Resources, Payload, typeof ForceVoid, ErrorResult<C>>>,
|
|
340
|
+
"success" | "error" | "stream"
|
|
341
|
+
>,
|
|
342
|
+
ModuleName,
|
|
343
|
+
Type,
|
|
344
|
+
true,
|
|
345
|
+
Resources
|
|
346
|
+
>
|
|
347
|
+
// ─── non-stream overloads ────────────────────────────────────────────────────────────────────
|
|
165
348
|
<
|
|
166
349
|
Tag extends string,
|
|
167
350
|
Payload extends S.Struct.Fields,
|
|
@@ -201,10 +384,11 @@ export const makeRpcClient = <
|
|
|
201
384
|
ErrorResult<C & { success: Success; error: Error }>
|
|
202
385
|
>
|
|
203
386
|
>,
|
|
204
|
-
"success" | "error"
|
|
387
|
+
"success" | "error" | "stream"
|
|
205
388
|
>,
|
|
206
389
|
ModuleName,
|
|
207
390
|
Type,
|
|
391
|
+
false,
|
|
208
392
|
Resources,
|
|
209
393
|
[Final] extends [never] ? never : SchemaOrFields<Final>
|
|
210
394
|
>
|
|
@@ -213,9 +397,12 @@ export const makeRpcClient = <
|
|
|
213
397
|
Payload extends S.Struct.Fields,
|
|
214
398
|
Success extends S.Top | S.Struct.Fields,
|
|
215
399
|
Final extends S.Top | S.Struct.Fields = never,
|
|
216
|
-
C extends RequestConfig & Record<string, any> & { error?: never } =
|
|
217
|
-
|
|
218
|
-
|
|
400
|
+
C extends RequestConfig & Record<string, any> & { error?: never } =
|
|
401
|
+
& RequestConfig
|
|
402
|
+
& Record<string, any>
|
|
403
|
+
& {
|
|
404
|
+
error?: never
|
|
405
|
+
}
|
|
219
406
|
>(
|
|
220
407
|
tag: Tag,
|
|
221
408
|
fields: Payload,
|
|
@@ -247,10 +434,11 @@ export const makeRpcClient = <
|
|
|
247
434
|
ErrorResult<C & { success: Success }>
|
|
248
435
|
>
|
|
249
436
|
>,
|
|
250
|
-
"success" | "error"
|
|
437
|
+
"success" | "error" | "stream"
|
|
251
438
|
>,
|
|
252
439
|
ModuleName,
|
|
253
440
|
Type,
|
|
441
|
+
false,
|
|
254
442
|
Resources,
|
|
255
443
|
[Final] extends [never] ? never : SchemaOrFields<Final>
|
|
256
444
|
>
|
|
@@ -290,10 +478,11 @@ export const makeRpcClient = <
|
|
|
290
478
|
ErrorResult<C & { error: Error }>
|
|
291
479
|
>
|
|
292
480
|
>,
|
|
293
|
-
"success" | "error"
|
|
481
|
+
"success" | "error" | "stream"
|
|
294
482
|
>,
|
|
295
483
|
ModuleName,
|
|
296
484
|
Type,
|
|
485
|
+
false,
|
|
297
486
|
Resources
|
|
298
487
|
>
|
|
299
488
|
<
|
|
@@ -319,10 +508,11 @@ export const makeRpcClient = <
|
|
|
319
508
|
Omit<
|
|
320
509
|
& Omit<C, "invalidatesQueries">
|
|
321
510
|
& Partial<InvalidationConfigForCommand<Resources, Payload, typeof ForceVoid, ErrorResult<C>>>,
|
|
322
|
-
"success" | "error"
|
|
511
|
+
"success" | "error" | "stream"
|
|
323
512
|
>,
|
|
324
513
|
ModuleName,
|
|
325
514
|
Type,
|
|
515
|
+
false,
|
|
326
516
|
Resources
|
|
327
517
|
>
|
|
328
518
|
<Tag extends string, Payload extends S.Struct.Fields>(
|
|
@@ -336,7 +526,8 @@ export const makeRpcClient = <
|
|
|
336
526
|
ErrorResult<{}>,
|
|
337
527
|
Record<string, never>,
|
|
338
528
|
ModuleName,
|
|
339
|
-
Type
|
|
529
|
+
Type,
|
|
530
|
+
false
|
|
340
531
|
>
|
|
341
532
|
} {
|
|
342
533
|
return (<Tag extends string, Fields extends S.Struct.Fields, C extends ServiceMap>(
|
|
@@ -345,9 +536,10 @@ export const makeRpcClient = <
|
|
|
345
536
|
config?: C,
|
|
346
537
|
invalidatesQueries?: InvalidationCallback<Resources>
|
|
347
538
|
) => {
|
|
539
|
+
const isStream = (config as any)?.stream === true
|
|
348
540
|
const requestConfig = invalidatesQueries === undefined ? config : { ...config, invalidatesQueries }
|
|
349
541
|
const cls = makeRequestClass(tag, fields, requestConfig)
|
|
350
|
-
Object.assign(cls, { id: `${moduleName}.${tag}`, moduleName, type })
|
|
542
|
+
Object.assign(cls, { id: `${moduleName}.${tag}`, moduleName, type, stream: isStream })
|
|
351
543
|
return cls
|
|
352
544
|
}) as any
|
|
353
545
|
}
|
|
@@ -357,26 +549,21 @@ export const makeRpcClient = <
|
|
|
357
549
|
function TaggedRequestFor<ModuleName extends string>(moduleName: ModuleName) {
|
|
358
550
|
const Query = makeTaggedRequestWithMeta(moduleName, "query")
|
|
359
551
|
const Command = makeTaggedRequestWithMeta(moduleName, "command")
|
|
360
|
-
const Stream = makeTaggedRequestWithMeta(moduleName, "stream")
|
|
361
552
|
|
|
362
553
|
return {
|
|
363
554
|
moduleName,
|
|
364
555
|
/**
|
|
365
556
|
* Create query request classes for this module.
|
|
366
557
|
* Queries read state and should not mutate server state.
|
|
558
|
+
* Pass `stream: true` in the config to produce a Stream of `success` values (QueryStream behaviour).
|
|
367
559
|
*/
|
|
368
560
|
Query,
|
|
369
561
|
/**
|
|
370
562
|
* Create command request classes for this module.
|
|
371
563
|
* Commands mutate state and should avoid returning complex read models.
|
|
564
|
+
* Pass `stream: true` in the config to produce a Stream of `success` values (CommandStream behaviour).
|
|
372
565
|
*/
|
|
373
|
-
Command
|
|
374
|
-
/**
|
|
375
|
-
* Create stream request classes for this module.
|
|
376
|
-
* Streams produce a Stream of `success` values, may also fail with `error`.
|
|
377
|
-
* Handlers must return an `Effect`-compatible Stream rather than an Effect.
|
|
378
|
-
*/
|
|
379
|
-
Stream
|
|
566
|
+
Command
|
|
380
567
|
} as const
|
|
381
568
|
}
|
|
382
569
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rpc.test.d.ts","sourceRoot":"","sources":["../rpc.test.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiB,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAErF,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":"AAEA,OAAO,EAAiB,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAErF,OAAO,EAAE,CAAC,EAAE,MAAM,iBAAiB,CAAA;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;;;;;;;;;;;;;;;;;;;;;;;;AAE7C,qBAAa,iBAAkB,SAAQ,sBAIrC;CAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKL,qBAAa,KAAM,SAAQ,UAQzB;CAAG"}
|