@effect-app/vue 2.77.5 → 2.77.7

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