@aedge-io/grugway 0.0.0 → 0.2.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 CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![codecov](https://codecov.io/github/aedge-io/grugway/graph/badge.svg?token=9WTDQ8WOKW)](https://codecov.io/github/aedge-io/grugway)
4
4
 
5
- > Safe abstractions for fallible flows — for humans and clankers alike.
5
+ > Safe abstractions for fallible flows — for humans, their clankers and foes.
6
6
 
7
7
  This is a ~~fork~~ rework of an old, personal project
8
8
  [eitherway](https://github.com/realpha/eitherway).
package/esm/async/task.js CHANGED
@@ -1,12 +1,13 @@
1
1
  import { asInfallible, Err, Ok } from "../core/result.js";
2
- import { andEnsureTask, chainTaskFailure, chainTaskSuccess, cloneTask, inspectTaskFailure, inspectTaskSuccess, iterTask, mapTaskFailure, mapTaskSuccess, mapTaskSuccessOr, mapTaskSuccessOrElse, orEnsureTask, tapTask, unwrapTask, unwrapTaskOr, unwrapTaskOrElse, zipTask, } from "./_internal.js";
3
2
  /**
4
3
  * # Task<T, E>
5
4
  *
6
- * `Task<T, E>` is a composeable extension of `Promise<Result<T, E>>`
5
+ * `Task<T, E>` is a composeable equivalent of `Promise<Result<T, E>>`
7
6
  *
8
- * It is a `Promise` sub-class, which never rejects, but always resolves.
9
- * Either with an `Ok<T>` or an `Err<E>`
7
+ * It never rejects, but always resolves. Either with an `Ok<T>` or an `Err<E>`
8
+ *
9
+ * It implements the full interface of `Promise<Result<T, E>>` and can be used
10
+ * as a drop-in replacement if desired.
10
11
  *
11
12
  * It supports almost the same API as {@linkcode Result} and allows for
12
13
  * the same composition patterns as {@linkcode Result}
@@ -16,33 +17,35 @@ import { andEnsureTask, chainTaskFailure, chainTaskSuccess, cloneTask, inspectTa
16
17
  *
17
18
  * @category Task#Basic
18
19
  */
19
- export class Task extends Promise {
20
- constructor(executor) {
21
- super(executor);
20
+ export class Task {
21
+ #promise;
22
+ constructor(promise) {
23
+ this.#promise = promise;
22
24
  }
23
25
  /**
24
- * =======================
25
- * TASK CONSTRUCTORS
26
- * =======================
26
+ * This is done to provide drop-in parity with native Promises, as some libraries
27
+ * are (IMO needlessly) invariant over `PromiseLike` types and test for `thenability`
28
+ * via `value instanceof Promise`
27
29
  */
30
+ static {
31
+ Object.setPrototypeOf(Task.prototype, Promise.prototype);
32
+ }
28
33
  /**
29
- * Use this to create a task from a `Result<T, E>` value
30
- *
31
- * @category Task#Basic
32
- *
33
- * @example
34
- * ```typescript
35
- * import { Ok, Result, Task } from "../mod.ts";
36
- *
37
- * async function produceRes(): Promise<Result<number, TypeError>> {
38
- * return Ok(42);
39
- * }
40
- *
41
- * const task = Task.of(produceRes());
42
- * ```
34
+ * =======================
35
+ * PROMISE INTERFACE
36
+ * =======================
43
37
  */
38
+ then(onfulfilled, onrejected) {
39
+ return this.#promise.then(onfulfilled, onrejected);
40
+ }
41
+ catch(onrejected) {
42
+ return this.#promise.catch(onrejected);
43
+ }
44
+ finally(onfinally) {
45
+ return this.#promise.finally(onfinally);
46
+ }
44
47
  static of(value) {
45
- return new Task((resolve) => resolve(value));
48
+ return new Task(Promise.resolve(value));
46
49
  }
47
50
  /**
48
51
  * Use this to create a `Task` which always succeeds with a value `<T>`
@@ -51,13 +54,13 @@ export class Task extends Promise {
51
54
  *
52
55
  * @example
53
56
  * ```typescript
54
- * import { Task } from "./task.ts";
57
+ * import { Task } from "@aedge-io/grugway";
55
58
  *
56
59
  * const task: Task<number, never> = Task.succeed(42);
57
60
  * ```
58
61
  */
59
62
  static succeed(value) {
60
- return new Task((resolve) => resolve(Ok(value)));
63
+ return new Task(Promise.resolve(Ok(value)));
61
64
  }
62
65
  /**
63
66
  * Use this to create a `Task` which always fails with a value `<E>`
@@ -66,13 +69,13 @@ export class Task extends Promise {
66
69
  *
67
70
  * @example
68
71
  * ```typescript
69
- * import { Task } from "./task.ts";
72
+ * import { Task } from "@aedge-io/grugway";
70
73
  *
71
74
  * const task: Task<never, number> = Task.fail(1);
72
75
  * ```
73
76
  */
74
77
  static fail(error) {
75
- return new Task((resolve) => resolve(Err(error)));
78
+ return new Task(Promise.resolve(Err(error)));
76
79
  }
77
80
  /**
78
81
  * Use this to create a deferred `Task<T, E>` which will either succeed with
@@ -87,7 +90,7 @@ export class Task extends Promise {
87
90
  *
88
91
  * @example
89
92
  * ```typescript
90
- * import { Task } from "./task.ts";
93
+ * import { Task } from "@aedge-io/grugway";
91
94
  *
92
95
  * class TimeoutError extends Error {}
93
96
  *
@@ -106,9 +109,10 @@ export class Task extends Promise {
106
109
  */
107
110
  static deferred() {
108
111
  let resolveBinding;
109
- const task = new Task((resolve) => {
112
+ const promise = new Promise((resolve) => {
110
113
  resolveBinding = resolve;
111
114
  });
115
+ const task = new Task(promise);
112
116
  const succeed = (value) => resolveBinding(Ok(value));
113
117
  const fail = (error) => resolveBinding(Err(error));
114
118
  return { task, succeed, fail };
@@ -125,7 +129,7 @@ export class Task extends Promise {
125
129
  *
126
130
  * @example
127
131
  * ```typescript
128
- * import { Ok, Result, Task } from "../mod.ts";
132
+ * import { Ok, Result, Task } from "@aedge-io/grugway";
129
133
  *
130
134
  * async function produceRes(): Promise<Result<number, TypeError>> {
131
135
  * return Ok(42);
@@ -137,7 +141,7 @@ export class Task extends Promise {
137
141
  static from(fn) {
138
142
  const p = new Promise((resolve) => resolve(fn()))
139
143
  .catch(asInfallible);
140
- return new Task((resolve) => resolve(p));
144
+ return new Task(p);
141
145
  }
142
146
  /**
143
147
  * Use this to create a `Task<T, E>` from a `Promise<T>`.
@@ -152,7 +156,7 @@ export class Task extends Promise {
152
156
  *
153
157
  * @example
154
158
  * ```typescript
155
- * import { asInfallible, Task } from "../mod.ts";
159
+ * import { asInfallible, Task } from "@aedge-io/grugway";
156
160
  *
157
161
  * const willBeString = Promise.resolve("42");
158
162
  *
@@ -165,7 +169,7 @@ export class Task extends Promise {
165
169
  * ```
166
170
  */
167
171
  static fromPromise(promise, errorMapFn) {
168
- return Task.fromFallible(() => promise, errorMapFn);
172
+ return new Task(promise.then((v) => Ok(v), (e) => Err(errorMapFn(e))));
169
173
  }
170
174
  /**
171
175
  * Use this to construct a `Task<T, E>` from the return value of a fallible
@@ -175,7 +179,7 @@ export class Task extends Promise {
175
179
  *
176
180
  * @example
177
181
  * ```typescript
178
- * import { Task } from "./task.ts";
182
+ * import { Task } from "@aedge-io/grugway";
179
183
  *
180
184
  * async function rand(): Promise<number> {
181
185
  * throw new TypeError("Oops");
@@ -195,7 +199,7 @@ export class Task extends Promise {
195
199
  static fromFallible(fn, errorMapFn) {
196
200
  const p = new Promise((resolve) => resolve(fn()))
197
201
  .then((v) => Ok(v), (e) => Err(errorMapFn(e)));
198
- return new Task((resolve) => resolve(p));
202
+ return new Task(p);
199
203
  }
200
204
  /**
201
205
  * Use this lift a function into a `Task` context, by composing the wrapped
@@ -210,7 +214,7 @@ export class Task extends Promise {
210
214
  *
211
215
  * @example
212
216
  * ```
213
- * import { Err, Ok, Result, Task } from "../mod.ts";
217
+ * import { Err, Ok, Result, Task } from "@aedge-io/grugway";
214
218
  *
215
219
  * async function toSpecialString(s: string): Promise<string> {
216
220
  * if (s.length % 3 === 0) return s;
@@ -231,7 +235,7 @@ export class Task extends Promise {
231
235
  return function (...args) {
232
236
  const p = new Promise((resolve) => resolve(fn(...args)))
233
237
  .then((v) => ctor(v), (e) => Err(errorMapFn(e)));
234
- return new Task((resolve) => resolve(p));
238
+ return new Task(p);
235
239
  };
236
240
  }
237
241
  /**
@@ -251,26 +255,175 @@ export class Task extends Promise {
251
255
  id() {
252
256
  return this;
253
257
  }
258
+ /**
259
+ * Use this to obtain a deep clone of `Task<T, E>`
260
+ *
261
+ * Under the hood, this uses the `structuredClone` algorithm
262
+ *
263
+ * @category Task#Basic
264
+ *
265
+ * @example
266
+ * ```typescript
267
+ * import { assert } from "@std/assert";
268
+ * import { Task } from "@aedge-io/grugway";
269
+ *
270
+ * const task = Task.succeed({ a: 1 });
271
+ * const cloned = task.clone();
272
+ *
273
+ * const res = await task;
274
+ * const clonedRes = await cloned;
275
+ *
276
+ * assert(res.unwrap() !== clonedRes.unwrap())
277
+ * ```
278
+ */
254
279
  clone() {
255
- return Task.of(cloneTask(this));
280
+ return new Task(this.#promise.then((res) => res.clone()));
256
281
  }
282
+ /**
283
+ * Use this to asynchronously map the encapsulated value `<T>` to `<T2>`
284
+ *
285
+ * In case of `Err<E>`, this method short-circuits.
286
+ * See {@linkcode Task#mapErr} for the opposite case.
287
+ *
288
+ * @category Task#Basic
289
+ *
290
+ * @example
291
+ * ```typescript
292
+ * import { Task } from "@aedge-io/grugway";
293
+ *
294
+ * const task = Task.succeed(21).map((n) => n * 2);
295
+ * const res = await task; // Ok(42)
296
+ * ```
297
+ */
257
298
  map(mapFn) {
258
- return Task.of(mapTaskSuccess(this, mapFn));
299
+ return new Task(this.#promise.then(async (res) => {
300
+ if (res.isErr())
301
+ return res;
302
+ return Ok(await mapFn(res.unwrap()));
303
+ }));
259
304
  }
305
+ /**
306
+ * Same as {@linkcode Task#map} but returns the provided `orValue` asynchronously
307
+ * as a fallback in case of `Err<E>`
308
+ *
309
+ * @category Task#Intermediate
310
+ *
311
+ * @example
312
+ * ```typescript
313
+ * import { Task } from "@aedge-io/grugway";
314
+ *
315
+ * const t1 = Task.succeed(5).mapOr((n) => n * 2, 0); // Task<number, never>
316
+ * const t2 = Task.fail("x").mapOr((n) => n * 2, 0); // Task<number, never>
317
+ * ```
318
+ */
260
319
  mapOr(mapFn, orValue) {
261
- return Task.of(mapTaskSuccessOr(this, mapFn, orValue));
320
+ return new Task(this.#promise.then(async (res) => {
321
+ const mapped = res.isErr() ? await orValue : await mapFn(res.unwrap());
322
+ return Ok(mapped);
323
+ }));
262
324
  }
325
+ /**
326
+ * Same as {@linkcode Task#map} but applies `orFn` asynchronously to the
327
+ * error value in case of `Err<E>`
328
+ *
329
+ * Use this if the fallback value is expensive to produce.
330
+ *
331
+ * @category Task#Intermediate
332
+ *
333
+ * @example
334
+ * ```typescript
335
+ * import { Task } from "@aedge-io/grugway";
336
+ *
337
+ * const t1 = Task.succeed(5).mapOrElse((n) => n * 2, (e) => -1); // Ok(10)
338
+ * const t2 = Task.fail("x").mapOrElse((n) => n * 2, (e) => -1); // Ok(-1)
339
+ * ```
340
+ */
263
341
  mapOrElse(mapFn, orFn) {
264
- return Task.of(mapTaskSuccessOrElse(this, mapFn, orFn));
342
+ return new Task(this.#promise.then(async (res) => {
343
+ const mapped = res.isErr()
344
+ ? await orFn(res.unwrap())
345
+ : await mapFn(res.unwrap());
346
+ return Ok(mapped);
347
+ }));
265
348
  }
349
+ /**
350
+ * Use this to asynchronously map the encapsulated error `<E>` to `<E2>`
351
+ *
352
+ * In case of `Ok<T>`, this method short-circuits.
353
+ * See {@linkcode Task#map} for the opposite case.
354
+ *
355
+ * @category Task#Basic
356
+ *
357
+ * @example
358
+ * ```typescript
359
+ * import { Task } from "@aedge-io/grugway";
360
+ *
361
+ * const task = Task.fail(Error("oops"))
362
+ * .mapErr((e) => TypeError(e.message));
363
+ *
364
+ * const res = await task; // Err<TypeError>
365
+ * ```
366
+ */
266
367
  mapErr(mapFn) {
267
- return Task.of(mapTaskFailure(this, mapFn));
368
+ return new Task(this.#promise.then(async (res) => {
369
+ if (res.isOk())
370
+ return res;
371
+ return Err(await mapFn(res.unwrap()));
372
+ }));
268
373
  }
374
+ /**
375
+ * Use this to produce a new `Task<T2, E2>` from the encapsulated
376
+ * value `<T>`. Canonical `.flatMap()` or `.chain()` method.
377
+ *
378
+ * In case of `Err<E>`, this method short-circuits.
379
+ * See {@linkcode Task#orElse} for the opposite case.
380
+ *
381
+ * @category Task#Intermediate
382
+ *
383
+ * @example
384
+ * ```typescript
385
+ * import { Err, Ok, Task } from "@aedge-io/grugway";
386
+ *
387
+ * const safeParse = async (s: string) => {
388
+ * const n = Number(s);
389
+ * return Number.isNaN(n) ? Err(TypeError("NaN")) : Ok(n);
390
+ * };
391
+ *
392
+ * const t = Task.succeed("42").andThen(safeParse); // Task<number, TypeError>
393
+ * ```
394
+ */
269
395
  andThen(thenFn) {
270
- return Task.of(chainTaskSuccess(this, thenFn));
396
+ return new Task(this.#promise.then((res) => {
397
+ if (res.isErr())
398
+ return res;
399
+ return thenFn(res.unwrap());
400
+ }));
271
401
  }
402
+ /**
403
+ * Use this to produce a new `Task<T2, E2>` from the encapsulated
404
+ * error `<E>`. Useful for recovery or error transformation.
405
+ *
406
+ * In case of `Ok<T>`, this method short-circuits.
407
+ * See {@linkcode Task#andThen} for the opposite case.
408
+ *
409
+ * @category Task#Intermediate
410
+ *
411
+ * @example
412
+ * ```typescript
413
+ * import { Ok, Task } from "@aedge-io/grugway";
414
+ *
415
+ * const task = Task.fail(Error("oops"))
416
+ * .orElse((e) => Ok(e.message));
417
+ *
418
+ * const res = await task; // Ok<string>
419
+ * ```
420
+ */
272
421
  orElse(elseFn) {
273
- return Task.of(chainTaskFailure(this, elseFn));
422
+ return new Task(this.#promise.then((res) => {
423
+ if (res.isOk())
424
+ return res;
425
+ return elseFn(res.unwrap());
426
+ }));
274
427
  }
275
428
  /**
276
429
  * Use this to conditionally pass-through the encapsulated value `<T>`
@@ -297,7 +450,7 @@ export class Task extends Promise {
297
450
  *
298
451
  * @example
299
452
  * ```typescript
300
- * import { Task } from "./task.ts";
453
+ * import { Task } from "@aedge-io/grugway";
301
454
  *
302
455
  * function getPath(): Task<string, Error> { return Task.succeed("/home")};
303
456
  * function isReadableDir(path: string): Task<void, TypeError> { return Task.succeed(undefined) };
@@ -311,7 +464,12 @@ export class Task extends Promise {
311
464
  * ```
312
465
  */
313
466
  andEnsure(ensureFn) {
314
- return Task.of(andEnsureTask(this, ensureFn));
467
+ return new Task(this.#promise.then(async (original) => {
468
+ if (original.isErr())
469
+ return original;
470
+ const res = await ensureFn(original.unwrap());
471
+ return res.and(original);
472
+ }));
315
473
  }
