@effect-app/vue 4.0.0-beta.22 → 4.0.0-beta.221
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 +1613 -0
- package/dist/commander.d.ts +634 -0
- package/dist/commander.d.ts.map +1 -0
- package/dist/commander.js +1070 -0
- package/dist/confirm.d.ts +21 -0
- package/dist/confirm.d.ts.map +1 -0
- package/dist/confirm.js +26 -0
- package/dist/errorReporter.d.ts +7 -5
- package/dist/errorReporter.d.ts.map +1 -1
- package/dist/errorReporter.js +14 -19
- package/dist/form.d.ts +15 -6
- package/dist/form.d.ts.map +1 -1
- package/dist/form.js +46 -13
- package/dist/index.d.ts +1 -1
- package/dist/intl.d.ts +15 -0
- package/dist/intl.d.ts.map +1 -0
- package/dist/intl.js +9 -0
- package/dist/lib.d.ts +8 -10
- package/dist/lib.d.ts.map +1 -1
- package/dist/lib.js +35 -10
- package/dist/makeClient.d.ts +156 -339
- package/dist/makeClient.d.ts.map +1 -1
- package/dist/makeClient.js +225 -376
- package/dist/makeContext.d.ts +1 -1
- package/dist/makeContext.d.ts.map +1 -1
- package/dist/makeIntl.d.ts +1 -1
- package/dist/makeIntl.d.ts.map +1 -1
- package/dist/makeUseCommand.d.ts +9 -0
- package/dist/makeUseCommand.d.ts.map +1 -0
- package/dist/makeUseCommand.js +13 -0
- package/dist/mutate.d.ts +54 -34
- package/dist/mutate.d.ts.map +1 -1
- package/dist/mutate.js +139 -46
- package/dist/query.d.ts +20 -39
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +133 -72
- package/dist/routeParams.d.ts +3 -2
- package/dist/routeParams.d.ts.map +1 -1
- package/dist/routeParams.js +4 -3
- package/dist/runtime.d.ts +10 -6
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +32 -18
- package/dist/toast.d.ts +51 -0
- package/dist/toast.d.ts.map +1 -0
- package/dist/toast.js +34 -0
- package/dist/withToast.d.ts +30 -0
- package/dist/withToast.d.ts.map +1 -0
- package/dist/withToast.js +64 -0
- package/examples/streamMutation.ts +72 -0
- package/package.json +48 -50
- package/src/commander.ts +3406 -0
- package/src/{experimental/confirm.ts → confirm.ts} +12 -14
- package/src/errorReporter.ts +65 -75
- package/src/form.ts +61 -18
- package/src/intl.ts +12 -0
- package/src/lib.ts +48 -20
- package/src/makeClient.ts +574 -1134
- package/src/{experimental/makeUseCommand.ts → makeUseCommand.ts} +8 -5
- package/src/mutate.ts +268 -127
- package/src/query.ts +203 -183
- package/src/routeParams.ts +3 -2
- package/src/runtime.ts +46 -21
- package/src/{experimental/toast.ts → toast.ts} +15 -27
- package/src/{experimental/withToast.ts → withToast.ts} +46 -12
- package/test/Mutation.test.ts +181 -24
- package/test/dist/form.test.d.ts.map +1 -1
- package/test/dist/lib.test.d.ts.map +1 -0
- package/test/dist/streamFinal.test.d.ts.map +1 -0
- package/test/dist/streamFn.test.d.ts.map +1 -0
- package/test/dist/stubs.d.ts +3531 -122
- package/test/dist/stubs.d.ts.map +1 -1
- package/test/dist/stubs.js +187 -32
- package/test/form-validation-errors.test.ts +25 -20
- package/test/form.test.ts +22 -3
- package/test/lib.test.ts +240 -0
- package/test/makeClient.test.ts +292 -38
- package/test/streamFinal.test.ts +64 -0
- package/test/streamFn.test.ts +457 -0
- package/test/stubs.ts +223 -43
- package/tsconfig.examples.json +20 -0
- package/tsconfig.json +0 -1
- package/tsconfig.json.bak +5 -2
- package/tsconfig.src.json +34 -34
- package/tsconfig.test.json +2 -2
- package/vitest.config.ts +5 -5
- package/dist/experimental/commander.d.ts +0 -359
- package/dist/experimental/commander.d.ts.map +0 -1
- package/dist/experimental/commander.js +0 -557
- package/dist/experimental/confirm.d.ts +0 -19
- package/dist/experimental/confirm.d.ts.map +0 -1
- package/dist/experimental/confirm.js +0 -28
- package/dist/experimental/intl.d.ts +0 -16
- package/dist/experimental/intl.d.ts.map +0 -1
- package/dist/experimental/intl.js +0 -5
- package/dist/experimental/makeUseCommand.d.ts +0 -8
- package/dist/experimental/makeUseCommand.d.ts.map +0 -1
- package/dist/experimental/makeUseCommand.js +0 -13
- package/dist/experimental/toast.d.ts +0 -47
- package/dist/experimental/toast.d.ts.map +0 -1
- package/dist/experimental/toast.js +0 -41
- package/dist/experimental/withToast.d.ts +0 -25
- package/dist/experimental/withToast.d.ts.map +0 -1
- package/dist/experimental/withToast.js +0 -45
- package/eslint.config.mjs +0 -24
- package/src/experimental/commander.ts +0 -1835
- package/src/experimental/intl.ts +0 -9
|
@@ -1,10 +1,18 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as Context from "effect-app/Context"
|
|
2
|
+
import * as Effect from "effect-app/Effect"
|
|
3
|
+
import * as Layer from "effect-app/Layer"
|
|
4
|
+
import type * as Option from "effect-app/Option"
|
|
5
|
+
import * as S from "effect-app/Schema"
|
|
2
6
|
import { wrapEffect } from "effect-app/utils"
|
|
3
|
-
import
|
|
7
|
+
import * as Cause from "effect/Cause"
|
|
8
|
+
import * as Fiber from "effect/Fiber"
|
|
9
|
+
import { CurrentToastId, Toast, type ToastId } from "./toast.js"
|
|
4
10
|
|
|
5
11
|
export interface ToastOptions<A, E, Args extends ReadonlyArray<unknown>, WaiR, SucR, ErrR> {
|
|
6
12
|
stableToastId?: undefined | string | ((...args: Args) => string | undefined)
|
|
7
13
|
timeout?: number
|
|
14
|
+
showSpanInfo?: false
|
|
15
|
+
groupId?: string
|
|
8
16
|
onWaiting:
|
|
9
17
|
| string
|
|
10
18
|
| ((...args: Args) => string | null)
|
|
@@ -33,10 +41,10 @@ export interface ToastOptions<A, E, Args extends ReadonlyArray<unknown>, WaiR, S
|
|
|
33
41
|
}
|
|
34
42
|
|
|
35
43
|
// @effect-diagnostics-next-line missingEffectServiceDependency:off
|
|
36
|
-
export class WithToast extends
|
|
44
|
+
export class WithToast extends Context.Service<WithToast>()("WithToast", {
|
|
37
45
|
make: Effect.gen(function*() {
|
|
38
46
|
const toast = yield* Toast
|
|
39
|
-
return <A, E, Args extends
|
|
47
|
+
return <A, E, Args extends readonly unknown[], R, WaiR = never, SucR = never, ErrR = never>(
|
|
40
48
|
options: ToastOptions<A, E, Args, WaiR, SucR, ErrR>
|
|
41
49
|
) =>
|
|
42
50
|
Effect.fnUntraced(function*(self: Effect.Effect<A, E, R>, ...args: Args) {
|
|
@@ -46,23 +54,41 @@ export class WithToast extends ServiceMap.Service<WithToast>()("WithToast", {
|
|
|
46
54
|
? options.stableToastId(...args)
|
|
47
55
|
: options.stableToastId
|
|
48
56
|
|
|
57
|
+
const requestId: string = yield* Effect.currentSpan.pipe(
|
|
58
|
+
Effect.map((span) => span.traceId),
|
|
59
|
+
Effect.orElseSucceed(() => S.StringId.make())
|
|
60
|
+
)
|
|
61
|
+
const groupId = options.groupId
|
|
62
|
+
const meta = { ...(groupId !== undefined ? { groupId } : {}), requestId }
|
|
63
|
+
|
|
49
64
|
const t = yield* wrapEffect(options.onWaiting)(...args)
|
|
50
|
-
const toastId = t === null
|
|
51
|
-
|
|
52
|
-
|
|
65
|
+
const toastId: ToastId | undefined = t === null
|
|
66
|
+
? stableToastId
|
|
67
|
+
: stableToastId ?? `wait-${Math.random().toString(36).slice(2)}`
|
|
68
|
+
|
|
69
|
+
const waitingFiber = t === null ? undefined : yield* Effect.forkChild(
|
|
70
|
+
Effect.sleep("1 seconds").pipe(
|
|
71
|
+
Effect.andThen(toast.info(t, { id: toastId!, timeout: Infinity, ...meta }))
|
|
72
|
+
)
|
|
53
73
|
)
|
|
74
|
+
const interruptWaiting = waitingFiber ? Fiber.interrupt(waitingFiber) : Effect.void
|
|
75
|
+
|
|
54
76
|
return yield* self.pipe(
|
|
55
77
|
Effect.tap(Effect.fnUntraced(function*(a) {
|
|
78
|
+
yield* interruptWaiting
|
|
56
79
|
const t = yield* wrapEffect(options.onSuccess)(a, ...args)
|
|
57
80
|
if (t === null) {
|
|
58
81
|
return
|
|
59
82
|
}
|
|
60
83
|
yield* toast.success(
|
|
61
84
|
t,
|
|
62
|
-
toastId !== undefined
|
|
85
|
+
toastId !== undefined
|
|
86
|
+
? { id: toastId, timeout: baseTimeout, ...meta }
|
|
87
|
+
: { timeout: baseTimeout, ...meta }
|
|
63
88
|
)
|
|
64
89
|
})),
|
|
65
90
|
Effect.tapCause(Effect.fnUntraced(function*(cause) {
|
|
91
|
+
yield* interruptWaiting
|
|
66
92
|
yield* Effect.logDebug(
|
|
67
93
|
"WithToast - caught error cause: " + Cause.squash(cause),
|
|
68
94
|
Cause.hasInterruptsOnly(cause),
|
|
@@ -74,15 +100,23 @@ export class WithToast extends ServiceMap.Service<WithToast>()("WithToast", {
|
|
|
74
100
|
return
|
|
75
101
|
}
|
|
76
102
|
|
|
103
|
+
const spanInfo = options.showSpanInfo !== false
|
|
104
|
+
? yield* Effect.currentSpan.pipe(
|
|
105
|
+
Effect.map((span) => `\nTrace: ${span.traceId}\nSpan: ${span.spanId}`),
|
|
106
|
+
Effect.orElseSucceed(() => "")
|
|
107
|
+
)
|
|
108
|
+
: ""
|
|
109
|
+
|
|
77
110
|
const t = yield* wrapEffect(options.onFailure)(Cause.findErrorOption(cause), ...args)
|
|
78
|
-
const opts = { timeout: baseTimeout * 2 }
|
|
111
|
+
const opts = { timeout: baseTimeout * 2, ...meta }
|
|
79
112
|
|
|
80
113
|
if (typeof t === "object") {
|
|
114
|
+
const message = t.message + spanInfo
|
|
81
115
|
return t.level === "warn"
|
|
82
|
-
? yield* toast.warning(
|
|
83
|
-
: yield* toast.error(
|
|
116
|
+
? yield* toast.warning(message, toastId !== undefined ? { ...opts, id: toastId } : opts)
|
|
117
|
+
: yield* toast.error(message, toastId !== undefined ? { ...opts, id: toastId } : opts)
|
|
84
118
|
}
|
|
85
|
-
yield* toast.error(t, toastId !== undefined ? { ...opts, id: toastId } : opts)
|
|
119
|
+
yield* toast.error(t + spanInfo, toastId !== undefined ? { ...opts, id: toastId } : opts)
|
|
86
120
|
}, Effect.uninterruptible)),
|
|
87
121
|
toastId !== undefined ? Effect.provideService(CurrentToastId, CurrentToastId.of({ toastId })) : (_) => _
|
|
88
122
|
)
|
package/test/Mutation.test.ts
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
2
|
import { it } from "@effect/vitest"
|
|
3
|
-
import
|
|
4
|
-
import
|
|
3
|
+
import * as Effect from "effect-app/Effect"
|
|
4
|
+
import * as Option from "effect-app/Option"
|
|
5
|
+
import * as Cause from "effect/Cause"
|
|
6
|
+
import * as Exit from "effect/Exit"
|
|
7
|
+
import * as Fiber from "effect/Fiber"
|
|
8
|
+
import { TestClock } from "effect/testing"
|
|
9
|
+
import { CommandContext, DefaultIntl } from "../src/commander.js"
|
|
5
10
|
import { AsyncResult } from "../src/lib.js"
|
|
6
|
-
import { useExperimental } from "./stubs.js"
|
|
11
|
+
import { useExperimental, useExperimentalE } from "./stubs.js"
|
|
7
12
|
|
|
8
13
|
const unwrap = <A, E>(r: Fiber.Fiber<Exit.Exit<A, E>, never>) => Fiber.join(r).pipe(Effect.flatten)
|
|
9
14
|
|
|
@@ -71,7 +76,10 @@ describe("alt2", () => {
|
|
|
71
76
|
expect(yield* Effect.currentSpan.pipe(Effect.map((_) => _.name))).toBe("Test Action")
|
|
72
77
|
})),
|
|
73
78
|
Effect.tap(() =>
|
|
74
|
-
Effect.currentSpan.pipe(
|
|
79
|
+
Effect.currentSpan.pipe(
|
|
80
|
+
Effect.map((_) => _.name),
|
|
81
|
+
Effect.tap((_) => Effect.sync(() => expect(_).toBe("Test Action")))
|
|
82
|
+
)
|
|
75
83
|
),
|
|
76
84
|
Effect.tap(() => Effect.sync(() => executed = true))
|
|
77
85
|
)
|
|
@@ -125,7 +133,10 @@ it.live("works", () =>
|
|
|
125
133
|
expect(yield* Effect.currentSpan.pipe(Effect.map((_) => _.name))).toBe("Test Action")
|
|
126
134
|
})),
|
|
127
135
|
Effect.tap(() =>
|
|
128
|
-
Effect.currentSpan.pipe(
|
|
136
|
+
Effect.currentSpan.pipe(
|
|
137
|
+
Effect.map((_) => _.name),
|
|
138
|
+
Effect.tap((_) => Effect.sync(() => expect(_).toBe("Test Action")))
|
|
139
|
+
)
|
|
129
140
|
),
|
|
130
141
|
Effect.tap(() => Effect.sync(() => executed = true))
|
|
131
142
|
)
|
|
@@ -175,7 +186,10 @@ it.live("works non-gen", () =>
|
|
|
175
186
|
expect(yield* Effect.currentSpan.pipe(Effect.map((_) => _.name))).toBe("Test Action")
|
|
176
187
|
})),
|
|
177
188
|
Effect.tap(() =>
|
|
178
|
-
Effect.currentSpan.pipe(
|
|
189
|
+
Effect.currentSpan.pipe(
|
|
190
|
+
Effect.map((_) => _.name),
|
|
191
|
+
Effect.tap((_) => Effect.sync(() => expect(_).toBe("Test Action")))
|
|
192
|
+
)
|
|
179
193
|
),
|
|
180
194
|
Effect.tap(() => Effect.sync(() => executed = true))
|
|
181
195
|
)
|
|
@@ -308,8 +322,8 @@ it.live("with toasts", () =>
|
|
|
308
322
|
function*() {
|
|
309
323
|
expect(yield* Effect.currentSpan.pipe(Effect.map((_) => _.name))).toBe("Test Action")
|
|
310
324
|
|
|
311
|
-
|
|
312
|
-
expect(toasts
|
|
325
|
+
// fast actions complete before the 1s waiting-toast delay, so no waiting toast is shown
|
|
326
|
+
expect(toasts.length).toBe(0)
|
|
313
327
|
|
|
314
328
|
return "test-value"
|
|
315
329
|
},
|
|
@@ -317,7 +331,10 @@ it.live("with toasts", () =>
|
|
|
317
331
|
expect(yield* Effect.currentSpan.pipe(Effect.map((_) => _.name))).toBe("Test Action")
|
|
318
332
|
})),
|
|
319
333
|
Effect.tap(() =>
|
|
320
|
-
Effect.currentSpan.pipe(
|
|
334
|
+
Effect.currentSpan.pipe(
|
|
335
|
+
Effect.map((_) => _.name),
|
|
336
|
+
Effect.tap((_) => Effect.sync(() => expect(_).toBe("Test Action")))
|
|
337
|
+
)
|
|
321
338
|
),
|
|
322
339
|
// WithToast.handle({
|
|
323
340
|
// onFailure: "failed",
|
|
@@ -346,7 +363,7 @@ it.live("interrupted", () =>
|
|
|
346
363
|
|
|
347
364
|
const command = Command.fn("Test Action")(
|
|
348
365
|
function*() {
|
|
349
|
-
expect(toasts.length).toBe(
|
|
366
|
+
expect(toasts.length).toBe(0)
|
|
350
367
|
yield* Effect.interrupt
|
|
351
368
|
return "test-value"
|
|
352
369
|
},
|
|
@@ -373,7 +390,7 @@ it.live("fail", () =>
|
|
|
373
390
|
|
|
374
391
|
const command = Command.fn("Test Action")(
|
|
375
392
|
function*() {
|
|
376
|
-
expect(toasts.length).toBe(
|
|
393
|
+
expect(toasts.length).toBe(0)
|
|
377
394
|
return yield* Effect.fail({ message: "Boom!" })
|
|
378
395
|
},
|
|
379
396
|
Command.withDefaultToast(),
|
|
@@ -388,9 +405,30 @@ it.live("fail", () =>
|
|
|
388
405
|
expect(command.waiting).toBe(false)
|
|
389
406
|
expect(Exit.isFailure(AsyncResult.toExit(command.result))).toBe(true)
|
|
390
407
|
expect(toasts.length).toBe(1) // toast should show error
|
|
391
|
-
expect(toasts[0].
|
|
408
|
+
expect(toasts[0].type).toBe("warning")
|
|
409
|
+
expect(toasts[0].message).toContain("Test Action Failed:\nBoom!")
|
|
410
|
+
expect(toasts[0].message).toMatch(/Trace: [a-f0-9]{32}/)
|
|
411
|
+
expect(toasts[0].message).toMatch(/Span: [a-f0-9]{16}/)
|
|
392
412
|
}))
|
|
393
413
|
|
|
414
|
+
it.live("fail with showSpanInfo disabled", () =>
|
|
415
|
+
Effect
|
|
416
|
+
.gen(function*() {
|
|
417
|
+
const toasts: any[] = []
|
|
418
|
+
const Command = useExperimental({ toasts, messages: DefaultIntl.en })
|
|
419
|
+
|
|
420
|
+
const command = Command.fn("Test Action")(
|
|
421
|
+
function*() {
|
|
422
|
+
return yield* Effect.fail({ message: "Boom!" })
|
|
423
|
+
},
|
|
424
|
+
Command.withDefaultToast({ showSpanInfo: false })
|
|
425
|
+
)
|
|
426
|
+
|
|
427
|
+
yield* Fiber.join(command.handle())
|
|
428
|
+
|
|
429
|
+
expect(toasts.length).toBe(1)
|
|
430
|
+
expect(toasts[0].message).toBe("Test Action Failed:\nBoom!")
|
|
431
|
+
}))
|
|
394
432
|
it.live("fail and recover", () =>
|
|
395
433
|
Effect
|
|
396
434
|
.gen(function*() {
|
|
@@ -400,7 +438,7 @@ it.live("fail and recover", () =>
|
|
|
400
438
|
|
|
401
439
|
const command = Command.fn("Test Action")(
|
|
402
440
|
function*() {
|
|
403
|
-
expect(toasts.length).toBe(
|
|
441
|
+
expect(toasts.length).toBe(0)
|
|
404
442
|
return yield* Effect.fail({ message: "Boom!" })
|
|
405
443
|
},
|
|
406
444
|
Effect.orElseSucceed(() => "recovered"), // we recover from the error here, so the final result is success
|
|
@@ -428,7 +466,7 @@ it.live("defect", () =>
|
|
|
428
466
|
|
|
429
467
|
const command = Command.fn("Test Action")(
|
|
430
468
|
function*() {
|
|
431
|
-
expect(toasts.length).toBe(
|
|
469
|
+
expect(toasts.length).toBe(0)
|
|
432
470
|
return yield* Effect.die({ message: "Boom!" })
|
|
433
471
|
},
|
|
434
472
|
Command.withDefaultToast(),
|
|
@@ -444,7 +482,8 @@ it.live("defect", () =>
|
|
|
444
482
|
expect(command.waiting).toBe(false)
|
|
445
483
|
expect(Exit.isFailure(AsyncResult.toExit(command.result))).toBe(true)
|
|
446
484
|
expect(toasts.length).toBe(1) // toast should show error
|
|
447
|
-
expect(toasts[0].
|
|
485
|
+
expect(toasts[0].type).toBe("error")
|
|
486
|
+
expect(toasts[0].message).toContain("Test Action unexpected error, please try again shortly.")
|
|
448
487
|
}))
|
|
449
488
|
|
|
450
489
|
it.live("works with alt", () =>
|
|
@@ -471,7 +510,10 @@ it.live("works with alt", () =>
|
|
|
471
510
|
expect(yield* Effect.currentSpan.pipe(Effect.map((_) => _.name))).toBe("Test Action")
|
|
472
511
|
})),
|
|
473
512
|
Effect.tap(() =>
|
|
474
|
-
Effect.currentSpan.pipe(
|
|
513
|
+
Effect.currentSpan.pipe(
|
|
514
|
+
Effect.map((_) => _.name),
|
|
515
|
+
Effect.tap((_) => Effect.sync(() => expect(_).toBe("Test Action")))
|
|
516
|
+
)
|
|
475
517
|
),
|
|
476
518
|
Effect.tap(() => Effect.sync(() => executed = true))
|
|
477
519
|
)
|
|
@@ -615,8 +657,8 @@ it.live("with toasts with alt", () =>
|
|
|
615
657
|
function*() {
|
|
616
658
|
expect(yield* Effect.currentSpan.pipe(Effect.map((_) => _.name))).toBe("Test Action")
|
|
617
659
|
|
|
618
|
-
|
|
619
|
-
expect(toasts
|
|
660
|
+
// fast actions complete before the 1s waiting-toast delay, so no waiting toast is shown
|
|
661
|
+
expect(toasts.length).toBe(0)
|
|
620
662
|
|
|
621
663
|
return "test-value"
|
|
622
664
|
},
|
|
@@ -624,7 +666,10 @@ it.live("with toasts with alt", () =>
|
|
|
624
666
|
expect(yield* Effect.currentSpan.pipe(Effect.map((_) => _.name))).toBe("Test Action")
|
|
625
667
|
})),
|
|
626
668
|
Effect.tap(() =>
|
|
627
|
-
Effect.currentSpan.pipe(
|
|
669
|
+
Effect.currentSpan.pipe(
|
|
670
|
+
Effect.map((_) => _.name),
|
|
671
|
+
Effect.tap((_) => Effect.sync(() => expect(_).toBe("Test Action")))
|
|
672
|
+
)
|
|
628
673
|
),
|
|
629
674
|
Command.withDefaultToast(),
|
|
630
675
|
Effect.tap(() => Effect.sync(() => executed = true))
|
|
@@ -650,7 +695,7 @@ it.live("interrupted with alt", () =>
|
|
|
650
695
|
const command = Command.alt("Test Action")(
|
|
651
696
|
Effect.fnUntraced(
|
|
652
697
|
function*() {
|
|
653
|
-
expect(toasts.length).toBe(
|
|
698
|
+
expect(toasts.length).toBe(0)
|
|
654
699
|
// @effect-diagnostics-next-line missingReturnYieldStar:off
|
|
655
700
|
yield* Effect.interrupt
|
|
656
701
|
return "test-value"
|
|
@@ -680,7 +725,7 @@ it.live("fail with alt", () =>
|
|
|
680
725
|
const command = Command.alt("Test Action")(
|
|
681
726
|
Effect.fnUntraced(
|
|
682
727
|
function*() {
|
|
683
|
-
expect(toasts.length).toBe(
|
|
728
|
+
expect(toasts.length).toBe(0)
|
|
684
729
|
return yield* Effect.fail({ message: "Boom!" })
|
|
685
730
|
},
|
|
686
731
|
Command.withDefaultToast(),
|
|
@@ -696,7 +741,8 @@ it.live("fail with alt", () =>
|
|
|
696
741
|
expect(command.waiting).toBe(false)
|
|
697
742
|
expect(Exit.isFailure(AsyncResult.toExit(command.result))).toBe(true)
|
|
698
743
|
expect(toasts.length).toBe(1) // toast should show error
|
|
699
|
-
expect(toasts[0].
|
|
744
|
+
expect(toasts[0].type).toBe("warning")
|
|
745
|
+
expect(toasts[0].message).toContain("Test Action Failed:\nBoom!")
|
|
700
746
|
}))
|
|
701
747
|
|
|
702
748
|
it.live("fail and recover with alt", () =>
|
|
@@ -709,7 +755,7 @@ it.live("fail and recover with alt", () =>
|
|
|
709
755
|
const command = Command.alt("Test Action")(
|
|
710
756
|
Effect.fnUntraced(
|
|
711
757
|
function*() {
|
|
712
|
-
expect(toasts.length).toBe(
|
|
758
|
+
expect(toasts.length).toBe(0)
|
|
713
759
|
return yield* Effect.fail({ message: "Boom!" })
|
|
714
760
|
},
|
|
715
761
|
Effect.orElseSucceed(() => "recovered"), // we recover from the error here, so the final result is success
|
|
@@ -729,6 +775,64 @@ it.live("fail and recover with alt", () =>
|
|
|
729
775
|
expect(toasts[0].message).toBe("Test Action Success")
|
|
730
776
|
}))
|
|
731
777
|
|
|
778
|
+
it.effect("slow action shows waiting toast after the 1s delay", () =>
|
|
779
|
+
Effect
|
|
780
|
+
.gen(function*() {
|
|
781
|
+
const toasts: any[] = []
|
|
782
|
+
const Command = yield* useExperimentalE({ toasts, messages: DefaultIntl.en })
|
|
783
|
+
|
|
784
|
+
const command = Command.fn("Test Action")(
|
|
785
|
+
function*() {
|
|
786
|
+
// before 1s the waiting toast must NOT have surfaced yet
|
|
787
|
+
expect(toasts.length).toBe(0)
|
|
788
|
+
yield* Effect.sleep("1100 millis")
|
|
789
|
+
// after the delay window the waiting info toast should be visible
|
|
790
|
+
expect(toasts.length).toBe(1)
|
|
791
|
+
expect(toasts[0].type).toBe("info")
|
|
792
|
+
expect(toasts[0].message).toBe("Test Action executing...")
|
|
793
|
+
return "test-value"
|
|
794
|
+
},
|
|
795
|
+
Command.withDefaultToast()
|
|
796
|
+
)
|
|
797
|
+
|
|
798
|
+
const fiber = command.handle()
|
|
799
|
+
yield* TestClock.adjust("2 seconds")
|
|
800
|
+
const r = yield* unwrap(fiber)
|
|
801
|
+
|
|
802
|
+
expect(r).toBe("test-value")
|
|
803
|
+
// waiting toast is replaced (same id) with the success toast
|
|
804
|
+
expect(toasts.length).toBe(1)
|
|
805
|
+
expect(toasts[0].type).toBe("success")
|
|
806
|
+
expect(toasts[0].message).toBe("Test Action Success")
|
|
807
|
+
}))
|
|
808
|
+
|
|
809
|
+
it.effect("slow failing action surfaces waiting toast then shows error", () =>
|
|
810
|
+
Effect
|
|
811
|
+
.gen(function*() {
|
|
812
|
+
const toasts: any[] = []
|
|
813
|
+
const Command = yield* useExperimentalE({ toasts, messages: DefaultIntl.en })
|
|
814
|
+
|
|
815
|
+
const command = Command.fn("Test Action")(
|
|
816
|
+
function*() {
|
|
817
|
+
expect(toasts.length).toBe(0)
|
|
818
|
+
yield* Effect.sleep("1100 millis")
|
|
819
|
+
expect(toasts.length).toBe(1)
|
|
820
|
+
expect(toasts[0].type).toBe("info")
|
|
821
|
+
return yield* Effect.fail({ message: "Boom!" })
|
|
822
|
+
},
|
|
823
|
+
Command.withDefaultToast()
|
|
824
|
+
)
|
|
825
|
+
|
|
826
|
+
const fiber = command.handle()
|
|
827
|
+
yield* TestClock.adjust("2 seconds")
|
|
828
|
+
const r = yield* Fiber.join(fiber)
|
|
829
|
+
|
|
830
|
+
expect(Exit.isFailure(r) && Cause.hasFails(r.cause)).toBe(true)
|
|
831
|
+
expect(toasts.length).toBe(1)
|
|
832
|
+
expect(toasts[0].type).toBe("warning")
|
|
833
|
+
expect(toasts[0].message).toContain("Test Action Failed:\nBoom!")
|
|
834
|
+
}))
|
|
835
|
+
|
|
732
836
|
it.live("defect with alt", () =>
|
|
733
837
|
Effect
|
|
734
838
|
.gen(function*() {
|
|
@@ -756,5 +860,58 @@ it.live("defect with alt", () =>
|
|
|
756
860
|
expect(command.waiting).toBe(false)
|
|
757
861
|
expect(Exit.isFailure(AsyncResult.toExit(command.result))).toBe(true)
|
|
758
862
|
expect(toasts.length).toBe(1) // toast should show error
|
|
759
|
-
expect(toasts[0].
|
|
863
|
+
expect(toasts[0].type).toBe("error")
|
|
864
|
+
expect(toasts[0].message).toContain("Test Action unexpected error, please try again shortly.")
|
|
760
865
|
}))
|
|
866
|
+
|
|
867
|
+
describe("state-in-toast", () => {
|
|
868
|
+
it("works", () => {
|
|
869
|
+
const toasts: any[] = []
|
|
870
|
+
const removeMutation = Object.assign(
|
|
871
|
+
Effect.fn(function*(_item: string) {
|
|
872
|
+
yield* Effect.sleep(1000)
|
|
873
|
+
}),
|
|
874
|
+
{ id: "remove_thing" }
|
|
875
|
+
)
|
|
876
|
+
|
|
877
|
+
const item = "x"
|
|
878
|
+
|
|
879
|
+
const Command = useExperimental({ toasts, messages: DefaultIntl.en })
|
|
880
|
+
|
|
881
|
+
Command.fn(removeMutation, {
|
|
882
|
+
state: () => ({ item }),
|
|
883
|
+
waitKey: (id) => `${id}.${item}`,
|
|
884
|
+
blockKey: () => `modify_thing.${item}`
|
|
885
|
+
// allowed: () => role.value === "admin"
|
|
886
|
+
})(
|
|
887
|
+
function*() {
|
|
888
|
+
// yield* Command.confirmOrInterrupt(yield* I18n.formatMessage({ id: "confirm.remove_item" }, { item }))
|
|
889
|
+
yield* removeMutation(item)
|
|
890
|
+
},
|
|
891
|
+
Command.withDefaultToast({
|
|
892
|
+
onSuccess: (a, b, c, d) => {
|
|
893
|
+
console.log("Success", { a, b, c, d })
|
|
894
|
+
expectTypeOf(d.state).toEqualTypeOf<{ readonly item: "x" }>()
|
|
895
|
+
}
|
|
896
|
+
})
|
|
897
|
+
)
|
|
898
|
+
|
|
899
|
+
Command.fn(removeMutation, {
|
|
900
|
+
state: () => ({ item }),
|
|
901
|
+
waitKey: (id) => `${id}.${item}`,
|
|
902
|
+
blockKey: () => `modify_thing.${item}`
|
|
903
|
+
// allowed: () => role.value === "admin"
|
|
904
|
+
})(
|
|
905
|
+
function*() {
|
|
906
|
+
// yield* Command.confirmOrInterrupt(yield* I18n.formatMessage({ id: "confirm.remove_item" }, { item }))
|
|
907
|
+
yield* removeMutation(item)
|
|
908
|
+
},
|
|
909
|
+
Command.withDefaultToast({
|
|
910
|
+
onSuccess: (a, b, c) => {
|
|
911
|
+
console.log("Success", { a, b, c })
|
|
912
|
+
expectTypeOf(c).toEqualTypeOf<undefined>()
|
|
913
|
+
}
|
|
914
|
+
})
|
|
915
|
+
)
|
|
916
|
+
})
|
|
917
|
+
})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"form.test.d.ts","sourceRoot":"","sources":["../form.test.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"form.test.d.ts","sourceRoot":"","sources":["../form.test.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,mBAAmB,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGtC,qBAAa,YAAa,SAAQ,iBAahC;CAAG;;;;AAEL,qBAAa,mBAAoB,SAAQ,wBAEvC;CAAG;;;;;;;;;;;;AAEL,qBAAa,WAAY,SAAQ,gBAK/B;CAAG;;;;;;;;AAEL,cAAM,MAAO,SAAQ,WAEnB;CAAG;;;;;;;;AAEL,cAAM,MAAO,SAAQ,WAEnB;CAAG;;;;;;;;;;;;AAEL,cAAM,QAAS,SAAQ,aAGrB;CAAG;;;;;;;;;;;;;;;;;;;;;;;;AAqBL,qBAAa,cAAe,SAAQ,mBAGlC;CAAG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lib.test.d.ts","sourceRoot":"","sources":["../lib.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"streamFinal.test.d.ts","sourceRoot":"","sources":["../streamFinal.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"streamFn.test.d.ts","sourceRoot":"","sources":["../streamFn.test.ts"],"names":[],"mappings":""}
|