@effect-app/vue 4.0.0-beta.62 → 4.0.0-beta.63

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
@@ -1,26 +1,20 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
2
  import { type InvalidateOptions, type InvalidateQueryFilters, isCancelledError, type QueryObserverResult, type RefetchOptions, type UseQueryReturnType } from "@tanstack/vue-query"
3
3
  import { camelCase } from "change-case"
4
- import { Cause, Context, Data, Effect, Exit, Layer, type ManagedRuntime, Match, Option, S, Struct } from "effect-app"
4
+ import { type Context, Effect, Exit, type Layer, type ManagedRuntime, Struct } from "effect-app"
5
5
  import { type ApiClientFactory, type Req } from "effect-app/client"
6
6
  import type { RequestHandler, RequestHandlers, RequestHandlerWithInput, Requests } from "effect-app/client/clientFor"
7
- import { ErrorSilenced, type SupportedErrors } from "effect-app/client/errors"
8
- import { constant, identity, pipe, tuple } from "effect-app/Function"
9
- import { type OperationFailure, OperationSuccess } from "effect-app/Operations"
10
- import { dropUndefinedT, extendM } from "effect-app/utils"
7
+ import { extendM } from "effect-app/utils"
11
8
  import { type Fiber } from "effect/Fiber"
12
9
  import * as AsyncResult from "effect/unstable/reactivity/AsyncResult"
13
- import { computed, type ComputedRef, onBeforeUnmount, type Ref, ref, watch, type WatchSource } from "vue"
10
+ import { type ComputedRef, onBeforeUnmount, ref, type WatchSource } from "vue"
14
11
  import { type Commander, CommanderStatic } from "./commander.js"
15
- import { reportMessage } from "./errorReporter.js"
16
- import { buildFieldInfoFromFieldsRoot } from "./form.js"
17
- import { I18n } from "./intl.js"
18
- import { reportRuntimeError } from "./lib.js"
12
+ import { type I18n } from "./intl.js"
19
13
  import { type CommanderResolved, makeUseCommand } from "./makeUseCommand.js"
20
- import { asResult, makeMutation, type MutationOptions, type MutationOptionsBase, mutationResultToVue, type Res, useMakeMutation } from "./mutate.js"
14
+ import { makeMutation, type MutationOptionsBase, useMakeMutation } from "./mutate.js"
21
15
  import { type CustomUndefinedInitialQueryOptions, makeQuery } from "./query.js"
22
16
  import { makeRunPromise } from "./runtime.js"
23
- import { Toast } from "./toast.js"
17
+ import { type Toast } from "./toast.js"
24
18
 