316
474
  /**
317
475
  * Use this to conditionally pass-through the encapsulated value `<E>`
@@ -338,7 +496,7 @@ export class Task extends Promise {
338
496
  *
339
497
  * @example
340
498
  * ```typescript
341
- * import { Task } from "./task.ts";
499
+ * import { Task } from "@aedge-io/grugway";
342
500
  *
343
501
  * function getConfig(): Task<string, RangeError> { return Task.succeed("secret")};
344
502
  * function getFallback(err: RangeError): Task<string, Error> { return Task.succeed("default")};
@@ -352,31 +510,110 @@ export class Task extends Promise {
352
510
  * ```
353
511
  */
354
512
  orEnsure(ensureFn) {
355
- return Task.of(orEnsureTask(this, ensureFn));
513
+ return new Task(this.#promise.then(async (original) => {
514
+ if (original.isOk())
515
+ return original;
516
+ const res = await ensureFn(original.unwrap());
517
+ return res.or(original);
518
+ }));
356
519
  }
520
+ /**
521
+ * Use this to asynchronously zip the encapsulated values of two `Ok`
522
+ * instances into a new `Task`
523
+ *
524
+ * If either side is `Err`, the respective `Err` is returned.
525
+ *
526
+ * |**LHS zip RHS** |**RHS: Ok<T2>**|**RHS: Err<E2>**|
527
+ * |:--------------:|:-------------:|:--------------:|
528
+ * | **LHS: Ok<T>** | Ok<[T, T2]> | Err<E2> |
529
+ * | **LHS: Err<E>**| Err<E> | Err<E> |
530
+ *
531
+ * @category Task#Advanced
532
+ *
533
+ * @example
534
+ * ```typescript
535
+ * import { Ok, Task } from "@aedge-io/grugway";
536
+ *
537
+ * const task = Task.succeed(1).zip(Task.of(Ok("two")));
538
+ * const res = await task; // Ok([1, "two"])
539
+ * ```
540
+ */
357
541
  zip(rhs) {
358
- return Task.of(zipTask(this, rhs));
542
+ return new Task(this.#promise.then(async (res) => {
543
+ return res.zip(await rhs);
544
+ }));
359
545
  }
