@effect-app/vue 2.77.4 → 2.77.6

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
@@ -8,7 +8,7 @@ import type { RequestHandler, RequestHandlers, RequestHandlerWithInput, Requests
8
8
  import { ErrorSilenced, type SupportedErrors } from "effect-app/client/errors"
9
9
  import { constant, identity, pipe, tuple } from "effect-app/Function"
10
10
  import { type OperationFailure, OperationSuccess } from "effect-app/Operations"
11
- import type { Schema } from "effect-app/Schema"
11
+ import { type Schema } from "effect-app/Schema"
12
12
  import { dropUndefinedT } from "effect-app/utils"
13
13
  import { type RuntimeFiber } from "effect/Fiber"
14
14
  import { computed, type ComputedRef, onBeforeUnmount, type Ref, ref, watch, type WatchSource } from "vue"
@@ -241,644 +241,645 @@ export const useMutationInt = (): typeof _useMutation => {
241
241
  )
242
242
  }
243
243
 
244
- // @effect-diagnostics-next-line missingEffectServiceDependency:off
245
- export class LegacyMutation extends Effect.Service<LegacyMutation>()("LegacyMutation", {
246
- effect: Effect.gen(function*() {
247
- const intl = yield* I18n
248
- const toast = yield* Toast
244
+ export class LegacyMutationImpl<RT> {
245
+ constructor(
246
+ private readonly getRuntime: () => Runtime.Runtime<RT>,
247
+ private readonly toast: Toast,
248
+ private readonly intl: I18n
249
+ ) {}
249
250
 
250
- return <R>(getRuntime: () => Runtime.Runtime<R>) => {
251
- /**
252
- * Effect results are converted to Exit, so errors are ignored by default.
253
- * you should use the result ref to render errors!
254
- */
255
- const _useSafeMutation: {
256
- <I, E, A, R, Request extends TaggedRequestClassAny, Name extends string, A2 = A, E2 = E, R2 = R>(
257
- self: RequestHandlerWithInput<I, A, E, R, Request, Name>,
258
- options?: MutationOptions<A, E, R, A2, E2, R2, I>
259
- ): readonly [
260
- ComputedRef<Result.Result<A2, E2>>,
261
- (i: I) => Effect.Effect<Exit.Exit<A2, E2>, never, R2>
262
- ]
263
- <E, A, R, Request extends TaggedRequestClassAny, Name extends string, A2 = A, E2 = E, R2 = R>(
264
- self: RequestHandler<A, E, R, Request, Name>,
265
- options?: MutationOptions<A, E, R, A2, E2, R2>
266
- ): readonly [
267
- ComputedRef<Result.Result<A2, E2>>,
268
- Effect.Effect<Exit.Exit<A2, E2>, never, R2>
269
- ]
270
- } = <I, E, A, R, Request extends TaggedRequestClassAny, Name extends string, A2 = A, E2 = E, R2 = R>(
271
- self: RequestHandlerWithInput<I, A, E, R, Request, Name> | RequestHandler<A, E, R, Request, Name>,
272
- options?: MutationOptions<A, E, R, A2, E2, R2, I>
273
- ) => {
274
- const unsafe = _useMutation(self as any, options)
275
-
276
- type MH = NonNullable<NonNullable<typeof options>["mapHandler"]>
277
- const mh = options?.mapHandler ?? identity as MH
278
-
279
- const [a, b] = asResult(mapHandler(mapHandler(unsafe as any, mh), Effect.tapDefect(reportRuntimeError)) as any)
280
- return [
281
- a,
282
- mapHandler(
283
- b,
284
- Effect.withSpan(`mutation ${self.id}`, { captureStackTrace: false })
285
- )
286
- ] as const as any
287
- }
251
+ /**
252
+ * Effect results are converted to Exit, so errors are ignored by default.
253
+ * you should use the result ref to render errors!
254
+ * @deprecated use `Command.fn` and friends instead
255
+ */
256
+ readonly useSafeMutation: {
257
+ <I, E, A, R, Request extends TaggedRequestClassAny, Name extends string, A2 = A, E2 = E, R2 = R>(
258
+ self: RequestHandlerWithInput<I, A, E, R, Request, Name>,
259
+ options?: MutationOptions<A, E, R, A2, E2, R2, I>
260
+ ): readonly [
261
+ ComputedRef<Result.Result<A2, E2>>,
262
+ (i: I) => Effect.Effect<Exit.Exit<A2, E2>, never, R2>
263
+ ]
264
+ <E, A, R, Request extends TaggedRequestClassAny, Name extends string, A2 = A, E2 = E, R2 = R>(
265
+ self: RequestHandler<A, E, R, Request, Name>,
266
+ options?: MutationOptions<A, E, R, A2, E2, R2>
267
+ ): readonly [
268
+ ComputedRef<Result.Result<A2, E2>>,
269
+ Effect.Effect<Exit.Exit<A2, E2>, never, R2>
270
+ ]
271
+ } = <I, E, A, R, Request extends TaggedRequestClassAny, Name extends string, A2 = A, E2 = E, R2 = R>(
272
+ self: RequestHandlerWithInput<I, A, E, R, Request, Name> | RequestHandler<A, E, R, Request, Name>,
273
+ options?: MutationOptions<A, E, R, A2, E2, R2, I>
274
+ ) => {
275
+ const unsafe = _useMutation(self as any, options)
288
276
 
289
- /** handles errors as toasts and reports defects */
290
- const _useHandleRequestWithToast = () => {
291
- return handleRequestWithToast
292
- /**
293
- * Pass a function that returns a Promise.
294
- * Returns an execution function which reports errors as Toast.
295
- */
296
- function handleRequestWithToast<
297
- A,
298
- E extends ResponseErrors,
299
- R,
300
- I = void,
301
- A2 = A,
302
- E2 extends ResponseErrors = E,
303
- R2 = R,
304
- ESuccess = never,
305
- RSuccess = never,
306
- EError = never,
307
- RError = never,
308
- EDefect = never,
309
- RDefect = never
310
- >(
311
- f: Effect.Effect<Exit.Exit<A2, E2>, never, R2> | ((i: I) => Effect.Effect<Exit.Exit<A2, E2>, never, R2>),
312
- id: string,
313
- action: string,
314
- options: Opts<A, E, R, I, A2, E2, R2, ESuccess, RSuccess, EError, RError, EDefect, RDefect> = {}
315
- ) {
316
- const actionMessage = intl.formatMessage({ id: `action.${action}`, defaultMessage: action })
317
- const defaultWarnMessage = intl.formatMessage(
318
- { id: "handle.with_warnings" },
319
- { action: actionMessage }
320
- )
321
- const defaultSuccessMessage = intl.formatMessage(
322
- { id: "handle.success" },
323
- { action: actionMessage }
324
- )
325
- const defaultErrorMessage = intl.formatMessage(
326
- { id: "handle.with_errors" },
327
- { action: actionMessage }
328
- )
277
+ type MH = NonNullable<NonNullable<typeof options>["mapHandler"]>
278
+ const mh = options?.mapHandler ?? identity as MH
329
279
 
330
- return handleRequest<E2, A2, R2, any, ESuccess, RSuccess, EError, RError, EDefect, RDefect>(f, id, action, {
331
- onSuccess: Effect.fnUntraced(function*(a, i) {
332
- const message = options.successMessage ? yield* options.successMessage(a, i) : defaultSuccessMessage
333
- + (S.is(OperationSuccess)(a) && a.message
334
- ? "\n" + a.message
335
- : "")
336
- if (message) {
337
- yield* toast.success(message)
338
- }
339
- }),
340
- onFail: Effect.fnUntraced(function*(e, i) {
341
- if (!options.failMessage && e._tag === "OperationFailure") {
342
- yield* toast.warning(
343
- defaultWarnMessage + e.message
344
- ? "\n" + e.message
345
- : ""
346
- )
347
- return
348
- }
280
+ const [a, b] = asResult(mapHandler(mapHandler(unsafe as any, mh), Effect.tapDefect(reportRuntimeError)) as any)
281
+ return [
282
+ a,
283
+ mapHandler(
284
+ b,
285
+ Effect.withSpan(`mutation ${self.id}`, { captureStackTrace: false })
286
+ )
287
+ ] as const as any
288
+ }
349
289
 
350
- const message = options.failMessage
351
- ? yield* options.failMessage(e, i)
352
- : `${defaultErrorMessage}:\n` + renderError(e)
353
- if (message) {
354
- yield* toast.error(message)
355
- }
356
- }),
357
- onDefect: Effect.fnUntraced(function*(cause, i) {
358
- const message = options.defectMessage
359
- ? yield* options.defectMessage(cause, i)
360
- : intl.formatMessage(
361
- { id: "handle.unexpected_error" },
362
- {
363
- action: actionMessage,
364
- error: Cause.pretty(cause)
365
- }
366
- )
367
- if (message) {
368
- yield* toast.error(message)
369
- }
370
- })
371
- })
372
- }
290
+ /** handles errors as toasts and reports defects
291
+ * @deprecated use `Command.fn` and friends instead
292
+ */
293
+ readonly useHandleRequestWithToast = () => {
294
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
295
+ const self = this
296
+ return handleRequestWithToast
297
+ /**
298
+ * Pass a function that returns a Promise.
299
+ * Returns an execution function which reports errors as Toast.
300
+ */
301
+ function handleRequestWithToast<
302
+ A,
303
+ E extends ResponseErrors,
304
+ R,
305
+ I = void,
306
+ A2 = A,
307
+ E2 extends ResponseErrors = E,
308
+ R2 = R,
309
+ ESuccess = never,
310
+ RSuccess = never,
311
+ EError = never,
312
+ RError = never,
313
+ EDefect = never,
314
+ RDefect = never
315
+ >(
316
+ f: Effect.Effect<Exit.Exit<A2, E2>, never, R2> | ((i: I) => Effect.Effect<Exit.Exit<A2, E2>, never, R2>),
317
+ id: string,
318
+ action: string,
319
+ options: Opts<A, E, R, I, A2, E2, R2, ESuccess, RSuccess, EError, RError, EDefect, RDefect> = {}
320
+ ) {
321
+ const actionMessage = self.intl.formatMessage({ id: `action.${action}`, defaultMessage: action })
322
+ const defaultWarnMessage = self.intl.formatMessage(
323
+ { id: "handle.with_warnings" },
324
+ { action: actionMessage }
325
+ )
326
+ const defaultSuccessMessage = self.intl.formatMessage(
327
+ { id: "handle.success" },
328
+ { action: actionMessage }
329
+ )
330
+ const defaultErrorMessage = self.intl.formatMessage(
331
+ { id: "handle.with_errors" },
332
+ { action: actionMessage }
333
+ )
373
334
 
374
- function renderError(e: ResponseErrors): string {
375
- return Match.value(e).pipe(
376
- Match.tags({
377
- // HttpErrorRequest: e =>
378
- // intl.value.formatMessage(
379
- // { id: "handle.request_error" },
380
- // { error: `${e.error}` },
381
- // ),
382
- // HttpErrorResponse: e =>
383
- // e.response.status >= 500 ||
384
- // e.response.body._tag !== "Some" ||
385
- // !e.response.body.value
386
- // ? intl.value.formatMessage(
387
- // { id: "handle.error_response" },
388
- // {
389
- // error: `${
390
- // e.response.body._tag === "Some" && e.response.body.value
391
- // ? parseError(e.response.body.value)
392
- // : "Unknown"
393
- // } (${e.response.status})`,
394
- // },
395
- // )
396
- // : intl.value.formatMessage(
397
- // { id: "handle.unexpected_error" },
398
- // {
399
- // error:
400
- // JSON.stringify(e.response.body, undefined, 2) +
401
- // "( " +
402
- // e.response.status +
403
- // ")",
404
- // },
405
- // ),
406
- // ResponseError: e =>
407
- // intl.value.formatMessage(
408
- // { id: "handle.response_error" },
409
- // { error: `${e.error}` },
410
- // ),
411
- ParseError: (e) => {
412
- console.warn(e.toString())
413
- return intl.formatMessage({ id: "validation.failed" })
335
+ return handleRequest<E2, A2, R2, any, ESuccess, RSuccess, EError, RError, EDefect, RDefect>(f, id, action, {
336
+ onSuccess: Effect.fnUntraced(function*(a, i) {
337
+ const message = options.successMessage ? yield* options.successMessage(a, i) : defaultSuccessMessage
338
+ + (S.is(OperationSuccess)(a) && a.message
339
+ ? "\n" + a.message
340
+ : "")
341
+ if (message) {
342
+ yield* self.toast.success(message)
343
+ }
344
+ }),
345
+ onFail: Effect.fnUntraced(function*(e, i) {
346
+ if (!options.failMessage && e._tag === "OperationFailure") {
347
+ yield* self.toast.warning(
348
+ defaultWarnMessage + e.message
349
+ ? "\n" + e.message
350
+ : ""
351
+ )
352
+ return
353
+ }
354
+
355
+ const message = options.failMessage
356
+ ? yield* options.failMessage(e, i)
357
+ : `${defaultErrorMessage}:\n` + renderError(e)
358
+ if (message) {
359
+ yield* self.toast.error(message)
360
+ }
361
+ }),
362
+ onDefect: Effect.fnUntraced(function*(cause, i) {
363
+ const message = options.defectMessage
364
+ ? yield* options.defectMessage(cause, i)
365
+ : self.intl.formatMessage(
366
+ { id: "handle.unexpected_error" },
367
+ {
368
+ action: actionMessage,
369
+ error: Cause.pretty(cause)
414
370
  }
415
- }),
416
- Match.orElse((e) => `${e.message ?? e._tag ?? e}`)
417
- )
418
- }
419
- }
371
+ )
372
+ if (message) {
373
+ yield* self.toast.error(message)
374
+ }
375
+ })
376
+ })
377
+ }
420
378
 
421
- /**
422
- * Pass a function that returns an Effect, e.g from a client action, give it a name.
423
- * Returns a tuple with raw Result and execution function which reports success and errors as Toast.
424
- */
425
- const _useAndHandleMutationResult: {
426
- <
427
- I,
428
- E extends ResponseErrors,
429
- A,
430
- R,
431
- Request extends TaggedRequestClassAny,
432
- Name extends string,
433
- A2 = A,
434
- E2 extends ResponseErrors = E,
435
- R2 = R,
436
- ESuccess = never,
437
- RSuccess = never,
438
- EError = never,
439
- RError = never,
440
- EDefect = never,
441
- RDefect = never
442
- >(
443
- self: RequestHandlerWithInput<I, A, E, R, Request, Name>,
444
- action: string,
445
- options?: Opts<A, E, R, I, A2, E2, R2, ESuccess, RSuccess, EError, RError, EDefect, RDefect>
446
- ): Resp<I, A2, E2, R2, ComputedRef<Result.Result<A2, E2>>>
447
- <
448
- E extends ResponseErrors,
449
- A,
450
- R,
451
- Request extends TaggedRequestClassAny,
452
- Name extends string,
453
- A2 = A,
454
- E2 extends ResponseErrors = E,
455
- R2 = R,
456
- ESuccess = never,
457
- RSuccess = never,
458
- EError = never,
459
- RError = never,
460
- EDefect = never,
461
- RDefect = never
462
- >(
463
- self: RequestHandler<A, E, R, Request, Name>,
464
- action: string,
465
- options?: Opts<A, E, R, void, A2, E2, R2, ESuccess, RSuccess, EError, RError, EDefect, RDefect>
466
- ): ActResp<A2, E2, R2, ComputedRef<Result.Result<A2, E2>>>
467
- } = <E extends ResponseErrors, A, R, Request extends TaggedRequestClassAny, Name extends string, I>(
468
- self: RequestHandlerWithInput<I, A, E, R, Request, Name> | RequestHandler<A, E, R, Request, Name>,
469
- action: any,
470
- options?: Opts<any, any, any, any, any, any, any, any, any, any, any, any, any>
471
- ): any => {
472
- const handleRequestWithToast = _useHandleRequestWithToast()
473
- const handler = self.handler
474
- const unsafe = _useMutation({
475
- ...self,
476
- handler: Effect.isEffect(handler)
477
- ? (pipe(
478
- Effect.annotateCurrentSpan({ action }),
479
- Effect.zipRight(handler)
480
- ) as any)
481
- : (...args: [any]) =>
482
- pipe(
483
- Effect.annotateCurrentSpan({ action }),
484
- Effect.zipRight(handler(...args))
485
- )
486
- }, options ? dropUndefinedT(options) : undefined)
487
-
488
- type MH = NonNullable<NonNullable<typeof options>["mapHandler"]>
489
- const mh = options?.mapHandler ?? identity as MH
490
-
491
- // Effect.tapDefect(reportRuntimeError) handled in toast handler,
492
- const [a, b] = asResult(mapHandler(unsafe, mh) as any)
493
-
494
- return tuple(
495
- a,
496
- handleRequestWithToast(b as any, self.id, action, options)
497
- )
498
- }
499
- //
500
-
501
- /**
502
- * Pass a function that returns an Effect, e.g from a client action, give it a name.
503
- * Returns a tuple with state ref and execution function which reports success and errors as Toast.
504
- */
505
- const _useAndHandleMutation: {
506
- <
507
- I,
508
- E extends ResponseErrors,
509
- A,
510
- R,
511
- Request extends TaggedRequestClassAny,
512
- Name extends string,
513
- A2 = A,
514
- E2 extends ResponseErrors = E,
515
- R2 = R,
516
- ESuccess = never,
517
- RSuccess = never,
518
- EError = never,
519
- RError = never,
520
- EDefect = never,
521
- RDefect = never
522
- >(
523
- self: RequestHandlerWithInput<I, A, E, R, Request, Name>,
524
- action: string,
525
- options?: Opts<A, E, R, I, A2, E2, R2, ESuccess, RSuccess, EError, RError, EDefect, RDefect>
526
- ): Resp<I, A2, E2, R2>
527
- <
528
- E extends ResponseErrors,
529
- A,
530
- R,
531
- Request extends TaggedRequestClassAny,
532
- Name extends string,
533
- A2 = A,
534
- E2 extends ResponseErrors = E,
535
- R2 = R,
536
- ESuccess = never,
537
- RSuccess = never,
538
- EError = never,
539
- RError = never,
540
- EDefect = never,
541
- RDefect = never
542
- >(
543
- self: RequestHandler<A, E, R, Request, Name>,
544
- action: string,
545
- options?: Opts<A, E, R, void, A2, E2, R2, ESuccess, RSuccess, EError, RError, EDefect, RDefect>
546
- ): ActResp<A2, E2, R2>
547
- } = (
548
- self: any,
549
- action: any,
550
- options?: Opts<any, any, any, any, any, any, any, any, any, any, any, any, any>
551
- ): any => {
552
- const [a, b] = _useAndHandleMutationResult(self, action, options)
553
-
554
- return tuple(
555
- computed(() => mutationResultToVue(a.value)),
556
- b
557
- )
558
- }
379
+ function renderError(e: ResponseErrors): string {
380
+ return Match.value(e).pipe(
381
+ Match.tags({
382
+ // HttpErrorRequest: e =>
383
+ // this.intl.value.formatMessage(
384
+ // { id: "handle.request_error" },
385
+ // { error: `${e.error}` },
386
+ // ),
387
+ // HttpErrorResponse: e =>
388
+ // e.response.status >= 500 ||
389
+ // e.response.body._tag !== "Some" ||
390
+ // !e.response.body.value
391
+ // ? this.intl.value.formatMessage(
392
+ // { id: "handle.error_response" },
393
+ // {
394
+ // error: `${
395
+ // e.response.body._tag === "Some" && e.response.body.value
396
+ // ? parseError(e.response.body.value)
397
+ // : "Unknown"
398
+ // } (${e.response.status})`,
399
+ // },
400
+ // )
401
+ // : this.intl.value.formatMessage(
402
+ // { id: "handle.unexpected_error" },
403
+ // {
404
+ // error:
405
+ // JSON.stringify(e.response.body, undefined, 2) +
406
+ // "( " +
407
+ // e.response.status +
408
+ // ")",
409
+ // },
410
+ // ),
411
+ // ResponseError: e =>
412
+ // this.intl.value.formatMessage(
413
+ // { id: "handle.response_error" },
414
+ // { error: `${e.error}` },
415
+ // ),
416
+ ParseError: (e) => {
417
+ console.warn(e.toString())
418
+ return self.intl.formatMessage({ id: "validation.failed" })
419
+ }
420
+ }),
421
+ Match.orElse((e) => `${e.message ?? e._tag ?? e}`)
422
+ )
423
+ }
424
+ }
559
425
 
560
- function _makeUseAndHandleMutation(
561
- defaultOptions?: Opts<any, any, any, any, any, any, any, any, any>
562
- ) {
563
- return ((self: any, action: any, options: any) => {
564
- return _useAndHandleMutation(
565
- self,
566
- action,
567
- { ...defaultOptions, ...options }
426
+ /**
427
+ * Pass a function that returns an Effect, e.g from a client action, give it a name.
428
+ * Returns a tuple with raw Result and execution function which reports success and errors as Toast.
429
+ * @deprecated use `Command.fn` and friends instead
430
+ */
431
+ readonly useAndHandleMutationResult: {
432
+ <
433
+ I,
434
+ E extends ResponseErrors,
435
+ A,
436
+ R,
437
+ Request extends TaggedRequestClassAny,
438
+ Name extends string,
439
+ A2 = A,
440
+ E2 extends ResponseErrors = E,
441
+ R2 = R,
442
+ ESuccess = never,
443
+ RSuccess = never,
444
+ EError = never,
445
+ RError = never,
446
+ EDefect = never,
447
+ RDefect = never
448
+ >(
449
+ self: RequestHandlerWithInput<I, A, E, R, Request, Name>,
450
+ action: string,
451
+ options?: Opts<A, E, R, I, A2, E2, R2, ESuccess, RSuccess, EError, RError, EDefect, RDefect>
452
+ ): Resp<I, A2, E2, R2, ComputedRef<Result.Result<A2, E2>>>
453
+ <
454
+ E extends ResponseErrors,
455
+ A,
456
+ R,
457
+ Request extends TaggedRequestClassAny,
458
+ Name extends string,
459
+ A2 = A,
460
+ E2 extends ResponseErrors = E,
461
+ R2 = R,
462
+ ESuccess = never,
463
+ RSuccess = never,
464
+ EError = never,
465
+ RError = never,
466
+ EDefect = never,
467
+ RDefect = never
468
+ >(
469
+ self: RequestHandler<A, E, R, Request, Name>,
470
+ action: string,
471
+ options?: Opts<A, E, R, void, A2, E2, R2, ESuccess, RSuccess, EError, RError, EDefect, RDefect>
472
+ ): ActResp<A2, E2, R2, ComputedRef<Result.Result<A2, E2>>>
473
+ } = <E extends ResponseErrors, A, R, Request extends TaggedRequestClassAny, Name extends string, I>(
474
+ self: RequestHandlerWithInput<I, A, E, R, Request, Name> | RequestHandler<A, E, R, Request, Name>,
475
+ action: any,
476
+ options?: Opts<any, any, any, any, any, any, any, any, any, any, any, any, any>
477
+ ): any => {
478
+ const handleRequestWithToast = this.useHandleRequestWithToast()
479
+ const handler = self.handler
480
+ const unsafe = _useMutation({
481
+ ...self,
482
+ handler: Effect.isEffect(handler)
483
+ ? (pipe(
484
+ Effect.annotateCurrentSpan({ action }),
485
+ Effect.zipRight(handler)
486
+ ) as any)
487
+ : (...args: [any]) =>
488
+ pipe(
489
+ Effect.annotateCurrentSpan({ action }),
490
+ Effect.zipRight(handler(...args))
568
491
  )
569
- }) as unknown as {
570
- <
571
- I,
572
- E extends ResponseErrors,
573
- A,
574
- R,
575
- Request extends TaggedRequestClassAny,
576
- Name extends string,
577
- A2 = A,
578
- E2 extends ResponseErrors = E,
579
- R2 = R,
580
- ESuccess = never,
581
- RSuccess = never,
582
- EError = never,
583
- RError = never,
584
- EDefect = never,
585
- RDefect = never
586
- >(
587
- self: RequestHandlerWithInput<I, A, E, R, Request, Name>,
588
- action: string,
589
- options?: Opts<A, E, R, I, A2, E2, R2, ESuccess, RSuccess, EError, RError, EDefect, RDefect>
590
- ): Resp<I, A2, E2, R2>
591
- <
592
- E extends ResponseErrors,
593
- A,
594
- Request extends TaggedRequestClassAny,
595
- Name extends string,
596
- A2 = A,
597
- E2 extends ResponseErrors = E,
598
- R2 = R,
599
- ESuccess = never,
600
- RSuccess = never,
601
- EError = never,
602
- RError = never,
603
- EDefect = never,
604
- RDefect = never
605
- >(
606
- self: RequestHandler<A, E, R, Request, Name>,
607
- action: string,
608
- options?: Opts<A, E, R, void, A2, E2, R2, ESuccess, RSuccess, EError, RError, EDefect, RDefect>
609
- ): ActResp<A2, E2, R2>
610
- }
611
- }
492
+ }, options ? dropUndefinedT(options) : undefined)
612
493
 
613
- /**
614
- * The same as @see useAndHandleMutation, but does not display any toasts by default.
615
- * Messages for success, error and defect toasts can be provided in the Options.
616
- */
617
- const _useAndHandleMutationSilently: {
618
- <
619
- I,
620
- E extends ResponseErrors,
621
- A,
622
- R,
623
- Request extends TaggedRequestClassAny,
624
- Name extends string,
625
- A2 = A,
626
- E2 extends ResponseErrors = E,
627
- R2 = R,
628
- ESuccess = never,
629
- RSuccess = never,
630
- EError = never,
631
- RError = never,
632
- EDefect = never,
633
- RDefect = never
634
- >(
635
- self: RequestHandlerWithInput<I, A, E, R, Request, Name>,
636
- action: string,
637
- options?: Opts<A, E, R, I, A2, E2, R2, ESuccess, RSuccess, EError, RError, EDefect, RDefect>
638
- ): Resp<I, A2, E2, R>
639
- <
640
- E extends ResponseErrors,
641
- A,
642
- R,
643
- Request extends TaggedRequestClassAny,
644
- Name extends string,
645
- A2 = A,
646
- E2 extends ResponseErrors = E,
647
- R2 = R,
648
- ESuccess = never,
649
- RSuccess = never,
650
- EError = never,
651
- RError = never,
652
- EDefect = never,
653
- RDefect = never
654
- >(
655
- self: RequestHandler<A, E, R, Request, Name>,
656
- action: string,
657
- options?: Opts<A, E, R, void, A2, E2, R2, ESuccess, RSuccess, EError, RError, EDefect, RDefect>
658
- ): ActResp<void, never, R>
659
- } = _makeUseAndHandleMutation({
660
- successMessage: suppressToast,
661
- failMessage: suppressToast,
662
- defectMessage: suppressToast
663
- }) as any
494
+ type MH = NonNullable<NonNullable<typeof options>["mapHandler"]>
495
+ const mh = options?.mapHandler ?? identity as MH
664
496
 
665
- /**
666
- * The same as @see useAndHandleMutation, but does not act on success, error or defect by default.
667
- * Actions for success, error and defect can be provided in the Options.
668
- */
669
- const _useAndHandleMutationCustom: {
670
- <
671
- I,
672
- E extends ResponseErrors,
673
- A,
674
- R,
675
- Request extends TaggedRequestClassAny,
676
- Name extends string,
677
- A2 = A,
678
- E2 extends ResponseErrors = E,
679
- R2 = R,
680
- ESuccess = never,
681
- RSuccess = never,
682
- EError = never,
683
- RError = never,
684
- EDefect = never,
685
- RDefect = never
686
- >(
687
- self: RequestHandlerWithInput<I, A, E, R, Request, Name>,
688
- action: string,
689
- options?: LowOptsOptional<A, E, R, I, A2, E2, R2, ESuccess, RSuccess, EError, RError, EDefect, RDefect>
690
- ): Resp<I, A2, E2, R2>
691
- <
692
- E extends ResponseErrors,
693
- A,
694
- R,
695
- Request extends TaggedRequestClassAny,
696
- Name extends string,
697
- A2 = A,
698
- E2 extends ResponseErrors = E,
699
- R2 = R,
700
- ESuccess = never,
701
- RSuccess = never,
702
- EError = never,
703
- RError = never,
704
- EDefect = never,
705
- RDefect = never
706
- >(
707
- self: RequestHandler<A, E, R, Request, Name>,
708
- action: string,
709
- options?: LowOptsOptional<A, E, R, void, A2, E2, R2, ESuccess, RSuccess, EError, RError, EDefect, RDefect>
710
- ): ActResp<A2, E2, R2>
711
- } = (self: any, action: string, options: any) => {
712
- const unsafe = _useMutation({
713
- ...self,
714
- handler: Effect.isEffect(self.handler)
715
- ? (pipe(
716
- Effect.annotateCurrentSpan({ action }),
717
- Effect.andThen(self.handler)
718
- ) as any)
719
- : (...args: any[]) =>
720
- pipe(
721
- Effect.annotateCurrentSpan({ action }),
722
- Effect.andThen(self.handler(...args))
723
- )
724
- }, options ? dropUndefinedT(options) : undefined)
725
-
726
- type MH = NonNullable<NonNullable<typeof options>["mapHandler"]>
727
- const mh = options?.mapHandler ?? identity as MH
728
-
729
- const [a, b] = asResult(mapHandler(mapHandler(unsafe as any, mh), Effect.tapDefect(reportRuntimeError)) as any)
730
-
731
- return tuple(
732
- computed(() => mutationResultToVue(a.value)),
733
- handleRequest(b as any, self.id, action, {
734
- onSuccess: suppressToast,
735
- onDefect: suppressToast,
736
- onFail: suppressToast,
737
- ...options
738
- })
739
- ) as any
740
- }
497
+ // Effect.tapDefect(reportRuntimeError) handled in toast handler,
498
+ const [a, b] = asResult(mapHandler(unsafe, mh) as any)
741
499
 
742
- /**
743
- * Effect results are converted to Exit, so errors are ignored by default.
744
- * you should use the result ref to render errors!
745
- */
746
- const _useSafeMutationWithState: {
747
- <I, E, A, R, Request extends TaggedRequestClassAny, Name extends string, A2 = A, E2 = E, R2 = R>(
748
- self: RequestHandlerWithInput<I, A, E, R, Request, Name>,
749
- options?: MutationOptions<A, E, R, A2, E2, R2, I>
750
- ): readonly [
751
- ComputedRef<Res<A, E>>,
752
- (i: I) => Effect.Effect<Exit.Exit<A2, E2>, never, R2>
753
- ]
754
- <E, A, R, Request extends TaggedRequestClassAny, Name extends string, A2 = A, E2 = E, R2 = R>(
755
- self: RequestHandler<A, E, R, Request, Name>,
756
- options?: MutationOptions<A, E, R, A2, E2, R2>
757
- ): readonly [
758
- ComputedRef<Res<A, E>>,
759
- Effect.Effect<Exit.Exit<A2, E2>, never, R2>
760
- ]
761
- } = <I, E, A, R, Request extends TaggedRequestClassAny, Name extends string, A2 = A, E2 = E, R2 = R>(
762
- self: RequestHandlerWithInput<I, A, E, R, Request, Name> | RequestHandler<A, E, R, Request, Name>,
763
- options?: MutationOptions<A, E, R, A2, E2, R2, I>
764
- ) => {
765
- const [a, b] = _useSafeMutation(self as any, options)
766
-
767
- return tuple(
768
- computed(() => mutationResultToVue(a.value)),
769
- b
770
- ) as any
771
- }
500
+ return tuple(
501
+ a,
502
+ handleRequestWithToast(b as any, self.id, action, options)
503
+ )
504
+ }
505
+ //
772
506
 
773
- /** @deprecated use OmegaForm */
774
- const _buildFormFromSchema = <
775
- From extends Record<PropertyKey, any>,
776
- To extends Record<PropertyKey, any>,
777
- C extends Record<PropertyKey, any>,
778
- OnSubmitA
507
+ /**
508
+ * Pass a function that returns an Effect, e.g from a client action, give it a name.
509
+ * Returns a tuple with state ref and execution function which reports success and errors as Toast.
510
+ *
511
+ * @deprecated use `Command.fn` and friends instead
512
+ */
513
+ readonly useAndHandleMutation: {
514
+ <
515
+ I,
516
+ E extends ResponseErrors,
517
+ A,
518
+ R,
519
+ Request extends TaggedRequestClassAny,
520
+ Name extends string,
521
+ A2 = A,
522
+ E2 extends ResponseErrors = E,
523
+ R2 = R,
524
+ ESuccess = never,
525
+ RSuccess = never,
526
+ EError = never,
527
+ RError = never,
528
+ EDefect = never,
529
+ RDefect = never
530
+ >(
531
+ self: RequestHandlerWithInput<I, A, E, R, Request, Name>,
532
+ action: string,
533
+ options?: Opts<A, E, R, I, A2, E2, R2, ESuccess, RSuccess, EError, RError, EDefect, RDefect>
534
+ ): Resp<I, A2, E2, R2>
535
+ <
536
+ E extends ResponseErrors,
537
+ A,
538
+ R,
539
+ Request extends TaggedRequestClassAny,
540
+ Name extends string,
541
+ A2 = A,
542
+ E2 extends ResponseErrors = E,
543
+ R2 = R,
544
+ ESuccess = never,
545
+ RSuccess = never,
546
+ EError = never,
547
+ RError = never,
548
+ EDefect = never,
549
+ RDefect = never
550
+ >(
551
+ self: RequestHandler<A, E, R, Request, Name>,
552
+ action: string,
553
+ options?: Opts<A, E, R, void, A2, E2, R2, ESuccess, RSuccess, EError, RError, EDefect, RDefect>
554
+ ): ActResp<A2, E2, R2>
555
+ } = (
556
+ self: any,
557
+ action: any,
558
+ options?: Opts<any, any, any, any, any, any, any, any, any, any, any, any, any>
559
+ ): any => {
560
+ const [a, b] = this.useAndHandleMutationResult(self, action, options)
561
+
562
+ return tuple(
563
+ computed(() => mutationResultToVue(a.value)),
564
+ b
565
+ )
566
+ }
567
+
568
+ /** @deprecated use `Command.fn` and friends instead */
569
+ readonly makeUseAndHandleMutation = (
570
+ defaultOptions?: Opts<any, any, any, any, any, any, any, any, any>
571
+ ) =>
572
+ ((self: any, action: any, options: any) => {
573
+ return this.useAndHandleMutation(
574
+ self,
575
+ action,
576
+ { ...defaultOptions, ...options }
577
+ )
578
+ }) as unknown as {
579
+ <
580
+ I,
581
+ E extends ResponseErrors,
582
+ A,
583
+ R,
584
+ Request extends TaggedRequestClassAny,
585
+ Name extends string,
586
+ A2 = A,
587
+ E2 extends ResponseErrors = E,
588
+ R2 = R,
589
+ ESuccess = never,
590
+ RSuccess = never,
591
+ EError = never,
592
+ RError = never,
593
+ EDefect = never,
594
+ RDefect = never
779
595
  >(
780
- s:
781
- & Schema<
782
- To,
783
- From,
784
- R
785
- >
786
- & { new(c: C): any; extend: any; fields: S.Struct.Fields },
787
- state: Ref<Omit<From, "_tag">>,
788
- onSubmit: (a: To) => Effect.Effect<OnSubmitA, never, R>
789
- ) => {
790
- const fields = buildFieldInfoFromFieldsRoot(s).fields
791
- const schema = S.Struct(Struct.omit(s.fields, "_tag")) as any
792
- const parse = S.decodeUnknown<any, any, R>(schema)
793
- const isDirty = ref(false)
794
- const isValid = ref(true)
795
- const isLoading = ref(false)
796
- const runPromise = Runtime.runPromise(getRuntime())
797
-
798
- const submit1 =
799
- (onSubmit: (a: To) => Effect.Effect<OnSubmitA, never, R>) =>
800
- async <T extends Promise<{ valid: boolean }>>(e: T) => {
801
- isLoading.value = true
802
- try {
803
- const r = await e
804
- if (!r.valid) return
805
- return await runPromise(onSubmit(new s(await runPromise(parse(state.value)))))
806
- } finally {
807
- isLoading.value = false
808
- }
809
- }
810
- const submit = submit1(onSubmit)
811
-
812
- watch(
813
- state,
814
- (v) => {
815
- // TODO: do better
816
- isDirty.value = JSON.stringify(v) !== JSON.stringify(state.value)
817
- },
818
- { deep: true }
819
- )
596
+ self: RequestHandlerWithInput<I, A, E, R, Request, Name>,
597
+ action: string,
598
+ options?: Opts<A, E, R, I, A2, E2, R2, ESuccess, RSuccess, EError, RError, EDefect, RDefect>
599
+ ): Resp<I, A2, E2, R2>
600
+ <
601
+ E extends ResponseErrors,
602
+ A,
603
+ R,
604
+ Request extends TaggedRequestClassAny,
605
+ Name extends string,
606
+ A2 = A,
607
+ E2 extends ResponseErrors = E,
608
+ R2 = R,
609
+ ESuccess = never,
610
+ RSuccess = never,
611
+ EError = never,
612
+ RError = never,
613
+ EDefect = never,
614
+ RDefect = never
615
+ >(
616
+ self: RequestHandler<A, E, R, Request, Name>,
617
+ action: string,
618
+ options?: Opts<A, E, R, void, A2, E2, R2, ESuccess, RSuccess, EError, RError, EDefect, RDefect>
619
+ ): ActResp<A2, E2, R2>
620
+ }
820
621
 
821
- const submitFromState = Effect.gen(function*() {
822
- return yield* onSubmit(yield* parse(state.value))
823
- })
622
+ /**
623
+ * The same as @see useAndHandleMutation, but does not display any toasts by default.
624
+ * Messages for success, error and defect toasts can be provided in the Options.
625
+ * @deprecated use `Command.fn` and friends instead
626
+ */
627
+ readonly useAndHandleMutationSilently: {
628
+ <
629
+ I,
630
+ E extends ResponseErrors,
631
+ A,
632
+ R,
633
+ Request extends TaggedRequestClassAny,
634
+ Name extends string,
635
+ A2 = A,
636
+ E2 extends ResponseErrors = E,
637
+ R2 = R,
638
+ ESuccess = never,
639
+ RSuccess = never,
640
+ EError = never,
641
+ RError = never,
642
+ EDefect = never,
643
+ RDefect = never
644
+ >(
645
+ self: RequestHandlerWithInput<I, A, E, R, Request, Name>,
646
+ action: string,
647
+ options?: Opts<A, E, R, I, A2, E2, R2, ESuccess, RSuccess, EError, RError, EDefect, RDefect>
648
+ ): Resp<I, A2, E2, R>
649
+ <
650
+ E extends ResponseErrors,
651
+ A,
652
+ R,
653
+ Request extends TaggedRequestClassAny,
654
+ Name extends string,
655
+ A2 = A,
656
+ E2 extends ResponseErrors = E,
657
+ R2 = R,
658
+ ESuccess = never,
659
+ RSuccess = never,
660
+ EError = never,
661
+ RError = never,
662
+ EDefect = never,
663
+ RDefect = never
664
+ >(
665
+ self: RequestHandler<A, E, R, Request, Name>,
666
+ action: string,
667
+ options?: Opts<A, E, R, void, A2, E2, R2, ESuccess, RSuccess, EError, RError, EDefect, RDefect>
668
+ ): ActResp<void, never, R>
669
+ } = this.makeUseAndHandleMutation({
670
+ successMessage: suppressToast,
671
+ failMessage: suppressToast,
672
+ defectMessage: suppressToast
673
+ }) as any
824
674
 
825
- const submitFromStatePromise = () => runPromise(submitFromState)
826
-
827
- return {
828
- fields,
829
- /** optimized for Vuetify v-form submit callback */
830
- submit,
831
- /** optimized for Native form submit callback or general use */
832
- submitFromState,
833
- submitFromStatePromise,
834
- isDirty,
835
- isValid,
836
- isLoading
675
+ /**
676
+ * The same as @see useAndHandleMutation, but does not act on success, error or defect by default.
677
+ * Actions for success, error and defect can be provided in the Options.
678
+ * @deprecated use `Command.fn` and friends instead
679
+ */
680
+ readonly useAndHandleMutationCustom: {
681
+ <
682
+ I,
683
+ E extends ResponseErrors,
684
+ A,
685
+ R,
686
+ Request extends TaggedRequestClassAny,
687
+ Name extends string,
688
+ A2 = A,
689
+ E2 extends ResponseErrors = E,
690
+ R2 = R,
691
+ ESuccess = never,
692
+ RSuccess = never,
693
+ EError = never,
694
+ RError = never,
695
+ EDefect = never,
696
+ RDefect = never
697
+ >(
698
+ self: RequestHandlerWithInput<I, A, E, R, Request, Name>,
699
+ action: string,
700
+ options?: LowOptsOptional<A, E, R, I, A2, E2, R2, ESuccess, RSuccess, EError, RError, EDefect, RDefect>
701
+ ): Resp<I, A2, E2, R2>
702
+ <
703
+ E extends ResponseErrors,
704
+ A,
705
+ R,
706
+ Request extends TaggedRequestClassAny,
707
+ Name extends string,
708
+ A2 = A,
709
+ E2 extends ResponseErrors = E,
710
+ R2 = R,
711
+ ESuccess = never,
712
+ RSuccess = never,
713
+ EError = never,
714
+ RError = never,
715
+ EDefect = never,
716
+ RDefect = never
717
+ >(
718
+ self: RequestHandler<A, E, R, Request, Name>,
719
+ action: string,
720
+ options?: LowOptsOptional<A, E, R, void, A2, E2, R2, ESuccess, RSuccess, EError, RError, EDefect, RDefect>
721
+ ): ActResp<A2, E2, R2>
722
+ } = (self: any, action: string, options: any) => {
723
+ const unsafe = _useMutation({
724
+ ...self,
725
+ handler: Effect.isEffect(self.handler)
726
+ ? (pipe(
727
+ Effect.annotateCurrentSpan({ action }),
728
+ Effect.andThen(self.handler)
729
+ ) as any)
730
+ : (...args: any[]) =>
731
+ pipe(
732
+ Effect.annotateCurrentSpan({ action }),
733
+ Effect.andThen(self.handler(...args))
734
+ )
735
+ }, options ? dropUndefinedT(options) : undefined)
736
+
737
+ type MH = NonNullable<NonNullable<typeof options>["mapHandler"]>
738
+ const mh = options?.mapHandler ?? identity as MH
739
+
740
+ const [a, b] = asResult(mapHandler(mapHandler(unsafe as any, mh), Effect.tapDefect(reportRuntimeError)) as any)
741
+
742
+ return tuple(
743
+ computed(() => mutationResultToVue(a.value)),
744
+ handleRequest(b as any, self.id, action, {
745
+ onSuccess: suppressToast,
746
+ onDefect: suppressToast,
747
+ onFail: suppressToast,
748
+ ...options
749
+ })
750
+ ) as any
751
+ }
752
+
753
+ /**
754
+ * Effect results are converted to Exit, so errors are ignored by default.
755
+ * you should use the result ref to render errors!
756
+ * @deprecated use `Command.fn` and friends instead
757
+ */
758
+ readonly useSafeMutationWithState: {
759
+ <I, E, A, R, Request extends TaggedRequestClassAny, Name extends string, A2 = A, E2 = E, R2 = R>(
760
+ self: RequestHandlerWithInput<I, A, E, R, Request, Name>,
761
+ options?: MutationOptions<A, E, R, A2, E2, R2, I>
762
+ ): readonly [
763
+ ComputedRef<Res<A, E>>,
764
+ (i: I) => Effect.Effect<Exit.Exit<A2, E2>, never, R2>
765
+ ]
766
+ <E, A, R, Request extends TaggedRequestClassAny, Name extends string, A2 = A, E2 = E, R2 = R>(
767
+ self: RequestHandler<A, E, R, Request, Name>,
768
+ options?: MutationOptions<A, E, R, A2, E2, R2>
769
+ ): readonly [
770
+ ComputedRef<Res<A, E>>,
771
+ Effect.Effect<Exit.Exit<A2, E2>, never, R2>
772
+ ]
773
+ } = <I, E, A, R, Request extends TaggedRequestClassAny, Name extends string, A2 = A, E2 = E, R2 = R>(
774
+ self: RequestHandlerWithInput<I, A, E, R, Request, Name> | RequestHandler<A, E, R, Request, Name>,
775
+ options?: MutationOptions<A, E, R, A2, E2, R2, I>
776
+ ) => {
777
+ const [a, b] = this.useSafeMutation(self as any, options)
778
+
779
+ return tuple(
780
+ computed(() => mutationResultToVue(a.value)),
781
+ b
782
+ ) as any
783
+ }
784
+
785
+ /** @deprecated use OmegaForm */
786
+ readonly buildFormFromSchema = <
787
+ From extends Record<PropertyKey, any>,
788
+ To extends Record<PropertyKey, any>,
789
+ C extends Record<PropertyKey, any>,
790
+ OnSubmitA
791
+ >(
792
+ s:
793
+ & Schema<
794
+ To,
795
+ From,
796
+ RT
797
+ >
798
+ & { new(c: C): any; extend: any; fields: S.Struct.Fields },
799
+ state: Ref<Omit<From, "_tag">>,
800
+ onSubmit: (a: To) => Effect.Effect<OnSubmitA, never, RT>
801
+ ) => {
802
+ const fields = buildFieldInfoFromFieldsRoot(s).fields
803
+ const schema = S.Struct(Struct.omit(s.fields, "_tag")) as any
804
+ const parse = S.decodeUnknown<any, any, RT>(schema)
805
+ const isDirty = ref(false)
806
+ const isValid = ref(true)
807
+ const isLoading = ref(false)
808
+ const runPromise = Runtime.runPromise(this.getRuntime())
809
+
810
+ const submit1 =
811
+ (onSubmit: (a: To) => Effect.Effect<OnSubmitA, never, RT>) =>
812
+ async <T extends Promise<{ valid: boolean }>>(e: T) => {
813
+ isLoading.value = true
814
+ try {
815
+ const r = await e
816
+ if (!r.valid) return
817
+ return await runPromise(onSubmit(new s(await runPromise(parse(state.value)))))
818
+ } finally {
819
+ isLoading.value = false
837
820
  }
838
821
  }
839
- return {
840
- /** @deprecated use Command.fn */
841
- useSafeMutationWithState: _useSafeMutationWithState,
842
- /** @deprecated use Command.fn */
843
- useAndHandleMutation: _useAndHandleMutation,
844
- /** @deprecated use Command.fn */
845
- useAndHandleMutationResult: _useAndHandleMutationResult,
846
- /** @deprecated use Command.fn */
847
- useAndHandleMutationSilently: _useAndHandleMutationSilently,
848
- /** @deprecated use Command.fn */
849
- useAndHandleMutationCustom: _useAndHandleMutationCustom,
850
- /** @deprecated use Command.fn */
851
- makeUseAndHandleMutation: _makeUseAndHandleMutation,
852
- /**
853
- * handles errors as toasts and reports defects
854
- * @deprecated use Command.fn
855
- */
856
- useHandleRequestWithToast: _useHandleRequestWithToast,
857
- /** @deprecated use OmegaForm */
858
- buildFormFromSchema: _buildFormFromSchema,
859
- /** @deprecated use Command.fn */
860
- useSafeMutation: _useSafeMutation
861
- }
822
+ const submit = submit1(onSubmit)
823
+
824
+ watch(
825
+ state,
826
+ (v) => {
827
+ // TODO: do better
828
+ isDirty.value = JSON.stringify(v) !== JSON.stringify(state.value)
829
+ },
830
+ { deep: true }
831
+ )
832
+
833
+ const submitFromState = Effect.gen(function*() {
834
+ return yield* onSubmit(yield* parse(state.value))
835
+ })
836
+
837
+ const submitFromStatePromise = () => runPromise(submitFromState)
838
+
839
+ return {
840
+ fields,
841
+ /** optimized for Vuetify v-form submit callback */
842
+ submit,
843
+ /** optimized for Native form submit callback or general use */
844
+ submitFromState,
845
+ submitFromStatePromise,
846
+ isDirty,
847
+ isValid,
848
+ isLoading
862
849
  }
850
+ }
851
+ }
852
+
853
+ // @effect-diagnostics-next-line missingEffectServiceDependency:off
854
+ export class LegacyMutation extends Effect.Service<LegacyMutation>()("LegacyMutation", {
855
+ effect: Effect.gen(function*() {
856
+ const intl = yield* I18n
857
+ const toast = yield* Toast
858
+
859
+ return <R>(getRuntime: () => Runtime.Runtime<R>) => new LegacyMutationImpl(getRuntime, toast, intl)
863
860
  })
864
861
  }) {}
865
862
 
866
863
  export type ClientFrom<M extends Requests> = RequestHandlers<never, never, Omit<M, "meta">, M["meta"]["moduleName"]>
867
864
 
868
- const mkQuery = <R>(getRuntime: () => Runtime.Runtime<R>) => {
869
- // making sure names do not collide with auto exports in nuxt apps, please do not rename..
865
+ export class QueryImpl<R> {
866
+ constructor(readonly getRuntime: () => Runtime.Runtime<R>) {
867
+ this.useQuery = makeQuery(this.getRuntime)
868
+ }
870
869
  /**
871
870
  * Effect results are passed to the caller, including errors.
871
+ * @deprecated use client helpers instead (.query())
872
872
  */
873
873
  // TODO
874
- const _useQuery = makeQuery(getRuntime)
874
+ readonly useQuery: ReturnType<typeof makeQuery<R>>
875
875
 
876
876
  /**
877
877
  * The difference with useQuery is that this function will return a Promise you can await in the Setup,
878
878
  * which ensures that either there always is a latest value, or an error occurs on load.
879
879
  * So that Suspense and error boundaries can be used.
880
+ * @deprecated use client helpers instead (.suspense())
880
881
  */
881
- const useSuspenseQuery: {
882
+ readonly useSuspenseQuery: {
882
883
  <
883
884
  E,
884
885
  A,
@@ -948,8 +949,8 @@ const mkQuery = <R>(getRuntime: () => Runtime.Runtime<R>) => {
948
949
  } = <Arg, E, A, Request extends TaggedRequestClassAny, Name extends string>(
949
950
  self: RequestHandlerWithInput<Arg, A, E, R, Request, Name> | RequestHandler<A, E, R, Request, Name>
950
951
  ) => {
951
- const runPromise = Runtime.runPromise(getRuntime())
952
- const q = _useQuery(self as any) as any
952
+ const runPromise = Runtime.runPromise(this.getRuntime())
953
+ const q = this.useQuery(self as any) as any
953
954
  return (argOrOptions?: any, options?: any) => {
954
955
  const [resultRef, latestRef, fetch, uqrt] = q(argOrOptions, { ...options, suspense: true } // experimental_prefetchInRender: true }
955
956
  )
@@ -998,8 +999,6 @@ const mkQuery = <R>(getRuntime: () => Runtime.Runtime<R>) => {
998
999
  return runPromise(eff)
999
1000
  }
1000
1001
  }
1001
-
1002
- return { useQuery: _useQuery, useSuspenseQuery }
1003
1002
  }
1004
1003
 
1005
1004
  // somehow mrt.runtimeEffect doesnt work sync, but this workaround works fine? not sure why though as the layers are generally only sync
@@ -1028,7 +1027,7 @@ export const makeClient = <RT>(
1028
1027
  let m: ReturnType<typeof useMutationInt>
1029
1028
  const useMutation = () => m ??= useMutationInt()
1030
1029
 
1031
- const keys: readonly (keyof ReturnType<typeof getMutation>)[] = [
1030
+ const keys = [
1032
1031
  "useSafeMutationWithState",
1033
1032
  "useAndHandleMutation",
1034
1033
  "useAndHandleMutationResult",
@@ -1038,20 +1037,20 @@ export const makeClient = <RT>(
1038
1037
  "useHandleRequestWithToast",
1039
1038
  "buildFormFromSchema",
1040
1039
  "useSafeMutation"
1041
- ]
1042
- type mut = ReturnType<typeof getMutation>
1040
+ ] as const satisfies readonly (keyof ReturnType<typeof getMutation>)[]
1041
+ type mut = Pick<LegacyMutationImpl<R>, typeof keys[number]>
1043
1042
 
1044
1043
  const mutations = keys.reduce(
1045
1044
  (prev, cur) => {
1046
- prev[cur] = ((...args: [any]) => {
1045
+ ;(prev as any)[cur] = ((...args: [any]) => {
1047
1046
  return (getMutation() as any)[cur](...args)
1048
1047
  }) as any
1049
1048
  return prev
1050
1049
  },
1051
- {} as { [K in keyof mut]: mut[K] }
1050
+ {} as Pick<LegacyMutationImpl<R>, typeof keys[number]>
1052
1051
  )
1053
1052
 
1054
- const query = mkQuery(getBaseRt)
1053
+ const query = new QueryImpl(getBaseRt)
1055
1054
  const useQuery = query.useQuery
1056
1055
  const useSuspenseQuery = query.useSuspenseQuery
1057
1056
 
@@ -1284,15 +1283,12 @@ export const makeClient = <RT>(
1284
1283
  return proxy
1285
1284
  }
1286
1285
 
1287
- const legacy = {
1286
+ const legacy: Legacy<R> = {
1288
1287
  ...mutations,
1289
- /** @deprecated use .query on the clientFor(x).Action */
1290
- useQuery,
1291
- /** @deprecated use .suspense on the clientFor(x).Action */
1292
- useSuspenseQuery
1288
+ ...query
1293
1289
  }
1294
1290
 
1295
- const Command: CommanderResolved<RT> = {
1291
+ const Command: CommanderResolved<R> = {
1296
1292
  ...{
1297
1293
  // delay initialisation until first use...
1298
1294
  fn: (...args: [any]) => useCommand().fn(...args),
@@ -1311,6 +1307,12 @@ export const makeClient = <RT>(
1311
1307
  }
1312
1308
  }
1313
1309
 
1310
+ export interface Legacy<R>
1311
+ extends
1312
+ Pick<QueryImpl<R>, "useQuery" | "useSuspenseQuery">,
1313
+ Omit<LegacyMutationImpl<R>, "getRuntime" | "toast" | "intl">
1314
+ {}
1315
+
1314
1316
  export type QueryInvalidation<M> = {
1315
1317
  [K in keyof M]?: (defaultKey: string[], name: string) => {
1316
1318
  filters?: InvalidateQueryFilters | undefined