@effect-app/vue 2.55.9 → 2.56.0
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 +17 -0
- package/dist/experimental/commander.d.ts +1 -1
- package/dist/experimental/commander.d.ts.map +1 -1
- package/dist/experimental/commander.js +9 -9
- package/dist/experimental/{makeExperimental.d.ts → makeUseCommand.d.ts} +2 -2
- package/dist/experimental/makeUseCommand.d.ts.map +1 -0
- package/dist/experimental/makeUseCommand.js +8 -0
- package/dist/form.d.ts +2 -28
- package/dist/form.d.ts.map +1 -1
- package/dist/form.js +3 -39
- package/dist/makeClient.d.ts +130 -47
- package/dist/makeClient.d.ts.map +1 -1
- package/dist/makeClient.js +310 -230
- package/dist/runtime.d.ts +4 -43
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +8 -28
- package/package.json +4 -4
- package/src/experimental/commander.ts +19 -15
- package/src/experimental/{makeExperimental.ts → makeUseCommand.ts} +1 -1
- package/src/form.ts +2 -60
- package/src/makeClient.ts +684 -597
- package/src/runtime.ts +7 -28
- package/test/dist/stubs.d.ts.map +1 -1
- package/test/dist/stubs.js +3 -3
- package/test/stubs.ts +2 -2
- package/dist/experimental/makeExperimental.d.ts.map +0 -1
- package/dist/experimental/makeExperimental.js +0 -8
package/src/makeClient.ts
CHANGED
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
2
|
import * as Result from "@effect-atom/atom/Result"
|
|
3
3
|
import { type InitialDataFunction, isCancelledError, type QueryObserverResult, type RefetchOptions, type UseQueryReturnType } from "@tanstack/vue-query"
|
|
4
|
-
import { Cause, Effect, Exit, Match, Option, Runtime, S, Struct } from "effect-app"
|
|
4
|
+
import { Cause, Effect, Exit, Layer, ManagedRuntime, Match, Option, Runtime, S, Struct } from "effect-app"
|
|
5
5
|
import type { RequestHandler, RequestHandlerWithInput, TaggedRequestClassAny } from "effect-app/client/clientFor"
|
|
6
6
|
import { ErrorSilenced, type SupportedErrors } from "effect-app/client/errors"
|
|
7
7
|
import { constant, pipe, tuple } from "effect-app/Function"
|
|
8
8
|
import { type OperationFailure, OperationSuccess } from "effect-app/Operations"
|
|
9
9
|
import type { Schema } from "effect-app/Schema"
|
|
10
10
|
import { dropUndefinedT } from "effect-app/utils"
|
|
11
|
-
import { computed, type ComputedRef, onBeforeUnmount, type Ref, ref,
|
|
11
|
+
import { computed, type ComputedRef, getCurrentInstance, onBeforeUnmount, onUnmounted, type Ref, ref, shallowRef, watch, type WatchSource } from "vue"
|
|
12
12
|
import { reportMessage } from "./errorReporter.js"
|
|
13
|
+
import { Commander } from "./experimental/commander.js"
|
|
14
|
+
import { I18n } from "./experimental/intl.js"
|
|
15
|
+
import { makeUseCommand } from "./experimental/makeUseCommand.js"
|
|
16
|
+
import { Toast } from "./experimental/toast.js"
|
|
13
17
|
import { buildFieldInfoFromFieldsRoot } from "./form.js"
|
|
14
|
-
import {
|
|
15
|
-
import type { MakeIntlReturn } from "./makeIntl.js"
|
|
18
|
+
import { reportRuntimeError } from "./lib.js"
|
|
16
19
|
import { asResult, makeMutation, type MutationOptions, mutationResultToVue, type Res } from "./mutate.js"
|
|
17
20
|
import { type KnownFiberFailure, makeQuery, type QueryObserverOptionsCustom } from "./query.js"
|
|
18
21
|
|
|
@@ -181,604 +184,623 @@ function handleRequest<
|
|
|
181
184
|
)
|
|
182
185
|
}
|
|
183
186
|
|
|
184
|
-
|
|
185
|
-
// NOTE: underscores to not collide with auto exports in nuxt apps
|
|
186
|
-
_useIntl: MakeIntlReturn<Locale>["useIntl"],
|
|
187
|
-
_useToast: () => {
|
|
188
|
-
error: (message: string) => void
|
|
189
|
-
warning: (message: string) => void
|
|
190
|
-
success: (message: string) => void
|
|
191
|
-
},
|
|
192
|
-
runtime: ShallowRef<Runtime.Runtime<R> | undefined>,
|
|
193
|
-
messages: Record<string, string | undefined> = {}
|
|
194
|
-
) => {
|
|
195
|
-
// making sure names do not collide with auto exports in nuxt apps, please do not rename..
|
|
196
|
-
/**
|
|
197
|
-
* Effect results are passed to the caller, including errors.
|
|
198
|
-
*/
|
|
199
|
-
const _useUnsafeMutation = makeMutation()
|
|
200
|
-
const _useSafeQuery = makeQuery(runtime)
|
|
201
|
-
|
|
202
|
-
const __useUnsafeMutation: {
|
|
203
|
-
<I, E, A, R, Request extends TaggedRequestClassAny, A2 = A, E2 = E, R2 = R>(
|
|
204
|
-
self: RequestHandlerWithInput<I, A, E, R, Request>,
|
|
205
|
-
options?: MutationOptions<A, E, R, A2, E2, R2, I>
|
|
206
|
-
): (i: I) => Effect.Effect<A2, E2, R2>
|
|
207
|
-
<E, A, R, Request extends TaggedRequestClassAny, A2 = A, E2 = E, R2 = R>(
|
|
208
|
-
self: RequestHandler<A, E, R, Request>,
|
|
209
|
-
options?: MutationOptions<A, E, R, A2, E2, R2>
|
|
210
|
-
): Effect.Effect<A2, E2, R2>
|
|
211
|
-
} = <I, E, A, R, Request extends TaggedRequestClassAny, A2 = A, E2 = E, R2 = R>(
|
|
212
|
-
self: RequestHandlerWithInput<I, A, E, R, Request> | RequestHandler<A, E, R, Request>,
|
|
213
|
-
options?: MutationOptions<A, E, R, A2, E2, R2, I>
|
|
214
|
-
) =>
|
|
215
|
-
tapHandler(
|
|
216
|
-
_useUnsafeMutation(self as any, options),
|
|
217
|
-
Effect.withSpan(`mutation ${self.name}`, { captureStackTrace: false })
|
|
218
|
-
) as any
|
|
219
|
-
|
|
220
|
-
/**
|
|
221
|
-
* Effect results are converted to Exit, so errors are ignored by default.
|
|
222
|
-
* you should use the result ref to render errors!
|
|
223
|
-
*/
|
|
224
|
-
const _useSafeMutation: {
|
|
225
|
-
<I, E, A, R, Request extends TaggedRequestClassAny, A2 = A, E2 = E, R2 = R>(
|
|
226
|
-
self: RequestHandlerWithInput<I, A, E, R, Request>,
|
|
227
|
-
options?: MutationOptions<A, E, R, A2, E2, R2, I>
|
|
228
|
-
): readonly [
|
|
229
|
-
ComputedRef<Result.Result<A2, E2>>,
|
|
230
|
-
(i: I) => Effect.Effect<Exit.Exit<A2, E2>, never, R2>
|
|
231
|
-
]
|
|
232
|
-
<E, A, R, Request extends TaggedRequestClassAny, A2 = A, E2 = E, R2 = R>(
|
|
233
|
-
self: RequestHandler<A, E, R, Request>,
|
|
234
|
-
options?: MutationOptions<A, E, R, A2, E2, R2>
|
|
235
|
-
): readonly [
|
|
236
|
-
ComputedRef<Result.Result<A2, E2>>,
|
|
237
|
-
Effect.Effect<Exit.Exit<A2, E2>, never, R2>
|
|
238
|
-
]
|
|
239
|
-
} = <I, E, A, R, Request extends TaggedRequestClassAny, A2 = A, E2 = E, R2 = R>(
|
|
240
|
-
self: RequestHandlerWithInput<I, A, E, R, Request> | RequestHandler<A, E, R, Request>,
|
|
241
|
-
options?: MutationOptions<A, E, R, A2, E2, R2, I>
|
|
242
|
-
) => {
|
|
243
|
-
const unsafe = _useUnsafeMutation(self as any, options)
|
|
244
|
-
|
|
245
|
-
const [a, b] = asResult(tapHandler(unsafe, Effect.tapDefect(reportRuntimeError)) as any)
|
|
246
|
-
return [
|
|
247
|
-
a,
|
|
248
|
-
tapHandler(
|
|
249
|
-
b,
|
|
250
|
-
Effect.withSpan(`mutation ${self.name}`, { captureStackTrace: false })
|
|
251
|
-
)
|
|
252
|
-
] as const as any
|
|
253
|
-
}
|
|
187
|
+
const _useUnsafeMutation = makeMutation()
|
|
254
188
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
>(
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
189
|
+
export const useUnsafeMutation: typeof _useUnsafeMutation = <
|
|
190
|
+
I,
|
|
191
|
+
E,
|
|
192
|
+
A,
|
|
193
|
+
R,
|
|
194
|
+
Request extends TaggedRequestClassAny,
|
|
195
|
+
A2 = A,
|
|
196
|
+
E2 = E,
|
|
197
|
+
R2 = R
|
|
198
|
+
>(
|
|
199
|
+
self: RequestHandlerWithInput<I, A, E, R, Request> | RequestHandler<A, E, R, Request>,
|
|
200
|
+
options?: MutationOptions<A, E, R, A2, E2, R2, I>
|
|
201
|
+
) =>
|
|
202
|
+
tapHandler(
|
|
203
|
+
_useUnsafeMutation(self as any, options),
|
|
204
|
+
Effect.withSpan(`mutation ${self.name}`, { captureStackTrace: false })
|
|
205
|
+
) as any
|
|
206
|
+
|
|
207
|
+
// @effect-diagnostics-next-line missingEffectServiceDependency:off
|
|
208
|
+
export class LegacyMutation extends Effect.Service<LegacyMutation>()("LegacyMutation", {
|
|
209
|
+
effect: Effect.gen(function*() {
|
|
210
|
+
const intl = yield* I18n
|
|
211
|
+
const toast = yield* Toast
|
|
212
|
+
return <R>(runtime: Runtime.Runtime<R>) => {
|
|
213
|
+
/**
|
|
214
|
+
* Effect results are converted to Exit, so errors are ignored by default.
|
|
215
|
+
* you should use the result ref to render errors!
|
|
216
|
+
*/
|
|
217
|
+
const _useSafeMutation: {
|
|
218
|
+
<I, E, A, R, Request extends TaggedRequestClassAny, A2 = A, E2 = E, R2 = R>(
|
|
219
|
+
self: RequestHandlerWithInput<I, A, E, R, Request>,
|
|
220
|
+
options?: MutationOptions<A, E, R, A2, E2, R2, I>
|
|
221
|
+
): readonly [
|
|
222
|
+
ComputedRef<Result.Result<A2, E2>>,
|
|
223
|
+
(i: I) => Effect.Effect<Exit.Exit<A2, E2>, never, R2>
|
|
224
|
+
]
|
|
225
|
+
<E, A, R, Request extends TaggedRequestClassAny, A2 = A, E2 = E, R2 = R>(
|
|
226
|
+
self: RequestHandler<A, E, R, Request>,
|
|
227
|
+
options?: MutationOptions<A, E, R, A2, E2, R2>
|
|
228
|
+
): readonly [
|
|
229
|
+
ComputedRef<Result.Result<A2, E2>>,
|
|
230
|
+
Effect.Effect<Exit.Exit<A2, E2>, never, R2>
|
|
231
|
+
]
|
|
232
|
+
} = <I, E, A, R, Request extends TaggedRequestClassAny, A2 = A, E2 = E, R2 = R>(
|
|
233
|
+
self: RequestHandlerWithInput<I, A, E, R, Request> | RequestHandler<A, E, R, Request>,
|
|
234
|
+
options?: MutationOptions<A, E, R, A2, E2, R2, I>
|
|
235
|
+
) => {
|
|
236
|
+
const unsafe = _useUnsafeMutation(self as any, options)
|
|
237
|
+
|
|
238
|
+
const [a, b] = asResult(tapHandler(unsafe, Effect.tapDefect(reportRuntimeError)) as any)
|
|
239
|
+
return [
|
|
240
|
+
a,
|
|
241
|
+
tapHandler(
|
|
242
|
+
b,
|
|
243
|
+
Effect.withSpan(`mutation ${self.name}`, { captureStackTrace: false })
|
|
244
|
+
)
|
|
245
|
+
] as const as any
|
|
246
|
+
}
|
|
297
247
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
248
|
+
const _useHandleRequestWithToast = () => {
|
|
249
|
+
return handleRequestWithToast
|
|
250
|
+
/**
|
|
251
|
+
* Pass a function that returns a Promise.
|
|
252
|
+
* Returns an execution function which reports errors as Toast.
|
|
253
|
+
*/
|
|
254
|
+
function handleRequestWithToast<
|
|
255
|
+
A,
|
|
256
|
+
E extends ResponseErrors,
|
|
257
|
+
R,
|
|
258
|
+
I = void,
|
|
259
|
+
A2 = A,
|
|
260
|
+
E2 extends ResponseErrors = E,
|
|
261
|
+
R2 = R,
|
|
262
|
+
ESuccess = never,
|
|
263
|
+
RSuccess = never,
|
|
264
|
+
EError = never,
|
|
265
|
+
RError = never,
|
|
266
|
+
EDefect = never,
|
|
267
|
+
RDefect = never
|
|
268
|
+
>(
|
|
269
|
+
f: Effect.Effect<Exit.Exit<A2, E2>, never, R2> | ((i: I) => Effect.Effect<Exit.Exit<A2, E2>, never, R2>),
|
|
270
|
+
name: string,
|
|
271
|
+
action: string,
|
|
272
|
+
options: Opts<A, E, R, I, A2, E2, R2, ESuccess, RSuccess, EError, RError, EDefect, RDefect> = {}
|
|
273
|
+
) {
|
|
274
|
+
const actionMessage = intl.formatMessage({ id: `action.${action}`, defaultMessage: action })
|
|
275
|
+
const defaultWarnMessage = intl.formatMessage(
|
|
276
|
+
{ id: "handle.with_warnings" },
|
|
277
|
+
{ action: actionMessage }
|
|
278
|
+
)
|
|
279
|
+
const defaultSuccessMessage = intl.formatMessage(
|
|
280
|
+
{ id: "handle.success" },
|
|
281
|
+
{ action: actionMessage }
|
|
282
|
+
)
|
|
283
|
+
const defaultErrorMessage = intl.formatMessage(
|
|
284
|
+
{ id: "handle.with_errors" },
|
|
285
|
+
{ action: actionMessage }
|
|
286
|
+
)
|
|
317
287
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
:
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
288
|
+
return handleRequest<E2, A2, R2, any, ESuccess, RSuccess, EError, RError, EDefect, RDefect>(f, name, action, {
|
|
289
|
+
onSuccess: Effect.fnUntraced(function*(a, i) {
|
|
290
|
+
const message = options.successMessage ? yield* options.successMessage(a, i) : defaultSuccessMessage
|
|
291
|
+
+ (S.is(OperationSuccess)(a) && a.message
|
|
292
|
+
? "\n" + a.message
|
|
293
|
+
: "")
|
|
294
|
+
if (message) {
|
|
295
|
+
yield* toast.success(message)
|
|
296
|
+
}
|
|
297
|
+
}),
|
|
298
|
+
onFail: Effect.fnUntraced(function*(e, i) {
|
|
299
|
+
if (!options.failMessage && e._tag === "OperationFailure") {
|
|
300
|
+
yield* toast.warning(
|
|
301
|
+
defaultWarnMessage + e.message
|
|
302
|
+
? "\n" + e.message
|
|
303
|
+
: ""
|
|
304
|
+
)
|
|
305
|
+
return
|
|
333
306
|
}
|
|
334
|
-
)
|
|
335
|
-
if (message) {
|
|
336
|
-
toast.error(message)
|
|
337
|
-
}
|
|
338
|
-
})
|
|
339
|
-
})
|
|
340
|
-
}
|
|
341
307
|
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
// { id: "handle.unexpected_error" },
|
|
366
|
-
// {
|
|
367
|
-
// error:
|
|
368
|
-
// JSON.stringify(e.response.body, undefined, 2) +
|
|
369
|
-
// "( " +
|
|
370
|
-
// e.response.status +
|
|
371
|
-
// ")",
|
|
372
|
-
// },
|
|
373
|
-
// ),
|
|
374
|
-
// ResponseError: e =>
|
|
375
|
-
// intl.value.formatMessage(
|
|
376
|
-
// { id: "handle.response_error" },
|
|
377
|
-
// { error: `${e.error}` },
|
|
378
|
-
// ),
|
|
379
|
-
ParseError: (e) => {
|
|
380
|
-
console.warn(e.toString())
|
|
381
|
-
return intl.formatMessage({ id: "validation.failed" })
|
|
382
|
-
}
|
|
383
|
-
}),
|
|
384
|
-
Match.orElse((e) => `${e.message ?? e._tag ?? e}`)
|
|
385
|
-
)
|
|
386
|
-
}
|
|
387
|
-
}
|
|
308
|
+
const message = options.failMessage
|
|
309
|
+
? yield* options.failMessage(e, i)
|
|
310
|
+
: `${defaultErrorMessage}:\n` + renderError(e)
|
|
311
|
+
if (message) {
|
|
312
|
+
yield* toast.error(message)
|
|
313
|
+
}
|
|
314
|
+
}),
|
|
315
|
+
onDefect: Effect.fnUntraced(function*(cause, i) {
|
|
316
|
+
const message = options.defectMessage
|
|
317
|
+
? yield* options.defectMessage(cause, i)
|
|
318
|
+
: intl.formatMessage(
|
|
319
|
+
{ id: "handle.unexpected_error" },
|
|
320
|
+
{
|
|
321
|
+
action: actionMessage,
|
|
322
|
+
error: Cause.pretty(cause)
|
|
323
|
+
}
|
|
324
|
+
)
|
|
325
|
+
if (message) {
|
|
326
|
+
yield* toast.error(message)
|
|
327
|
+
}
|
|
328
|
+
})
|
|
329
|
+
})
|
|
330
|
+
}
|
|
388
331
|
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
): ActResp<A2, E2, R2, ComputedRef<Result.Result<A2, E2>>>
|
|
433
|
-
} = <E extends ResponseErrors, A, R, Request extends TaggedRequestClassAny, I>(
|
|
434
|
-
self: RequestHandlerWithInput<I, A, E, R, Request> | RequestHandler<A, E, R, Request>,
|
|
435
|
-
action: any,
|
|
436
|
-
options?: Opts<any, any, any, any, any, any, any, any, any, any, any, any, any>
|
|
437
|
-
): any => {
|
|
438
|
-
const handleRequestWithToast = _useHandleRequestWithToast()
|
|
439
|
-
const handler = self.handler
|
|
440
|
-
const [a, b] = asResult(_useUnsafeMutation({
|
|
441
|
-
...self,
|
|
442
|
-
handler: Effect.isEffect(handler)
|
|
443
|
-
? (pipe(
|
|
444
|
-
Effect.annotateCurrentSpan({ action }),
|
|
445
|
-
Effect.zipRight(handler)
|
|
446
|
-
) as any)
|
|
447
|
-
: (...args: [any]) =>
|
|
448
|
-
pipe(
|
|
449
|
-
Effect.annotateCurrentSpan({ action }),
|
|
450
|
-
Effect.zipRight(handler(...args))
|
|
332
|
+
function renderError(e: ResponseErrors): string {
|
|
333
|
+
return Match.value(e).pipe(
|
|
334
|
+
Match.tags({
|
|
335
|
+
// HttpErrorRequest: e =>
|
|
336
|
+
// intl.value.formatMessage(
|
|
337
|
+
// { id: "handle.request_error" },
|
|
338
|
+
// { error: `${e.error}` },
|
|
339
|
+
// ),
|
|
340
|
+
// HttpErrorResponse: e =>
|
|
341
|
+
// e.response.status >= 500 ||
|
|
342
|
+
// e.response.body._tag !== "Some" ||
|
|
343
|
+
// !e.response.body.value
|
|
344
|
+
// ? intl.value.formatMessage(
|
|
345
|
+
// { id: "handle.error_response" },
|
|
346
|
+
// {
|
|
347
|
+
// error: `${
|
|
348
|
+
// e.response.body._tag === "Some" && e.response.body.value
|
|
349
|
+
// ? parseError(e.response.body.value)
|
|
350
|
+
// : "Unknown"
|
|
351
|
+
// } (${e.response.status})`,
|
|
352
|
+
// },
|
|
353
|
+
// )
|
|
354
|
+
// : intl.value.formatMessage(
|
|
355
|
+
// { id: "handle.unexpected_error" },
|
|
356
|
+
// {
|
|
357
|
+
// error:
|
|
358
|
+
// JSON.stringify(e.response.body, undefined, 2) +
|
|
359
|
+
// "( " +
|
|
360
|
+
// e.response.status +
|
|
361
|
+
// ")",
|
|
362
|
+
// },
|
|
363
|
+
// ),
|
|
364
|
+
// ResponseError: e =>
|
|
365
|
+
// intl.value.formatMessage(
|
|
366
|
+
// { id: "handle.response_error" },
|
|
367
|
+
// { error: `${e.error}` },
|
|
368
|
+
// ),
|
|
369
|
+
ParseError: (e) => {
|
|
370
|
+
console.warn(e.toString())
|
|
371
|
+
return intl.formatMessage({ id: "validation.failed" })
|
|
372
|
+
}
|
|
373
|
+
}),
|
|
374
|
+
Match.orElse((e) => `${e.message ?? e._tag ?? e}`)
|
|
451
375
|
)
|
|
452
|
-
|
|
376
|
+
}
|
|
377
|
+
}
|
|
453
378
|
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
379
|
+
/**
|
|
380
|
+
* Pass a function that returns an Effect, e.g from a client action, give it a name.
|
|
381
|
+
* Returns a tuple with raw Result and execution function which reports success and errors as Toast.
|
|
382
|
+
*/
|
|
383
|
+
const _useAndHandleMutationResult: {
|
|
384
|
+
<
|
|
385
|
+
I,
|
|
386
|
+
E extends ResponseErrors,
|
|
387
|
+
A,
|
|
388
|
+
R,
|
|
389
|
+
Request extends TaggedRequestClassAny,
|
|
390
|
+
A2 = A,
|
|
391
|
+
E2 extends ResponseErrors = E,
|
|
392
|
+
R2 = R,
|
|
393
|
+
ESuccess = never,
|
|
394
|
+
RSuccess = never,
|
|
395
|
+
EError = never,
|
|
396
|
+
RError = never,
|
|
397
|
+
EDefect = never,
|
|
398
|
+
RDefect = never
|
|
399
|
+
>(
|
|
400
|
+
self: RequestHandlerWithInput<I, A, E, R, Request>,
|
|
401
|
+
action: string,
|
|
402
|
+
options?: Opts<A, E, R, I, A2, E2, R2, ESuccess, RSuccess, EError, RError, EDefect, RDefect>
|
|
403
|
+
): Resp<I, A2, E2, R2, ComputedRef<Result.Result<A2, E2>>>
|
|
404
|
+
<
|
|
405
|
+
E extends ResponseErrors,
|
|
406
|
+
A,
|
|
407
|
+
R,
|
|
408
|
+
Request extends TaggedRequestClassAny,
|
|
409
|
+
A2 = A,
|
|
410
|
+
E2 extends ResponseErrors = E,
|
|
411
|
+
R2 = R,
|
|
412
|
+
ESuccess = never,
|
|
413
|
+
RSuccess = never,
|
|
414
|
+
EError = never,
|
|
415
|
+
RError = never,
|
|
416
|
+
EDefect = never,
|
|
417
|
+
RDefect = never
|
|
418
|
+
>(
|
|
419
|
+
self: RequestHandler<A, E, R, Request>,
|
|
420
|
+
action: string,
|
|
421
|
+
options?: Opts<A, E, R, void, A2, E2, R2, ESuccess, RSuccess, EError, RError, EDefect, RDefect>
|
|
422
|
+
): ActResp<A2, E2, R2, ComputedRef<Result.Result<A2, E2>>>
|
|
423
|
+
} = <E extends ResponseErrors, A, R, Request extends TaggedRequestClassAny, I>(
|
|
424
|
+
self: RequestHandlerWithInput<I, A, E, R, Request> | RequestHandler<A, E, R, Request>,
|
|
425
|
+
action: any,
|
|
426
|
+
options?: Opts<any, any, any, any, any, any, any, any, any, any, any, any, any>
|
|
427
|
+
): any => {
|
|
428
|
+
const handleRequestWithToast = _useHandleRequestWithToast()
|
|
429
|
+
const handler = self.handler
|
|
430
|
+
const [a, b] = asResult(_useUnsafeMutation({
|
|
431
|
+
...self,
|
|
432
|
+
handler: Effect.isEffect(handler)
|
|
433
|
+
? (pipe(
|
|
434
|
+
Effect.annotateCurrentSpan({ action }),
|
|
435
|
+
Effect.zipRight(handler)
|
|
436
|
+
) as any)
|
|
437
|
+
: (...args: [any]) =>
|
|
438
|
+
pipe(
|
|
439
|
+
Effect.annotateCurrentSpan({ action }),
|
|
440
|
+
Effect.zipRight(handler(...args))
|
|
441
|
+
)
|
|
442
|
+
}, options ? dropUndefinedT(options) : undefined))
|
|
443
|
+
|
|
444
|
+
return tuple(
|
|
445
|
+
a,
|
|
446
|
+
handleRequestWithToast(b as any, self.name, action, options)
|
|
447
|
+
)
|
|
448
|
+
}
|
|
449
|
+
//
|
|
450
|
+
|
|
451
|
+
/**
|
|
452
|
+
* Pass a function that returns an Effect, e.g from a client action, give it a name.
|
|
453
|
+
* Returns a tuple with state ref and execution function which reports success and errors as Toast.
|
|
454
|
+
*/
|
|
455
|
+
const _useAndHandleMutation: {
|
|
456
|
+
<
|
|
457
|
+
I,
|
|
458
|
+
E extends ResponseErrors,
|
|
459
|
+
A,
|
|
460
|
+
R,
|
|
461
|
+
Request extends TaggedRequestClassAny,
|
|
462
|
+
A2 = A,
|
|
463
|
+
E2 extends ResponseErrors = E,
|
|
464
|
+
R2 = R,
|
|
465
|
+
ESuccess = never,
|
|
466
|
+
RSuccess = never,
|
|
467
|
+
EError = never,
|
|
468
|
+
RError = never,
|
|
469
|
+
EDefect = never,
|
|
470
|
+
RDefect = never
|
|
471
|
+
>(
|
|
472
|
+
self: RequestHandlerWithInput<I, A, E, R, Request>,
|
|
473
|
+
action: string,
|
|
474
|
+
options?: Opts<A, E, R, I, A2, E2, R2, ESuccess, RSuccess, EError, RError, EDefect, RDefect>
|
|
475
|
+
): Resp<I, A2, E2, R2>
|
|
476
|
+
<
|
|
477
|
+
E extends ResponseErrors,
|
|
478
|
+
A,
|
|
479
|
+
R,
|
|
480
|
+
Request extends TaggedRequestClassAny,
|
|
481
|
+
A2 = A,
|
|
482
|
+
E2 extends ResponseErrors = E,
|
|
483
|
+
R2 = R,
|
|
484
|
+
ESuccess = never,
|
|
485
|
+
RSuccess = never,
|
|
486
|
+
EError = never,
|
|
487
|
+
RError = never,
|
|
488
|
+
EDefect = never,
|
|
489
|
+
RDefect = never
|
|
490
|
+
>(
|
|
491
|
+
self: RequestHandler<A, E, R, Request>,
|
|
492
|
+
action: string,
|
|
493
|
+
options?: Opts<A, E, R, void, A2, E2, R2, ESuccess, RSuccess, EError, RError, EDefect, RDefect>
|
|
494
|
+
): ActResp<A2, E2, R2>
|
|
495
|
+
} = (
|
|
496
|
+
self: any,
|
|
497
|
+
action: any,
|
|
498
|
+
options?: Opts<any, any, any, any, any, any, any, any, any, any, any, any, any>
|
|
499
|
+
): any => {
|
|
500
|
+
const [a, b] = _useAndHandleMutationResult(self, action, options)
|
|
501
|
+
|
|
502
|
+
return tuple(
|
|
503
|
+
computed(() => mutationResultToVue(a.value)),
|
|
504
|
+
b
|
|
505
|
+
)
|
|
506
|
+
}
|
|
460
507
|
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
return tuple(
|
|
513
|
-
computed(() => mutationResultToVue(a.value)),
|
|
514
|
-
b
|
|
515
|
-
)
|
|
516
|
-
}
|
|
508
|
+
function _makeUseAndHandleMutation(
|
|
509
|
+
defaultOptions?: Opts<any, any, any, any, any, any, any, any, any>
|
|
510
|
+
) {
|
|
511
|
+
return ((self: any, action: any, options: any) => {
|
|
512
|
+
return _useAndHandleMutation(
|
|
513
|
+
self,
|
|
514
|
+
action,
|
|
515
|
+
{ ...defaultOptions, ...options }
|
|
516
|
+
)
|
|
517
|
+
}) as unknown as {
|
|
518
|
+
<
|
|
519
|
+
I,
|
|
520
|
+
E extends ResponseErrors,
|
|
521
|
+
A,
|
|
522
|
+
R,
|
|
523
|
+
Request extends TaggedRequestClassAny,
|
|
524
|
+
A2 = A,
|
|
525
|
+
E2 extends ResponseErrors = E,
|
|
526
|
+
R2 = R,
|
|
527
|
+
ESuccess = never,
|
|
528
|
+
RSuccess = never,
|
|
529
|
+
EError = never,
|
|
530
|
+
RError = never,
|
|
531
|
+
EDefect = never,
|
|
532
|
+
RDefect = never
|
|
533
|
+
>(
|
|
534
|
+
self: RequestHandlerWithInput<I, A, E, R, Request>,
|
|
535
|
+
action: string,
|
|
536
|
+
options?: Opts<A, E, R, I, A2, E2, R2, ESuccess, RSuccess, EError, RError, EDefect, RDefect>
|
|
537
|
+
): Resp<I, A2, E2, R2>
|
|
538
|
+
<
|
|
539
|
+
E extends ResponseErrors,
|
|
540
|
+
A,
|
|
541
|
+
Request extends TaggedRequestClassAny,
|
|
542
|
+
A2 = A,
|
|
543
|
+
E2 extends ResponseErrors = E,
|
|
544
|
+
R2 = R,
|
|
545
|
+
ESuccess = never,
|
|
546
|
+
RSuccess = never,
|
|
547
|
+
EError = never,
|
|
548
|
+
RError = never,
|
|
549
|
+
EDefect = never,
|
|
550
|
+
RDefect = never
|
|
551
|
+
>(
|
|
552
|
+
self: RequestHandler<A, E, R, Request>,
|
|
553
|
+
action: string,
|
|
554
|
+
options?: Opts<A, E, R, void, A2, E2, R2, ESuccess, RSuccess, EError, RError, EDefect, RDefect>
|
|
555
|
+
): ActResp<A2, E2, R2>
|
|
556
|
+
}
|
|
557
|
+
}
|
|
517
558
|
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
559
|
+
/**
|
|
560
|
+
* The same as @see useAndHandleMutation, but does not display any toasts by default.
|
|
561
|
+
* Messages for success, error and defect toasts can be provided in the Options.
|
|
562
|
+
*/
|
|
563
|
+
const _useAndHandleMutationSilently: {
|
|
564
|
+
<
|
|
565
|
+
I,
|
|
566
|
+
E extends ResponseErrors,
|
|
567
|
+
A,
|
|
568
|
+
R,
|
|
569
|
+
Request extends TaggedRequestClassAny,
|
|
570
|
+
A2 = A,
|
|
571
|
+
E2 extends ResponseErrors = E,
|
|
572
|
+
R2 = R,
|
|
573
|
+
ESuccess = never,
|
|
574
|
+
RSuccess = never,
|
|
575
|
+
EError = never,
|
|
576
|
+
RError = never,
|
|
577
|
+
EDefect = never,
|
|
578
|
+
RDefect = never
|
|
579
|
+
>(
|
|
580
|
+
self: RequestHandlerWithInput<I, A, E, R, Request>,
|
|
581
|
+
action: string,
|
|
582
|
+
options?: Opts<A, E, R, I, A2, E2, R2, ESuccess, RSuccess, EError, RError, EDefect, RDefect>
|
|
583
|
+
): Resp<I, A2, E2, R>
|
|
584
|
+
<
|
|
585
|
+
E extends ResponseErrors,
|
|
586
|
+
A,
|
|
587
|
+
R,
|
|
588
|
+
Request extends TaggedRequestClassAny,
|
|
589
|
+
A2 = A,
|
|
590
|
+
E2 extends ResponseErrors = E,
|
|
591
|
+
R2 = R,
|
|
592
|
+
ESuccess = never,
|
|
593
|
+
RSuccess = never,
|
|
594
|
+
EError = never,
|
|
595
|
+
RError = never,
|
|
596
|
+
EDefect = never,
|
|
597
|
+
RDefect = never
|
|
598
|
+
>(
|
|
599
|
+
self: RequestHandler<A, E, R, Request>,
|
|
600
|
+
action: string,
|
|
601
|
+
options?: Opts<A, E, R, void, A2, E2, R2, ESuccess, RSuccess, EError, RError, EDefect, RDefect>
|
|
602
|
+
): ActResp<void, never, R>
|
|
603
|
+
} = _makeUseAndHandleMutation({
|
|
604
|
+
successMessage: suppressToast,
|
|
605
|
+
failMessage: suppressToast,
|
|
606
|
+
defectMessage: suppressToast
|
|
607
|
+
}) as any
|
|
608
|
+
|
|
609
|
+
/**
|
|
610
|
+
* The same as @see useAndHandleMutation, but does not act on success, error or defect by default.
|
|
611
|
+
* Actions for success, error and defect can be provided in the Options.
|
|
612
|
+
*/
|
|
613
|
+
const _useAndHandleMutationCustom: {
|
|
614
|
+
<
|
|
615
|
+
I,
|
|
616
|
+
E extends ResponseErrors,
|
|
617
|
+
A,
|
|
618
|
+
R,
|
|
619
|
+
Request extends TaggedRequestClassAny,
|
|
620
|
+
A2 = A,
|
|
621
|
+
E2 extends ResponseErrors = E,
|
|
622
|
+
R2 = R,
|
|
623
|
+
ESuccess = never,
|
|
624
|
+
RSuccess = never,
|
|
625
|
+
EError = never,
|
|
626
|
+
RError = never,
|
|
627
|
+
EDefect = never,
|
|
628
|
+
RDefect = never
|
|
629
|
+
>(
|
|
630
|
+
self: RequestHandlerWithInput<I, A, E, R, Request>,
|
|
631
|
+
action: string,
|
|
632
|
+
options?: LowOptsOptional<A, E, R, I, A2, E2, R2, ESuccess, RSuccess, EError, RError, EDefect, RDefect>
|
|
633
|
+
): Resp<I, A2, E2, R2>
|
|
634
|
+
<
|
|
635
|
+
E extends ResponseErrors,
|
|
636
|
+
A,
|
|
637
|
+
R,
|
|
638
|
+
Request extends TaggedRequestClassAny,
|
|
639
|
+
A2 = A,
|
|
640
|
+
E2 extends ResponseErrors = E,
|
|
641
|
+
R2 = R,
|
|
642
|
+
ESuccess = never,
|
|
643
|
+
RSuccess = never,
|
|
644
|
+
EError = never,
|
|
645
|
+
RError = never,
|
|
646
|
+
EDefect = never,
|
|
647
|
+
RDefect = never
|
|
648
|
+
>(
|
|
649
|
+
self: RequestHandler<A, E, R, Request>,
|
|
650
|
+
action: string,
|
|
651
|
+
options?: LowOptsOptional<A, E, R, void, A2, E2, R2, ESuccess, RSuccess, EError, RError, EDefect, RDefect>
|
|
652
|
+
): ActResp<A2, E2, R2>
|
|
653
|
+
} = (self: any, action: string, options: any) => {
|
|
654
|
+
const [a, b] = asResult(_useUnsafeMutation({
|
|
655
|
+
...self,
|
|
656
|
+
handler: Effect.isEffect(self.handler)
|
|
657
|
+
? (pipe(
|
|
658
|
+
Effect.annotateCurrentSpan({ action }),
|
|
659
|
+
Effect.andThen(self.handler)
|
|
660
|
+
) as any)
|
|
661
|
+
: (...args: any[]) =>
|
|
662
|
+
pipe(
|
|
663
|
+
Effect.annotateCurrentSpan({ action }),
|
|
664
|
+
Effect.andThen(self.handler(...args))
|
|
665
|
+
)
|
|
666
|
+
}, options ? dropUndefinedT(options) : undefined))
|
|
667
|
+
|
|
668
|
+
return tuple(
|
|
669
|
+
computed(() => mutationResultToVue(a.value)),
|
|
670
|
+
handleRequest(b as any, self.name, action, {
|
|
671
|
+
onSuccess: suppressToast,
|
|
672
|
+
onDefect: suppressToast,
|
|
673
|
+
onFail: suppressToast,
|
|
674
|
+
...options
|
|
675
|
+
})
|
|
676
|
+
) as any
|
|
677
|
+
}
|
|
568
678
|
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
A2 = A,
|
|
600
|
-
E2 extends ResponseErrors = E,
|
|
601
|
-
R2 = R,
|
|
602
|
-
ESuccess = never,
|
|
603
|
-
RSuccess = never,
|
|
604
|
-
EError = never,
|
|
605
|
-
RError = never,
|
|
606
|
-
EDefect = never,
|
|
607
|
-
RDefect = never
|
|
608
|
-
>(
|
|
609
|
-
self: RequestHandler<A, E, R, Request>,
|
|
610
|
-
action: string,
|
|
611
|
-
options?: Opts<A, E, R, void, A2, E2, R2, ESuccess, RSuccess, EError, RError, EDefect, RDefect>
|
|
612
|
-
): ActResp<void, never, R>
|
|
613
|
-
} = _makeUseAndHandleMutation({
|
|
614
|
-
successMessage: suppressToast,
|
|
615
|
-
failMessage: suppressToast,
|
|
616
|
-
defectMessage: suppressToast
|
|
617
|
-
}) as any
|
|
679
|
+
/**
|
|
680
|
+
* Effect results are converted to Exit, so errors are ignored by default.
|
|
681
|
+
* you should use the result ref to render errors!
|
|
682
|
+
*/
|
|
683
|
+
const _useSafeMutationWithState: {
|
|
684
|
+
<I, E, A, R, Request extends TaggedRequestClassAny, A2 = A, E2 = E, R2 = R>(
|
|
685
|
+
self: RequestHandlerWithInput<I, A, E, R, Request>,
|
|
686
|
+
options?: MutationOptions<A, E, R, A2, E2, R2, I>
|
|
687
|
+
): readonly [
|
|
688
|
+
ComputedRef<Res<A, E>>,
|
|
689
|
+
(i: I) => Effect.Effect<Exit.Exit<A2, E2>, never, R2>
|
|
690
|
+
]
|
|
691
|
+
<E, A, R, Request extends TaggedRequestClassAny, A2 = A, E2 = E, R2 = R>(
|
|
692
|
+
self: RequestHandler<A, E, R, Request>,
|
|
693
|
+
options?: MutationOptions<A, E, R, A2, E2, R2>
|
|
694
|
+
): readonly [
|
|
695
|
+
ComputedRef<Res<A, E>>,
|
|
696
|
+
Effect.Effect<Exit.Exit<A2, E2>, never, R2>
|
|
697
|
+
]
|
|
698
|
+
} = <I, E, A, R, Request extends TaggedRequestClassAny, A2 = A, E2 = E, R2 = R>(
|
|
699
|
+
self: RequestHandlerWithInput<I, A, E, R, Request> | RequestHandler<A, E, R, Request>,
|
|
700
|
+
options?: MutationOptions<A, E, R, A2, E2, R2, I>
|
|
701
|
+
) => {
|
|
702
|
+
const [a, b] = _useSafeMutation(self as any, options)
|
|
703
|
+
|
|
704
|
+
return tuple(
|
|
705
|
+
computed(() => mutationResultToVue(a.value)),
|
|
706
|
+
b
|
|
707
|
+
) as any
|
|
708
|
+
}
|
|
618
709
|
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
handler: Effect.isEffect(self.handler)
|
|
667
|
-
? (pipe(
|
|
668
|
-
Effect.annotateCurrentSpan({ action }),
|
|
669
|
-
Effect.andThen(self.handler)
|
|
670
|
-
) as any)
|
|
671
|
-
: (...args: any[]) =>
|
|
672
|
-
pipe(
|
|
673
|
-
Effect.annotateCurrentSpan({ action }),
|
|
674
|
-
Effect.andThen(self.handler(...args))
|
|
675
|
-
)
|
|
676
|
-
}, options ? dropUndefinedT(options) : undefined))
|
|
677
|
-
|
|
678
|
-
return tuple(
|
|
679
|
-
computed(() => mutationResultToVue(a.value)),
|
|
680
|
-
handleRequest(b as any, self.name, action, {
|
|
681
|
-
onSuccess: suppressToast,
|
|
682
|
-
onDefect: suppressToast,
|
|
683
|
-
onFail: suppressToast,
|
|
684
|
-
...options
|
|
685
|
-
})
|
|
686
|
-
) as any
|
|
687
|
-
}
|
|
710
|
+
/** @deprecated use OmegaForm */
|
|
711
|
+
const _buildFormFromSchema = <
|
|
712
|
+
From extends Record<PropertyKey, any>,
|
|
713
|
+
To extends Record<PropertyKey, any>,
|
|
714
|
+
C extends Record<PropertyKey, any>,
|
|
715
|
+
OnSubmitA
|
|
716
|
+
>(
|
|
717
|
+
s:
|
|
718
|
+
& Schema<
|
|
719
|
+
To,
|
|
720
|
+
From,
|
|
721
|
+
R
|
|
722
|
+
>
|
|
723
|
+
& { new(c: C): any; extend: any; fields: S.Struct.Fields },
|
|
724
|
+
state: Ref<Omit<From, "_tag">>,
|
|
725
|
+
onSubmit: (a: To) => Effect.Effect<OnSubmitA, never, R>
|
|
726
|
+
) => {
|
|
727
|
+
const fields = buildFieldInfoFromFieldsRoot(s).fields
|
|
728
|
+
const schema = S.Struct(Struct.omit(s.fields, "_tag")) as any
|
|
729
|
+
const parse = S.decodeUnknown<any, any, R>(schema)
|
|
730
|
+
const isDirty = ref(false)
|
|
731
|
+
const isValid = ref(true)
|
|
732
|
+
const isLoading = ref(false)
|
|
733
|
+
const runPromise = Runtime.runPromise(runtime)
|
|
734
|
+
|
|
735
|
+
const submit1 =
|
|
736
|
+
(onSubmit: (a: To) => Effect.Effect<OnSubmitA, never, R>) =>
|
|
737
|
+
async <T extends Promise<{ valid: boolean }>>(e: T) => {
|
|
738
|
+
isLoading.value = true
|
|
739
|
+
try {
|
|
740
|
+
const r = await e
|
|
741
|
+
if (!r.valid) return
|
|
742
|
+
return await runPromise(onSubmit(new s(await runPromise(parse(state.value)))))
|
|
743
|
+
} finally {
|
|
744
|
+
isLoading.value = false
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
const submit = submit1(onSubmit)
|
|
748
|
+
|
|
749
|
+
watch(
|
|
750
|
+
state,
|
|
751
|
+
(v) => {
|
|
752
|
+
// TODO: do better
|
|
753
|
+
isDirty.value = JSON.stringify(v) !== JSON.stringify(state.value)
|
|
754
|
+
},
|
|
755
|
+
{ deep: true }
|
|
756
|
+
)
|
|
688
757
|
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
*/
|
|
693
|
-
const _useSafeMutationWithState: {
|
|
694
|
-
<I, E, A, R, Request extends TaggedRequestClassAny, A2 = A, E2 = E, R2 = R>(
|
|
695
|
-
self: RequestHandlerWithInput<I, A, E, R, Request>,
|
|
696
|
-
options?: MutationOptions<A, E, R, A2, E2, R2, I>
|
|
697
|
-
): readonly [
|
|
698
|
-
ComputedRef<Res<A, E>>,
|
|
699
|
-
(i: I) => Effect.Effect<Exit.Exit<A2, E2>, never, R2>
|
|
700
|
-
]
|
|
701
|
-
<E, A, R, Request extends TaggedRequestClassAny, A2 = A, E2 = E, R2 = R>(
|
|
702
|
-
self: RequestHandler<A, E, R, Request>,
|
|
703
|
-
options?: MutationOptions<A, E, R, A2, E2, R2>
|
|
704
|
-
): readonly [
|
|
705
|
-
ComputedRef<Res<A, E>>,
|
|
706
|
-
Effect.Effect<Exit.Exit<A2, E2>, never, R2>
|
|
707
|
-
]
|
|
708
|
-
} = <I, E, A, R, Request extends TaggedRequestClassAny, A2 = A, E2 = E, R2 = R>(
|
|
709
|
-
self: RequestHandlerWithInput<I, A, E, R, Request> | RequestHandler<A, E, R, Request>,
|
|
710
|
-
options?: MutationOptions<A, E, R, A2, E2, R2, I>
|
|
711
|
-
) => {
|
|
712
|
-
const [a, b] = _useSafeMutation(self as any, options)
|
|
713
|
-
|
|
714
|
-
return tuple(
|
|
715
|
-
computed(() => mutationResultToVue(a.value)),
|
|
716
|
-
b
|
|
717
|
-
) as any
|
|
718
|
-
}
|
|
758
|
+
const submitFromState = Effect.gen(function*() {
|
|
759
|
+
return yield* onSubmit(yield* parse(state.value))
|
|
760
|
+
})
|
|
719
761
|
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
From,
|
|
730
|
-
R
|
|
731
|
-
>
|
|
732
|
-
& { new(c: C): any; extend: any; fields: S.Struct.Fields },
|
|
733
|
-
state: Ref<Omit<From, "_tag">>,
|
|
734
|
-
onSubmit: (a: To) => Effect.Effect<OnSubmitA, never, R>
|
|
735
|
-
) => {
|
|
736
|
-
const fields = buildFieldInfoFromFieldsRoot(s).fields
|
|
737
|
-
const schema = S.Struct(Struct.omit(s.fields, "_tag")) as any
|
|
738
|
-
const parse = S.decodeUnknown<any, any, R>(schema)
|
|
739
|
-
const isDirty = ref(false)
|
|
740
|
-
const isValid = ref(true)
|
|
741
|
-
const isLoading = ref(false)
|
|
742
|
-
const runPromise = Runtime.runPromise(getRuntime(runtime))
|
|
743
|
-
|
|
744
|
-
const submit1 =
|
|
745
|
-
(onSubmit: (a: To) => Effect.Effect<OnSubmitA, never, R>) =>
|
|
746
|
-
async <T extends Promise<{ valid: boolean }>>(e: T) => {
|
|
747
|
-
isLoading.value = true
|
|
748
|
-
try {
|
|
749
|
-
const r = await e
|
|
750
|
-
if (!r.valid) return
|
|
751
|
-
return await runPromise(onSubmit(new s(await runPromise(parse(state.value)))))
|
|
752
|
-
} finally {
|
|
753
|
-
isLoading.value = false
|
|
762
|
+
return {
|
|
763
|
+
fields,
|
|
764
|
+
/** optimized for Vuetify v-form submit callback */
|
|
765
|
+
submit,
|
|
766
|
+
/** optimized for Native form submit callback or general use */
|
|
767
|
+
submitFromState,
|
|
768
|
+
isDirty,
|
|
769
|
+
isValid,
|
|
770
|
+
isLoading
|
|
754
771
|
}
|
|
755
772
|
}
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
submitFromState,
|
|
777
|
-
isDirty,
|
|
778
|
-
isValid,
|
|
779
|
-
isLoading
|
|
773
|
+
return {
|
|
774
|
+
/** @deprecated use Command.fn */
|
|
775
|
+
useSafeMutationWithState: _useSafeMutationWithState,
|
|
776
|
+
/** @deprecated use Command.fn */
|
|
777
|
+
useAndHandleMutation: _useAndHandleMutation,
|
|
778
|
+
/** @deprecated use Command.fn */
|
|
779
|
+
useAndHandleMutationResult: _useAndHandleMutationResult,
|
|
780
|
+
/** @deprecated use Command.fn */
|
|
781
|
+
useAndHandleMutationSilently: _useAndHandleMutationSilently,
|
|
782
|
+
/** @deprecated use Command.fn */
|
|
783
|
+
useAndHandleMutationCustom: _useAndHandleMutationCustom,
|
|
784
|
+
/** @deprecated use Command.fn */
|
|
785
|
+
makeUseAndHandleMutation: _makeUseAndHandleMutation,
|
|
786
|
+
/** @deprecated use Command.fn */
|
|
787
|
+
useHandleRequestWithToast: _useHandleRequestWithToast,
|
|
788
|
+
/** @deprecated use OmegaForm */
|
|
789
|
+
buildFormFromSchema: _buildFormFromSchema,
|
|
790
|
+
/** @deprecated use Command.fn */
|
|
791
|
+
useSafeMutation: _useSafeMutation
|
|
792
|
+
}
|
|
780
793
|
}
|
|
781
|
-
}
|
|
794
|
+
})
|
|
795
|
+
}) {}
|
|
796
|
+
|
|
797
|
+
const mkQuery = <R>(runtime: Runtime.Runtime<R>) => {
|
|
798
|
+
// making sure names do not collide with auto exports in nuxt apps, please do not rename..
|
|
799
|
+
/**
|
|
800
|
+
* Effect results are passed to the caller, including errors.
|
|
801
|
+
*/
|
|
802
|
+
// TODO
|
|
803
|
+
const _useSafeQuery = makeQuery(shallowRef(runtime))
|
|
782
804
|
|
|
783
805
|
/**
|
|
784
806
|
* The difference with useSafeQuery is that this function will return a Promise you can await in the Setup,
|
|
@@ -914,18 +936,83 @@ export const makeClient = <Locale extends string, R>(
|
|
|
914
936
|
})
|
|
915
937
|
}
|
|
916
938
|
|
|
939
|
+
return { useSafeQuery: _useSafeQuery, useSafeSuspenseQuery }
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
type Base = I18n | Toast
|
|
943
|
+
export const makeClient = <RT, RE, RL>(
|
|
944
|
+
baseMrt: ManagedRuntime.ManagedRuntime<RT, never>,
|
|
945
|
+
rootLayer: Layer.Layer<RL | Base, RE>
|
|
946
|
+
) => {
|
|
947
|
+
const baseRt = Effect.runSync(baseMrt.runtimeEffect)
|
|
948
|
+
const getRt = () => {
|
|
949
|
+
const instance = getCurrentInstance() as {
|
|
950
|
+
__effa?: {
|
|
951
|
+
rt: ManagedRuntime.ManagedRuntime<I18n | Toast, RE>
|
|
952
|
+
rts: Map<string, any>
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
if (!instance.__effa) {
|
|
956
|
+
const rt = ManagedRuntime.make(rootLayer, baseMrt.memoMap)
|
|
957
|
+
instance.__effa = { rt, rts: new Map() }
|
|
958
|
+
onUnmounted(() => rt.dispose())
|
|
959
|
+
}
|
|
960
|
+
return instance.__effa!
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
const makeRuntime = <A, E>(l: Layer.Layer<A, E, Base>) => {
|
|
964
|
+
const ctx = getRt()
|
|
965
|
+
const rt = ManagedRuntime.make(Layer.mergeAll(l.pipe(Layer.provide(rootLayer)), rootLayer), ctx.rt.memoMap)
|
|
966
|
+
onUnmounted(() => rt.dispose())
|
|
967
|
+
return rt
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
const get = <A>(key: string, maker: () => A) => {
|
|
971
|
+
const ctx = getRt()
|
|
972
|
+
const existing = ctx.rts.get(key)
|
|
973
|
+
if (existing) {
|
|
974
|
+
return existing as A
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
const made = maker()
|
|
978
|
+
ctx.rts.set(key, made)
|
|
979
|
+
return made
|
|
980
|
+
}
|
|
981
|
+
// const getQuery = () => get("query", LegacyQuery.Default)
|
|
982
|
+
const getMutation = () =>
|
|
983
|
+
get("mutation", () => {
|
|
984
|
+
const mrt = makeRuntime(LegacyMutation.Default)
|
|
985
|
+
const mut = mrt.runSync(LegacyMutation)
|
|
986
|
+
const rt = Effect.runSync(mrt.runtimeEffect)
|
|
987
|
+
return mut(rt)
|
|
988
|
+
})
|
|
989
|
+
const useCommand = () =>
|
|
990
|
+
get("command", () => {
|
|
991
|
+
const mrt = makeRuntime(Commander.Default)
|
|
992
|
+
const cmd = mrt.runSync(makeUseCommand())
|
|
993
|
+
return cmd
|
|
994
|
+
})
|
|
995
|
+
const keys: readonly (keyof ReturnType<typeof getMutation>)[] = [
|
|
996
|
+
"useSafeMutationWithState",
|
|
997
|
+
"useAndHandleMutation",
|
|
998
|
+
"useAndHandleMutationResult",
|
|
999
|
+
"useAndHandleMutationSilently",
|
|
1000
|
+
"useAndHandleMutationCustom",
|
|
1001
|
+
"makeUseAndHandleMutation",
|
|
1002
|
+
"useHandleRequestWithToast",
|
|
1003
|
+
"buildFormFromSchema",
|
|
1004
|
+
"useSafeMutation"
|
|
1005
|
+
]
|
|
1006
|
+
type mut = ReturnType<typeof getMutation>
|
|
1007
|
+
|
|
917
1008
|
return {
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
useSafeQuery: _useSafeQuery,
|
|
927
|
-
useSafeMutation: _useSafeMutation,
|
|
928
|
-
useUnsafeMutation: __useUnsafeMutation,
|
|
929
|
-
useSafeSuspenseQuery
|
|
1009
|
+
useCommand,
|
|
1010
|
+
...mkQuery(baseRt),
|
|
1011
|
+
...keys.reduce((prev, cur) => {
|
|
1012
|
+
prev[cur] = ((...args: [any]) => {
|
|
1013
|
+
return (getMutation() as any)[cur](...args)
|
|
1014
|
+
}) as any
|
|
1015
|
+
return prev
|
|
1016
|
+
}, {} as { /** @deprecated use useCommand */ [K in keyof mut]: mut[K] })
|
|
930
1017
|
}
|
|
931
1018
|
}
|