546
+ /**
547
+ * Use this to perform asynchronous side-effects transparently.
548
+ *
549
+ * The `tapFn` receives a deep clone of the `Result<T, E>` to ensure
550
+ * the original value cannot be mutated.
551
+ *
552
+ * @category Task#Intermediate
553
+ *
554
+ * @example
555
+ * ```typescript
556
+ * import { Task } from "@aedge-io/grugway";
557
+ *
558
+ * const task = Task.succeed(42)
559
+ * .tap((res) => console.log("got:", res.unwrap()));
560
+ * ```
561
+ */
360
562
  tap(tapFn) {
361
- return Task.of(tapTask(this, tapFn));
362
- }
363
- inspect(inspectFn) {
364
- return Task.of(inspectTaskSuccess(this, inspectFn));
365
- }
366
- inspectErr(inspectFn) {
367
- return Task.of(inspectTaskFailure(this, inspectFn));
563
+ return new Task(this.#promise.then(async (res) => {
564
+ await tapFn(res.clone());
565
+ return res;
566
+ }));
368
567
  }
369
568
  /**
370
- * @deprecated (will be removed in 1.0.0) use {@linkcode Task#andEnsure} instead
569
+ * Use this to asynchronously inspect the encapsulated value `<T>`.
570
+ *
571
+ * Mainly used for debugging and logging.
572
+ *
573
+ * In case of `Err<E>`, this method short-circuits.
574
+ * See {@linkcode Task#inspectErr} for the opposite case.
575
+ *
576
+ * @category Task#Basic
577
+ *
578
+ * @example
579
+ * ```typescript
580
+ * import { Task } from "@aedge-io/grugway";
581
+ *
582
+ * const task = Task.succeed(42)
583
+ * .inspect((n) => console.log("value:", n));
584
+ * ```
371
585
  */