25
19
  const mapHandler = <A, E, R, I = void, A2 = A, E2 = E, R2 = R>(
26
20
  handler: Effect.Effect<A, E, R> | ((i: I) => Effect.Effect<A, E, R>),
@@ -177,166 +171,6 @@ export type Queries<RT, Req> = Req extends
177
171
  : { query: MissingDependencies<RT, R> & {}; suspense: MissingDependencies<RT, R> & {} }
178
172
  : never
179
173
 
180
- /**
181
- * Use this after handling an error yourself, still continueing on the Error track, but the error will not be reported.
182
- */
183
- export class SuppressErrors extends Data.TaggedError("SuppressErrors")<{}> {
184
- readonly [ErrorSilenced] = true as const
185
- }
186
-
187
- export type ResponseErrors = S.SchemaError | SupportedErrors | SuppressErrors | OperationFailure
188
-
189
- export interface Opts<
190
- A,
191
- E,
192
- R,
193
- I = void,
194
- A2 = A,
195
- E2 = E,
196
- R2 = R,
197
- ESuccess = never,
198
- RSuccess = never,
199
- EError = never,
200
- RError = never,
201
- EDefect = never,
202
- RDefect = never
203
- > extends MutationOptions<A, E, R, A2, E2, R2, I> {
204
- /** set to `undefined` to use default message */
205
- successMessage?: ((a: A2, i: I) => Effect.Effect<string | undefined, ESuccess, RSuccess>) | undefined
206
- /** set to `undefined` to use default message */
207
- failMessage?: ((e: E2, i: I) => Effect.Effect<string | undefined, EError, RError>) | undefined
208
- /** set to `undefined` to use default message */
209
- defectMessage?: ((e: Cause.Cause<E2>, i: I) => Effect.Effect<string | undefined, EDefect, RDefect>) | undefined
210
- }
211
-
212
- export interface LowOpts<
213
- A,
214
- E,
215
- I = void,
216
- ESuccess = never,
217
- RSuccess = never,
218
- EError = never,
219
- RError = never,
220
- EDefect = never,
221
- RDefect = never
222
- > {
223
- onSuccess: (a: A, i: I) => Effect.Effect<void, ESuccess, RSuccess>
224
- onFail: (e: E, i: I) => Effect.Effect<void, EError, RError>
225
- onDefect: (e: Cause.Cause<E>, i: I) => Effect.Effect<void, EDefect, RDefect>
226
- }
227
-
228
- export interface LowOptsOptional<
229
- A,
230
- E,
231
- R,
232
- I = void,
233
- A2 = A,
234
- E2 = E,
235
- R2 = R,
236
- ESuccess = never,
237
- RSuccess = never,
238
- EError = never,
239
- RError = never,
240
- EDefect = never,
241
- RDefect = never
242
- > extends MutationOptions<A, E, R, A2, E2, R2, I> {
243
- onSuccess?: (a: A, i: I) => Effect.Effect<void, ESuccess, RSuccess>
244
- onFail?: (e: E, i: I) => Effect.Effect<void, EError, RError>
245
- onDefect?: (e: Cause.Cause<E>, i: I) => Effect.Effect<void, EDefect, RDefect>
246
- }
247
-
248
- type WithAction<A> = A & {
249
- action: string
250
- }
251
-
252
- // computed() takes a getter function and returns a readonly reactive ref
253
- // object for the returned value from the getter.
254
-
255
- type Resp<I, A, E, R, V = ComputedRef<Res<A, E>>> = readonly [
256
- V,
257
- WithAction<(I: I) => Effect.Effect<Exit.Exit<A, E>, never, R>>
258
- ]
259
-
260
- type ActResp<A, E, R, V = ComputedRef<Res<A, E>>> = readonly [
261
- V,
262
- WithAction<Effect.Effect<Exit.Exit<A, E>, never, R>>
263
- ]
264
-
265
- export const suppressToast = constant(Effect.succeed(undefined))
266
-
267
- /** handles errors as specified and reports defects */
268
- function handleRequest<
269
- E extends ResponseErrors,
270
- A,
271
- R,
272
- I = void,
273
- ESuccess = never,
274
- RSuccess = never,
275
- EError = never,
276
- RError = never,
277
- EDefect = never,
278
- RDefect = never
279
- >(
280
- f: Effect.Effect<Exit.Exit<A, E>, never, R> | ((i: I) => Effect.Effect<Exit.Exit<A, E>, never, R>),
281
- id: string,
282
- action: string,
283
- options: {
284
- onSuccess: (a: A, i: I) => Effect.Effect<void, ESuccess, RSuccess>
285
- onFail: (e: E, i: I) => Effect.Effect<void, EError, RError>
286
- onDefect: (e: Cause.Cause<E>, i: I) => Effect.Effect<void, EDefect, RDefect>
287
- }
288
- ) {
289
- const handleEffect = (i: any) => (self: Effect.Effect<Exit.Exit<A, E>, never, R>) =>
290
- self.pipe(
291
- Effect.tap(
292
- Effect.matchCauseEffect({
293
- onSuccess: (r) => options.onSuccess(r, i),
294
- onFailure: (cause) =>
295
- Effect.gen(function*() {
296
- if (Cause.hasInterruptsOnly(cause)) {
297
- console.info(`Interrupted while trying to ${action}`)
298
- return
299
- }
300
-
301
- const fail = Cause.findErrorOption(cause)
302
- if (Option.isSome(fail)) {
303
- if (fail.value._tag === "SuppressErrors") {
304
- console.info(`Suppressed error trying to ${action}`, fail.value)
305
- return
306
- }
307
- const message = `Failure trying to ${action}`
308
- yield* reportMessage(message, { action, error: fail.value })
309
- yield* options.onFail(fail.value, i)
310
- return
311
- }
312
-
313
- const extra = {
314
- action,
315
- message: `Unexpected Error trying to ${action}`
316
- }
317
- yield* reportRuntimeError(cause, extra)
318
-
319
- yield* options.onDefect(cause, i)
320
- })
321
- })
322
- ),
323
- Effect.withSpan(`mutation ${id}`, {}, { captureStackTrace: false })
324
- )
325
- return Object.assign(
326
- Effect.isEffect(f)
327
- ? pipe(
328
- f,
329
- handleEffect(void 0)
330
- )
331
- : (i: I) =>
332
- pipe(
333
- f(i),
334
- handleEffect(i)
335
- ),
336
- { action }
337
- )
338
- }
339
-
340
174
  const _useMutation = makeMutation()
341
175
 
342
176
  /**
@@ -390,698 +224,6 @@ export const useMutationInt = (): typeof _useMutation => {
390
224
  )
391
225
  }
392
226
 
393
- export class LegacyMutationImpl<RT> {
394
- constructor(
395
- private readonly getRuntime: () => Context.Context<RT>,
396
- private readonly toast: Toast,
397
- private readonly intl: I18n
398
- ) {}
399
-
400
- /**
401
- * Effect results are converted to Exit, so errors are ignored by default.
402
- * you should use the result ref to render errors!
403
- * @deprecated use `Command.fn` and friends instead
404
- */
405
- readonly useSafeMutation: {
406
- /**
407
- * Effect results are converted to Exit, so errors are ignored by default.
408
- * you should use the result ref to render errors!
409
- * @deprecated use `Command.fn` and friends instead
410
- */
411
- <I, E, A, R, Request extends Req, Name extends string, A2 = A, E2 = E, R2 = R>(
412
- self: RequestHandlerWithInput<I, A, E, R, Request, Name>,
413
- options?: MutationOptions<A, E, R, A2, E2, R2, I>
414
- ): readonly [
415
- ComputedRef<AsyncResult.AsyncResult<A2, E2>>,
416
- (i: I) => Effect.Effect<Exit.Exit<A2, E2>, never, R2>
417
- ]
418
- /**
419
- * Effect results are converted to Exit, so errors are ignored by default.
420
- * you should use the result ref to render errors!
421
- * @deprecated use `Command.fn` and friends instead
422
- */
423
- <E, A, R, Request extends Req, Name extends string, A2 = A, E2 = E, R2 = R>(
424
- self: RequestHandler<A, E, R, Request, Name>,
425
- options?: MutationOptions<A, E, R, A2, E2, R2>
426
- ): readonly [
427
- ComputedRef<AsyncResult.AsyncResult<A2, E2>>,
428
- Effect.Effect<Exit.Exit<A2, E2>, never, R2>
429
- ]
430
- } = <I, E, A, R, Request extends Req, Name extends string, A2 = A, E2 = E, R2 = R>(
431
- self: RequestHandlerWithInput<I, A, E, R, Request, Name> | RequestHandler<A, E, R, Request, Name>,
432
- options?: MutationOptions<A, E, R, A2, E2, R2, I>
433
- ) => {
434
- const unsafe = _useMutation(self as any, options)
435
-
436
- type MH = NonNullable<NonNullable<typeof options>["mapHandler"]>
437
- const mh = options?.mapHandler ?? identity as MH
438
-
439
- const [a, b] = asResult(
440
- mapHandler(
441
- mapHandler(unsafe as any, mh),
442
- Effect.tapCauseIf(Cause.hasDies, (cause) => reportRuntimeError(cause))
443
- ) as any
444
- )
445
- return [
446
- a,
447
- mapHandler(
448
- b,
449
- Effect.withSpan(`mutation ${self.id}`, {}, { captureStackTrace: false })
450
- )
451
- ] as const as any
452
- }
453
-
454
- /** handles errors as toasts and reports defects
455
- * @deprecated use `Command.fn` and friends instead
456
- */
457
- readonly useHandleRequestWithToast = () => {
458
- // eslint-disable-next-line @typescript-eslint/no-this-alias
459
- const self = this
460
- return handleRequestWithToast
461
- /**
462
- * Pass a function that returns a Promise.
463
- * Returns an execution function which reports errors as Toast.
464
- */
465
- function handleRequestWithToast<
466
- A,
467
- E extends ResponseErrors,
468
- R,
469
- I = void,
470
- A2 = A,
471
- E2 extends ResponseErrors = E,
472
- R2 = R,
473
- ESuccess = never,
474
- RSuccess = never,
475
- EError = never,
476
- RError = never,
477
- EDefect = never,
478
- RDefect = never
479
- >(
480
- f: Effect.Effect<Exit.Exit<A2, E2>, never, R2> | ((i: I) => Effect.Effect<Exit.Exit<A2, E2>, never, R2>),
481
- id: string,
482
- action: string,
483
- options: Opts<A, E, R, I, A2, E2, R2, ESuccess, RSuccess, EError, RError, EDefect, RDefect> = {}
484
- ) {
485
- const actionMessage = self.intl.formatMessage({ id: `action.${action}`, defaultMessage: action })
486
- const defaultWarnMessage = self.intl.formatMessage(
487
- { id: "handle.with_warnings" },
488
- { action: actionMessage }
489
- )
490
- const defaultSuccessMessage = self.intl.formatMessage(
491
- { id: "handle.success" },
492
- { action: actionMessage }
493
- )
494
- const defaultErrorMessage = self.intl.formatMessage(
495
- { id: "handle.with_errors" },
496
- { action: actionMessage }
497
- )
498
-
499
- return handleRequest<E2, A2, R2, any, ESuccess, RSuccess, EError, RError, EDefect, RDefect>(f, id, action, {
500
- onSuccess: Effect.fnUntraced(function*(a, i) {
501
- const message = options.successMessage ? yield* options.successMessage(a, i) : defaultSuccessMessage
502
- + (S.is(OperationSuccess)(a) && a.message
503
- ? "\n" + a.message
504
- : "")
505
- if (message) {
506
- yield* self.toast.success(message)
507
- }
508
- }),
509
- onFail: Effect.fnUntraced(function*(e, i) {
510
- if (!options.failMessage && e._tag === "OperationFailure") {
511
- yield* self.toast.warning(
512
- defaultWarnMessage + e.message
513
- ? "\n" + e.message
514
- : ""
515
- )
516
- return
517
- }
518
-
519
- const message = options.failMessage
520
- ? yield* options.failMessage(e, i)
521
- : `${defaultErrorMessage}:\n` + renderError(e)
522
- if (message) {
523
- yield* self.toast.error(message)
524
- }
525
- }),
526
- onDefect: Effect.fnUntraced(function*(cause, i) {
527
- const message = options.defectMessage
528
- ? yield* options.defectMessage(cause, i)
529
- : self.intl.formatMessage(
530
- { id: "handle.unexpected_error" },
531
- {
532
- action: actionMessage,
533
- error: Cause.pretty(cause)
534
- }
535
- )
536
- if (message) {
537
- yield* self.toast.error(message)
538
- }
539
- })
540
- })
541
- }
542
-
543
- function renderError(e: ResponseErrors): string {
544
- return Match.value(e as any).pipe(
545
- Match.tags({
546
- // HttpErrorRequest: e =>
547
- // this.intl.value.formatMessage(
548
- // { id: "handle.request_error" },
549
- // { error: `${e.error}` },
550
- // ),
551
- // HttpErrorResponse: e =>
552
- // e.response.status >= 500 ||
553
- // e.response.body._tag !== "Some" ||
554
- // !e.response.body.value
555
- // ? this.intl.value.formatMessage(
556
- // { id: "handle.error_response" },
557
- // {
558
- // error: `${
559
- // e.response.body._tag === "Some" && e.response.body.value
560
- // ? parseError(e.response.body.value)
561
- // : "Unknown"
562
- // } (${e.response.status})`,
563
- // },
564
- // )
565
- // : this.intl.value.formatMessage(
566
- // { id: "handle.unexpected_error" },
567
- // {
568
- // error:
569
- // JSON.stringify(e.response.body, undefined, 2) +
570
- // "( " +
571
- // e.response.status +
572
- // ")",
573
- // },
574
- // ),
575
- // ResponseError: e =>
576
- // this.intl.value.formatMessage(
577
- // { id: "handle.response_error" },
578
- // { error: `${e.error}` },
579
- // ),
580
- SchemaError: (e: any) => {
581
- console.warn(e.toString())
582
- return self.intl.formatMessage({ id: "validation.failed" })
583
- }
584
- }),
585
- Match.orElse((e: any) => `${e.message ?? e._tag ?? e}`)
586
- )
587
- }
588
- }
589
-
590
- /**
591
- * Pass a function that returns an Effect, e.g from a client action, give it a name.
592
- * Returns a tuple with raw Result and execution function which reports success and errors as Toast.
593
- * @deprecated use `Command.fn` and friends instead
594
- */
595
- readonly useAndHandleMutationResult: {
596
- /**
597
- * Pass a function that returns an Effect, e.g from a client action, give it a name.
598
- * Returns a tuple with raw Result and execution function which reports success and errors as Toast.
599
- * @deprecated use `Command.fn` and friends instead
600
- */
601
- <
602
- I,
603
- E extends ResponseErrors,
604
- A,
605
- R,
606
- Request extends Req,
607
- Name extends string,
608
- A2 = A,
609
- E2 extends ResponseErrors = E,
610
- R2 = R,
611
- ESuccess = never,
612
- RSuccess = never,
613
- EError = never,
614
- RError = never,
615
- EDefect = never,
616
- RDefect = never
617
- >(
618
- self: RequestHandlerWithInput<I, A, E, R, Request, Name>,
619
- action: string,
620
- options?: Opts<A, E, R, I, A2, E2, R2, ESuccess, RSuccess, EError, RError, EDefect, RDefect>
621
- ): Resp<I, A2, E2, R2, ComputedRef<AsyncResult.AsyncResult<A2, E2>>>
622
- /**
623
- * Pass a function that returns an Effect, e.g from a client action, give it a name.
624
- * Returns a tuple with raw Result and execution function which reports success and errors as Toast.
625
- * @deprecated use `Command.fn` and friends instead
626
- */
627
- <
628
- E extends ResponseErrors,
629
- A,
630
- R,
631
- Request extends Req,
632
- Name extends string,
633
- A2 = A,
634
- E2 extends ResponseErrors = E,
635
- R2 = R,
636
- ESuccess = never,
637
- RSuccess = never,
638
- EError = never,
639
- RError = never,
640
- EDefect = never,
641
- RDefect = never
642
- >(
643
- self: RequestHandler<A, E, R, Request, Name>,
644
- action: string,
645
- options?: Opts<A, E, R, void, A2, E2, R2, ESuccess, RSuccess, EError, RError, EDefect, RDefect>
646
- ): ActResp<A2, E2, R2, ComputedRef<AsyncResult.AsyncResult<A2, E2>>>
647
- } = <E extends ResponseErrors, A, R, Request extends Req, Name extends string, I>(
648
- self: RequestHandlerWithInput<I, A, E, R, Request, Name> | RequestHandler<A, E, R, Request, Name>,
649
- action: any,
650
- options?: Opts<any, any, any, any, any, any, any, any, any, any, any, any, any>
651
- ): any => {
652
- const handleRequestWithToast = this.useHandleRequestWithToast()
653
- const handler = self.handler
654
- const unsafe = _useMutation({
655
- ...self,
656
- handler: Effect.isEffect(handler)
657
- ? (pipe(
658
- Effect.annotateCurrentSpan({ action }),
659
- Effect.andThen(handler)
660
- ) as any)
661
- : (...args: [any]) =>
662
- pipe(
663
- Effect.annotateCurrentSpan({ action }),
664
- Effect.andThen(handler(...args))
665
- )
666
- }, options ? dropUndefinedT(options) : undefined)
667
-
668
- type MH = NonNullable<NonNullable<typeof options>["mapHandler"]>
669
- const mh = options?.mapHandler ?? identity as MH
670
-
671
- // Effect.tapDefect(reportRuntimeError) handled in toast handler,
672
- const [a, b] = asResult(mapHandler(unsafe, mh) as any)
673
-
674
- return tuple(
675
- a,
676
- handleRequestWithToast(b as any, self.id, action, options)
677
- )
678
- }
679
- //
680
-
681
- /**
682
- * Pass a function that returns an Effect, e.g from a client action, give it a name.
683
- * Returns a tuple with state ref and execution function which reports success and errors as Toast.
684
- *
685
- * @deprecated use `Command.fn` and friends instead
686
- */
687
- readonly useAndHandleMutation: {
688
- /**
689
- * Pass a function that returns an Effect, e.g from a client action, give it a name.
690
- * Returns a tuple with state ref and execution function which reports success and errors as Toast.
691
- *
692
- * @deprecated use `Command.fn` and friends instead
693
- */
694
- <
695
- I,
696
- E extends ResponseErrors,
697
- A,
698
- R,
699
- Request extends Req,
700
- Name extends string,
701
- A2 = A,
702
- E2 extends ResponseErrors = E,
703
- R2 = R,
704
- ESuccess = never,
705
- RSuccess = never,
706
- EError = never,
707
- RError = never,
708
- EDefect = never,
709
- RDefect = never
710
- >(
711
- self: RequestHandlerWithInput<I, A, E, R, Request, Name>,
712
- action: string,
713
- options?: Opts<A, E, R, I, A2, E2, R2, ESuccess, RSuccess, EError, RError, EDefect, RDefect>
714
- ): Resp<I, A2, E2, R2>
715
- /**
716
- * Pass a function that returns an Effect, e.g from a client action, give it a name.
717
- * Returns a tuple with state ref and execution function which reports success and errors as Toast.
718
- *
719
- * @deprecated use `Command.fn` and friends instead
720
- */
721
- <
722
- E extends ResponseErrors,
723
- A,
724
- R,
725
- Request extends Req,
726
- Name extends string,
727
- A2 = A,
728
- E2 extends ResponseErrors = E,
729
- R2 = R,
730
- ESuccess = never,
731
- RSuccess = never,
732
- EError = never,
733
- RError = never,
734
- EDefect = never,
735
- RDefect = never
736
- >(
737
- self: RequestHandler<A, E, R, Request, Name>,
738
- action: string,
739
- options?: Opts<A, E, R, void, A2, E2, R2, ESuccess, RSuccess, EError, RError, EDefect, RDefect>
740
- ): ActResp<A2, E2, R2>
741
- } = (
742
- self: any,
743
- action: any,
744
- options?: Opts<any, any, any, any, any, any, any, any, any, any, any, any, any>
745
- ): any => {
746
- const [a, b] = this.useAndHandleMutationResult(self, action, options)
747
-
748
- return tuple(
749
- computed(() => mutationResultToVue(a.value)),
750
- b
751
- )
752
- }
753
-
754
- /** @deprecated use `Command.fn` and friends instead */
755
- readonly makeUseAndHandleMutation = (
756
- defaultOptions?: Opts<any, any, any, any, any, any, any, any, any>
757
- ) =>
758
- ((self: any, action: any, options: any) => {
759
- return this.useAndHandleMutation(
760
- self,
761
- action,
762
- { ...defaultOptions, ...options }
763
- )
764
- }) as unknown as {
765
- <
766
- I,
767
- E extends ResponseErrors,
768
- A,
769
- R,
770
- Request extends Req,
771
- Name extends string,
772
- A2 = A,
773
- E2 extends ResponseErrors = E,
774
- R2 = R,
775
- ESuccess = never,
776
- RSuccess = never,
777
- EError = never,
778
- RError = never,
779
- EDefect = never,
780
- RDefect = never
781
- >(
782
- self: RequestHandlerWithInput<I, A, E, R, Request, Name>,
783
- action: string,
784
- options?: Opts<A, E, R, I, A2, E2, R2, ESuccess, RSuccess, EError, RError, EDefect, RDefect>
785
- ): Resp<I, A2, E2, R2>
786
- <
787
- E extends ResponseErrors,
788
- A,
789
- R,
790
- Request extends Req,
791
- Name extends string,
792
- A2 = A,
793
- E2 extends ResponseErrors = E,
794
- R2 = R,
795
- ESuccess = never,
796
- RSuccess = never,
797
- EError = never,
798
- RError = never,
799
- EDefect = never,
800
- RDefect = never
801
- >(
802
- self: RequestHandler<A, E, R, Request, Name>,
803
- action: string,
804
- options?: Opts<A, E, R, void, A2, E2, R2, ESuccess, RSuccess, EError, RError, EDefect, RDefect>
805
- ): ActResp<A2, E2, R2>
806
- }
807
-
808
- /**
809
- * The same as @see useAndHandleMutation, but does not display any toasts by default.
810
- * Messages for success, error and defect toasts can be provided in the Options.
811
- * @deprecated use `Command.fn` and friends instead
812
- */
813
- readonly useAndHandleMutationSilently: {
814
- /**
815
- * The same as @see useAndHandleMutation, but does not display any toasts by default.
816
- * Messages for success, error and defect toasts can be provided in the Options.
817
- * @deprecated use `Command.fn` and friends instead
818
- */
819
- <
820
- I,
821
- E extends ResponseErrors,
822
- A,
823
- R,
824
- Request extends Req,
825
- Name extends string,
826
- A2 = A,
827
- E2 extends ResponseErrors = E,
828
- R2 = R,
829
- ESuccess = never,
830
- RSuccess = never,
831
- EError = never,
832
- RError = never,
833
- EDefect = never,
834
- RDefect = never
835
- >(
836
- self: RequestHandlerWithInput<I, A, E, R, Request, Name>,
837
- action: string,
838
- options?: Opts<A, E, R, I, A2, E2, R2, ESuccess, RSuccess, EError, RError, EDefect, RDefect>
839
- ): Resp<I, A2, E2, R>
840
- /**
841
- * The same as @see useAndHandleMutation, but does not display any toasts by default.
842
- * Messages for success, error and defect toasts can be provided in the Options.
843
- * @deprecated use `Command.fn` and friends instead
844
- */
845
- <
846
- E extends ResponseErrors,
847
- A,
848
- R,
849
- Request extends Req,
850
- Name extends string,
851
- A2 = A,
852
- E2 extends ResponseErrors = E,
853
- R2 = R,
854
- ESuccess = never,
855
- RSuccess = never,
856
- EError = never,
857
- RError = never,
858
- EDefect = never,
859
- RDefect = never
860
- >(
861
- self: RequestHandler<A, E, R, Request, Name>,
862
- action: string,
863
- options?: Opts<A, E, R, void, A2, E2, R2, ESuccess, RSuccess, EError, RError, EDefect, RDefect>
864
- ): ActResp<void, never, R>
865
- } = this.makeUseAndHandleMutation({
866
- successMessage: suppressToast,
867
- failMessage: suppressToast,
868
- defectMessage: suppressToast
869
- }) as any
870
-
871
- /**
872
- * The same as @see useAndHandleMutation, but does not act on success, error or defect by default.
873
- * Actions for success, error and defect can be provided in the Options.
874
- * @deprecated use `Command.fn` and friends instead
875
- */
876
- readonly useAndHandleMutationCustom: {
877
- /**
878
- * The same as @see useAndHandleMutation, but does not act on success, error or defect by default.
879
- * Actions for success, error and defect can be provided in the Options.
880
- * @deprecated use `Command.fn` and friends instead
881
- */
882
- <
883
- I,
884
- E extends ResponseErrors,
885
- A,
886
- R,
887
- Request extends Req,
888
- Name extends string,
889
- A2 = A,
890
- E2 extends ResponseErrors = E,
891
- R2 = R,
892
- ESuccess = never,
893
- RSuccess = never,
894
- EError = never,
895
- RError = never,
896
- EDefect = never,
897
- RDefect = never
898
- >(
899
- self: RequestHandlerWithInput<I, A, E, R, Request, Name>,
900
- action: string,
901
- options?: LowOptsOptional<A, E, R, I, A2, E2, R2, ESuccess, RSuccess, EError, RError, EDefect, RDefect>
902
- ): Resp<I, A2, E2, R2>
903
- /**
904
- * The same as @see useAndHandleMutation, but does not act on success, error or defect by default.
905
- * Actions for success, error and defect can be provided in the Options.
906
- * @deprecated use `Command.fn` and friends instead
907
- */
908
- <
909
- E extends ResponseErrors,
910
- A,
911
- R,
912
- Request extends Req,
913
- Name extends string,
914
- A2 = A,
915
- E2 extends ResponseErrors = E,
916
- R2 = R,
917
- ESuccess = never,
918
- RSuccess = never,
919
- EError = never,
920
- RError = never,
921
- EDefect = never,
922
- RDefect = never
923
- >(
924
- self: RequestHandler<A, E, R, Request, Name>,
925
- action: string,
926
- options?: LowOptsOptional<A, E, R, void, A2, E2, R2, ESuccess, RSuccess, EError, RError, EDefect, RDefect>
927
- ): ActResp<A2, E2, R2>
928
- } = (self: any, action: string, options: any) => {
929
- const unsafe = _useMutation({
930
- ...self,
931
- handler: Effect.isEffect(self.handler)
932
- ? (pipe(
933
- Effect.annotateCurrentSpan({ action }),
934
- Effect.andThen(self.handler)
935
- ) as any)
936
- : (...args: any[]) =>
937
- pipe(
938
- Effect.annotateCurrentSpan({ action }),
939
- Effect.andThen(self.handler(...args))
940
- )
941
- }, options ? dropUndefinedT(options) : undefined)
942
-
943
- type MH = NonNullable<NonNullable<typeof options>["mapHandler"]>
944
- const mh = options?.mapHandler ?? identity as MH
945
-
946
- const [a, b] = asResult(
947
- mapHandler(
948
- mapHandler(unsafe as any, mh),
949
- Effect.tapCauseIf(Cause.hasDies, (cause) => reportRuntimeError(cause))
950
- ) as any
951
- )
952
-
953
- return tuple(
954
- computed(() => mutationResultToVue(a.value)),
955
- handleRequest(b as any, self.id, action, {
956
- onSuccess: suppressToast,
957
- onDefect: suppressToast,
958
- onFail: suppressToast,
959
- ...options
960
- })
961
- ) as any
962
- }
963
-
964
- /**
965
- * Effect results are converted to Exit, so errors are ignored by default.
966
- * you should use the result ref to render errors!
967
- * @deprecated use `Command.fn` and friends instead
968
- */
969
- readonly useSafeMutationWithState: {
970
- /**
971
- * Effect results are converted to Exit, so errors are ignored by default.
972
- * you should use the result ref to render errors!
973
- * @deprecated use `Command.fn` and friends instead
974
- */
975
- <I, E, A, R, Request extends Req, Name extends string, A2 = A, E2 = E, R2 = R>(
976
- self: RequestHandlerWithInput<I, A, E, R, Request, Name>,
977
- options?: MutationOptions<A, E, R, A2, E2, R2, I>
978
- ): readonly [
979
- ComputedRef<Res<A, E>>,
980
- (i: I) => Effect.Effect<Exit.Exit<A2, E2>, never, R2>
981
- ]
982
- /**
983
- * Effect results are converted to Exit, so errors are ignored by default.
984
- * you should use the result ref to render errors!
985
- * @deprecated use `Command.fn` and friends instead
986
- */
987
- <E, A, R, Request extends Req, Name extends string, A2 = A, E2 = E, R2 = R>(
988
- self: RequestHandler<A, E, R, Request, Name>,
989
- options?: MutationOptions<A, E, R, A2, E2, R2>
990
- ): readonly [
991
- ComputedRef<Res<A, E>>,
992
- Effect.Effect<Exit.Exit<A2, E2>, never, R2>
993
- ]
994
- } = <I, E, A, R, Request extends Req, Name extends string, A2 = A, E2 = E, R2 = R>(
995
- self: RequestHandlerWithInput<I, A, E, R, Request, Name> | RequestHandler<A, E, R, Request, Name>,
996
- options?: MutationOptions<A, E, R, A2, E2, R2, I>
997
- ) => {
998
- const [a, b] = this.useSafeMutation(self as any, options)
999
-
1000
- return tuple(
1001
- computed(() => mutationResultToVue(a.value)),
1002
- b
1003
- ) as any
1004
- }
1005
-
1006
- /** @deprecated use OmegaForm */
1007
- readonly buildFormFromSchema = <
1008
- From extends Record<PropertyKey, any>,
1009
- To extends Record<PropertyKey, any>,
1010
- C extends Record<PropertyKey, any>,
1011
- OnSubmitA
1012
- >(
1013
- s:
1014
- & S.Codec<To>
1015
- & { new(c: C): any; extend: any; fields: S.Struct.Fields },
1016
- state: Ref<Omit<From, "_tag">>,
1017
- onSubmit: (a: To) => Effect.Effect<OnSubmitA, never, RT>
1018
- ) => {
1019
- const fields = buildFieldInfoFromFieldsRoot(s).fields
1020
- const schema = S.Struct(Struct.omit(s.fields, ["_tag"])) as unknown as S.Codec<any> & {
1021
- readonly DecodingServices: never
1022
- }
1023
- const parse = S.decodeUnknownSync(schema)
1024
- const isDirty = ref(false)
1025
- const isValid = ref(true)
1026
- const isLoading = ref(false)
1027
- const runPromise = makeRunPromise(this.getRuntime())
1028
-
1029
- const submit1 =
1030
- (onSubmit: (a: To) => Effect.Effect<OnSubmitA, never, never>) =>
1031
- async <T extends Promise<{ valid: boolean }>>(e: T) => {
1032
- isLoading.value = true
1033
- try {
1034
- const r = await e
1035
- if (!r.valid) return
1036
- return await runPromise(onSubmit(new (s as any)(await runPromise(parse(state.value)))) as any)
1037
- } finally {
1038
- isLoading.value = false
1039
- }
1040
- }
1041
- const submit = submit1(onSubmit as any)
1042
-
1043
- watch(
1044
- state,
1045
- (v) => {
1046
- // TODO: do better
1047
- isDirty.value = JSON.stringify(v) !== JSON.stringify(state.value)
1048
- },
1049
- { deep: true }
1050
- )
1051
-
1052
- const submitFromState = Effect.gen(function*() {
1053
- return yield* (onSubmit(yield* parse(state.value)) as any)
1054
- })
1055
-
1056
- const submitFromStatePromise = () => runPromise(submitFromState as any)
1057
-
1058
- return {
1059
- fields,
1060
- /** optimized for Vuetify v-form submit callback */
1061
- submit,
1062
- /** optimized for Native form submit callback or general use */
1063
- submitFromState,
1064
- submitFromStatePromise,
1065
- isDirty,
1066
- isValid,
1067
- isLoading
1068
- }
1069
- }
1070
- }
1071
-
1072
- // @effect-diagnostics-next-line missingEffectServiceDependency:off
1073
- export class LegacyMutation extends Context.Service<LegacyMutation>()("LegacyMutation", {
1074
- make: Effect.gen(function*() {
1075
- const intl = yield* I18n
1076
- const toast = yield* Toast
1077
-
1078
- return <R>(getRuntime: () => Context.Context<R>) => new LegacyMutationImpl(getRuntime, toast, intl)
1079
- })
1080
- }) {
1081
- static readonly DefaultWithoutDependencies = Layer.effect(this, this.make)
1082
- static readonly Default = this.DefaultWithoutDependencies
1083
- }
1084
-
1085
227
  export type ClientFrom<M extends Requests> = RequestHandlers<never, never, M, M["meta"]["moduleName"]>
