@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/CHANGELOG.md +12 -0
- package/dist/experimental/commander.d.ts +3 -3
- package/dist/experimental/makeUseCommand.d.ts +1 -1
- package/dist/makeClient.d.ts +173 -164
- package/dist/makeClient.d.ts.map +1 -1
- package/dist/makeClient.js +254 -255
- package/package.json +1 -1
- package/src/makeClient.ts +623 -621
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
|
|
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
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
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
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
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
|
-
|
|
290
|
-
|
|
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
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
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
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
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
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
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
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
371
|
+
)
|
|
372
|
+
if (message) {
|
|
373
|
+
yield* self.toast.error(message)
|
|
374
|
+
}
|
|
375
|
+
})
|
|
376
|
+
})
|
|
377
|
+
}
|
|
420
378
|
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
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
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
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
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
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
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
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
|
-
|
|
822
|
-
|
|
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
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
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
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
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
|
-
|
|
869
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
1050
|
+
{} as Pick<LegacyMutationImpl<R>, typeof keys[number]>
|
|
1052
1051
|
)
|
|
1053
1052
|
|
|
1054
|
-
const query =
|
|
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
|
-
|
|
1290
|
-
useQuery,
|
|
1291
|
-
/** @deprecated use .suspense on the clientFor(x).Action */
|
|
1292
|
-
useSuspenseQuery
|
|
1288
|
+
...query
|
|
1293
1289
|
}
|
|
1294
1290
|
|
|
1295
|
-
const Command: CommanderResolved<
|
|
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
|