372
- trip(tripFn) {
373
- return Task.of(andEnsureTask(this, tripFn));
586
+ inspect(inspectFn) {
587
+ return new Task(this.#promise.then(async (res) => {
588
+ if (res.isOk())
589
+ await inspectFn(res.unwrap());
590
+ return res;
591
+ }));
374
592
  }
375
593
  /**
376
- * @deprecated (will be removed in 1.0.0) use {@linkcode Task#orEnsure} instead
594
+ * Use this to asynchronously inspect the encapsulated error `<E>`.
595
+ *
596
+ * Mainly used for debugging and logging.
597
+ *
598
+ * In case of `Ok<T>`, this method short-circuits.
599
+ * See {@linkcode Task#inspect} for the opposite case.
600
+ *
601
+ * @category Task#Basic
602
+ *
603
+ * @example
604
+ * ```typescript
605
+ * import { Task } from "@aedge-io/grugway";
606
+ *
607
+ * const task = Task.fail(Error("oops"))
608
+ * .inspectErr((e) => console.error("error:", e.message));
609
+ * ```
377
610
  */
378
- rise(riseFn) {
379
- return Task.of(orEnsureTask(this, riseFn));
611
+ inspectErr(inspectFn) {
612
+ return new Task(this.#promise.then(async (res) => {
613
+ if (res.isErr())
614
+ await inspectFn(res.unwrap());
615
+ return res;
616
+ }));
380
617
  }