1086
228
 
1087
229
  export class QueryImpl<R> {
@@ -1218,7 +360,7 @@ export class QueryImpl<R> {
1218
360
  const managedRuntimeRt = <A, E>(mrt: ManagedRuntime.ManagedRuntime<A, E>) => mrt.runSync(Effect.services<A>())
1219
361
 
1220
362
  type Base = I18n | Toast
1221
- type Mix = ApiClientFactory | Commander | LegacyMutation | Base
363
+ type Mix = ApiClientFactory | Commander | Base
1222
364
  export const makeClient = <RT_, RTHooks>(
1223
365
  // global, but only accessible after startup has completed
1224
366
  getBaseMrt: () => ManagedRuntime.ManagedRuntime<RT_ | Mix, never>,
@@ -1226,45 +368,14 @@ export const makeClient = <RT_, RTHooks>(
1226
368
  rtHooks: Layer.Layer<RTHooks, never, Mix>
1227
369
  ) => {
1228
370
  type RT = RT_ | Mix
1229
- const getRt = Effect.services<RT>()
1230
371
  const getBaseRt = () => managedRuntimeRt(getBaseMrt())
1231
372
  const makeCommand = makeUseCommand<RT, RTHooks>(rtHooks)
1232
- const makeMutation = Effect.gen(function*() {
1233
- const mut = yield* LegacyMutation
1234
-
1235
- return mut(() => getBaseMrt().runSync(getRt))
1236
- })
1237
373
  let cmd: Effect.Success<typeof makeCommand>
1238
374
  const useCommand = () => cmd ??= getBaseMrt().runSync(makeCommand)
1239
- let mut: Effect.Success<typeof makeMutation>
1240
- const getMutation = () => mut ??= getBaseMrt().runSync(makeMutation)
1241
375
 
1242
376
  let m: ReturnType<typeof useMutationInt>
1243
377
  const useMutation = () => m ??= useMutationInt()
1244
378
 
1245
- const keys = [
1246
- "useSafeMutationWithState",
1247
- "useAndHandleMutation",
1248
- "useAndHandleMutationResult",
1249
- "useAndHandleMutationSilently",
1250
- "useAndHandleMutationCustom",
1251
- "makeUseAndHandleMutation",
1252
- "useHandleRequestWithToast",
1253
- "buildFormFromSchema",
1254
- "useSafeMutation"
1255
- ] as const satisfies readonly (keyof ReturnType<typeof getMutation>)[]
1256
- type mut = Pick<LegacyMutationImpl<RT>, typeof keys[number]>
1257
-
1258
- const mutations = keys.reduce(
1259
- (prev, cur) => {
1260
- ;(prev as any)[cur] = ((...args: [any]) => {
1261
- return (getMutation() as any)[cur](...args)
1262
- }) as any
1263
- return prev
1264
- },
1265
- {} as Pick<LegacyMutationImpl<RT>, typeof keys[number]>
1266
- )
1267
-
1268
379
  const query = new QueryImpl(getBaseRt)
1269
380
  const useQuery = query.useQuery
1270
381
  const useSuspenseQuery = query.useSuspenseQuery
@@ -1448,11 +559,6 @@ export const makeClient = <RT_, RTHooks>(
1448
559
  return proxy
1449
560
  }
1450
561
 
1451
- const legacy: Legacy<RT> = {
1452
- ...mutations,
1453
- ...query
1454
- }
1455
-
1456
562
  const Command: CommanderResolved<RT, RTHooks> = {
1457
563
  ...{
1458
564
  // delay initialisation until first use...
@@ -1467,17 +573,10 @@ export const makeClient = <RT_, RTHooks>(
1467
573
  return {
1468
574
  Command,
1469
575
  useCommand,
1470
- clientFor,
1471
- legacy
576
+ clientFor
1472
577
  }
1473
578
  }
1474
579
 
1475
- export interface Legacy<R>
1476
- extends
1477
- Pick<QueryImpl<R>, "useQuery" | "useSuspenseQuery">,
1478
- Omit<LegacyMutationImpl<R>, "getRuntime" | "toast" | "intl">
1479
- {}
1480
-
1481
580
  export type QueryInvalidation<M> = {
1482
581
  [K in keyof M]?: (defaultKey: string[], name: string) => {
1483
582
  filters?: InvalidateQueryFilters | undefined