@typed/async-data 0.13.1 → 1.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/README.md +159 -0
- package/dist/index.d.ts +92 -4
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +169 -5
- package/package.json +18 -28
- package/src/AsyncData.test.ts +417 -62
- package/src/index.test.ts +497 -0
- package/src/index.ts +291 -4
- package/tsconfig.json +5 -26
- package/.nvmrc +0 -1
- package/biome.json +0 -36
- package/dist/AsyncData.d.ts +0 -203
- package/dist/AsyncData.js +0 -294
- package/dist/AsyncData.js.map +0 -1
- package/dist/LazyRef.d.ts +0 -22
- package/dist/LazyRef.js +0 -28
- package/dist/LazyRef.js.map +0 -1
- package/dist/Progress.d.ts +0 -25
- package/dist/Progress.js +0 -22
- package/dist/Progress.js.map +0 -1
- package/dist/TypeId.d.ts +0 -11
- package/dist/TypeId.js +0 -8
- package/dist/TypeId.js.map +0 -1
- package/dist/_internal.d.ts +0 -20
- package/dist/_internal.js +0 -58
- package/dist/_internal.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/readme.md +0 -218
- package/src/AsyncData.ts +0 -651
- package/src/LazyRef.ts +0 -89
- package/src/Progress.ts +0 -34
- package/src/TypeId.ts +0 -13
- package/src/_internal.ts +0 -111
package/src/AsyncData.test.ts
CHANGED
|
@@ -1,89 +1,444 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
1
|
+
// oxlint-disable require-yield
|
|
2
|
+
import { assert, describe, it } from "vitest";
|
|
3
|
+
import { Effect } from "effect";
|
|
4
|
+
import * as Cause from "effect/Cause";
|
|
5
|
+
import * as Exit from "effect/Exit";
|
|
6
|
+
import * as Option from "effect/Option";
|
|
7
|
+
import * as Result from "effect/Result";
|
|
8
|
+
import * as AsyncData from "./index.js";
|
|
4
9
|
|
|
5
|
-
describe(
|
|
6
|
-
describe(
|
|
7
|
-
it
|
|
10
|
+
describe("AsyncData", () => {
|
|
11
|
+
describe("constructors", () => {
|
|
12
|
+
it("NoData", () =>
|
|
8
13
|
Effect.gen(function* () {
|
|
9
|
-
const
|
|
10
|
-
|
|
14
|
+
const data = AsyncData.NoData;
|
|
15
|
+
assert(AsyncData.isNoData(data));
|
|
16
|
+
assert(data._tag === "NoData");
|
|
17
|
+
}).pipe(Effect.scoped, Effect.runPromise));
|
|
11
18
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
19
|
+
it("loading without progress", () =>
|
|
20
|
+
Effect.gen(function* () {
|
|
21
|
+
const data = AsyncData.loading();
|
|
22
|
+
assert(AsyncData.isLoading(data));
|
|
23
|
+
assert(data._tag === "Loading");
|
|
24
|
+
assert(data.progress === undefined);
|
|
25
|
+
}).pipe(Effect.scoped, Effect.runPromise));
|
|
26
|
+
|
|
27
|
+
it("loading with progress", () =>
|
|
28
|
+
Effect.gen(function* () {
|
|
29
|
+
const progress = { loaded: 50, total: 100 };
|
|
30
|
+
const data = AsyncData.loading(progress);
|
|
31
|
+
assert(AsyncData.isLoading(data));
|
|
32
|
+
assert(data.progress?.loaded === 50);
|
|
33
|
+
assert(data.progress?.total === 100);
|
|
34
|
+
}).pipe(Effect.scoped, Effect.runPromise));
|
|
35
|
+
|
|
36
|
+
it("success without progress", () =>
|
|
37
|
+
Effect.gen(function* () {
|
|
38
|
+
const data = AsyncData.success(42);
|
|
39
|
+
assert(AsyncData.isSuccess(data));
|
|
40
|
+
assert(data._tag === "Success");
|
|
41
|
+
assert(data.value === 42);
|
|
42
|
+
assert(data.progress === undefined);
|
|
43
|
+
}).pipe(Effect.scoped, Effect.runPromise));
|
|
44
|
+
|
|
45
|
+
it("success with progress", () =>
|
|
46
|
+
Effect.gen(function* () {
|
|
47
|
+
const progress = { loaded: 75, total: 100 };
|
|
48
|
+
const data = AsyncData.success(42, progress);
|
|
49
|
+
assert(AsyncData.isSuccess(data));
|
|
50
|
+
assert(data.value === 42);
|
|
51
|
+
assert(data.progress?.loaded === 75);
|
|
52
|
+
assert(data.progress?.total === 100);
|
|
53
|
+
}).pipe(Effect.scoped, Effect.runPromise));
|
|
54
|
+
|
|
55
|
+
it("failure without progress", () =>
|
|
56
|
+
Effect.gen(function* () {
|
|
57
|
+
const cause = Cause.fail("error");
|
|
58
|
+
const data = AsyncData.failure(cause);
|
|
59
|
+
assert(AsyncData.isFailure(data));
|
|
60
|
+
assert(data._tag === "Failure");
|
|
61
|
+
assert(data.cause === cause);
|
|
62
|
+
assert(data.progress === undefined);
|
|
63
|
+
}).pipe(Effect.scoped, Effect.runPromise));
|
|
64
|
+
|
|
65
|
+
it("failure with progress", () =>
|
|
66
|
+
Effect.gen(function* () {
|
|
67
|
+
const cause = Cause.fail("error");
|
|
68
|
+
const progress = { loaded: 25 };
|
|
69
|
+
const data = AsyncData.failure(cause, progress);
|
|
70
|
+
assert(AsyncData.isFailure(data));
|
|
71
|
+
assert(data.progress?.loaded === 25);
|
|
72
|
+
assert(data.progress?.total === undefined);
|
|
73
|
+
}).pipe(Effect.scoped, Effect.runPromise));
|
|
74
|
+
|
|
75
|
+
it("optimistic", () =>
|
|
76
|
+
Effect.gen(function* () {
|
|
77
|
+
const previous = AsyncData.success(10);
|
|
78
|
+
const data = AsyncData.optimistic(previous, 20);
|
|
79
|
+
assert(AsyncData.isOptimistic(data));
|
|
80
|
+
assert(data._tag === "Optimistic");
|
|
81
|
+
assert(data.value === 20);
|
|
82
|
+
assert(data.previous === previous);
|
|
83
|
+
}).pipe(Effect.scoped, Effect.runPromise));
|
|
84
|
+
});
|
|
15
85
|
|
|
16
|
-
|
|
86
|
+
describe("type guards", () => {
|
|
87
|
+
it("isNoData", () =>
|
|
17
88
|
Effect.gen(function* () {
|
|
18
|
-
|
|
19
|
-
|
|
89
|
+
assert(AsyncData.isNoData(AsyncData.NoData));
|
|
90
|
+
assert(!AsyncData.isNoData(AsyncData.loading()));
|
|
91
|
+
assert(!AsyncData.isNoData(AsyncData.success(1)));
|
|
92
|
+
}).pipe(Effect.scoped, Effect.runPromise));
|
|
20
93
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
94
|
+
it("isLoading", () =>
|
|
95
|
+
Effect.gen(function* () {
|
|
96
|
+
assert(AsyncData.isLoading(AsyncData.loading()));
|
|
97
|
+
assert(!AsyncData.isLoading(AsyncData.NoData));
|
|
98
|
+
assert(!AsyncData.isLoading(AsyncData.success(1)));
|
|
99
|
+
}).pipe(Effect.scoped, Effect.runPromise));
|
|
24
100
|
|
|
25
|
-
it
|
|
101
|
+
it("isSuccess", () =>
|
|
26
102
|
Effect.gen(function* () {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
103
|
+
assert(AsyncData.isSuccess(AsyncData.success(1)));
|
|
104
|
+
assert(!AsyncData.isSuccess(AsyncData.NoData));
|
|
105
|
+
assert(!AsyncData.isSuccess(AsyncData.loading()));
|
|
106
|
+
}).pipe(Effect.scoped, Effect.runPromise));
|
|
30
107
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
108
|
+
it("isFailure", () =>
|
|
109
|
+
Effect.gen(function* () {
|
|
110
|
+
const cause = Cause.fail("error");
|
|
111
|
+
assert(AsyncData.isFailure(AsyncData.failure(cause)));
|
|
112
|
+
assert(!AsyncData.isFailure(AsyncData.NoData));
|
|
113
|
+
assert(!AsyncData.isFailure(AsyncData.success(1)));
|
|
114
|
+
}).pipe(Effect.scoped, Effect.runPromise));
|
|
34
115
|
|
|
35
|
-
it
|
|
116
|
+
it("isOptimistic", () =>
|
|
36
117
|
Effect.gen(function* () {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
118
|
+
const previous = AsyncData.success(10);
|
|
119
|
+
const data = AsyncData.optimistic(previous, 20);
|
|
120
|
+
assert(AsyncData.isOptimistic(data));
|
|
121
|
+
assert(!AsyncData.isOptimistic(AsyncData.NoData));
|
|
122
|
+
assert(!AsyncData.isOptimistic(AsyncData.success(1)));
|
|
123
|
+
}).pipe(Effect.scoped, Effect.runPromise));
|
|
40
124
|
|
|
41
|
-
it
|
|
125
|
+
it("isAsyncData", () =>
|
|
42
126
|
Effect.gen(function* () {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
127
|
+
assert(AsyncData.isAsyncData(AsyncData.NoData));
|
|
128
|
+
assert(AsyncData.isAsyncData(AsyncData.loading()));
|
|
129
|
+
assert(AsyncData.isAsyncData(AsyncData.success(1)));
|
|
130
|
+
assert(AsyncData.isAsyncData(AsyncData.failure(Cause.fail("error"))));
|
|
131
|
+
assert(!AsyncData.isAsyncData(null));
|
|
132
|
+
assert(!AsyncData.isAsyncData({}));
|
|
133
|
+
assert(!AsyncData.isAsyncData({ _tag: "Invalid" }));
|
|
134
|
+
}).pipe(Effect.scoped, Effect.runPromise));
|
|
46
135
|
|
|
47
|
-
it
|
|
136
|
+
it("isRefreshing", () =>
|
|
48
137
|
Effect.gen(function* () {
|
|
49
|
-
const
|
|
50
|
-
const
|
|
51
|
-
const
|
|
138
|
+
const progress = { loaded: 50 };
|
|
139
|
+
const successWithProgress = AsyncData.success(1, progress);
|
|
140
|
+
const failureWithProgress = AsyncData.failure(Cause.fail("error"), progress);
|
|
141
|
+
assert(AsyncData.isRefreshing(successWithProgress));
|
|
142
|
+
assert(AsyncData.isRefreshing(failureWithProgress));
|
|
143
|
+
assert(!AsyncData.isRefreshing(AsyncData.success(1)));
|
|
144
|
+
assert(!AsyncData.isRefreshing(AsyncData.loading()));
|
|
145
|
+
}).pipe(Effect.scoped, Effect.runPromise));
|
|
52
146
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
147
|
+
it("isPending", () =>
|
|
148
|
+
Effect.gen(function* () {
|
|
149
|
+
assert(AsyncData.isPending(AsyncData.loading()));
|
|
150
|
+
const progress = { loaded: 50 };
|
|
151
|
+
assert(AsyncData.isPending(AsyncData.success(1, progress)));
|
|
152
|
+
assert(AsyncData.isPending(AsyncData.failure(Cause.fail("error"), progress)));
|
|
153
|
+
assert(!AsyncData.isPending(AsyncData.NoData));
|
|
154
|
+
assert(!AsyncData.isPending(AsyncData.success(1)));
|
|
155
|
+
}).pipe(Effect.scoped, Effect.runPromise));
|
|
156
|
+
});
|
|
56
157
|
|
|
57
|
-
|
|
158
|
+
describe("extractors", () => {
|
|
159
|
+
it("getSuccess", () =>
|
|
58
160
|
Effect.gen(function* () {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
161
|
+
const successData = AsyncData.success(42);
|
|
162
|
+
const successOption = AsyncData.getSuccess(successData);
|
|
163
|
+
assert(Option.isSome(successOption));
|
|
164
|
+
assert(successOption.value === 42);
|
|
165
|
+
assert(Option.isNone(AsyncData.getSuccess(AsyncData.NoData)));
|
|
166
|
+
assert(Option.isNone(AsyncData.getSuccess(AsyncData.loading())));
|
|
167
|
+
const previous = AsyncData.success(10);
|
|
168
|
+
const optimistic = AsyncData.optimistic(previous, 20);
|
|
169
|
+
const optimisticOption = AsyncData.getSuccess(optimistic);
|
|
170
|
+
assert(Option.isSome(optimisticOption));
|
|
171
|
+
assert(optimisticOption.value === 20);
|
|
172
|
+
}).pipe(Effect.scoped, Effect.runPromise));
|
|
63
173
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
174
|
+
it("getCause", () =>
|
|
175
|
+
Effect.gen(function* () {
|
|
176
|
+
const cause = Cause.fail("error");
|
|
177
|
+
const failureData = AsyncData.failure(cause);
|
|
178
|
+
const causeOption = AsyncData.getCause(failureData);
|
|
179
|
+
assert(Option.isSome(causeOption));
|
|
180
|
+
assert(causeOption.value === cause);
|
|
181
|
+
assert(Option.isNone(AsyncData.getCause(AsyncData.NoData)));
|
|
182
|
+
assert(Option.isNone(AsyncData.getCause(AsyncData.loading())));
|
|
183
|
+
assert(Option.isNone(AsyncData.getCause(AsyncData.success(1))));
|
|
184
|
+
}).pipe(Effect.scoped, Effect.runPromise));
|
|
69
185
|
|
|
70
|
-
it
|
|
186
|
+
it("getError", () =>
|
|
71
187
|
Effect.gen(function* () {
|
|
72
|
-
const
|
|
188
|
+
const error = "error";
|
|
189
|
+
const cause = Cause.fail(error);
|
|
190
|
+
const failureData = AsyncData.failure(cause);
|
|
191
|
+
const errorOption = AsyncData.getError(failureData);
|
|
192
|
+
assert(Option.isSome(errorOption));
|
|
193
|
+
assert(errorOption.value === error);
|
|
194
|
+
assert(Option.isNone(AsyncData.getError(AsyncData.NoData)));
|
|
195
|
+
assert(Option.isNone(AsyncData.getError(AsyncData.loading())));
|
|
196
|
+
assert(Option.isNone(AsyncData.getError(AsyncData.success(1))));
|
|
197
|
+
}).pipe(Effect.scoped, Effect.runPromise));
|
|
198
|
+
});
|
|
73
199
|
|
|
74
|
-
|
|
75
|
-
|
|
200
|
+
describe("transformations", () => {
|
|
201
|
+
it("map", () =>
|
|
202
|
+
Effect.gen(function* () {
|
|
203
|
+
const data = AsyncData.success(5);
|
|
204
|
+
const mapped = AsyncData.map(data, (n) => n * 2);
|
|
205
|
+
assert(AsyncData.isSuccess(mapped));
|
|
206
|
+
assert(mapped.value === 10);
|
|
207
|
+
const noData = AsyncData.NoData;
|
|
208
|
+
const mappedNoData = AsyncData.map(noData, (n: number) => n * 2);
|
|
209
|
+
assert(AsyncData.isNoData(mappedNoData));
|
|
210
|
+
const optimistic = AsyncData.optimistic(AsyncData.success(5), 10);
|
|
211
|
+
const mappedOptimistic = AsyncData.map(optimistic, (n) => n * 2);
|
|
212
|
+
assert(AsyncData.isOptimistic(mappedOptimistic));
|
|
213
|
+
assert(mappedOptimistic.value === 20);
|
|
214
|
+
assert(AsyncData.isSuccess(mappedOptimistic.previous));
|
|
215
|
+
assert(mappedOptimistic.previous.value === 10);
|
|
216
|
+
}).pipe(Effect.scoped, Effect.runPromise));
|
|
76
217
|
|
|
77
|
-
|
|
218
|
+
it("map preserves progress", () =>
|
|
219
|
+
Effect.gen(function* () {
|
|
220
|
+
const progress = { loaded: 50, total: 100 };
|
|
221
|
+
const data = AsyncData.success(5, progress);
|
|
222
|
+
const mapped = AsyncData.map(data, (n) => n * 2);
|
|
223
|
+
assert(AsyncData.isSuccess(mapped));
|
|
224
|
+
assert(mapped.progress?.loaded === 50);
|
|
225
|
+
assert(mapped.progress?.total === 100);
|
|
226
|
+
}).pipe(Effect.scoped, Effect.runPromise));
|
|
78
227
|
|
|
79
|
-
|
|
228
|
+
it("flatMap", () =>
|
|
229
|
+
Effect.gen(function* () {
|
|
230
|
+
const data = AsyncData.success(5);
|
|
231
|
+
const flatMapped = AsyncData.flatMap(data, (n) => AsyncData.success(n * 2));
|
|
232
|
+
assert(AsyncData.isSuccess(flatMapped));
|
|
233
|
+
assert(flatMapped.value === 10);
|
|
234
|
+
const noData = AsyncData.NoData;
|
|
235
|
+
const flatMappedNoData = AsyncData.flatMap(noData, (n: number) => AsyncData.success(n * 2));
|
|
236
|
+
assert(AsyncData.isNoData(flatMappedNoData));
|
|
237
|
+
const optimistic = AsyncData.optimistic(AsyncData.success(5), 10);
|
|
238
|
+
const flatMappedOptimistic = AsyncData.flatMap(optimistic, (n) => AsyncData.success(n * 2));
|
|
239
|
+
assert(AsyncData.isSuccess(flatMappedOptimistic));
|
|
240
|
+
assert(flatMappedOptimistic.value === 20);
|
|
241
|
+
const optimisticToOptimistic = AsyncData.optimistic(AsyncData.success(5), 10);
|
|
242
|
+
const flatMappedOptimistic2 = AsyncData.flatMap(optimisticToOptimistic, (n, prev) =>
|
|
243
|
+
AsyncData.optimistic(prev, n * 2),
|
|
244
|
+
);
|
|
245
|
+
assert(AsyncData.isOptimistic(flatMappedOptimistic2));
|
|
246
|
+
assert(flatMappedOptimistic2.value === 20);
|
|
247
|
+
}).pipe(Effect.scoped, Effect.runPromise));
|
|
80
248
|
|
|
81
|
-
|
|
249
|
+
it("mapError", () =>
|
|
250
|
+
Effect.gen(function* () {
|
|
251
|
+
const cause = Cause.fail("error");
|
|
252
|
+
const data = AsyncData.failure(cause);
|
|
253
|
+
const mapped = AsyncData.mapError(data, (e) => `mapped: ${e}`);
|
|
254
|
+
assert(AsyncData.isFailure(mapped));
|
|
255
|
+
const error = Cause.findErrorOption(mapped.cause);
|
|
256
|
+
assert(Option.isSome(error));
|
|
257
|
+
assert(error.value === "mapped: error");
|
|
258
|
+
const noData = AsyncData.NoData;
|
|
259
|
+
const mappedNoData = AsyncData.mapError(noData, (e: string) => `mapped: ${e}`);
|
|
260
|
+
assert(AsyncData.isNoData(mappedNoData));
|
|
261
|
+
const optimistic = AsyncData.optimistic(AsyncData.failure(cause), 10);
|
|
262
|
+
const mappedOptimistic = AsyncData.mapError(optimistic, (e) => `mapped: ${e}`);
|
|
263
|
+
assert(AsyncData.isOptimistic(mappedOptimistic));
|
|
264
|
+
assert(AsyncData.isFailure(mappedOptimistic.previous));
|
|
265
|
+
}).pipe(Effect.scoped, Effect.runPromise));
|
|
266
|
+
|
|
267
|
+
it("mapError preserves progress", () =>
|
|
268
|
+
Effect.gen(function* () {
|
|
269
|
+
const progress = { loaded: 50 };
|
|
270
|
+
const cause = Cause.fail("error");
|
|
271
|
+
const data = AsyncData.failure(cause, progress);
|
|
272
|
+
const mapped = AsyncData.mapError(data, (e) => `mapped: ${e}`);
|
|
273
|
+
assert(AsyncData.isFailure(mapped));
|
|
274
|
+
assert(mapped.progress?.loaded === 50);
|
|
275
|
+
}).pipe(Effect.scoped, Effect.runPromise));
|
|
276
|
+
});
|
|
82
277
|
|
|
83
|
-
|
|
278
|
+
describe("utilities", () => {
|
|
279
|
+
it("startLoading from NoData", () =>
|
|
280
|
+
Effect.gen(function* () {
|
|
281
|
+
const data = AsyncData.NoData;
|
|
282
|
+
const started = AsyncData.startLoading(data);
|
|
283
|
+
assert(AsyncData.isLoading(started));
|
|
284
|
+
}).pipe(Effect.scoped, Effect.runPromise));
|
|
285
|
+
|
|
286
|
+
it("startLoading from Success", () =>
|
|
287
|
+
Effect.gen(function* () {
|
|
288
|
+
const data = AsyncData.success(42);
|
|
289
|
+
const progress = { loaded: 50 };
|
|
290
|
+
const started = AsyncData.startLoading(data, progress);
|
|
291
|
+
assert(AsyncData.isSuccess(started));
|
|
292
|
+
assert(started.value === 42);
|
|
293
|
+
assert(started.progress?.loaded === 50);
|
|
294
|
+
}).pipe(Effect.scoped, Effect.runPromise));
|
|
84
295
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
296
|
+
it("startLoading from Failure", () =>
|
|
297
|
+
Effect.gen(function* () {
|
|
298
|
+
const cause = Cause.fail("error");
|
|
299
|
+
const data = AsyncData.failure(cause);
|
|
300
|
+
const progress = { loaded: 50 };
|
|
301
|
+
const started = AsyncData.startLoading(data, progress);
|
|
302
|
+
assert(AsyncData.isFailure(started));
|
|
303
|
+
assert(started.cause === cause);
|
|
304
|
+
assert(started.progress?.loaded === 50);
|
|
305
|
+
}).pipe(Effect.scoped, Effect.runPromise));
|
|
306
|
+
|
|
307
|
+
it("startLoading from Optimistic", () =>
|
|
308
|
+
Effect.gen(function* () {
|
|
309
|
+
const previous = AsyncData.success(10);
|
|
310
|
+
const data = AsyncData.optimistic(previous, 20);
|
|
311
|
+
const progress = { loaded: 50 };
|
|
312
|
+
const started = AsyncData.startLoading(data, progress);
|
|
313
|
+
assert(AsyncData.isOptimistic(started));
|
|
314
|
+
assert(started.value === 20);
|
|
315
|
+
assert(AsyncData.isSuccess(started.previous));
|
|
316
|
+
assert(started.previous.progress?.loaded === 50);
|
|
317
|
+
}).pipe(Effect.scoped, Effect.runPromise));
|
|
318
|
+
|
|
319
|
+
it("stopLoading from Success with progress", () =>
|
|
320
|
+
Effect.gen(function* () {
|
|
321
|
+
const progress = { loaded: 50 };
|
|
322
|
+
const data = AsyncData.success(42, progress);
|
|
323
|
+
const stopped = AsyncData.stopLoading(data);
|
|
324
|
+
assert(AsyncData.isSuccess(stopped));
|
|
325
|
+
assert(stopped.value === 42);
|
|
326
|
+
assert(stopped.progress === undefined);
|
|
327
|
+
}).pipe(Effect.scoped, Effect.runPromise));
|
|
328
|
+
|
|
329
|
+
it("stopLoading from Failure with progress", () =>
|
|
330
|
+
Effect.gen(function* () {
|
|
331
|
+
const cause = Cause.fail("error");
|
|
332
|
+
const progress = { loaded: 50 };
|
|
333
|
+
const data = AsyncData.failure(cause, progress);
|
|
334
|
+
const stopped = AsyncData.stopLoading(data);
|
|
335
|
+
assert(AsyncData.isFailure(stopped));
|
|
336
|
+
assert(stopped.cause === cause);
|
|
337
|
+
assert(stopped.progress === undefined);
|
|
338
|
+
}).pipe(Effect.scoped, Effect.runPromise));
|
|
339
|
+
|
|
340
|
+
it("stopLoading from Optimistic", () =>
|
|
341
|
+
Effect.gen(function* () {
|
|
342
|
+
const previous = AsyncData.success(10, { loaded: 50 });
|
|
343
|
+
const data = AsyncData.optimistic(previous, 20);
|
|
344
|
+
const stopped = AsyncData.stopLoading(data);
|
|
345
|
+
assert(AsyncData.isOptimistic(stopped));
|
|
346
|
+
assert(stopped.value === 20);
|
|
347
|
+
assert(AsyncData.isSuccess(stopped.previous));
|
|
348
|
+
assert(stopped.previous.progress === undefined);
|
|
349
|
+
}).pipe(Effect.scoped, Effect.runPromise));
|
|
350
|
+
|
|
351
|
+
it("stopLoading from NoData", () =>
|
|
352
|
+
Effect.gen(function* () {
|
|
353
|
+
const data = AsyncData.NoData;
|
|
354
|
+
const stopped = AsyncData.stopLoading(data);
|
|
355
|
+
assert(AsyncData.isNoData(stopped));
|
|
356
|
+
}).pipe(Effect.scoped, Effect.runPromise));
|
|
357
|
+
|
|
358
|
+
it("match", () =>
|
|
359
|
+
Effect.gen(function* () {
|
|
360
|
+
const noDataResult = AsyncData.match(AsyncData.NoData, {
|
|
361
|
+
NoData: () => "no-data",
|
|
362
|
+
Loading: () => "loading",
|
|
363
|
+
Failure: () => "failure",
|
|
364
|
+
Success: () => "success",
|
|
365
|
+
Optimistic: () => "optimistic",
|
|
366
|
+
});
|
|
367
|
+
assert(noDataResult === "no-data");
|
|
368
|
+
|
|
369
|
+
const loadingResult = AsyncData.match(AsyncData.loading(), {
|
|
370
|
+
NoData: () => "no-data",
|
|
371
|
+
Loading: () => "loading",
|
|
372
|
+
Failure: () => "failure",
|
|
373
|
+
Success: () => "success",
|
|
374
|
+
Optimistic: () => "optimistic",
|
|
375
|
+
});
|
|
376
|
+
assert(loadingResult === "loading");
|
|
377
|
+
|
|
378
|
+
const successResult = AsyncData.match(AsyncData.success(42), {
|
|
379
|
+
NoData: () => "no-data",
|
|
380
|
+
Loading: () => "loading",
|
|
381
|
+
Failure: () => "failure",
|
|
382
|
+
Success: (value) => `success-${value}`,
|
|
383
|
+
Optimistic: () => "optimistic",
|
|
384
|
+
});
|
|
385
|
+
assert(successResult === "success-42");
|
|
386
|
+
|
|
387
|
+
const cause = Cause.fail("error");
|
|
388
|
+
const failureResult = AsyncData.match(AsyncData.failure(cause), {
|
|
389
|
+
NoData: () => "no-data",
|
|
390
|
+
Loading: () => "loading",
|
|
391
|
+
Failure: (cause) =>
|
|
392
|
+
`failure-${Cause.findErrorOption(cause).pipe(Option.getOrElse(() => "unknown"))}`,
|
|
393
|
+
Success: () => "success",
|
|
394
|
+
Optimistic: () => "optimistic",
|
|
395
|
+
});
|
|
396
|
+
assert(failureResult === "failure-error");
|
|
397
|
+
|
|
398
|
+
const previous = AsyncData.success(10);
|
|
399
|
+
const optimisticResult = AsyncData.match(AsyncData.optimistic(previous, 20), {
|
|
400
|
+
NoData: () => "no-data",
|
|
401
|
+
Loading: () => "loading",
|
|
402
|
+
Failure: () => "failure",
|
|
403
|
+
Success: () => "success",
|
|
404
|
+
Optimistic: (value) => `optimistic-${value}`,
|
|
405
|
+
});
|
|
406
|
+
assert(optimisticResult === "optimistic-20");
|
|
407
|
+
}).pipe(Effect.scoped, Effect.runPromise));
|
|
408
|
+
|
|
409
|
+
it("fromExit Success", () =>
|
|
410
|
+
Effect.gen(function* () {
|
|
411
|
+
const exit = Exit.succeed(42);
|
|
412
|
+
const data = AsyncData.fromExit(exit);
|
|
413
|
+
assert(AsyncData.isSuccess(data));
|
|
414
|
+
assert(data.value === 42);
|
|
415
|
+
}).pipe(Effect.scoped, Effect.runPromise));
|
|
416
|
+
|
|
417
|
+
it("fromExit Failure", () =>
|
|
418
|
+
Effect.gen(function* () {
|
|
419
|
+
const cause = Cause.fail("error");
|
|
420
|
+
const exit = Exit.failCause(cause);
|
|
421
|
+
const data = AsyncData.fromExit(exit);
|
|
422
|
+
assert(AsyncData.isFailure(data));
|
|
423
|
+
assert(data.cause === cause);
|
|
424
|
+
}).pipe(Effect.scoped, Effect.runPromise));
|
|
425
|
+
|
|
426
|
+
it("fromResult Success", () =>
|
|
427
|
+
Effect.gen(function* () {
|
|
428
|
+
const result = Result.succeed(42);
|
|
429
|
+
const data = AsyncData.fromResult(result);
|
|
430
|
+
assert(AsyncData.isSuccess(data));
|
|
431
|
+
assert(data.value === 42);
|
|
432
|
+
}).pipe(Effect.scoped, Effect.runPromise));
|
|
433
|
+
|
|
434
|
+
it("fromResult Failure", () =>
|
|
435
|
+
Effect.gen(function* () {
|
|
436
|
+
const result = Result.fail("error");
|
|
437
|
+
const data = AsyncData.fromResult(result);
|
|
438
|
+
assert(AsyncData.isFailure(data));
|
|
439
|
+
const error = Cause.findErrorOption(data.cause);
|
|
440
|
+
assert(Option.isSome(error));
|
|
441
|
+
assert(error.value === "error");
|
|
442
|
+
}).pipe(Effect.scoped, Effect.runPromise));
|
|
443
|
+
});
|
|
444
|
+
});
|