381
618
  /**
382
619
  * Use this to get the wrapped value out of an `Task<T, E>` instance
@@ -391,9 +628,8 @@ export class Task extends Promise {
391
628
  *
392
629
  * @example
393
630
  * ```typescript
394
- * import { assert } from "../core/assert.ts";
395
- * import { Result } from "../core/result.ts";
396
- * import { Task } from "./task.ts";
631
+ * import { assert } from "@std/assert";
632
+ * import { Result, Task } from "@aedge-io/grugway";
397
633
  *
398
634
  * const ok = Result(42) as Result<number, string>;
399
635
  * const task = Task.of(ok);
@@ -403,8 +639,8 @@ export class Task extends Promise {
403
639
  * assert(union === 42);
404
640
  * ```
405
641
  */
406
- unwrap() {
407
- return unwrapTask(this);
642
+ async unwrap() {
643
+ return (await this.#promise).unwrap();
408
644
  }
409
645
  /**
410
646
  * Same as {@linkcode Task#unwrap} but returns a default value in case the
@@ -414,9 +650,8 @@ export class Task extends Promise {
414
650
  *
415
651
  * @example
416
652
  * ```typescript
417
- * import { assert } from "../core/assert.ts";
418
- * import { Result } from "../core/result.ts";
419
- * import { Task } from "./task.ts";
653
+ * import { assert } from "@std/assert";
654
+ * import { Result, Task } from "@aedge-io/grugway";
420
655
  *
421
656
  * const err = Result(Error()) as Result<number, Error>;
422
657
  * const task = Task.of(err);
@@ -426,8 +661,11 @@ export class Task extends Promise {
426
661
  * assert(union === "foo");
427
662
  * ```
428
663
  */
429
- unwrapOr(orValue) {
430
- return unwrapTaskOr(this, orValue);
664
+ async unwrapOr(orValue) {
665
+ const res = await this.#promise;
666
+ if (res.isOk())
667
+ return res.unwrap();
668
+ return await orValue;
431
669
  }
432
670
  /**
433
671
  * Same as {@linkcode Task#unwrap} but returns a fallback value, which can based
@@ -437,9 +675,8 @@ export class Task extends Promise {
437
675
  *
438
676
  * @example
439
677
  * ```typescript
440
- * import { assert } from "../core/assert.ts";
441
- * import { Result } from "../core/result.ts";
442
- * import { Task } from "./task.ts";
678
+ * import { assert } from "@std/assert";
679
+ * import { Result, Task } from "@aedge-io/grugway";
443
680
  *
444
681
  * const err = Result(Error("foo")) as Result<number, Error>;
445
682
  * const task = Task.of(err);
@@ -451,8 +688,11 @@ export class Task extends Promise {
451
688
  * assert(union === "foo");
452
689
  * ```
453
690
  */
454
- unwrapOrElse(orFn) {
455
- return unwrapTaskOrElse(this, orFn);
691
+ async unwrapOrElse(orFn) {
692
+ const res = await this.#promise;
693
+ if (res.isOk())
694
+ return res.unwrap();
695
+ return await orFn(res.unwrap());
456
696
  }
457
697
  /**
458
698
  * Use this to obtain an async iterator of the encapsulated value `<T>`
@@ -463,8 +703,8 @@ export class Task extends Promise {
463
703
  *
464
704
  * @example
465
705
  * ```typescript
466
- * import { assert } from "../core/assert.ts"
467
- * import { Err, Ok, Result, Task } from "../mod.ts";
706
+ * import { assert } from "@std/assert"
707
+ * import { Err, Ok, Result, Task } from "@aedge-io/grugway";
468
708
  *
469
709
  * const success = Task.succeed(42);
470
710
  * const failure = Task.fail(Error());
@@ -498,8 +738,11 @@ export class Task extends Promise {
498
738
  * main().then(() => console.log("Done"));
499
739
  * ```
500
740
  */
501
- iter() {
502
- return iterTask(this);
741
+ async *iter() {
742
+ const res = await this.#promise;
743
+ if (res.isErr())
744
+ return;
745
+ yield res.unwrap();
503
746
  }
504
747
  /**
505
748
  * ============================
@@ -516,12 +759,12 @@ export class Task extends Promise {
516
759
  *
517
760
  * @example
518
761
  * ```typescript
519
- * import { assert } from "../core/assert.ts";
520
- * import { Task } from "./task.ts"
762
+ * import { assert } from "@std/assert";
763
+ * import { Task } from "@aedge-io/grugway"
521
764
  *
522
765
  * const tag = Task.succeed(42).toString();
523
766
  *
524
- * assert(tag === "[object aetherway.Task]");
767
+ * assert(tag === "[object grugway.Task]");
525
768
  * ```
526
769
  */
527
770
  toString() {
@@ -541,22 +784,19 @@ export class Task extends Promise {
541
784
  *
542
785
  * @example
543
786
  * ```typescript
544
- * import { assert } from "../core/assert.ts";
545
- * import { Task } from "./task.ts"
787
+ * import { assert } from "@std/assert";
788
+ * import { Task } from "@aedge-io/grugway"
546
789
  *
547
790
  * const task = Task.succeed({ a: 1, b: 2 });
548
791
  *
549
792
  * const toString = Object.prototype.toString;
550
793
  *
551
- * assert(toString.call(task) === "[object aetherway.Task]");
552
- * assert(toString.call(Task) === "[object aetherway.Task]");
794
+ * assert(toString.call(task) === "[object grugway.Task]");
795
+ * assert(toString.call(Task) === "[object grugway.Task]");
553
796
  * ```
554
797
  */
555
798
  get [Symbol.toStringTag]() {
556
- return "aetherway.Task";
557
- }
558
- static get [Symbol.toStringTag]() {
559
- return "aetherway.Task";
799
+ return "grugway.Task";
560
800
  }
561
801
  /**
562
802
  * In case of success AND that the encapsulated value `<T>` implements the