effect-app 4.0.0-beta.196 → 4.0.0-beta.197
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 +28 -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 +83 -63
- 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 +131 -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,124 @@ 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
|
+
// ─── non-stream overloads ────────────────────────────────────────────────────────────────────
|
|
165
268
|
<
|
|
166
269
|
Tag extends string,
|
|
167
270
|
Payload extends S.Struct.Fields,
|
|
@@ -201,10 +304,11 @@ export const makeRpcClient = <
|
|
|
201
304
|
ErrorResult<C & { success: Success; error: Error }>
|
|
202
305
|
>
|
|
203
306
|
>,
|
|
204
|
-
"success" | "error"
|
|
307
|
+
"success" | "error" | "stream"
|
|
205
308
|
>,
|
|
206
309
|
ModuleName,
|
|
207
310
|
Type,
|
|
311
|
+
false,
|
|
208
312
|
Resources,
|
|
209
313
|
[Final] extends [never] ? never : SchemaOrFields<Final>
|
|
210
314
|
>
|
|
@@ -213,9 +317,12 @@ export const makeRpcClient = <
|
|
|
213
317
|
Payload extends S.Struct.Fields,
|
|
214
318
|
Success extends S.Top | S.Struct.Fields,
|
|
215
319
|
Final extends S.Top | S.Struct.Fields = never,
|
|
216
|
-
C extends RequestConfig & Record<string, any> & { error?: never } =
|
|
217
|
-
|
|
218
|
-
|
|
320
|
+
C extends RequestConfig & Record<string, any> & { error?: never } =
|
|
321
|
+
& RequestConfig
|
|
322
|
+
& Record<string, any>
|
|
323
|
+
& {
|
|
324
|
+
error?: never
|
|
325
|
+
}
|
|
219
326
|
>(
|
|
220
327
|
tag: Tag,
|
|
221
328
|
fields: Payload,
|
|
@@ -247,10 +354,11 @@ export const makeRpcClient = <
|
|
|
247
354
|
ErrorResult<C & { success: Success }>
|
|
248
355
|
>
|
|
249
356
|
>,
|
|
250
|
-
"success" | "error"
|
|
357
|
+
"success" | "error" | "stream"
|
|
251
358
|
>,
|
|
252
359
|
ModuleName,
|
|
253
360
|
Type,
|
|
361
|
+
false,
|
|
254
362
|
Resources,
|
|
255
363
|
[Final] extends [never] ? never : SchemaOrFields<Final>
|
|
256
364
|
>
|
|
@@ -290,10 +398,11 @@ export const makeRpcClient = <
|
|
|
290
398
|
ErrorResult<C & { error: Error }>
|
|
291
399
|
>
|
|
292
400
|
>,
|
|
293
|
-
"success" | "error"
|
|
401
|
+
"success" | "error" | "stream"
|
|
294
402
|
>,
|
|
295
403
|
ModuleName,
|
|
296
404
|
Type,
|
|
405
|
+
false,
|
|
297
406
|
Resources
|
|
298
407
|
>
|
|
299
408
|
<
|
|
@@ -319,10 +428,11 @@ export const makeRpcClient = <
|
|
|
319
428
|
Omit<
|
|
320
429
|
& Omit<C, "invalidatesQueries">
|
|
321
430
|
& Partial<InvalidationConfigForCommand<Resources, Payload, typeof ForceVoid, ErrorResult<C>>>,
|
|
322
|
-
"success" | "error"
|
|
431
|
+
"success" | "error" | "stream"
|
|
323
432
|
>,
|
|
324
433
|
ModuleName,
|
|
325
434
|
Type,
|
|
435
|
+
false,
|
|
326
436
|
Resources
|
|
327
437
|
>
|
|
328
438
|
<Tag extends string, Payload extends S.Struct.Fields>(
|
|
@@ -336,7 +446,8 @@ export const makeRpcClient = <
|
|
|
336
446
|
ErrorResult<{}>,
|
|
337
447
|
Record<string, never>,
|
|
338
448
|
ModuleName,
|
|
339
|
-
Type
|
|
449
|
+
Type,
|
|
450
|
+
false
|
|
340
451
|
>
|
|
341
452
|
} {
|
|
342
453
|
return (<Tag extends string, Fields extends S.Struct.Fields, C extends ServiceMap>(
|
|
@@ -345,9 +456,10 @@ export const makeRpcClient = <
|
|
|
345
456
|
config?: C,
|
|
346
457
|
invalidatesQueries?: InvalidationCallback<Resources>
|
|
347
458
|
) => {
|
|
459
|
+
const isStream = (config as any)?.stream === true
|
|
348
460
|
const requestConfig = invalidatesQueries === undefined ? config : { ...config, invalidatesQueries }
|
|
349
461
|
const cls = makeRequestClass(tag, fields, requestConfig)
|
|
350
|
-
Object.assign(cls, { id: `${moduleName}.${tag}`, moduleName, type })
|
|
462
|
+
Object.assign(cls, { id: `${moduleName}.${tag}`, moduleName, type, stream: isStream })
|
|
351
463
|
return cls
|
|
352
464
|
}) as any
|
|
353
465
|
}
|
|
@@ -357,26 +469,21 @@ export const makeRpcClient = <
|
|
|
357
469
|
function TaggedRequestFor<ModuleName extends string>(moduleName: ModuleName) {
|
|
358
470
|
const Query = makeTaggedRequestWithMeta(moduleName, "query")
|
|
359
471
|
const Command = makeTaggedRequestWithMeta(moduleName, "command")
|
|
360
|
-
const Stream = makeTaggedRequestWithMeta(moduleName, "stream")
|
|
361
472
|
|
|
362
473
|
return {
|
|
363
474
|
moduleName,
|
|
364
475
|
/**
|
|
365
476
|
* Create query request classes for this module.
|
|
366
477
|
* Queries read state and should not mutate server state.
|
|
478
|
+
* Pass `stream: true` in the config to produce a Stream of `success` values (QueryStream behaviour).
|
|
367
479
|
*/
|
|
368
480
|
Query,
|
|
369
481
|
/**
|
|
370
482
|
* Create command request classes for this module.
|
|
371
483
|
* Commands mutate state and should avoid returning complex read models.
|
|
484
|
+
* Pass `stream: true` in the config to produce a Stream of `success` values (CommandStream behaviour).
|
|
372
485
|
*/
|
|
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
|
|
486
|
+
Command
|
|
380
487
|
} as const
|
|
381
488
|
}
|
|
382
489
|
|
|
@@ -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"}
|