@effect-app/vue 4.0.0-beta.195 → 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/src/makeClient.ts CHANGED
@@ -3,11 +3,11 @@ import { type InvalidateOptions, type InvalidateQueryFilters, isCancelledError,
3
3
  import { camelCase } from "change-case"
4
4
  import { type Context, Effect, Exit, Hash, type Layer, type ManagedRuntime, S, Struct } from "effect-app"
5
5
  import { type ApiClientFactory, type Req } from "effect-app/client"
6
- import type { ExtractModuleName, HandlerInput, RequestHandler, RequestHandlers, RequestHandlerWithInput, RequestsAny, RequestStreamHandler, RequestStreamHandlerWithInput } from "effect-app/client/clientFor"
6
+ import type { ExtractModuleName, HandlerInput, RequestHandlers, RequestHandlerWithInput, RequestsAny, RequestStreamHandlerWithInput } from "effect-app/client/clientFor"
7
7
  import type { InvalidationCallback } from "effect-app/client/makeClient"
8
8
  import type * as ExitResult from "effect/Exit"
9
9
  import { type Fiber } from "effect/Fiber"
10
- import * as Stream from "effect/Stream"
10
+ import type * as Stream from "effect/Stream"
11
11
  import * as AsyncResult from "effect/unstable/reactivity/AsyncResult"
12
12
  import { type ComputedRef, onBeforeUnmount, ref, type WatchSource } from "vue"
13
13
  import { type Commander, CommanderStatic, type Progress } from "./commander.js"
@@ -20,24 +20,15 @@ import { type Toast } from "./toast.js"
20
20
 
21
21
  export type { Progress }
22
22
 
23
- const mapHandler = <A, E, R, I = void, A2 = A, E2 = E, R2 = R>(
24
- handler: Effect.Effect<A, E, R> | ((i: I) => Effect.Effect<A, E, R>),
25
- map: (self: Effect.Effect<A, E, R>, i: I) => Effect.Effect<A2, E2, R2>
26
- ) => Effect.isEffect(handler) ? map(handler, undefined as any) : (i: I) => map(handler(i), i)
27
-
28
23
  // TODO: optimize - work from encoded shape directly
29
24
  const projectHandler = (
30
- handler: Effect.Effect<any, any, any> | ((i: any) => Effect.Effect<any, any, any>),
25
+ handler: (i: any) => Effect.Effect<any, any, any>,
31
26
  successSchema: S.Top,
32
27
  projectionSchema: S.Top
33
28
  ) => {
34
29
  const encode = S.encodeEffect(successSchema)
35
30
  const decode = S.decodeEffectConcurrently(projectionSchema)
36
- return mapHandler(handler, (self) =>
37
- self.pipe(
38
- Effect.flatMap(encode),
39
- Effect.flatMap(decode)
40
- ))
31
+ return (i: any) => handler(i).pipe(Effect.flatMap(encode), Effect.flatMap(decode))
41
32
  }
42
33
 
43
34
  const projectionSchemaHash = (schema: S.Top) => String(Hash.hash(schema.ast))
@@ -46,53 +37,41 @@ export interface CommandRequestExtensions<RT, Id extends string, I, A, E, R> {
46
37
  /** Defines a Command based on this call, taking the `id` of the call as the `id` of the Command.
47
38
  * The Request function will be taken as the first member of the Command, the Command required input will be the Request input.
48
39
  * see Command.wrap for details */
49
- wrap: Commander.CommanderWrap<RT, Id, Id, undefined, I, A, E, R>
40
+ wrap: <I18nKey extends string = Id, State extends Commander.IntlRecord | undefined = undefined>(
41
+ options?: Commander.FnOptions<Id, I18nKey, State>
42
+ ) => Commander.CommanderWrap<RT, Id, I18nKey, State, I, A, E, R>
50
43
  /** Defines a Command based on this call, taking the `id` of the call as the `id` of the Command.
51
44
  * see Command.fn for details */
52
- fn: Commander.CommanderFn<RT, Id, Id, undefined>
45
+ fn: <I18nKey extends string = Id, State extends Commander.IntlRecord | undefined = undefined>(
46
+ options?: Commander.FnOptions<Id, I18nKey, State>
47
+ ) => Commander.CommanderFn<RT, Id, I18nKey, State>
53
48
  }
54
49
 
55
50
  /** my other doc */
56
- export interface RequestExtWithInput<
57
- RT,
58
- Id extends string,
59
- I,
60
- A,
61
- E,
62
- R
63
- > extends Commander.CommandContextLocal<Id, Id>, CommandRequestExtensions<RT, Id, I, A, E, R> {
64
- /**
65
- * Send the request to the endpoint and return the raw Effect response.
66
- * This does not perform query cache invalidation.
67
- */
68
- request: (i: I) => Effect.Effect<A, E, R>
69
- }
70
-
71
51
  export interface RequestExt<
72
52
  RT,
73
53
  Id extends string,
54
+ I,
74
55
  A,
75
56
  E,
76
57
  R
77
58
  > extends
78
59
  Commander.CommandContextLocal<Id, Id>,
79
- Commander.CommanderWrap<RT, Id, Id, undefined, void, A, E, R>,
80
- CommandRequestExtensions<RT, Id, void, A, E, R>
60
+ Commander.CommanderWrap<RT, Id, Id, undefined, I, A, E, R>,
61
+ CommandRequestExtensions<RT, Id, I, A, E, R>
81
62
  {
82
63
  /**
83
64
  * Send the request to the endpoint and return the raw Effect response.
84
65
  * This does not perform query cache invalidation.
85
66
  */
86
- request: Effect.Effect<A, E, R>
67
+ request: (i: I) => Effect.Effect<A, E, R>
87
68
  }
88
69
 
89
70
  export type CommandRequestWithExtensions<RT, Req> = Req extends
90
- RequestHandlerWithInput<infer I, infer A, infer E, infer R, infer _Request, infer Id>
91
- ? RequestExtWithInput<RT, Id, I, A, E, R>
92
- : Req extends RequestHandler<infer A, infer E, infer R, infer _Request, infer Id> ? RequestExt<RT, Id, A, E, R>
71
+ RequestHandlerWithInput<infer I, infer A, infer E, infer R, infer _Request, infer Id> ? RequestExt<RT, Id, I, A, E, R>
93
72
  : never
94
73
 
95
- export interface QueryExtensionsWithInput<I, A, E, R> {
74
+ export interface QueryExtensions<I, A, E, R> {
96
75
  /**
97
76
  * Send the request to the endpoint and return the raw Effect response.
98
77
  * This does not set up query state tracking.
@@ -100,85 +79,46 @@ export interface QueryExtensionsWithInput<I, A, E, R> {
100
79
  request: (i: I) => Effect.Effect<A, E, R>
101
80
  }
102
81
 
103
- export interface QueryExtensions<A, E, R> {
104
- /**
105
- * Send the request to the endpoint and return the raw Effect response.
106
- * This does not set up query state tracking.
107
- */
108
- request: Effect.Effect<A, E, R>
109
- }
110
-
111
82
  export type QueryRequestWithExtensions<Req> = Req extends
112
- RequestHandlerWithInput<infer I, infer A, infer E, infer R, infer _Request, infer _Id>
113
- ? QueryExtensionsWithInput<I, A, E, R>
114
- : Req extends RequestHandler<infer A, infer E, infer R, infer _Request, infer _Id> ? QueryExtensions<A, E, R>
83
+ RequestHandlerWithInput<infer I, infer A, infer E, infer R, infer _Request, infer _Id> ? QueryExtensions<I, A, E, R>
115
84
  : never
116
85
 
117
86
  type QueryHandler<Req> = Req extends
118
87
  RequestHandlerWithInput<infer I, infer A, infer E, infer R, infer Request, infer Id>
119
88
  ? Request["type"] extends "query" ? RequestHandlerWithInput<I, A, E, R, Request, Id> : never
120
- : Req extends RequestHandler<infer A, infer E, infer R, infer Request, infer Id>
121
- ? Request["type"] extends "query" ? RequestHandler<A, E, R, Request, Id> : never
122
89
  : never
123
90
 
124
91
  type CommandHandler<Req> = Req extends
125
92
  RequestHandlerWithInput<infer I, infer A, infer E, infer R, infer Request, infer Id>
126
93
  ? Request["type"] extends "command" ? RequestHandlerWithInput<I, A, E, R, Request, Id> : never
127
- : Req extends RequestHandler<infer A, infer E, infer R, infer Request, infer Id>
128
- ? Request["type"] extends "command" ? RequestHandler<A, E, R, Request, Id> : never
129
94
  : never
130
95
 
131
- type StreamHandler<Req> = Req extends
96
+ type QueryStreamHandler<Req> = Req extends
132
97
  RequestStreamHandlerWithInput<infer I, infer A, infer E, infer R, infer Request, infer Id, infer Final>
133
- ? Request["type"] extends "stream" ? RequestStreamHandlerWithInput<I, A, E, R, Request, Id, Final> : never
134
- : Req extends RequestStreamHandler<infer A, infer E, infer R, infer Request, infer Id, infer Final>
135
- ? Request["type"] extends "stream" ? RequestStreamHandler<A, E, R, Request, Id, Final> : never
98
+ ? [Request["stream"], Request["type"]] extends [true, "query"]
99
+ ? RequestStreamHandlerWithInput<I, A, E, R, Request, Id, Final>
100
+ : never
101
+ : never
102
+
103
+ type CommandStreamHandler<Req> = Req extends
104
+ RequestStreamHandlerWithInput<infer I, infer A, infer E, infer R, infer Request, infer Id, infer Final>
105
+ ? [Request["stream"], Request["type"]] extends [true, "command"]
106
+ ? RequestStreamHandlerWithInput<I, A, E, R, Request, Id, Final>
107
+ : never
136
108
  : never
137
109
 
138
110
  export interface MutationExtensions<RT, Id extends string, I, A, E, R> {
139
111
  /** Defines a Command based on this mutation, taking the `id` of the mutation as the `id` of the Command.
140
112
  * The Mutation function will be taken as the first member of the Command, the Command required input will be the Mutation input.
141
113
  * see Command.wrap for details */
142
- wrap: Commander.CommanderWrap<RT, Id, Id, undefined, I, A, E, R>
143
- }
144
-
145
- /** my other doc */
146
- export interface MutationExtWithInput<
147
- RT,
148
- Id extends string,
149
- I,
150
- A,
151
- E,
152
- R,
153
- EA = unknown
154
- > extends MutationExtensions<RT, Id, I, A, E, R> {
155
- /**
156
- * Send the request to the endpoint and return the raw Effect response.
157
- * Also invalidates query caches using the request namespace by default.
158
- * Namespace invalidation targets parent namespace keys
159
- * (for example `$project/$configuration.get` invalidates `$project`).
160
- * Override invalidation in client options via `queryInvalidation`.
161
- *
162
- * Pass `options` to attach a `select` Effect that runs after the mutation
163
- * succeeds (its output is returned to the caller) and/or override the default
164
- * `queryInvalidation`.
165
- */
166
- <B = A, E2 = never, R2 = never>(
167
- input: I,
168
- options?: MutationOptionsBase<A, B, E2, R2>
169
- ): Effect.Effect<B, E | E2, R | R2>
170
-
171
- project: <ProjSchema extends S.Top>(
172
- schema: EA extends ProjSchema["Encoded"] ? ProjSchema : never
173
- ) => MutationExtWithInput<
174
- RT,
175
- Id,
176
- I,
177
- S.Schema.Type<ProjSchema>,
178
- E | S.SchemaError,
179
- R | S.Codec.DecodingServices<ProjSchema>,
180
- S.Codec.Encoded<ProjSchema>
181
- >
114
+ wrap: <I18nKey extends string = Id, State extends Commander.IntlRecord | undefined = undefined>(
115
+ options?: Commander.FnOptions<Id, I18nKey, State>
116
+ ) => Commander.CommanderWrap<RT, Id, I18nKey, State, I, A, E, R>
117
+ /** Defines a Command based on this call, taking the `id` of the mutation as the `id` of the Command.
118
+ * see Command.fn for details */
119
+ fn: <I18nKey extends string = Id, State extends Commander.IntlRecord | undefined = undefined>(
120
+ options?: Commander.FnOptions<Id, I18nKey, State>
121
+ ) => Commander.CommanderFn<RT, Id, I18nKey, State>
182
122
  }
183
123
 
184
124
  /**
@@ -187,24 +127,24 @@ export interface MutationExtWithInput<
187
127
  * Namespace invalidation targets parent namespace keys
188
128
  * (for example `$project/$configuration.get` invalidates `$project`).
189
129
  * Override invalidation in client options via `queryInvalidation`.
130
+ *
131
+ * Pass `options` to attach a `select` Effect that runs after the mutation
132
+ * succeeds (its output is returned to the caller) and/or override the default
133
+ * `queryInvalidation`.
134
+ *
135
+ * When `I = void` the input argument may be omitted.
190
136
  */
191
137
  export interface MutationExt<
192
138
  RT,
193
139
  Id extends string,
140
+ I,
194
141
  A,
195
142
  E,
196
143
  R,
197
144
  EA = unknown
198
- > extends MutationExtensions<RT, Id, void, A, E, R> {
199
- /**
200
- * Send the request to the endpoint and return the raw Effect response.
201
- * Also invalidates query caches using the request namespace by default.
202
- *
203
- * Pass `options` to attach a `select` Effect that runs after the mutation
204
- * succeeds (its output is returned to the caller) and/or override the default
205
- * `queryInvalidation`.
206
- */
145
+ > extends MutationExtensions<RT, Id, I, A, E, R> {
207
146
  <B = A, E2 = never, R2 = never>(
147
+ input: I,
208
148
  options?: MutationOptionsBase<A, B, E2, R2>
209
149
  ): Effect.Effect<B, E | E2, R | R2>
210
150
 
@@ -213,6 +153,7 @@ export interface MutationExt<
213
153
  ) => MutationExt<
214
154
  RT,
215
155
  Id,
156
+ I,
216
157
  S.Schema.Type<ProjSchema>,
217
158
  E | S.SchemaError,
218
159
  R | S.Codec.DecodingServices<ProjSchema>,
@@ -222,9 +163,7 @@ export interface MutationExt<
222
163
 
223
164
  export type MutationWithExtensions<RT, Req> = Req extends
224
165
  RequestHandlerWithInput<infer I, infer A, infer E, infer R, infer Request, infer Id>
225
- ? MutationExtWithInput<RT, Id, I, A, E, R, S.Codec.Encoded<Request["success"]>>
226
- : Req extends RequestHandler<infer A, infer E, infer R, infer Request, infer Id>
227
- ? MutationExt<RT, Id, A, E, R, S.Codec.Encoded<Request["success"]>>
166
+ ? MutationExt<RT, Id, I, A, E, R, S.Codec.Encoded<Request["success"]>>
228
167
  : never
229
168
 
230
169
  /**
@@ -233,8 +172,6 @@ export type MutationWithExtensions<RT, Req> = Req extends
233
172
  export type StreamFnStreamExtension<RT, Req> = Req extends
234
173
  RequestStreamHandlerWithInput<infer _I, infer _A, infer _E, infer _R, infer _Request, infer Id, infer _Final>
235
174
  ? Commander.StreamGen<RT, Id, Id, undefined> & Commander.NonGenStream<RT, Id, Id, undefined>
236
- : Req extends RequestStreamHandler<infer _A, infer _E, infer _R, infer _Request, infer Id, infer _Final>
237
- ? Commander.StreamGen<RT, Id, Id, undefined> & Commander.NonGenStream<RT, Id, Id, undefined>
238
175
  : never
239
176
 
240
177
  /**
@@ -246,14 +183,10 @@ export type StreamMutation2WithExtensions<RT, Req> = Req extends
246
183
  & ((input: I) => Stream.Stream<A, E, R>)
247
184
  & {
248
185
  readonly id: Id
249
- readonly wrap: Commander.StreamerWrap<RT, Id, Id, undefined, I, A, E, R>
186
+ readonly wrap: <I18nKey extends string = Id, State extends Commander.IntlRecord | undefined = undefined>(
187
+ options?: Commander.FnOptions<Id, I18nKey, State>
188
+ ) => Commander.StreamerWrap<RT, Id, I18nKey, State, I, A, E, R>
250
189
  }
251
- : Req extends RequestStreamHandler<infer A, infer E, infer R, infer _Request, infer Id, infer _Final> ?
252
- & Stream.Stream<A, E, R>
253
- & {
254
- readonly id: Id
255
- readonly wrap: Commander.StreamerWrap<RT, Id, Id, undefined, void, A, E, R>
256
- }
257
190
  : never
258
191
 
259
192
  // we don't really care about the RT, as we are in charge of ensuring runtime safety anyway
@@ -288,28 +221,14 @@ export type QueryProjection<RT, HandlerReq> = HandlerReq extends
288
221
  >
289
222
  }
290
223
  : {}
291
- : HandlerReq extends RequestHandler<infer _A, infer E, infer R, infer Request, infer Id>
292
- ? Request["type"] extends "query" ? {
293
- project: <ProjSchema extends S.Top>(
294
- schema: S.Codec.Encoded<Request["success"]> extends ProjSchema["Encoded"] ? ProjSchema : never
295
- ) => ProjectResult<
296
- RT,
297
- void,
298
- S.Schema.Type<ProjSchema>,
299
- E | S.SchemaError,
300
- R | S.Codec.DecodingServices<ProjSchema>,
301
- Request,
302
- Id
303
- >
304
- }
305
- : {}
306
224
  : {}
307
225
 
308
- export interface QueriesWithInput<Request extends Req, Id extends string, I, A, E> {
226
+ export interface QueryResultExtensions<Request extends Req, Id extends string, I, A, E> {
309
227
  /**
310
228
  * Read helper for query requests.
311
229
  * Runs as a tracked Vue Query and returns reactive state.
312
230
  * Queries read state and should not be used to mutate it.
231
+ * When `I = void` the input argument may be omitted.
313
232
  */
314
233
  query: ReturnType<typeof useQuery_<I, E, A, Request, Id>>
315
234
  // TODO or suspense as Option?
@@ -319,20 +238,6 @@ export interface QueriesWithInput<Request extends Req, Id extends string, I, A,
319
238
  */
320
239
  suspense: ReturnType<typeof useSuspenseQuery_<I, E, A, Request, Id>>
321
240
  }
322
- export interface QueriesWithoutInput<Request extends Req, Id extends string, A, E> {
323
- /**
324
- * Read helper for query requests.
325
- * Runs as a tracked Vue Query and returns reactive state.
326
- * Queries read state and should not be used to mutate it.
327
- */
328
- query: ReturnType<typeof useQuery_<E, A, Request, Id>>
329
- // TODO or suspense as Option?
330
- /**
331
- * Like `.query`, but returns a Promise for setup-time awaiting.
332
- * Use this when integrating with Vue Suspense / error boundaries.
333
- */
334
- suspense: ReturnType<typeof useSuspenseQuery_<E, A, Request, Id>>
335
- }
336
241
 
337
242
  export type MissingDependencies<RT, R> = {
338
243
  message: "Dependencies required that are not provided by the runtime"
@@ -341,52 +246,32 @@ export type MissingDependencies<RT, R> = {
341
246
 
342
247
  export type Queries<RT, Req> = Req extends
343
248
  RequestHandlerWithInput<infer I, infer A, infer E, infer R, infer Request, infer Id>
344
- ? Request["type"] extends "query" ? Exclude<R, RT> extends never ? QueriesWithInput<Request, Id, I, A, E>
345
- : {
346
- query: MissingDependencies<RT, R> & {}
347
- suspense: MissingDependencies<RT, R> & {}
348
- }
249
+ ? Request["type"] extends "query" ? Exclude<R, RT> extends never ? QueryResultExtensions<Request, Id, I, A, E>
250
+ : { query: MissingDependencies<RT, R> & {}; suspense: MissingDependencies<RT, R> & {} }
349
251
  : never
350
- : Req extends RequestHandler<infer A, infer E, infer R, infer Request, infer Id>
351
- ? Request["type"] extends "query" ? Exclude<R, RT> extends never ? QueriesWithoutInput<Request, Id, A, E>
352
- : { query: MissingDependencies<RT, R> & {}; suspense: MissingDependencies<RT, R> & {} }
353
- : never
354
252
  : never
355
253
 
356
- export interface StreamQueriesWithInput<Request extends Req, Id extends string, I, A, E> {
254
+ export interface StreamQueryExtensions<Request extends Req, Id extends string, I, A, E> {
357
255
  /**
358
- * Stream helper for stream requests.
256
+ * Stream helper for query-stream requests.
359
257
  * Runs as a tracked Vue Query and returns reactive state with accumulated chunks.
360
258
  * Data is an array of all chunks received so far.
259
+ * When `I = void` the input argument may be omitted.
361
260
  */
362
- streamQuery: ReturnType<typeof useStreamQuery_<I, E, A, Request, Id>>
261
+ query: ReturnType<typeof useStreamQuery_<I, E, A, Request, Id>>
363
262
  }
364
- export interface StreamQueriesWithoutInput<Request extends Req, Id extends string, A, E> {
365
- /**
366
- * Stream helper for stream requests.
367
- * Runs as a tracked Vue Query and returns reactive state with accumulated chunks.
368
- * Data is an array of all chunks received so far.
369
- */
370
- streamQuery: ReturnType<typeof useStreamQuery_<E, A, Request, Id>>
371
- }
372
-
373
263
  export type StreamQueries<RT, HandlerReq> = HandlerReq extends
374
264
  RequestStreamHandlerWithInput<infer I, infer A, infer E, infer R, infer Request, infer Id, infer _Final>
375
- ? Exclude<R, RT> extends never ? StreamQueriesWithInput<Request, Id, I, A, E>
376
- : { streamQuery: MissingDependencies<RT, R> & {} }
377
- : HandlerReq extends RequestStreamHandler<infer A, infer E, infer R, infer Request, infer Id, infer _Final>
378
- ? Exclude<R, RT> extends never ? StreamQueriesWithoutInput<Request, Id, A, E>
379
- : { streamQuery: MissingDependencies<RT, R> & {} }
265
+ ? Exclude<R, RT> extends never ? StreamQueryExtensions<Request, Id, I, A, E>
266
+ : { query: MissingDependencies<RT, R> & {} }
380
267
  : never
381
268
 
382
269
  const _useMutation = makeMutation()
383
270
 
384
- const wrapWithSpan = (self: { id: string; handler: any }, mut: any) => {
271
+ const wrapWithSpan = (self: { id: string }, mut: any) => {
385
272
  const span = (eff: Effect.Effect<any, any, any>) =>
386
273
  Effect.withSpan(`mutation ${self.id}`, {}, { captureStackTrace: false })(eff)
387
- return Effect.isEffect(self.handler)
388
- ? (options?: MutationOptionsBase) => span(mut(options))
389
- : (input: any, options?: MutationOptionsBase) => span(mut(input, options))
274
+ return (input: any, options?: MutationOptionsBase) => span(mut(input, options))
390
275
  }
391
276
 
392
277
  /**
@@ -402,7 +287,7 @@ export const useMutation: typeof _useMutation = (<
402
287
  Request extends Req,
403
288
  Name extends string
404
289
  >(
405
- self: RequestHandlerWithInput<I, A, E, R, Request, Name> | RequestHandler<A, E, R, Request, Name>
290
+ self: RequestHandlerWithInput<I, A, E, R, Request, Name>
406
291
  ) =>
407
292
  Object.assign(
408
293
  wrapWithSpan(self, _useMutation(self as any)),
@@ -424,7 +309,7 @@ export const useMutationInt = (): typeof _useMutation => {
424
309
  Request extends Req,
425
310
  Name extends string
426
311
  >(
427
- self: RequestHandlerWithInput<I, A, E, R, Request, Name> | RequestHandler<A, E, R, Request, Name>
312
+ self: RequestHandlerWithInput<I, A, E, R, Request, Name>
428
313
  ) =>
429
314
  Object.assign(
430
315
  wrapWithSpan(self, _useMutation(self as any)),
@@ -447,7 +332,7 @@ export class QueryImpl<R> {
447
332
 
448
333
  /**
449
334
  * Stream results are accumulated as an array of chunks and returned as reactive state.
450
- * @deprecated use client helpers instead (.streamQuery())
335
+ * @deprecated use client helpers instead (.query())
451
336
  */
452
337
  readonly useStreamQuery: ReturnType<typeof makeStreamQuery<R>>
453
338
 
@@ -462,22 +347,18 @@ export class QueryImpl<R> {
462
347
  * The difference with useQuery is that this function will return a Promise you can await in the Setup,
463
348
  * which ensures that either there always is a latest value, or an error occurs on load.
464
349
  * So that Suspense and error boundaries can be used.
465
- * @deprecated use client helpers instead (.suspense())
350
+ * When `I = void` the input argument may be omitted.
466
351
  */
467
352
  <
353
+ I,
468
354
  E,
469
355
  A,
470
356
  Request extends Req,
471
357
  Name extends string
472
358
  >(
473
- self: RequestHandler<A, E, R, Request, Name>
359
+ self: RequestHandlerWithInput<I, A, E, R, Request, Name>
474
360
  ): {
475
- /**
476
- * The difference with useQuery is that this function will return a Promise you can await in the Setup,
477
- * which ensures that either there always is a latest value, or an error occurs on load.
478
- * So that Suspense and error boundaries can be used.
479
- */
480
- <TData = A>(options?: CustomUndefinedInitialQueryOptions<A, E, TData>): Promise<
361
+ <TData = A>(arg: I | WatchSource<I>, options?: CustomUndefinedInitialQueryOptions<A, E, TData>): Promise<
481
362
  readonly [
482
363
  ComputedRef<AsyncResult.AsyncResult<TData, E>>,
483
364
  ComputedRef<TData>,
@@ -488,38 +369,8 @@ export class QueryImpl<R> {
488
369
  ]
489
370
  >
490
371
  }
491
- /**
492
- * The difference with useQuery is that this function will return a Promise you can await in the Setup,
493
- * which ensures that either there always is a latest value, or an error occurs on load.
494
- * So that Suspense and error boundaries can be used.
495
- */
496
- <
497
- Arg,
498
- E,
499
- A,
500
- Request extends Req,
501
- Name extends string
502
- >(
503
- self: RequestHandlerWithInput<Arg, A, E, R, Request, Name>
504
- ): {
505
- /**
506
- * The difference with useQuery is that this function will return a Promise you can await in the Setup,
507
- * which ensures that either there always is a latest value, or an error occurs on load.
508
- * So that Suspense and error boundaries can be used.
509
- */
510
- <TData = A>(arg: Arg | WatchSource<Arg>, options?: CustomUndefinedInitialQueryOptions<A, E, TData>): Promise<
511
- readonly [
512
- ComputedRef<AsyncResult.AsyncResult<TData, E>>,
513
- ComputedRef<TData>,
514
- (
515
- options?: RefetchOptions
516
- ) => Effect.Effect<QueryObserverResult<TData, E>>,
517
- UseQueryReturnType<any, any>
518
- ]
519
- >
520
- }
521
- } = <Arg, E, A, Request extends Req, Name extends string>(
522
- self: RequestHandlerWithInput<Arg, A, E, R, Request, Name> | RequestHandler<A, E, R, Request, Name>
372
+ } = <I, E, A, Request extends Req, Name extends string>(
373
+ self: RequestHandlerWithInput<I, A, E, R, Request, Name>
523
374
  ) => {
524
375
  const runPromise = makeRunPromise(this.getRuntime())
525
376
  const q = this.useQuery(self as any) as any
@@ -668,7 +519,6 @@ export const makeClient = <RT_, RTHooks>(
668
519
 
669
520
  const withDefaultInvalidation = (
670
521
  mut: any,
671
- isWithInput: boolean,
672
522
  defaultInvalidation?: MutationOptionsBase["queryInvalidation"]
673
523
  ) => {
674
524
  if (!defaultInvalidation) return mut
@@ -678,9 +528,7 @@ export const makeClient = <RT_, RTHooks>(
678
528
  ? mergeInvalidation(defaultInvalidation, callerOpts.queryInvalidation)
679
529
  : defaultInvalidation
680
530
  })
681
- return isWithInput
682
- ? (input: any, callerOpts?: MutationOptionsBase) => mut(input, apply(callerOpts))
683
- : (callerOpts?: MutationOptionsBase) => mut(apply(callerOpts))
531
+ return (input: any, callerOpts?: MutationOptionsBase) => mut(input, apply(callerOpts))
684
532
  }
685
533
 
686
534
  const makeQueryResources = <Resources extends InvalidationResources>(resources: Resources | undefined) => {
@@ -696,15 +544,16 @@ export const makeClient = <RT_, RTHooks>(
696
544
  const queries = Struct.keys(client).reduce(
697
545
  (acc, key) => {
698
546
  const requestType = client[key].Request.type
699
- if (requestType === "query") {
547
+ const isStream = client[key].Request.stream
548
+ if (requestType === "query" && !isStream) {
700
549
  ;(acc as any)[camelCase(key) + "Query"] = Object.assign(useQuery(client[key] as any), {
701
550
  id: client[key].id
702
551
  })
703
552
  ;(acc as any)[camelCase(key) + "SuspenseQuery"] = Object.assign(useSuspenseQuery(client[key] as any), {
704
553
  id: client[key].id
705
554
  })
706
- } else if (requestType === "stream") {
707
- ;(acc as any)[camelCase(key) + "StreamQuery"] = Object.assign(useStreamQuery(client[key] as any), {
555
+ } else if (requestType === "query" && isStream) {
556
+ ;(acc as any)[camelCase(key) + "Query"] = Object.assign(useStreamQuery(client[key] as any), {
708
557
  id: client[key].id
709
558
  })
710
559
  }
@@ -731,9 +580,9 @@ export const makeClient = <RT_, RTHooks>(
731
580
  }
732
581
  & {
733
582
  [
734
- Key in keyof typeof client as StreamHandler<typeof client[Key]> extends never ? never
735
- : `${ToCamel<string & Key>}StreamQuery`
736
- ]: StreamQueries<RT, StreamHandler<typeof client[Key]>>["streamQuery"]
583
+ Key in keyof typeof client as QueryStreamHandler<typeof client[Key]> extends never ? never
584
+ : `${ToCamel<string & Key>}Query`
585
+ ]: StreamQueries<RT, QueryStreamHandler<typeof client[Key]>>["query"]
737
586
  }
738
587
  )
739
588
  return queries
@@ -745,16 +594,17 @@ export const makeClient = <RT_, RTHooks>(
745
594
  const Command = useCommand()
746
595
  const mutations = Struct.keys(client).reduce(
747
596
  (acc, key) => {
748
- if (client[key].Request.type !== "command") {
597
+ if (!(client[key].Request.type === "command" && !client[key].Request.stream)) {
749
598
  return acc
750
599
  }
751
600
  const mut = client[key].handler
752
- const fn = Command.fn(client[key].id)
753
- const wrap = Command.wrap({ mutate: Effect.isEffect(mut) ? () => mut : mut, id: client[key].id })
601
+ const request = mut
602
+ const fn = (options?: any) => Command.fn(client[key].id, options)
603
+ const wrap = (options?: any) => Command.wrap({ mutate: request, id: client[key].id }, options)
754
604
  ;(acc as any)[camelCase(key) + "Request"] = Object.assign(
755
605
  mut,
756
- fn, // to get the i18n key etc.
757
- { wrap, fn }
606
+ Command.fn(client[key].id), // to get the i18n key etc.
607
+ { wrap, fn, request }
758
608
  )
759
609
  return acc
760
610
  },
@@ -782,7 +632,7 @@ export const makeClient = <RT_, RTHooks>(
782
632
  const queryResources = makeQueryResources(invalidationResources)
783
633
  const mutations = Struct.keys(client).reduce(
784
634
  (acc, key) => {
785
- if (client[key].Request.type !== "command") {
635
+ if (!(client[key].Request.type === "command" && !client[key].Request.stream)) {
786
636
  return acc
787
637
  }
788
638
  const fromRequestConfig = client[key].Request.config?.["invalidatesQueries"] as
@@ -797,11 +647,10 @@ export const makeClient = <RT_, RTHooks>(
797
647
  : undefined
798
648
  const mergedInvalidation = mergeInvalidation(fromRequest, invalidation?.[key])
799
649
  const makeProjectedMutation = (handler: any): any => {
800
- const isWithInput = !Effect.isEffect(handler.handler)
801
- const mut: any = withDefaultInvalidation(mutation(handler), isWithInput, mergedInvalidation)
802
- const wrap = Command.wrap({ mutate: mut, id: client[key].id })
650
+ const mut: any = withDefaultInvalidation(mutation(handler), mergedInvalidation)
803
651
  return Object.assign(mut, {
804
- wrap,
652
+ wrap: (options?: any) => Command.wrap({ mutate: mut, id: client[key].id }, options),
653
+ fn: (options?: any) => Command.fn(client[key].id, options),
805
654
  project: (projectionSchema: any) => {
806
655
  const projected = {
807
656
  ...handler,
@@ -843,14 +692,12 @@ export const makeClient = <RT_, RTHooks>(
843
692
  const extended = Struct.keys(client).reduce(
844
693
  (acc, key) => {
845
694
  const requestType = client[key].Request.type
695
+ const isStream = client[key].Request.stream
846
696
  const fn = Command.fn(client[key].id)
847
697
  const h_ = client[key].handler
848
- const wrapInput = Effect.isEffect(h_)
849
- ? () => h_
850
- : (...args: [any]) => h_(...args)
851
- const request = Effect.isEffect(h_) ? h_ : wrapInput
698
+ const request = h_
852
699
  ;(acc as any)[key] = Object.assign(
853
- requestType === "query"
700
+ requestType === "query" && !isStream
854
701
  ? {
855
702
  ...client[key],
856
703
  request,
@@ -874,7 +721,13 @@ export const makeClient = <RT_, RTHooks>(
874
721
  }
875
722
  }
876
723
  }
877
- : requestType === "stream"
724
+ : requestType === "query" && isStream
725
+ ? {
726
+ ...client[key],
727
+ request,
728
+ query: useStreamQuery(client[key] as any)
729
+ }
730
+ : requestType === "command" && isStream
878
731
  ? (() => {
879
732
  const fromRequestConfig = client[key].Request.config?.["invalidatesQueries"] as
880
733
  | InvalidationCallback<InvalidationResourcesFor<M>>
@@ -889,20 +742,18 @@ export const makeClient = <RT_, RTHooks>(
889
742
  })))
890
743
  : undefined
891
744
  const mergedInvalidation = mergeInvalidation(fromRequest, invalidation?.[key])
745
+ const streamCmd = useCommand()
892
746
  return {
893
747
  ...client[key],
894
- request: h_,
895
- streamQuery: useStreamQuery(client[key] as any),
896
- streamFn: useCommand().streamFn(client[key].id as any) as any,
748
+ request,
749
+ query: useStreamQuery(client[key] as any),
750
+ fn: streamCmd.streamFn(client[key].id as any) as any,
897
751
  mutate: (() => {
898
752
  const sm2Act = useStreamMutation2()(client[key] as any, mergedInvalidation)
899
- const originalHandler = (client[key] as any).handler
900
- const sm2Handler = Stream.isStream(originalHandler)
901
- ? (_input: any, _ctx: any) => sm2Act
902
- : (input: any, _ctx: any) => (sm2Act as (i: any) => any)(input)
753
+ const sm2Handler = (input: any, _ctx: any) => (sm2Act as (i: any) => any)(input)
903
754
  return Object.assign(sm2Act, {
904
755
  id: client[key].id,
905
- wrap: useCommand().streamWrap(sm2Handler, client[key].id as any)
756
+ wrap: (options?: any) => streamCmd.streamWrap(sm2Handler, client[key].id as any, options)
906
757
  })
907
758
  })()
908
759
  }
@@ -923,15 +774,16 @@ export const makeClient = <RT_, RTHooks>(
923
774
  : undefined
924
775
  const mergedInvalidation = mergeInvalidation(fromRequest, invalidation?.[key])
925
776
  const makeProjectedMutation = (h: any): any => {
926
- const isWithInput = !Effect.isEffect(h.handler)
927
- const mutate = withDefaultInvalidation(mutation(h), isWithInput, mergedInvalidation)
777
+ const mutate = withDefaultInvalidation(mutation(h), mergedInvalidation)
928
778
  return Object.assign(
929
779
  mutate,
930
780
  {
931
- wrap: Command.wrap({
932
- mutate,
933
- id: client[key].id
934
- }),
781
+ wrap: (options?: any) =>
782
+ Command.wrap({
783
+ mutate,
784
+ id: client[key].id
785
+ }, options),
786
+ fn: (options?: any) => Command.fn(client[key].id, options),
935
787
  project: (projectionSchema: any) => {
936
788
  const projected = {
937
789
  ...h,
@@ -947,8 +799,8 @@ export const makeClient = <RT_, RTHooks>(
947
799
  ...client[key],
948
800
  ...fn, // to get the i18n key etc.
949
801
  request,
950
- fn,
951
- wrap: Command.wrap({ mutate: wrapInput, id: client[key].id })
802
+ fn: (options?: any) => Command.fn(client[key].id, options),
803
+ wrap: (options?: any) => Command.wrap({ mutate: h_, id: client[key].id }, options)
952
804
  }
953
805
  )
954
806
  return acc
@@ -961,16 +813,16 @@ export const makeClient = <RT_, RTHooks>(
961
813
  & QueryRequestWithExtensions<QueryHandler<typeof client[Key]>>
962
814
  & Queries<RT, QueryHandler<typeof client[Key]>>
963
815
  & QueryProjection<RT, QueryHandler<typeof client[Key]>>)
964
- & (StreamHandler<typeof client[Key]> extends never ? {}
965
- : StreamQueries<RT, StreamHandler<typeof client[Key]>>)
816
+ & (QueryStreamHandler<typeof client[Key]> extends never ? {}
817
+ : StreamQueries<RT, QueryStreamHandler<typeof client[Key]>>)
966
818
  & (CommandHandler<typeof client[Key]> extends never ? {}
967
819
  : CommandRequestWithExtensions<RT | RTHooks, CommandHandler<typeof client[Key]>>)
968
820
  & (CommandHandler<typeof client[Key]> extends never ? {}
969
821
  : { mutate: MutationWithExtensions<RT | RTHooks, CommandHandler<typeof client[Key]>> })
970
- & (StreamHandler<typeof client[Key]> extends never ? {}
822
+ & (CommandStreamHandler<typeof client[Key]> extends never ? {}
971
823
  : {
972
- streamFn: StreamFnStreamExtension<RT | RTHooks, StreamHandler<typeof client[Key]>>
973
- mutate: StreamMutation2WithExtensions<RT | RTHooks, StreamHandler<typeof client[Key]>>
824
+ fn: StreamFnStreamExtension<RT | RTHooks, CommandStreamHandler<typeof client[Key]>>
825
+ mutate: StreamMutation2WithExtensions<RT | RTHooks, CommandStreamHandler<typeof client[Key]>>
974
826
  })
975
827
  & { Input: typeof client[Key] extends RequestHandlerWithInput<infer I, any, any, any, any, any> ? I : never }
976
828
  }