@effect-app/vue 2.94.0 → 4.0.0-beta.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 +11 -0
- package/dist/errorReporter.d.ts +2 -2
- package/dist/errorReporter.d.ts.map +1 -1
- package/dist/errorReporter.js +9 -9
- package/dist/experimental/commander.d.ts +46 -66
- package/dist/experimental/commander.d.ts.map +1 -1
- package/dist/experimental/commander.js +27 -29
- package/dist/experimental/confirm.d.ts +11 -5
- package/dist/experimental/confirm.d.ts.map +1 -1
- package/dist/experimental/confirm.js +19 -6
- package/dist/experimental/intl.d.ts +2 -21
- package/dist/experimental/intl.d.ts.map +1 -1
- package/dist/experimental/intl.js +4 -4
- package/dist/experimental/makeUseCommand.js +2 -2
- package/dist/experimental/toast.d.ts +3 -35
- package/dist/experimental/toast.d.ts.map +1 -1
- package/dist/experimental/toast.js +19 -5
- package/dist/experimental/withToast.d.ts +6 -4
- package/dist/experimental/withToast.d.ts.map +1 -1
- package/dist/experimental/withToast.js +10 -8
- package/dist/form.d.ts +2 -2
- package/dist/form.d.ts.map +1 -1
- package/dist/form.js +47 -47
- package/dist/lib.d.ts.map +1 -1
- package/dist/lib.js +11 -9
- package/dist/makeClient.d.ts +24 -21
- package/dist/makeClient.d.ts.map +1 -1
- package/dist/makeClient.js +28 -29
- package/dist/mutate.d.ts.map +1 -1
- package/dist/mutate.js +7 -7
- package/dist/query.d.ts +6 -4
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +26 -17
- package/dist/routeParams.d.ts +2 -4
- package/dist/routeParams.d.ts.map +1 -1
- package/dist/routeParams.js +3 -15
- package/dist/runtime.d.ts +1 -1
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +4 -4
- package/package.json +20 -20
- package/src/errorReporter.ts +11 -11
- package/src/experimental/commander.ts +81 -84
- package/src/experimental/confirm.ts +21 -6
- package/src/experimental/intl.ts +3 -3
- package/src/experimental/makeUseCommand.ts +1 -1
- package/src/experimental/toast.ts +23 -4
- package/src/experimental/withToast.ts +10 -7
- package/src/form.ts +56 -64
- package/src/lib.ts +10 -8
- package/src/makeClient.ts +61 -54
- package/src/mutate.ts +6 -7
- package/src/query.ts +28 -21
- package/src/routeParams.ts +9 -23
- package/src/runtime.ts +6 -6
- package/test/Mutation.test.ts +41 -42
- package/test/dist/form.test.d.ts.map +1 -1
- package/test/dist/stubs.d.ts +111 -53
- package/test/dist/stubs.d.ts.map +1 -1
- package/test/dist/stubs.js +8 -8
- package/test/form.test.ts +7 -6
- package/test/stubs.ts +43 -41
- package/tsconfig.json +1 -27
package/src/query.ts
CHANGED
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
|
4
4
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
5
5
|
import * as Result from "@effect-atom/atom/Result"
|
|
6
|
-
import { isHttpClientError } from "@effect/platform/HttpClientError"
|
|
7
6
|
import { type DefaultError, type Enabled, type InitialDataFunction, type NonUndefinedGuard, type PlaceholderDataFunction, type QueryKey, type QueryObserverOptions, type QueryObserverResult, type RefetchOptions, useQuery as useTanstackQuery, useQueryClient, type UseQueryDefinedReturnType, type UseQueryReturnType } from "@tanstack/vue-query"
|
|
8
|
-
import { Array, Cause, Effect,
|
|
7
|
+
import { Array, Cause, Effect, Exit, flow, Option, S, type ServiceMap } from "effect-app"
|
|
9
8
|
import { type Req } from "effect-app/client"
|
|
10
9
|
import type { RequestHandler, RequestHandlerWithInput } from "effect-app/client/clientFor"
|
|
11
10
|
import { ServiceUnavailableError } from "effect-app/client/errors"
|
|
12
11
|
import { type Span } from "effect/Tracer"
|
|
12
|
+
import { isHttpClientError } from "effect/unstable/http/HttpClientError"
|
|
13
13
|
import { computed, type ComputedRef, type MaybeRefOrGetter, ref, shallowRef, watch, type WatchSource } from "vue"
|
|
14
14
|
import { makeQueryKey, reportRuntimeError } from "./lib.js"
|
|
15
15
|
|
|
@@ -74,11 +74,15 @@ export interface CustomDefinedPlaceholderQueryOptions<
|
|
|
74
74
|
| PlaceholderDataFunction<NonFunctionGuard<TQueryData>, TError, NonFunctionGuard<TQueryData>, TQueryKey>
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
export
|
|
78
|
-
readonly
|
|
77
|
+
export class KnownFiberFailure<E> extends Error {
|
|
78
|
+
readonly error: unknown
|
|
79
|
+
constructor(public effectCause: Cause.Cause<E>) {
|
|
80
|
+
super("Query failed with cause: " + Cause.squash(effectCause))
|
|
81
|
+
this.error = Cause.squash(effectCause)
|
|
82
|
+
}
|
|
79
83
|
}
|
|
80
84
|
|
|
81
|
-
export const makeQuery = <R>(getRuntime: () =>
|
|
85
|
+
export const makeQuery = <R>(getRuntime: () => ServiceMap.ServiceMap<R>) => {
|
|
82
86
|
const useQuery_: {
|
|
83
87
|
<I, A, E, Request extends Req, Name extends string>(
|
|
84
88
|
q:
|
|
@@ -126,7 +130,14 @@ export const makeQuery = <R>(getRuntime: () => Runtime.Runtime<R>) => {
|
|
|
126
130
|
options?: any
|
|
127
131
|
// TODO
|
|
128
132
|
) => {
|
|
129
|
-
|
|
133
|
+
// we wrap into KnownFiberFailure because we want to keep the full cause of the failure.
|
|
134
|
+
const runPromise = flow(Effect.runPromiseExitWith(getRuntime()), (_) =>
|
|
135
|
+
_.then(
|
|
136
|
+
Exit.match({
|
|
137
|
+
onFailure: (cause) => Promise.reject(new KnownFiberFailure(cause)),
|
|
138
|
+
onSuccess: (value) => Promise.resolve(value)
|
|
139
|
+
})
|
|
140
|
+
))
|
|
130
141
|
const arr = arg
|
|
131
142
|
const req: { value: I } = !arg
|
|
132
143
|
? undefined
|
|
@@ -145,10 +156,8 @@ export const makeQuery = <R>(getRuntime: () => Runtime.Runtime<R>) => {
|
|
|
145
156
|
? {
|
|
146
157
|
...options,
|
|
147
158
|
retry: (retryCount, error) => {
|
|
148
|
-
if (
|
|
149
|
-
|
|
150
|
-
const sq = Cause.squash(cause)
|
|
151
|
-
if (!isHttpClientError(sq) && !S.is(ServiceUnavailableError)(sq)) {
|
|
159
|
+
if (error instanceof KnownFiberFailure) {
|
|
160
|
+
if (!isHttpClientError(error.error) && !S.is(ServiceUnavailableError)(error.error)) {
|
|
152
161
|
return false
|
|
153
162
|
}
|
|
154
163
|
}
|
|
@@ -160,8 +169,8 @@ export const makeQuery = <R>(getRuntime: () => Runtime.Runtime<R>) => {
|
|
|
160
169
|
runPromise(
|
|
161
170
|
handler
|
|
162
171
|
.pipe(
|
|
163
|
-
Effect.
|
|
164
|
-
Effect.withSpan(`query ${q.id}`, { captureStackTrace: false }),
|
|
172
|
+
Effect.tapCauseIf(Cause.hasDies, (cause) => reportRuntimeError(cause)),
|
|
173
|
+
Effect.withSpan(`query ${q.id}`, {}, { captureStackTrace: false }),
|
|
165
174
|
meta?.["span"] ? Effect.withParentSpan(meta["span"] as Span) : (_) => _
|
|
166
175
|
),
|
|
167
176
|
{ signal }
|
|
@@ -170,10 +179,8 @@ export const makeQuery = <R>(getRuntime: () => Runtime.Runtime<R>) => {
|
|
|
170
179
|
: {
|
|
171
180
|
...options,
|
|
172
181
|
retry: (retryCount, error) => {
|
|
173
|
-
if (
|
|
174
|
-
|
|
175
|
-
const sq = Cause.squash(cause)
|
|
176
|
-
if (!isHttpClientError(sq) && !S.is(ServiceUnavailableError)(sq)) {
|
|
182
|
+
if (error instanceof KnownFiberFailure) {
|
|
183
|
+
if (!isHttpClientError(error.error) && !S.is(ServiceUnavailableError)(error.error)) {
|
|
177
184
|
return false
|
|
178
185
|
}
|
|
179
186
|
}
|
|
@@ -185,8 +192,8 @@ export const makeQuery = <R>(getRuntime: () => Runtime.Runtime<R>) => {
|
|
|
185
192
|
runPromise(
|
|
186
193
|
handler(req.value)
|
|
187
194
|
.pipe(
|
|
188
|
-
Effect.
|
|
189
|
-
Effect.withSpan(`query ${q.id}`, { captureStackTrace: false }),
|
|
195
|
+
Effect.tapCauseIf(Cause.hasDies, (cause) => reportRuntimeError(cause)),
|
|
196
|
+
Effect.withSpan(`query ${q.id}`, {}, { captureStackTrace: false }),
|
|
190
197
|
meta?.["span"] ? Effect.withParentSpan(meta["span"] as Span) : (_) => _
|
|
191
198
|
),
|
|
192
199
|
{ signal }
|
|
@@ -209,7 +216,7 @@ export const makeQuery = <R>(getRuntime: () => Runtime.Runtime<R>) => {
|
|
|
209
216
|
result,
|
|
210
217
|
computed(() => latestSuccess.value),
|
|
211
218
|
// one thing to keep in mind is that span will be disconnected as Context does not pass from outside.
|
|
212
|
-
// TODO: consider how we should handle the Result here which is `QueryObserverResult<A,
|
|
219
|
+
// TODO: consider how we should handle the Result here which is `QueryObserverResult<A, E>`
|
|
213
220
|
// and always ends up in the success channel, even when error..
|
|
214
221
|
(options?: RefetchOptions) =>
|
|
215
222
|
Effect.currentSpan.pipe(
|
|
@@ -225,9 +232,9 @@ export const makeQuery = <R>(getRuntime: () => Runtime.Runtime<R>) => {
|
|
|
225
232
|
data: A | undefined
|
|
226
233
|
isValidating: boolean
|
|
227
234
|
}): Result.Result<A, E> {
|
|
228
|
-
if (r.error) {
|
|
235
|
+
if (r.error !== undefined) {
|
|
229
236
|
return Result.failureWithPrevious(
|
|
230
|
-
r.error
|
|
237
|
+
r.error.effectCause,
|
|
231
238
|
{
|
|
232
239
|
previous: r.data === undefined ? Option.none() : Option.some(Result.success(r.data)),
|
|
233
240
|
waiting: r.isValidating
|
package/src/routeParams.ts
CHANGED
|
@@ -12,34 +12,18 @@ export function getQueryParam(search: ParsedQuery, param: string) {
|
|
|
12
12
|
return v ?? null
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
export const getQueryParamO = flow(getQueryParam, Option.
|
|
15
|
+
export const getQueryParamO = flow(getQueryParam, Option.fromNullishOr)
|
|
16
16
|
|
|
17
|
-
export
|
|
18
|
-
const dec = flow(S.decodeUnknownEither(t), (x) =>
|
|
19
|
-
x._tag === "Right"
|
|
20
|
-
? Option.some(x.right)
|
|
21
|
-
: Option.none())
|
|
22
|
-
return dec
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export const parseOptUnknown = <E, A>(t: S.Schema<A, E, never>) => {
|
|
26
|
-
const dec = flow(S.decodeUnknownEither(t), (x) =>
|
|
27
|
-
x._tag === "Right"
|
|
28
|
-
? Option.some(x.right)
|
|
29
|
-
: Option.none())
|
|
30
|
-
return dec
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export function parseRouteParamsOption<NER extends Record<string, Schema<any, any, never>>>(
|
|
34
|
-
query: Record<string, any>,
|
|
35
|
-
t: NER // enforce non empty
|
|
17
|
+
export function parseRouteParamsOption<NER extends Record<string, S.Codec<any, any>>>(query: Record<string, any>, t: NER // enforce non empty
|
|
36
18
|
): {
|
|
37
19
|
[K in keyof NER]: Option.Option<Schema.Type<NER[K]>>
|
|
38
20
|
} {
|
|
39
21
|
return typedKeysOf(t).reduce(
|
|
40
22
|
(prev, cur) => {
|
|
41
23
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
42
|
-
prev[cur] = getQueryParamO(query, cur as string).pipe(
|
|
24
|
+
prev[cur] = getQueryParamO(query, cur as string).pipe(
|
|
25
|
+
Option.flatMap(S.decodeUnknownOption(t[cur]!))
|
|
26
|
+
)
|
|
43
27
|
|
|
44
28
|
return prev
|
|
45
29
|
},
|
|
@@ -49,7 +33,7 @@ export function parseRouteParamsOption<NER extends Record<string, Schema<any, an
|
|
|
49
33
|
)
|
|
50
34
|
}
|
|
51
35
|
|
|
52
|
-
export function parseRouteParams<NER extends Record<string,
|
|
36
|
+
export function parseRouteParams<NER extends Record<string, S.Codec<any, any>>>(
|
|
53
37
|
query: Record<string, any>,
|
|
54
38
|
t: NER // enforce non empty
|
|
55
39
|
): {
|
|
@@ -58,7 +42,9 @@ export function parseRouteParams<NER extends Record<string, Schema<any, any, nev
|
|
|
58
42
|
return typedKeysOf(t).reduce(
|
|
59
43
|
(prev, cur) => {
|
|
60
44
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
61
|
-
prev[cur] = S.decodeUnknownSync(t[cur]!)(
|
|
45
|
+
prev[cur] = S.decodeUnknownSync(t[cur]!)(
|
|
46
|
+
(query as any)[cur]
|
|
47
|
+
)
|
|
62
48
|
|
|
63
49
|
return prev
|
|
64
50
|
},
|
package/src/runtime.ts
CHANGED
|
@@ -3,12 +3,12 @@ import { Effect, Layer, Logger } from "effect-app"
|
|
|
3
3
|
|
|
4
4
|
export function makeAppRuntime<A, E>(layer: Layer.Layer<A, E>) {
|
|
5
5
|
return Effect.gen(function*() {
|
|
6
|
-
|
|
7
|
-
Layer.provide(Logger.
|
|
8
|
-
)
|
|
9
|
-
const mrt = ManagedRuntime.make(
|
|
10
|
-
yield* mrt.
|
|
11
|
-
return Object.assign(mrt
|
|
6
|
+
const l = layer.pipe(
|
|
7
|
+
Layer.provide(Logger.layer([Logger.consolePretty()]))
|
|
8
|
+
) as Layer.Layer<A, never>
|
|
9
|
+
const mrt = ManagedRuntime.make(l)
|
|
10
|
+
yield* mrt.servicesEffect
|
|
11
|
+
return Object.assign(mrt, {
|
|
12
12
|
[Symbol.dispose]() {
|
|
13
13
|
return Effect.runSync(mrt.disposeEffect)
|
|
14
14
|
},
|
package/test/Mutation.test.ts
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
2
|
import { it } from "@effect/vitest"
|
|
3
3
|
import { Cause, Effect, Exit, Fiber, Option } from "effect-app"
|
|
4
|
-
import { type RuntimeFiber } from "effect/Fiber"
|
|
5
4
|
import { CommandContext, DefaultIntl } from "../src/experimental/commander.js"
|
|
6
5
|
import { Result } from "../src/lib.js"
|
|
7
6
|
import { useExperimental } from "./stubs.js"
|
|
8
7
|
|
|
9
|
-
const unwrap = <A, E>(r:
|
|
8
|
+
const unwrap = <A, E>(r: Fiber.Fiber<Exit.Exit<A, E>, never>) => Fiber.join(r).pipe(Effect.flatten)
|
|
10
9
|
|
|
11
10
|
// declare const mutation: {
|
|
12
11
|
// name: "myMutation"
|
|
@@ -72,9 +71,9 @@ describe("alt2", () => {
|
|
|
72
71
|
expect(yield* Effect.currentSpan.pipe(Effect.map((_) => _.name))).toBe("Test Action")
|
|
73
72
|
})),
|
|
74
73
|
Effect.tap(() =>
|
|
75
|
-
Effect.currentSpan.pipe(Effect.map((_) => _.name), Effect.tap((_) => expect(_).toBe("Test Action")))
|
|
74
|
+
Effect.currentSpan.pipe(Effect.map((_) => _.name), Effect.tap((_) => Effect.sync(() => expect(_).toBe("Test Action"))))
|
|
76
75
|
),
|
|
77
|
-
Effect.tap(() => executed = true)
|
|
76
|
+
Effect.tap(() => Effect.sync(() => executed = true))
|
|
78
77
|
)
|
|
79
78
|
)
|
|
80
79
|
|
|
@@ -126,9 +125,9 @@ it.live("works", () =>
|
|
|
126
125
|
expect(yield* Effect.currentSpan.pipe(Effect.map((_) => _.name))).toBe("Test Action")
|
|
127
126
|
})),
|
|
128
127
|
Effect.tap(() =>
|
|
129
|
-
Effect.currentSpan.pipe(Effect.map((_) => _.name), Effect.tap((_) => expect(_).toBe("Test Action")))
|
|
128
|
+
Effect.currentSpan.pipe(Effect.map((_) => _.name), Effect.tap((_) => Effect.sync(() => expect(_).toBe("Test Action"))))
|
|
130
129
|
),
|
|
131
|
-
Effect.tap(() => executed = true)
|
|
130
|
+
Effect.tap(() => Effect.sync(() => executed = true))
|
|
132
131
|
)
|
|
133
132
|
expect(command.action).toBe("Test Action")
|
|
134
133
|
expect(command.id).toBe("Test Action")
|
|
@@ -176,9 +175,9 @@ it.live("works non-gen", () =>
|
|
|
176
175
|
expect(yield* Effect.currentSpan.pipe(Effect.map((_) => _.name))).toBe("Test Action")
|
|
177
176
|
})),
|
|
178
177
|
Effect.tap(() =>
|
|
179
|
-
Effect.currentSpan.pipe(Effect.map((_) => _.name), Effect.tap((_) => expect(_).toBe("Test Action")))
|
|
178
|
+
Effect.currentSpan.pipe(Effect.map((_) => _.name), Effect.tap((_) => Effect.sync(() => expect(_).toBe("Test Action"))))
|
|
180
179
|
),
|
|
181
|
-
Effect.tap(() => executed = true)
|
|
180
|
+
Effect.tap(() => Effect.sync(() => executed = true))
|
|
182
181
|
)
|
|
183
182
|
expect(command.action).toBe("Test Action")
|
|
184
183
|
|
|
@@ -211,7 +210,7 @@ it.live("has custom action name", () =>
|
|
|
211
210
|
expect(yield* CommandContext).toMatchObject({ action: "Test Action Translated", id: "Test Action" })
|
|
212
211
|
return "test-value"
|
|
213
212
|
},
|
|
214
|
-
Effect.tap(() => executed = true)
|
|
213
|
+
Effect.tap(() => Effect.sync(() => executed = true))
|
|
215
214
|
)
|
|
216
215
|
expect(command.action).toBe("Test Action Translated")
|
|
217
216
|
const r = yield* unwrap(command.handle())
|
|
@@ -235,7 +234,7 @@ it.live("can map the result", () =>
|
|
|
235
234
|
return "test-value"
|
|
236
235
|
},
|
|
237
236
|
Effect.map((_) => _ + _),
|
|
238
|
-
Effect.tap(() => executed = true)
|
|
237
|
+
Effect.tap(() => Effect.sync(() => executed = true))
|
|
239
238
|
)
|
|
240
239
|
const r = yield* unwrap(command.handle())
|
|
241
240
|
|
|
@@ -257,7 +256,7 @@ it.live("can receive and use input", () =>
|
|
|
257
256
|
|
|
258
257
|
return { input1, input2 }
|
|
259
258
|
},
|
|
260
|
-
Effect.tap(() => executed = true)
|
|
259
|
+
Effect.tap(() => Effect.sync(() => executed = true))
|
|
261
260
|
)
|
|
262
261
|
const r = yield* unwrap(command.handle(1))
|
|
263
262
|
|
|
@@ -285,8 +284,8 @@ it.live("can replace the result", () =>
|
|
|
285
284
|
|
|
286
285
|
return "test-value"
|
|
287
286
|
},
|
|
288
|
-
Effect.
|
|
289
|
-
Effect.tap(() => executed = true)
|
|
287
|
+
Effect.andThen(Effect.succeed(42)),
|
|
288
|
+
Effect.tap(() => Effect.sync(() => executed = true))
|
|
290
289
|
)
|
|
291
290
|
const r = yield* unwrap(command.handle())
|
|
292
291
|
|
|
@@ -318,7 +317,7 @@ it.live("with toasts", () =>
|
|
|
318
317
|
expect(yield* Effect.currentSpan.pipe(Effect.map((_) => _.name))).toBe("Test Action")
|
|
319
318
|
})),
|
|
320
319
|
Effect.tap(() =>
|
|
321
|
-
Effect.currentSpan.pipe(Effect.map((_) => _.name), Effect.tap((_) => expect(_).toBe("Test Action")))
|
|
320
|
+
Effect.currentSpan.pipe(Effect.map((_) => _.name), Effect.tap((_) => Effect.sync(() => expect(_).toBe("Test Action"))))
|
|
322
321
|
),
|
|
323
322
|
// WithToast.handle({
|
|
324
323
|
// onFailure: "failed",
|
|
@@ -326,7 +325,7 @@ it.live("with toasts", () =>
|
|
|
326
325
|
// onWaiting: null
|
|
327
326
|
// }),
|
|
328
327
|
Command.withDefaultToast(),
|
|
329
|
-
Effect.tap(() => executed = true)
|
|
328
|
+
Effect.tap(() => Effect.sync(() => executed = true))
|
|
330
329
|
)
|
|
331
330
|
|
|
332
331
|
const r = yield* unwrap(command.handle())
|
|
@@ -352,16 +351,16 @@ it.live("interrupted", () =>
|
|
|
352
351
|
return "test-value"
|
|
353
352
|
},
|
|
354
353
|
Command.withDefaultToast(),
|
|
355
|
-
Effect.tap(() => executed = true)
|
|
354
|
+
Effect.tap(() => Effect.sync(() => executed = true))
|
|
356
355
|
)
|
|
357
356
|
|
|
358
357
|
const r = yield* Fiber.join(command.handle())
|
|
359
358
|
|
|
360
359
|
expect(executed).toBe(false) // we were interrupted after all :)
|
|
361
|
-
expect(Exit.
|
|
360
|
+
expect(Exit.hasInterrupts(r)).toBe(true) // to confirm that the initial function has interrupted
|
|
362
361
|
|
|
363
362
|
expect(command.waiting).toBe(false)
|
|
364
|
-
expect(Exit.
|
|
363
|
+
expect(Exit.hasInterrupts(Result.toExit(command.result))).toBe(true)
|
|
365
364
|
expect(toasts.length).toBe(0) // toast is removed on interruption. TODO: maybe a nicer user experience can be had?
|
|
366
365
|
}))
|
|
367
366
|
|
|
@@ -378,13 +377,13 @@ it.live("fail", () =>
|
|
|
378
377
|
return yield* Effect.fail({ message: "Boom!" })
|
|
379
378
|
},
|
|
380
379
|
Command.withDefaultToast(),
|
|
381
|
-
Effect.tap(() => executed = true)
|
|
380
|
+
Effect.tap(() => Effect.sync(() => executed = true))
|
|
382
381
|
)
|
|
383
382
|
|
|
384
383
|
const r = yield* Fiber.join(command.handle())
|
|
385
384
|
|
|
386
385
|
expect(executed).toBe(false) // we failed after all :)
|
|
387
|
-
expect(Exit.isFailure(r) && Cause.
|
|
386
|
+
expect(Exit.isFailure(r) && Cause.hasFails(r.cause)).toBe(true) // to confirm that the initial function has failed
|
|
388
387
|
|
|
389
388
|
expect(command.waiting).toBe(false)
|
|
390
389
|
expect(Exit.isFailure(Result.toExit(command.result))).toBe(true)
|
|
@@ -404,9 +403,9 @@ it.live("fail and recover", () =>
|
|
|
404
403
|
expect(toasts.length).toBe(1)
|
|
405
404
|
return yield* Effect.fail({ message: "Boom!" })
|
|
406
405
|
},
|
|
407
|
-
Effect.
|
|
406
|
+
Effect.orElseSucceed(() => "recovered"), // we recover from the error here, so the final result is success
|
|
408
407
|
Command.withDefaultToast(),
|
|
409
|
-
Effect.tap(() => executed = true)
|
|
408
|
+
Effect.tap(() => Effect.sync(() => executed = true))
|
|
410
409
|
)
|
|
411
410
|
|
|
412
411
|
const r = yield* unwrap(command.handle())
|
|
@@ -433,14 +432,14 @@ it.live("defect", () =>
|
|
|
433
432
|
return yield* Effect.die({ message: "Boom!" })
|
|
434
433
|
},
|
|
435
434
|
Command.withDefaultToast(),
|
|
436
|
-
Effect.tap(() => executed = true)
|
|
435
|
+
Effect.tap(() => Effect.sync(() => executed = true))
|
|
437
436
|
)
|
|
438
437
|
|
|
439
438
|
const r = yield* Fiber.join(command.handle())
|
|
440
439
|
// TODO: confirm we reported error
|
|
441
440
|
|
|
442
441
|
expect(executed).toBe(false) // we died after all :)
|
|
443
|
-
expect(Exit.isFailure(r) && Cause.
|
|
442
|
+
expect(Exit.isFailure(r) && Cause.hasDies(r.cause)).toBe(true) // to confirm that the initial function has died
|
|
444
443
|
|
|
445
444
|
expect(command.waiting).toBe(false)
|
|
446
445
|
expect(Exit.isFailure(Result.toExit(command.result))).toBe(true)
|
|
@@ -472,9 +471,9 @@ it.live("works with alt", () =>
|
|
|
472
471
|
expect(yield* Effect.currentSpan.pipe(Effect.map((_) => _.name))).toBe("Test Action")
|
|
473
472
|
})),
|
|
474
473
|
Effect.tap(() =>
|
|
475
|
-
Effect.currentSpan.pipe(Effect.map((_) => _.name), Effect.tap((_) => expect(_).toBe("Test Action")))
|
|
474
|
+
Effect.currentSpan.pipe(Effect.map((_) => _.name), Effect.tap((_) => Effect.sync(() => expect(_).toBe("Test Action"))))
|
|
476
475
|
),
|
|
477
|
-
Effect.tap(() => executed = true)
|
|
476
|
+
Effect.tap(() => Effect.sync(() => executed = true))
|
|
478
477
|
)
|
|
479
478
|
)
|
|
480
479
|
expect(command.action).toBe("Test Action")
|
|
@@ -509,7 +508,7 @@ it.live("has custom action name with alt", () =>
|
|
|
509
508
|
expect(yield* CommandContext).toMatchObject({ action: "Test Action Translated", id: "Test Action" })
|
|
510
509
|
return "test-value"
|
|
511
510
|
},
|
|
512
|
-
Effect.tap(() => executed = true)
|
|
511
|
+
Effect.tap(() => Effect.sync(() => executed = true))
|
|
513
512
|
)
|
|
514
513
|
)
|
|
515
514
|
expect(command.action).toBe("Test Action Translated")
|
|
@@ -534,7 +533,7 @@ it.live("can map the result with alt", () =>
|
|
|
534
533
|
return "test-value"
|
|
535
534
|
},
|
|
536
535
|
Effect.map((_) => _ + _),
|
|
537
|
-
Effect.tap(() => executed = true)
|
|
536
|
+
Effect.tap(() => Effect.sync(() => executed = true))
|
|
538
537
|
))
|
|
539
538
|
const r = yield* unwrap(command.handle())
|
|
540
539
|
|
|
@@ -560,7 +559,7 @@ it.live("can receive and use input with alt", () =>
|
|
|
560
559
|
}
|
|
561
560
|
)
|
|
562
561
|
.pipe(
|
|
563
|
-
Effect.tap(() => executed = true)
|
|
562
|
+
Effect.tap(() => Effect.sync(() => executed = true))
|
|
564
563
|
)
|
|
565
564
|
)
|
|
566
565
|
const r = yield* unwrap(command.handle(1))
|
|
@@ -590,8 +589,8 @@ it.live("can replace the result with alt", () =>
|
|
|
590
589
|
|
|
591
590
|
return "test-value"
|
|
592
591
|
},
|
|
593
|
-
Effect.
|
|
594
|
-
Effect.tap(() => executed = true)
|
|
592
|
+
Effect.andThen(Effect.succeed(42)),
|
|
593
|
+
Effect.tap(() => Effect.sync(() => executed = true))
|
|
595
594
|
)
|
|
596
595
|
)
|
|
597
596
|
const r = yield* unwrap(command.handle())
|
|
@@ -625,10 +624,10 @@ it.live("with toasts with alt", () =>
|
|
|
625
624
|
expect(yield* Effect.currentSpan.pipe(Effect.map((_) => _.name))).toBe("Test Action")
|
|
626
625
|
})),
|
|
627
626
|
Effect.tap(() =>
|
|
628
|
-
Effect.currentSpan.pipe(Effect.map((_) => _.name), Effect.tap((_) => expect(_).toBe("Test Action")))
|
|
627
|
+
Effect.currentSpan.pipe(Effect.map((_) => _.name), Effect.tap((_) => Effect.sync(() => expect(_).toBe("Test Action"))))
|
|
629
628
|
),
|
|
630
629
|
Command.withDefaultToast(),
|
|
631
|
-
Effect.tap(() => executed = true)
|
|
630
|
+
Effect.tap(() => Effect.sync(() => executed = true))
|
|
632
631
|
)
|
|
633
632
|
)
|
|
634
633
|
|
|
@@ -657,17 +656,17 @@ it.live("interrupted with alt", () =>
|
|
|
657
656
|
return "test-value"
|
|
658
657
|
},
|
|
659
658
|
Command.withDefaultToast(),
|
|
660
|
-
Effect.tap(() => executed = true)
|
|
659
|
+
Effect.tap(() => Effect.sync(() => executed = true))
|
|
661
660
|
)
|
|
662
661
|
)
|
|
663
662
|
|
|
664
663
|
const r = yield* Fiber.join(command.handle())
|
|
665
664
|
|
|
666
665
|
expect(executed).toBe(false) // we were interrupted after all :)
|
|
667
|
-
expect(Exit.
|
|
666
|
+
expect(Exit.hasInterrupts(r)).toBe(true) // to confirm that the initial function has interrupted
|
|
668
667
|
|
|
669
668
|
expect(command.waiting).toBe(false)
|
|
670
|
-
expect(Exit.
|
|
669
|
+
expect(Exit.hasInterrupts(Result.toExit(command.result))).toBe(true)
|
|
671
670
|
expect(toasts.length).toBe(0) // toast is removed on interruption. TODO: maybe a nicer user experience can be had?
|
|
672
671
|
}))
|
|
673
672
|
|
|
@@ -685,14 +684,14 @@ it.live("fail with alt", () =>
|
|
|
685
684
|
return yield* Effect.fail({ message: "Boom!" })
|
|
686
685
|
},
|
|
687
686
|
Command.withDefaultToast(),
|
|
688
|
-
Effect.tap(() => executed = true)
|
|
687
|
+
Effect.tap(() => Effect.sync(() => executed = true))
|
|
689
688
|
)
|
|
690
689
|
)
|
|
691
690
|
|
|
692
691
|
const r = yield* Fiber.join(command.handle())
|
|
693
692
|
|
|
694
693
|
expect(executed).toBe(false) // we failed after all :)
|
|
695
|
-
expect(Exit.isFailure(r) && Cause.
|
|
694
|
+
expect(Exit.isFailure(r) && Cause.hasFails(r.cause)).toBe(true) // to confirm that the initial function has failed
|
|
696
695
|
|
|
697
696
|
expect(command.waiting).toBe(false)
|
|
698
697
|
expect(Exit.isFailure(Result.toExit(command.result))).toBe(true)
|
|
@@ -713,9 +712,9 @@ it.live("fail and recover with alt", () =>
|
|
|
713
712
|
expect(toasts.length).toBe(1)
|
|
714
713
|
return yield* Effect.fail({ message: "Boom!" })
|
|
715
714
|
},
|
|
716
|
-
Effect.
|
|
715
|
+
Effect.orElseSucceed(() => "recovered"), // we recover from the error here, so the final result is success
|
|
717
716
|
Command.withDefaultToast(),
|
|
718
|
-
Effect.tap(() => executed = true)
|
|
717
|
+
Effect.tap(() => Effect.sync(() => executed = true))
|
|
719
718
|
)
|
|
720
719
|
)
|
|
721
720
|
|
|
@@ -744,7 +743,7 @@ it.live("defect with alt", () =>
|
|
|
744
743
|
return yield* Effect.die({ message: "Boom!" })
|
|
745
744
|
},
|
|
746
745
|
Command.withDefaultToast(),
|
|
747
|
-
Effect.tap(() => executed = true)
|
|
746
|
+
Effect.tap(() => Effect.sync(() => executed = true))
|
|
748
747
|
)
|
|
749
748
|
)
|
|
750
749
|
|
|
@@ -752,7 +751,7 @@ it.live("defect with alt", () =>
|
|
|
752
751
|
// TODO: confirm we reported error
|
|
753
752
|
|
|
754
753
|
expect(executed).toBe(false) // we died after all :)
|
|
755
|
-
expect(Exit.isFailure(r) && Cause.
|
|
754
|
+
expect(Exit.isFailure(r) && Cause.hasDies(r.cause)).toBe(true) // to confirm that the initial function has died
|
|
756
755
|
|
|
757
756
|
expect(command.waiting).toBe(false)
|
|
758
757
|
expect(Exit.isFailure(Result.toExit(command.result))).toBe(true)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"form.test.d.ts","sourceRoot":"","sources":["../form.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,CAAC,EAAE,MAAM,YAAY,CAAA
|
|
1
|
+
{"version":3,"file":"form.test.d.ts","sourceRoot":"","sources":["../form.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,CAAC,EAAE,MAAM,YAAY,CAAA;;;;;;;;;;;;;;;;;AAGtC,qBAAa,YAAa,SAAQ,iBAShC;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"}
|