@jeengbe/prelude 0.1.2 → 0.1.4

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
@@ -1,9 +1,135 @@
1
1
  <h1 align="center">@jeengbe/prelude</h1>
2
2
  <div align="center">
3
3
 
4
+ A small, dependency-free functional programming toolkit for TypeScript.
5
+
4
6
  [![License](https://img.shields.io/npm/l/@jeengbe/prelude)](https://github.com/jeengbe/ts-packages/blob/master/packages/prelude/LICENSE)
5
7
  [![Version](https://img.shields.io/npm/v/@jeengbe/prelude)](https://www.npmjs.com/package/@jeengbe/prelude)
6
8
  [![JSR](https://jsr.io/badges/@jeengbe/prelude)](https://jsr.io/@jeengbe/prelude)
7
9
  [![Coverage](https://codecov.io/gh/jeengbe/ts-packages/branch/master/graph/badge.svg?component=prelude)](https://app.codecov.io/gh/jeengbe/ts-packages/tree/master/packages/prelude)
8
10
 
9
11
  </div>
12
+
13
+ It provides an `Either` type for representing a value that's either a success or a failure (with an async-aware `EitherP` counterpart for `Promise`-returning pipelines), and a handful of small `Maybe` helpers for working with values that may be `undefined`.
14
+
15
+ ## Installation
16
+
17
+ The package is published to [npm](https://www.npmjs.com/package/@jeengbe/prelude) and [JSR](https://jsr.io/@jeengbe/prelude) as `@jeengbe/prelude`. Versions follow Semantic Versioning.
18
+
19
+ ## Usage
20
+
21
+ ### `Either`
22
+
23
+ `Either<L, R>` is a union of `Left<L>` and `Right<R>`, conventionally used to represent a failure (`Left`) or a success (`Right`).
24
+
25
+ ```ts
26
+ import { Either } from '@jeengbe/prelude';
27
+
28
+ const ok: Either<string, number> = Either.right(42);
29
+ const err: Either<string, number> = Either.left('something went wrong');
30
+ ```
31
+
32
+ Because `Either<L, R>` is a plain union type, `isLeft()`/`isRight()` narrow it in both directions:
33
+
34
+ ```ts
35
+ declare const e: Either<string, number>;
36
+
37
+ if (e.isLeft()) {
38
+ e; // Left<string>
39
+ } else {
40
+ e; // Right<number>
41
+ }
42
+ ```
43
+
44
+ Use `map`/`leftMap`/`bimap` to transform the contained value without unwrapping it:
45
+
46
+ ```ts
47
+ Either.right(2).map((n) => n * 2); // Right(4)
48
+ Either.left('oops').leftMap((e) => e.toUpperCase()); // Left('OOPS')
49
+ ```
50
+
51
+ Use `flatMap`/`leftFlatMap` to chain further `Either`-returning operations:
52
+
53
+ ```ts
54
+ declare function parseAge(input: string): Either<string, number>;
55
+
56
+ Either.right('42').flatMap(parseAge);
57
+ ```
58
+
59
+ Use `tap`/`flatTap` to run a side effect on the right value without altering the `Either`:
60
+
61
+ ```ts
62
+ Either.right(user).tap((u) => console.log(`loaded user ${u.id}`));
63
+ ```
64
+
65
+ To get the values back out, `get()`/`getLeft()` return a `Maybe<T>` (i.e. `undefined` if this is the other side), `getOrElse` takes a fallback function for the right value, and `pair()` deconstructs the `Either` into a `[Maybe<L>, Maybe<R>]` tuple:
66
+
67
+ ```ts
68
+ const [error, value] = result.pair();
69
+ const value2 = result.getOrElse(() => defaultValue);
70
+ ```
71
+
72
+ `Either.fromMaybe` and `Either.cond` build an `Either` out of a `Maybe` or a boolean condition, respectively:
73
+
74
+ ```ts
75
+ Either.fromMaybe(maybeUser, () => 'user not found');
76
+ Either.cond(
77
+ items.length > 0,
78
+ () => 'no items',
79
+ () => items[0],
80
+ );
81
+ ```
82
+
83
+ ### `EitherP`
84
+
85
+ `EitherP<L, R>` it wraps a `PromiseLike<Either<L, R>>`: It exposes the same API as `Either`, and is itself directly awaitable.
86
+
87
+ ```ts
88
+ import { EitherP } from '@jeengbe/prelude';
89
+
90
+ declare function fetchUser(id: string): Promise<Either<string, User>>;
91
+
92
+ const name = await EitherP.fromPromise(fetchUser('1'))
93
+ .map((u) => u.name)
94
+ .getOrElse(() => 'anonymous');
95
+ ```
96
+
97
+ Every `Either` method has an `Async` counterpart (`mapAsync`, `flatMapAsync`, `tapAsync`, etc.) that accepts a function returning a `Promise` and returns an `EitherP`, letting you chain asynchronous steps without leaving the `Either` world:
98
+
99
+ ```ts
100
+ Either.right(orderId)
101
+ .flatMapAsync(async (id) =>
102
+ (await isValid(id)) ? Either.right(id) : Either.left('invalid order'),
103
+ )
104
+ .tapAsync(async (id) => audit.log(id))
105
+ .then((result) => result.get());
106
+ ```
107
+
108
+ ### `Maybe`
109
+
110
+ `Maybe<T>` is a type alias for `T | undefined`, along with a few helpers for working with values that may be missing:
111
+
112
+ - `isDefined` narrows a `Maybe<T>` to `T`.
113
+ - `mapMaybe` transforms the value if present, and passes `undefined` through otherwise.
114
+ - `flattenMaybe` collapses a `Maybe<Maybe<T>>` into a single level.
115
+ - `ifTrue`/`ifFalse` run a function conditionally, returning its result or `undefined`.
116
+ - `matchPair` pattern-matches a `[Maybe<A>, Maybe<B>]` tuple against all four presence combinations.
117
+
118
+ ```ts
119
+ import { ifTrue, isDefined, mapMaybe, matchPair } from '@jeengbe/prelude';
120
+
121
+ const upper = mapMaybe(name, (n) => n.toUpperCase());
122
+
123
+ if (isDefined(upper)) {
124
+ // upper: string
125
+ }
126
+
127
+ const warning = ifTrue(retries > 3, () => 'too many retries');
128
+
129
+ matchPair([error, value], {
130
+ neither: () => 'nothing to report',
131
+ a: (e) => `error: ${e}`,
132
+ b: (v) => `value: ${v}`,
133
+ both: (e, v) => `error ${e}, but got a partial value: ${v}`,
134
+ });
135
+ ```
package/dist/either.d.mts CHANGED
@@ -5,37 +5,59 @@ declare abstract class EitherBase<L, R> {
5
5
  * Maps the value of this Either if it is a Right, performs no operation if this is a Left.
6
6
  */
7
7
  map<R2>(fn: (t: R) => R2): Either<L, R2>;
8
+ /**
9
+ * Maps the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
10
+ */
8
11
  mapAsync<R2>(fn: (t: R) => Promise<R2>): EitherP<L, R2>;
9
12
  /**
10
13
  * Flat maps the value of this Either if it is a Left, performs no operation if this is a Right.
11
14
  */
12
15
  leftFlatMap<L2, R2>(fn: (t: L) => Either<L2, R2>): Either<L2, R | R2>;
16
+ /**
17
+ * Flat maps the value of this Either if it is a Left, performs no operation if this is a Right, asynchronously.
18
+ */
13
19
  leftFlatMapAsync<L2, R2>(fn: (t: L) => PromiseLike<Either<L2, R2>>): EitherP<L2, R | R2>;
14
20
  /**
15
21
  * Maps the value of this Either if it is a Left, performs no operation if this is a Right.
16
22
  */
17
23
  leftMap<L2>(fn: (t: L) => L2): Either<L2, R>;
24
+ /**
25
+ * Maps the value of this Either if it is a Left, performs no operation if this is a Right, asynchronously.
26
+ */
18
27
  leftMapAsync<L2>(fn: (t: L) => Promise<L2>): EitherP<L2, R>;
19
28
  /**
20
29
  * Applies the provided functions to the value of this Either, depending on whether it is a Right or a Left and returns a new Either.
21
30
  */
22
31
  bimap<L2, R2>(leftFn: (l: L) => L2, rightFn: (r: R) => R2): Either<L2, R2>;
32
+ /**
33
+ * Applies the provided functions to the value of this Either, depending on whether it is a Right or a Left and returns a new Either, asynchronously.
34
+ */
23
35
  bimapAsync<L2, R2>(leftFn: (l: L) => Promise<L2>, rightFn: (r: R) => Promise<R2>): EitherP<L2, R2>;
24
36
  /**
25
37
  * Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left.
26
38
  */
27
39
  tap(fn: (t: R) => void): Either<L, R>;
40
+ /**
41
+ * Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
42
+ */
28
43
  tapAsync(fn: (t: R) => Promise<void>): EitherP<L, R>;
29
44
  /**
30
45
  * Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left.
31
46
  * If the result of the function is a Left, it will be returned, otherwise the original Right value will be returned.
32
47
  */
33
48
  flatTap<L2>(fn: (t: R) => Either<L2, void>): Either<L | L2, R>;
49
+ /**
50
+ * Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
51
+ * If the result of the function is a Left, it will be returned, otherwise the original Right value will be returned.
52
+ */
34
53
  flatTapAsync<L2>(fn: (t: R) => PromiseLike<Either<L2, void>>): EitherP<L | L2, R>;
35
54
  /**
36
55
  * Flat maps the value of this Either if it is a Right, performs no operation if this is a Left.
37
56
  */
38
57
  flatMap<L2, R2>(fn: (t: R) => Either<L2, R2>): Either<L | L2, R2>;
58
+ /**
59
+ * Flat maps the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
60
+ */
39
61
  flatMapAsync<L2, R2>(fn: (t: R) => PromiseLike<Either<L2, R2>>): EitherP<L | L2, R2>;
40
62
  /**
41
63
  * Applies the provided functions to the value of this Either, depending on whether it is a Right or a Left and returns the result.
@@ -80,16 +102,18 @@ declare class Left<L> extends EitherBase<L, never> {
80
102
  constructor(value: L);
81
103
  fold<U1, U2>(leftFn: (l: L) => U1, _rightFn: (r: never) => U2): U1 | U2;
82
104
  getLeft(): L;
105
+ toString(): string;
106
+ get [Symbol.toStringTag](): string;
83
107
  }
84
108
  declare class Right<R> extends EitherBase<never, R> {
85
109
  private readonly value;
86
110
  constructor(value: R);
87
111
  fold<U1, U2>(_leftFn: (l: never) => U1, rightFn: (r: R) => U2): U1 | U2;
88
112
  get(): R;
113
+ toString(): string;
114
+ get [Symbol.toStringTag](): string;
89
115
  }
90
116
  /**
91
- * Mimics the [Cats Either[L, R]](https://typelevel.org/cats/datatypes/either.html) type.
92
- *
93
117
  * Either<L, R> is a union of Left<L> and Right<R>, so narrowing works in both directions:
94
118
  *
95
119
  * ```ts
@@ -112,11 +136,22 @@ declare namespace Either {
112
136
  * Creates a new Right Either with the provided value.
113
137
  */
114
138
  function right<R>(value: R): Either<never, R>;
139
+ /**
140
+ * Creates a Right Either from a Maybe if it is defined, or a Left Either from the result of the provided function otherwise.
141
+ */
115
142
  function fromMaybe<L, R>(value: Maybe<R>, leftValue: () => L): Either<L, R>;
143
+ /**
144
+ * Creates a Right Either from the result of `rightFn` if `bool` is true, or a Left Either from the result of `leftFn` otherwise.
145
+ */
116
146
  function cond<L, R>(bool: boolean, leftFn: () => L, rightFn: () => R): Either<L, R>;
117
147
  }
118
148
  /**
119
- * Mimics the [Cats EitherT[Future, L, R]](https://typelevel.org/cats/datatypes/eithert.html) type.
149
+ * Asynchronous version of @{link Either}, allowing for asynchronous operations on the values of the Either.
150
+ *
151
+ * ```ts
152
+ * declare const e: EitherP<string, number>;
153
+ *
154
+ * const result = await e.get(); // result is of type Maybe<number>
120
155
  */
121
156
  declare class EitherP<L, R> implements PromiseLike<Either<L, R>> {
122
157
  private readonly value;
@@ -125,37 +160,59 @@ declare class EitherP<L, R> implements PromiseLike<Either<L, R>> {
125
160
  * Maps the value of this Either if it is a Right, performs no operation if this is a Left.
126
161
  */
127
162
  map<R2>(fn: (t: R) => R2): EitherP<L, R2>;
163
+ /**
164
+ * Maps the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
165
+ */
128
166
  mapAsync<R2>(fn: (t: R) => Promise<R2>): EitherP<L, R2>;
129
167
  /**
130
168
  * Maps the value of this Either if it is a Left, performs no operation if this is a Right.
131
169
  */
132
170
  leftMap<L2>(fn: (t: L) => L2): EitherP<L2, R>;
171
+ /**
172
+ * Maps the value of this Either if it is a Left, performs no operation if this is a Right, asynchronously.
173
+ */
133
174
  leftMapAsync<L2>(fn: (t: L) => Promise<L2>): EitherP<L2, R>;
134
175
  /**
135
176
  * Flat maps the value of this Either if it is a Left, performs no operation if this is a Right.
136
177
  */
137
178
  leftFlatMap<L2, R2>(fn: (t: L) => Either<L2, R2>): EitherP<L2, R | R2>;
179
+ /**
180
+ * Flat maps the value of this Either if it is a Left, performs no operation if this is a Right, asynchronously.
181
+ */
138
182
  leftFlatMapAsync<L2, R2>(fn: (t: L) => PromiseLike<Either<L2, R2>>): EitherP<L2, R | R2>;
139
183
  /**
140
184
  * Applies the provided functions to the value of this Either, depending on whether it is a Right or a Left and returns a new Either.
141
185
  */
142
186
  bimap<L2, R2>(leftFn: (l: L) => L2, rightFn: (r: R) => R2): EitherP<L2, R2>;
187
+ /**
188
+ * Applies the provided functions to the value of this Either, depending on whether it is a Right or a Left and returns a new Either, asynchronously.
189
+ */
143
190
  bimapAsync<L2, R2>(leftFn: (l: L) => Promise<L2>, rightFn: (r: R) => Promise<R2>): EitherP<L2, R2>;
144
191
  /**
145
192
  * Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left.
146
193
  */
147
194
  tap(fn: (t: R) => void): EitherP<L, R>;
195
+ /**
196
+ * Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
197
+ */
148
198
  tapAsync(fn: (t: R) => Promise<void>): EitherP<L, R>;
149
199
  /**
150
200
  * Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left.
151
201
  * If the result of the function is a Left, it will be returned, otherwise the original Right value will be returned.
152
202
  */
153
203
  flatTap<L2>(fn: (t: R) => Either<L2, void>): EitherP<L | L2, R>;
204
+ /**
205
+ * Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
206
+ * If the result of the function is a Left, it will be returned, otherwise the original Right value will be returned.
207
+ */
154
208
  flatTapAsync<L2>(fn: (t: R) => PromiseLike<Either<L2, void>>): EitherP<L | L2, R>;
155
209
  /**
156
210
  * Flat maps the value of this Either if it is a Right, performs no operation if this is a Left.
157
211
  */
158
212
  flatMap<L2, R2>(fn: (t: R) => Either<L2, R2>): EitherP<L | L2, R2>;
213
+ /**
214
+ * Flat maps the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
215
+ */
159
216
  flatMapAsync<L2, R2>(fn: (t: R) => PromiseLike<Either<L2, R2>>): EitherP<L | L2, R2>;
160
217
  /**
161
218
  * Applies the provided functions to the value of this Either, depending on whether it is a Right or a Left and returns the result.
@@ -202,15 +259,23 @@ declare class EitherP<L, R> implements PromiseLike<Either<L, R>> {
202
259
  * Creates a new Right EitherP with the provided value.
203
260
  */
204
261
  static right<R>(value: Promise<R>): EitherP<never, R>;
262
+ /**
263
+ * Creates a Right EitherP from a Promise of a Maybe if it resolves to a defined value, or a Left EitherP from the result of the provided function otherwise.
264
+ */
205
265
  static fromMaybe<L, R>(value: Promise<Maybe<R>>, leftValue: () => Promise<L>): EitherP<L, R>;
206
266
  /**
207
- * @deprecated
267
+ * Creates a new EitherP from a Promise of an Either.
208
268
  */
209
- static fromEither<L, R>(either: PromiseLike<Either<L, R>>): EitherP<L, R>;
210
269
  static fromPromise<L, R>(either: PromiseLike<Either<L, R>>): EitherP<L, R>;
270
+ /**
271
+ * Creates a new Right EitherP if the provided Promise resolves to true, or a new Left EitherP otherwise.
272
+ */
211
273
  static cond<L, R>(bool: Promise<boolean>, leftFn: () => Promise<L>, rightFn: () => Promise<R>): EitherP<L, R>;
274
+ /**
275
+ * Resolves this EitherP to its underlying Either, allowing `await` usage on EitherP instances.
276
+ */
212
277
  then<U>(onfulfilled?: (value: Either<L, R>) => U | PromiseLike<U>): PromiseLike<U>;
213
278
  }
214
279
  //#endregion
215
- export { Either, EitherP, Left, Right };
280
+ export { Either, EitherBase, EitherP, Left, Right };
216
281
  //# sourceMappingURL=either.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"either.d.mts","names":[],"sources":["../src/either.ts"],"mappings":"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"}
1
+ {"version":3,"file":"either.d.mts","names":[],"sources":["../src/either.ts"],"mappings":";;uBASsB,WAAW,GAAG;;;;EAIlC,IAAI,IAAI,KAAK,GAAG,MAAM,KAAK,OAAO,GAAG;;;;EAOrC,SAAS,IAAI,KAAK,GAAG,MAAM,QAAQ,MAAM,QAAQ,GAAG;;;;EAOpD,YAAY,IAAI,IAAI,KAAK,GAAG,MAAM,OAAO,IAAI,MAAM,OAAO,IAAI,IAAI;;;;EAUlE,iBAAiB,IAAI,IAAI,KAAK,GAAG,MAAM,YAAY,OAAO,IAAI,OAAO,QAAQ,IAAI,IAAI;;;;EAOrF,QAAQ,IAAI,KAAK,GAAG,MAAM,KAAK,OAAO,IAAI;;;;EAU1C,aAAa,IAAI,KAAK,GAAG,MAAM,QAAQ,MAAM,QAAQ,IAAI;;;;EAOzD,MAAM,IAAI,IAAI,SAAS,GAAG,MAAM,IAAI,UAAU,GAAG,MAAM,KAAK,OAAO,IAAI;;;;EAUvE,WAAW,IAAI,IACb,SAAS,GAAG,MAAM,QAAQ,KAC1B,UAAU,GAAG,MAAM,QAAQ,MAC1B,QAAQ,IAAI;;;;EAOf,IAAI,KAAK,GAAG,aAAa,OAAO,GAAG;;;;EAUnC,SAAS,KAAK,GAAG,MAAM,gBAAgB,QAAQ,GAAG;;;;;EAQlD,QAAQ,IAAI,KAAK,GAAG,MAAM,OAAO,YAAY,OAAO,IAAI,IAAI;;;;;EAQ5D,aAAa,IAAI,KAAK,GAAG,MAAM,YAAY,OAAO,aAAa,QAAQ,IAAI,IAAI;;;;EAO/E,QAAQ,IAAI,IAAI,KAAK,GAAG,MAAM,OAAO,IAAI,MAAM,OAAO,IAAI,IAAI;;;;EAU9D,aAAa,IAAI,IAAI,KAAK,GAAG,MAAM,YAAY,OAAO,IAAI,OAAO,QAAQ,IAAI,IAAI;;;;WAOxE,KAAK,IAAI,IAAI,SAAS,GAAG,MAAM,IAAI,UAAU,GAAG,MAAM,KAAK,KAAK;;;;;;;;;;;;;EAczE,SAAS,MAAM,IAAI,MAAM;;;;EAOzB,mBAAmB,MAAM;;;;EAUzB,kBAAkB,KAAK;;;;EAUvB,OAAO,MAAM;;;;EAQb,WAAW,MAAM;;;;EAQjB,UAAU,GAAG,eAAe,GAAG,MAAM,IAAI,IAAI;;cAalC,KAAK,WAAW,WAAW;mBACT;EAA7B,YAA6B,OAAO;EAIpC,KAAK,IAAI,IAAI,SAAS,GAAG,MAAM,IAAI,WAAW,aAAa,KAAK,KAAK;EAI5D,WAAW;EAIX;OAIJ,OAAO;;cAKD,MAAM,WAAW,kBAAkB;mBACjB;EAA7B,YAA6B,OAAO;EAIpC,KAAK,IAAI,IAAI,UAAU,aAAa,IAAI,UAAU,GAAG,MAAM,KAAK,KAAK;EAI5D,OAAO;EAIP;OAIJ,OAAO;;;;;;;;;;;;;;;KAkBF,OAAO,GAAG,KAAK,KAAK,KAAK,MAAM;kBAE1B;;;;WAIC,KAAK,GAAG,OAAO,IAAI,OAAO;;;;WAO1B,MAAM,GAAG,OAAO,IAAI,cAAc;;;;WAOlC,UAAU,GAAG,GAAG,OAAO,MAAM,IAAI,iBAAiB,IAAI,OAAO,GAAG;;;;WAOhE,KAAK,GAAG,GAAG,eAAe,cAAc,GAAG,eAAe,IAAI,OAAO,GAAG;;;;;;;;;;cAa7E,QAAQ,GAAG,cAAc,YAAY,OAAO,GAAG;mBACrB;UAA9B;;;;EAKP,IAAI,IAAI,KAAK,GAAG,MAAM,KAAK,QAAQ,GAAG;;;;EAOtC,SAAS,IAAI,KAAK,GAAG,MAAM,QAAQ,MAAM,QAAQ,GAAG;;;;EAOpD,QAAQ,IAAI,KAAK,GAAG,MAAM,KAAK,QAAQ,IAAI;;;;EAO3C,aAAa,IAAI,KAAK,GAAG,MAAM,QAAQ,MAAM,QAAQ,IAAI;;;;EAezD,YAAY,IAAI,IAAI,KAAK,GAAG,MAAM,OAAO,IAAI,MAAM,QAAQ,IAAI,IAAI;;;;EAOnE,iBAAiB,IAAI,IAAI,KAAK,GAAG,MAAM,YAAY,OAAO,IAAI,OAAO,QAAQ,IAAI,IAAI;;;;EAerF,MAAM,IAAI,IAAI,SAAS,GAAG,MAAM,IAAI,UAAU,GAAG,MAAM,KAAK,QAAQ,IAAI;;;;EAOxE,WAAW,IAAI,IACb,SAAS,GAAG,MAAM,QAAQ,KAC1B,UAAU,GAAG,MAAM,QAAQ,MAC1B,QAAQ,IAAI;;;;EAef,IAAI,KAAK,GAAG,aAAa,QAAQ,GAAG;;;;EAOpC,SAAS,KAAK,GAAG,MAAM,gBAAgB,QAAQ,GAAG;;;;;EAWlD,QAAQ,IAAI,KAAK,GAAG,MAAM,OAAO,YAAY,QAAQ,IAAI,IAAI;;;;;EAQ7D,aAAa,IAAI,KAAK,GAAG,MAAM,YAAY,OAAO,aAAa,QAAQ,IAAI,IAAI;;;;EAO/E,QAAQ,IAAI,IAAI,KAAK,GAAG,MAAM,OAAO,IAAI,MAAM,QAAQ,IAAI,IAAI;;;;EAO/D,aAAa,IAAI,IAAI,KAAK,GAAG,MAAM,YAAY,OAAO,IAAI,OAAO,QAAQ,IAAI,IAAI;;;;EAc3E,KAAK,IAAI,IAAI,SAAS,GAAG,MAAM,IAAI,UAAU,GAAG,MAAM,KAAK,QAAQ,KAAK;;;;;;;;;;;;;EAgBxE,QAAQ,SAAS,MAAM,IAAI,MAAM;;;;EAOjC,WAAW;;;;EAOX,UAAU;;;;EAOV,OAAO,QAAQ,MAAM;;;;EAOrB,WAAW,QAAQ,MAAM;;;;EAOzB,UAAU,GAAG,eAAe,GAAG,MAAM,IAAI,QAAQ,IAAI;;;;SAOpD,KAAK,GAAG,OAAO,QAAQ,KAAK,QAAQ;;;;SAOpC,MAAM,GAAG,OAAO,QAAQ,KAAK,eAAe;;;;SAO5C,UAAU,GAAG,GAAG,OAAO,QAAQ,MAAM,KAAK,iBAAiB,QAAQ,KAAK,QAAQ,GAAG;;;;SASnF,YAAY,GAAG,GAAG,QAAQ,YAAY,OAAO,GAAG,MAAM,QAAQ,GAAG;;;;SAOjE,KAAK,GAAG,GACb,MAAM,kBACN,cAAc,QAAQ,IACtB,eAAe,QAAQ,KACtB,QAAQ,GAAG;;;;EAUd,KAAK,GAAG,eAAe,OAAO,OAAO,GAAG,OAAO,IAAI,YAAY,KAAK,YAAY"}
package/dist/either.mjs CHANGED
@@ -8,6 +8,9 @@ var EitherBase = class {
8
8
  map(fn) {
9
9
  return this.flatMap((value) => Either.right(fn(value)));
10
10
  }
11
+ /**
12
+ * Maps the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
13
+ */
11
14
  mapAsync(fn) {
12
15
  return EitherP.fromPromise(toEitherPromise(this)).mapAsync(fn);
13
16
  }
@@ -17,6 +20,9 @@ var EitherBase = class {
17
20
  leftFlatMap(fn) {
18
21
  return this.fold((l) => fn(l), (r) => Either.right(r));
19
22
  }
23
+ /**
24
+ * Flat maps the value of this Either if it is a Left, performs no operation if this is a Right, asynchronously.
25
+ */
20
26
  leftFlatMapAsync(fn) {
21
27
  return EitherP.fromPromise(toEitherPromise(this)).leftFlatMapAsync(fn);
22
28
  }
@@ -26,6 +32,9 @@ var EitherBase = class {
26
32
  leftMap(fn) {
27
33
  return this.fold((l) => Either.left(fn(l)), (r) => Either.right(r));
28
34
  }
35
+ /**
36
+ * Maps the value of this Either if it is a Left, performs no operation if this is a Right, asynchronously.
37
+ */
29
38
  leftMapAsync(fn) {
30
39
  return EitherP.fromPromise(toEitherPromise(this)).leftMapAsync(fn);
31
40
  }
@@ -35,6 +44,9 @@ var EitherBase = class {
35
44
  bimap(leftFn, rightFn) {
36
45
  return this.fold((l) => Either.left(leftFn(l)), (r) => Either.right(rightFn(r)));
37
46
  }
47
+ /**
48
+ * Applies the provided functions to the value of this Either, depending on whether it is a Right or a Left and returns a new Either, asynchronously.
49
+ */
38
50
  bimapAsync(leftFn, rightFn) {
39
51
  return EitherP.fromPromise(toEitherPromise(this)).bimapAsync(leftFn, rightFn);
40
52
  }
@@ -47,6 +59,9 @@ var EitherBase = class {
47
59
  return Either.right(value);
48
60
  });
49
61
  }
62
+ /**
63
+ * Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
64
+ */
50
65
  tapAsync(fn) {
51
66
  return EitherP.fromPromise(toEitherPromise(this)).tapAsync(fn);
52
67
  }
@@ -57,6 +72,10 @@ var EitherBase = class {
57
72
  flatTap(fn) {
58
73
  return this.flatMap((value) => fn(value).map(() => value));
59
74
  }
75
+ /**
76
+ * Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
77
+ * If the result of the function is a Left, it will be returned, otherwise the original Right value will be returned.
78
+ */
60
79
  flatTapAsync(fn) {
61
80
  return EitherP.fromPromise(toEitherPromise(this)).flatTapAsync(fn);
62
81
  }
@@ -66,6 +85,9 @@ var EitherBase = class {
66
85
  flatMap(fn) {
67
86
  return this.fold((l) => Either.left(l), (r) => fn(r));
68
87
  }
88
+ /**
89
+ * Flat maps the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
90
+ */
69
91
  flatMapAsync(fn) {
70
92
  return EitherP.fromPromise(toEitherPromise(this)).flatMapAsync(fn);
71
93
  }
@@ -99,15 +121,11 @@ var EitherBase = class {
99
121
  /**
100
122
  * Gets the right value if this is a Right or undefined if it's a Left.
101
123
  */
102
- get() {
103
- return this.fold(() => void 0, (r) => r);
104
- }
124
+ get() {}
105
125
  /**
106
126
  * Returns the left value if this is a Left or undefined if it's a Right.
107
127
  */
108
- getLeft() {
109
- return this.fold((l) => l, () => void 0);
110
- }
128
+ getLeft() {}
111
129
  /**
112
130
  * Gets the right value if this is a Right or the result of the provided function if it's a Left.
113
131
  */
@@ -130,6 +148,12 @@ var Left = class extends EitherBase {
130
148
  getLeft() {
131
149
  return this.value;
132
150
  }
151
+ toString() {
152
+ return `Left(${String(this.value)})`;
153
+ }
154
+ get [Symbol.toStringTag]() {
155
+ return "Left";
156
+ }
133
157
  };
134
158
  var Right = class extends EitherBase {
135
159
  value;
@@ -143,6 +167,12 @@ var Right = class extends EitherBase {
143
167
  get() {
144
168
  return this.value;
145
169
  }
170
+ toString() {
171
+ return `Right(${String(this.value)})`;
172
+ }
173
+ get [Symbol.toStringTag]() {
174
+ return "Right";
175
+ }
146
176
  };
147
177
  let Either;
148
178
  (function(_Either) {
@@ -164,7 +194,12 @@ let Either;
164
194
  _Either.cond = cond;
165
195
  })(Either || (Either = {}));
166
196
  /**
167
- * Mimics the [Cats EitherT[Future, L, R]](https://typelevel.org/cats/datatypes/eithert.html) type.
197
+ * Asynchronous version of @{link Either}, allowing for asynchronous operations on the values of the Either.
198
+ *
199
+ * ```ts
200
+ * declare const e: EitherP<string, number>;
201
+ *
202
+ * const result = await e.get(); // result is of type Maybe<number>
168
203
  */
169
204
  var EitherP = class EitherP {
170
205
  value;
@@ -177,6 +212,9 @@ var EitherP = class EitherP {
177
212
  map(fn) {
178
213
  return new EitherP(this.value.then((e) => e.map(fn)));
179
214
  }
215
+ /**
216
+ * Maps the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
217
+ */
180
218
  mapAsync(fn) {
181
219
  return this.flatMapAsync(async (value) => Either.right(await fn(value)));
182
220
  }
@@ -186,6 +224,9 @@ var EitherP = class EitherP {
186
224
  leftMap(fn) {
187
225
  return new EitherP(this.value.then((e) => e.leftMap(fn)));
188
226
  }
227
+ /**
228
+ * Maps the value of this Either if it is a Left, performs no operation if this is a Right, asynchronously.
229
+ */
189
230
  leftMapAsync(fn) {
190
231
  return new EitherP(this.value.then(async (e) => await e.fold(async (l) => Either.left(await fn(l)), async (r) => Either.right(r))));
191
232
  }
@@ -195,6 +236,9 @@ var EitherP = class EitherP {
195
236
  leftFlatMap(fn) {
196
237
  return new EitherP(this.value.then((e) => e.leftFlatMap(fn)));
197
238
  }
239
+ /**
240
+ * Flat maps the value of this Either if it is a Left, performs no operation if this is a Right, asynchronously.
241
+ */
198
242
  leftFlatMapAsync(fn) {
199
243
  return new EitherP(this.value.then(async (e) => await e.fold(async (left) => await fn(left), async (right) => Either.right(right))));
200
244
  }
@@ -204,6 +248,9 @@ var EitherP = class EitherP {
204
248
  bimap(leftFn, rightFn) {
205
249
  return new EitherP(this.value.then((e) => e.bimap(leftFn, rightFn)));
206
250
  }
251
+ /**
252
+ * Applies the provided functions to the value of this Either, depending on whether it is a Right or a Left and returns a new Either, asynchronously.
253
+ */
207
254
  bimapAsync(leftFn, rightFn) {
208
255
  return new EitherP(this.value.then(async (e) => await e.fold(async (l) => Either.left(await leftFn(l)), async (r) => Either.right(await rightFn(r)))));
209
256
  }
@@ -213,6 +260,9 @@ var EitherP = class EitherP {
213
260
  tap(fn) {
214
261
  return new EitherP(this.value.then((e) => e.tap(fn)));
215
262
  }
263
+ /**
264
+ * Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
265
+ */
216
266
  tapAsync(fn) {
217
267
  return this.flatMapAsync(async (value) => {
218
268
  await fn(value);
@@ -226,6 +276,10 @@ var EitherP = class EitherP {
226
276
  flatTap(fn) {
227
277
  return new EitherP(this.value.then((e) => e.flatTap(fn)));
228
278
  }
279
+ /**
280
+ * Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
281
+ * If the result of the function is a Left, it will be returned, otherwise the original Right value will be returned.
282
+ */
229
283
  flatTapAsync(fn) {
230
284
  return this.flatMapAsync(async (value) => (await fn(value)).map(() => value));
231
285
  }
@@ -235,6 +289,9 @@ var EitherP = class EitherP {
235
289
  flatMap(fn) {
236
290
  return new EitherP(this.value.then((e) => e.flatMap(fn)));
237
291
  }
292
+ /**
293
+ * Flat maps the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
294
+ */
238
295
  flatMapAsync(fn) {
239
296
  return new EitherP(this.value.then((e) => e.fold(async (left) => Either.left(left), (right) => fn(right))));
240
297
  }
@@ -301,26 +358,32 @@ var EitherP = class EitherP {
301
358
  static right(value) {
302
359
  return new EitherP(value.then((v) => Either.right(v)));
303
360
  }
361
+ /**
362
+ * Creates a Right EitherP from a Promise of a Maybe if it resolves to a defined value, or a Left EitherP from the result of the provided function otherwise.
363
+ */
304
364
  static fromMaybe(value, leftValue) {
305
365
  return new EitherP(value.then(async (v) => isDefined(v) ? Either.right(v) : Either.left(await leftValue())));
306
366
  }
307
367
  /**
308
- * @deprecated
368
+ * Creates a new EitherP from a Promise of an Either.
309
369
  */
310
- static fromEither(either) {
311
- return new EitherP(either);
312
- }
313
370
  static fromPromise(either) {
314
371
  return new EitherP(either);
315
372
  }
373
+ /**
374
+ * Creates a new Right EitherP if the provided Promise resolves to true, or a new Left EitherP otherwise.
375
+ */
316
376
  static cond(bool, leftFn, rightFn) {
317
377
  return new EitherP(bool.then(async (b) => b ? Either.right(await rightFn()) : Either.left(await leftFn())));
318
378
  }
379
+ /**
380
+ * Resolves this EitherP to its underlying Either, allowing `await` usage on EitherP instances.
381
+ */
319
382
  then(onfulfilled) {
320
383
  return this.value.then(onfulfilled);
321
384
  }
322
385
  };
323
386
 
324
387
  //#endregion
325
- export { Either, EitherP, Left, Right };
388
+ export { Either, EitherBase, EitherP, Left, Right };
326
389
  //# sourceMappingURL=either.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"either.mjs","names":[],"sources":["../src/either.ts"],"sourcesContent":["import type { Maybe } from './maybe.js';\nimport { isDefined } from './maybe.js';\n\n// Note that xxxAsync implementations in Either all look like:\n// EitherP.fromPromise(toEitherPromise(this)).xxxAsync(...)\n//\n// And conversely, xxx implementations in EitherP all look like:\n// new EitherP(this.value.then(e => e.xxx(...)))\n\nabstract class EitherBase<L, R> {\n /**\n * Maps the value of this Either if it is a Right, performs no operation if this is a Left.\n */\n map<R2>(fn: (t: R) => R2): Either<L, R2> {\n return this.flatMap((value) => Either.right(fn(value)));\n }\n\n mapAsync<R2>(fn: (t: R) => Promise<R2>): EitherP<L, R2> {\n return EitherP.fromPromise(toEitherPromise(this)).mapAsync(fn);\n }\n\n /**\n * Flat maps the value of this Either if it is a Left, performs no operation if this is a Right.\n */\n leftFlatMap<L2, R2>(fn: (t: L) => Either<L2, R2>): Either<L2, R | R2> {\n return this.fold(\n (l) => fn(l),\n (r) => Either.right(r),\n );\n }\n\n leftFlatMapAsync<L2, R2>(fn: (t: L) => PromiseLike<Either<L2, R2>>): EitherP<L2, R | R2> {\n return EitherP.fromPromise(toEitherPromise(this)).leftFlatMapAsync(fn);\n }\n\n /**\n * Maps the value of this Either if it is a Left, performs no operation if this is a Right.\n */\n leftMap<L2>(fn: (t: L) => L2): Either<L2, R> {\n return this.fold(\n (l) => Either.left(fn(l)),\n (r) => Either.right(r),\n );\n }\n\n leftMapAsync<L2>(fn: (t: L) => Promise<L2>): EitherP<L2, R> {\n return EitherP.fromPromise(toEitherPromise(this)).leftMapAsync(fn);\n }\n\n /**\n * Applies the provided functions to the value of this Either, depending on whether it is a Right or a Left and returns a new Either.\n */\n bimap<L2, R2>(leftFn: (l: L) => L2, rightFn: (r: R) => R2): Either<L2, R2> {\n return this.fold(\n (l) => Either.left(leftFn(l)),\n (r) => Either.right(rightFn(r)),\n );\n }\n\n bimapAsync<L2, R2>(\n leftFn: (l: L) => Promise<L2>,\n rightFn: (r: R) => Promise<R2>,\n ): EitherP<L2, R2> {\n return EitherP.fromPromise(toEitherPromise(this)).bimapAsync(leftFn, rightFn);\n }\n\n /**\n * Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left.\n */\n tap(fn: (t: R) => void): Either<L, R> {\n return this.flatMap((value) => {\n fn(value);\n return Either.right(value);\n });\n }\n\n tapAsync(fn: (t: R) => Promise<void>): EitherP<L, R> {\n return EitherP.fromPromise(toEitherPromise(this)).tapAsync(fn);\n }\n\n /**\n * Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left.\n * If the result of the function is a Left, it will be returned, otherwise the original Right value will be returned.\n */\n flatTap<L2>(fn: (t: R) => Either<L2, void>): Either<L | L2, R> {\n return this.flatMap((value) => fn(value).map(() => value));\n }\n\n flatTapAsync<L2>(fn: (t: R) => PromiseLike<Either<L2, void>>): EitherP<L | L2, R> {\n return EitherP.fromPromise(toEitherPromise(this)).flatTapAsync(fn);\n }\n\n /**\n * Flat maps the value of this Either if it is a Right, performs no operation if this is a Left.\n */\n flatMap<L2, R2>(fn: (t: R) => Either<L2, R2>): Either<L | L2, R2> {\n return this.fold(\n (l) => Either.left(l),\n (r) => fn(r),\n );\n }\n\n flatMapAsync<L2, R2>(fn: (t: R) => PromiseLike<Either<L2, R2>>): EitherP<L | L2, R2> {\n return EitherP.fromPromise(toEitherPromise(this)).flatMapAsync(fn);\n }\n\n /**\n * Applies the provided functions to the value of this Either, depending on whether it is a Right or a Left and returns the result.\n */\n abstract fold<U1, U2>(leftFn: (l: L) => U1, rightFn: (r: R) => U2): U1 | U2;\n\n /**\n * Allows to deconstruct the Either using:\n *\n * @example\n *\n * ```ts\n * declare const e: Either<string, number>;\n *\n * const [left, right] = e.pair();\n * ```\n *\n */\n pair(): [Maybe<L>, Maybe<R>] {\n return [this.getLeft(), this.get()];\n }\n\n /**\n * Returns true if this Either is a Right, false otherwise.\n */\n isRight(): this is Right<R> {\n return this.fold(\n () => false,\n () => true,\n );\n }\n\n /**\n * Returns true if this Either is a Left, false otherwise.\n */\n isLeft(): this is Left<L> {\n return this.fold(\n () => true,\n () => false,\n );\n }\n\n /**\n * Gets the right value if this is a Right or undefined if it's a Left.\n */\n get(): Maybe<R> {\n return this.fold(\n () => undefined,\n (r) => r,\n );\n }\n\n /**\n * Returns the left value if this is a Left or undefined if it's a Right.\n */\n getLeft(): Maybe<L> {\n return this.fold(\n (l) => l,\n () => undefined,\n );\n }\n\n /**\n * Gets the right value if this is a Right or the result of the provided function if it's a Left.\n */\n getOrElse<T>(defaultValue: (l: L) => T): R | T {\n return this.fold(\n (l) => defaultValue(l),\n (r) => r,\n );\n }\n}\n\n// EitherBase is abstract with only Left/Right as concrete subclasses; the cast is always valid.\nfunction toEitherPromise<L, R>(e: EitherBase<L, R>): Promise<Either<L, R>> {\n return Promise.resolve(e as unknown as Either<L, R>);\n}\n\nexport class Left<L> extends EitherBase<L, never> {\n constructor(private readonly value: L) {\n super();\n }\n\n fold<U1, U2>(leftFn: (l: L) => U1, _rightFn: (r: never) => U2): U1 | U2 {\n return leftFn(this.value);\n }\n\n override getLeft(): L {\n return this.value;\n }\n}\n\nexport class Right<R> extends EitherBase<never, R> {\n constructor(private readonly value: R) {\n super();\n }\n\n fold<U1, U2>(_leftFn: (l: never) => U1, rightFn: (r: R) => U2): U1 | U2 {\n return rightFn(this.value);\n }\n\n override get(): R {\n return this.value;\n }\n}\n\n/**\n * Mimics the [Cats Either[L, R]](https://typelevel.org/cats/datatypes/either.html) type.\n *\n * Either<L, R> is a union of Left<L> and Right<R>, so narrowing works in both directions:\n *\n * ```ts\n * declare const e: Either<string, number>;\n *\n * if (e.isLeft()) {\n * e; // Left<string>\n * } else {\n * e; // Right<number>\n * }\n * ```\n */\nexport type Either<L, R> = Left<L> | Right<R>;\n\nexport namespace Either {\n /**\n * Creates a new Left Either with the provided value.\n */\n export function left<L>(value: L): Either<L, never> {\n return new Left(value);\n }\n\n /**\n * Creates a new Right Either with the provided value.\n */\n export function right<R>(value: R): Either<never, R> {\n return new Right(value);\n }\n\n export function fromMaybe<L, R>(value: Maybe<R>, leftValue: () => L): Either<L, R> {\n return isDefined(value) ? Either.right(value) : Either.left(leftValue());\n }\n\n export function cond<L, R>(bool: boolean, leftFn: () => L, rightFn: () => R): Either<L, R> {\n return bool ? Either.right(rightFn()) : Either.left(leftFn());\n }\n}\n\n/**\n * Mimics the [Cats EitherT[Future, L, R]](https://typelevel.org/cats/datatypes/eithert.html) type.\n */\nexport class EitherP<L, R> implements PromiseLike<Either<L, R>> {\n private constructor(private readonly value: PromiseLike<Either<L, R>>) {}\n\n /**\n * Maps the value of this Either if it is a Right, performs no operation if this is a Left.\n */\n map<R2>(fn: (t: R) => R2): EitherP<L, R2> {\n return new EitherP(this.value.then((e) => e.map(fn)));\n }\n\n mapAsync<R2>(fn: (t: R) => Promise<R2>): EitherP<L, R2> {\n return this.flatMapAsync(async (value) => Either.right(await fn(value)));\n }\n\n /**\n * Maps the value of this Either if it is a Left, performs no operation if this is a Right.\n */\n leftMap<L2>(fn: (t: L) => L2): EitherP<L2, R> {\n return new EitherP(this.value.then((e) => e.leftMap(fn)));\n }\n\n leftMapAsync<L2>(fn: (t: L) => Promise<L2>): EitherP<L2, R> {\n return new EitherP(\n this.value.then(\n async (e) =>\n await e.fold(\n async (l) => Either.left(await fn(l)),\n async (r) => Either.right(r),\n ),\n ),\n );\n }\n\n /**\n * Flat maps the value of this Either if it is a Left, performs no operation if this is a Right.\n */\n leftFlatMap<L2, R2>(fn: (t: L) => Either<L2, R2>): EitherP<L2, R | R2> {\n return new EitherP(this.value.then((e) => e.leftFlatMap(fn)));\n }\n\n leftFlatMapAsync<L2, R2>(fn: (t: L) => PromiseLike<Either<L2, R2>>): EitherP<L2, R | R2> {\n return new EitherP(\n this.value.then<Either<L2, R | R2>>(\n async (e) =>\n await e.fold(\n async (left) => await fn(left),\n async (right) => Either.right(right),\n ),\n ),\n );\n }\n\n /**\n * Applies the provided functions to the value of this Either, depending on whether it is a Right or a Left and returns a new Either.\n */\n bimap<L2, R2>(leftFn: (l: L) => L2, rightFn: (r: R) => R2): EitherP<L2, R2> {\n return new EitherP(this.value.then((e) => e.bimap(leftFn, rightFn)));\n }\n\n bimapAsync<L2, R2>(\n leftFn: (l: L) => Promise<L2>,\n rightFn: (r: R) => Promise<R2>,\n ): EitherP<L2, R2> {\n return new EitherP(\n this.value.then(\n async (e) =>\n await e.fold(\n async (l) => Either.left(await leftFn(l)),\n async (r) => Either.right(await rightFn(r)),\n ),\n ),\n );\n }\n\n /**\n * Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left.\n */\n tap(fn: (t: R) => void): EitherP<L, R> {\n return new EitherP(this.value.then((e) => e.tap(fn)));\n }\n\n tapAsync(fn: (t: R) => Promise<void>): EitherP<L, R> {\n return this.flatMapAsync(async (value) => {\n await fn(value);\n return Either.right(value);\n });\n }\n\n /**\n * Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left.\n * If the result of the function is a Left, it will be returned, otherwise the original Right value will be returned.\n */\n flatTap<L2>(fn: (t: R) => Either<L2, void>): EitherP<L | L2, R> {\n return new EitherP(this.value.then((e) => e.flatTap(fn)));\n }\n\n flatTapAsync<L2>(fn: (t: R) => PromiseLike<Either<L2, void>>): EitherP<L | L2, R> {\n return this.flatMapAsync(async (value) => (await fn(value)).map(() => value));\n }\n\n /**\n * Flat maps the value of this Either if it is a Right, performs no operation if this is a Left.\n */\n flatMap<L2, R2>(fn: (t: R) => Either<L2, R2>): EitherP<L | L2, R2> {\n return new EitherP(this.value.then((e) => e.flatMap(fn)));\n }\n\n flatMapAsync<L2, R2>(fn: (t: R) => PromiseLike<Either<L2, R2>>): EitherP<L | L2, R2> {\n return new EitherP(\n this.value.then<Either<L | L2, R2>>((e) =>\n e.fold(\n async (left) => Either.left(left),\n (right) => fn(right),\n ),\n ),\n );\n }\n\n /**\n * Applies the provided functions to the value of this Either, depending on whether it is a Right or a Left and returns the result.\n */\n async fold<U1, U2>(leftFn: (l: L) => U1, rightFn: (r: R) => U2): Promise<U1 | U2> {\n return (await this.value).fold(leftFn, rightFn);\n }\n\n /**\n * Allows to deconstruct the Either using:\n *\n * @example\n *\n * ```ts\n * declare const e: EitherP<string, number>;\n *\n * const [left, right] = await e.pair();\n * ```\n *\n */\n async pair(): Promise<[Maybe<L>, Maybe<R>]> {\n return [await this.getLeft(), await this.get()];\n }\n\n /**\n * Returns true if this Either is a Right, false otherwise.\n */\n async isRight(): Promise<boolean> {\n return (await this.value).isRight();\n }\n\n /**\n * Returns true if this Either is a Left, false otherwise.\n */\n async isLeft(): Promise<boolean> {\n return !(await this.isRight());\n }\n\n /**\n * Gets the right value if this is a Right or undefined if it's a Left.\n */\n async get(): Promise<Maybe<R>> {\n return (await this.value).get();\n }\n\n /**\n * Returns the left value if this is a Left or undefined if it's a Right.\n */\n async getLeft(): Promise<Maybe<L>> {\n return (await this.value).getLeft();\n }\n\n /**\n * Gets the right value if this is a Right or the result of the provided function if it's a Left.\n */\n async getOrElse<T>(defaultValue: (l: L) => T): Promise<R | T> {\n return (await this.value).getOrElse(defaultValue);\n }\n\n /**\n * Creates a new Left EitherP with the provided value.\n */\n static left<L>(value: Promise<L>): EitherP<L, never> {\n return new EitherP(value.then((v) => Either.left(v)));\n }\n\n /**\n * Creates a new Right EitherP with the provided value.\n */\n static right<R>(value: Promise<R>): EitherP<never, R> {\n return new EitherP(value.then((v) => Either.right(v)));\n }\n\n static fromMaybe<L, R>(value: Promise<Maybe<R>>, leftValue: () => Promise<L>): EitherP<L, R> {\n return new EitherP(\n value.then(async (v) => (isDefined(v) ? Either.right(v) : Either.left(await leftValue()))),\n );\n }\n\n /**\n * @deprecated\n */\n static fromEither<L, R>(either: PromiseLike<Either<L, R>>): EitherP<L, R> {\n return new EitherP(either);\n }\n\n static fromPromise<L, R>(either: PromiseLike<Either<L, R>>): EitherP<L, R> {\n return new EitherP(either);\n }\n\n static cond<L, R>(\n bool: Promise<boolean>,\n leftFn: () => Promise<L>,\n rightFn: () => Promise<R>,\n ): EitherP<L, R> {\n return new EitherP(\n bool.then(async (b) => (b ? Either.right(await rightFn()) : Either.left(await leftFn()))),\n );\n }\n\n // oxlint-disable-next-line unicorn/no-thenable -- Deliberately implementing PromiseLike to allow for `await` usage on EitherP instances.\n then<U>(onfulfilled?: (value: Either<L, R>) => U | PromiseLike<U>): PromiseLike<U> {\n return this.value.then(onfulfilled);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"either.mjs","names":[],"sources":["../src/either.ts"],"sourcesContent":["import type { Maybe } from './maybe.js';\nimport { isDefined } from './maybe.js';\n\n// Note that xxxAsync implementations in Either all look like:\n// EitherP.fromPromise(toEitherPromise(this)).xxxAsync(...)\n//\n// And conversely, xxx implementations in EitherP all look like:\n// new EitherP(this.value.then(e => e.xxx(...)))\n\nexport abstract class EitherBase<L, R> {\n /**\n * Maps the value of this Either if it is a Right, performs no operation if this is a Left.\n */\n map<R2>(fn: (t: R) => R2): Either<L, R2> {\n return this.flatMap((value) => Either.right(fn(value)));\n }\n\n /**\n * Maps the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.\n */\n mapAsync<R2>(fn: (t: R) => Promise<R2>): EitherP<L, R2> {\n return EitherP.fromPromise(toEitherPromise(this)).mapAsync(fn);\n }\n\n /**\n * Flat maps the value of this Either if it is a Left, performs no operation if this is a Right.\n */\n leftFlatMap<L2, R2>(fn: (t: L) => Either<L2, R2>): Either<L2, R | R2> {\n return this.fold(\n (l) => fn(l),\n (r) => Either.right(r),\n );\n }\n\n /**\n * Flat maps the value of this Either if it is a Left, performs no operation if this is a Right, asynchronously.\n */\n leftFlatMapAsync<L2, R2>(fn: (t: L) => PromiseLike<Either<L2, R2>>): EitherP<L2, R | R2> {\n return EitherP.fromPromise(toEitherPromise(this)).leftFlatMapAsync(fn);\n }\n\n /**\n * Maps the value of this Either if it is a Left, performs no operation if this is a Right.\n */\n leftMap<L2>(fn: (t: L) => L2): Either<L2, R> {\n return this.fold(\n (l) => Either.left(fn(l)),\n (r) => Either.right(r),\n );\n }\n\n /**\n * Maps the value of this Either if it is a Left, performs no operation if this is a Right, asynchronously.\n */\n leftMapAsync<L2>(fn: (t: L) => Promise<L2>): EitherP<L2, R> {\n return EitherP.fromPromise(toEitherPromise(this)).leftMapAsync(fn);\n }\n\n /**\n * Applies the provided functions to the value of this Either, depending on whether it is a Right or a Left and returns a new Either.\n */\n bimap<L2, R2>(leftFn: (l: L) => L2, rightFn: (r: R) => R2): Either<L2, R2> {\n return this.fold(\n (l) => Either.left(leftFn(l)),\n (r) => Either.right(rightFn(r)),\n );\n }\n\n /**\n * Applies the provided functions to the value of this Either, depending on whether it is a Right or a Left and returns a new Either, asynchronously.\n */\n bimapAsync<L2, R2>(\n leftFn: (l: L) => Promise<L2>,\n rightFn: (r: R) => Promise<R2>,\n ): EitherP<L2, R2> {\n return EitherP.fromPromise(toEitherPromise(this)).bimapAsync(leftFn, rightFn);\n }\n\n /**\n * Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left.\n */\n tap(fn: (t: R) => void): Either<L, R> {\n return this.flatMap((value) => {\n fn(value);\n return Either.right(value);\n });\n }\n\n /**\n * Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.\n */\n tapAsync(fn: (t: R) => Promise<void>): EitherP<L, R> {\n return EitherP.fromPromise(toEitherPromise(this)).tapAsync(fn);\n }\n\n /**\n * Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left.\n * If the result of the function is a Left, it will be returned, otherwise the original Right value will be returned.\n */\n flatTap<L2>(fn: (t: R) => Either<L2, void>): Either<L | L2, R> {\n return this.flatMap((value) => fn(value).map(() => value));\n }\n\n /**\n * Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.\n * If the result of the function is a Left, it will be returned, otherwise the original Right value will be returned.\n */\n flatTapAsync<L2>(fn: (t: R) => PromiseLike<Either<L2, void>>): EitherP<L | L2, R> {\n return EitherP.fromPromise(toEitherPromise(this)).flatTapAsync(fn);\n }\n\n /**\n * Flat maps the value of this Either if it is a Right, performs no operation if this is a Left.\n */\n flatMap<L2, R2>(fn: (t: R) => Either<L2, R2>): Either<L | L2, R2> {\n return this.fold(\n (l) => Either.left(l),\n (r) => fn(r),\n );\n }\n\n /**\n * Flat maps the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.\n */\n flatMapAsync<L2, R2>(fn: (t: R) => PromiseLike<Either<L2, R2>>): EitherP<L | L2, R2> {\n return EitherP.fromPromise(toEitherPromise(this)).flatMapAsync(fn);\n }\n\n /**\n * Applies the provided functions to the value of this Either, depending on whether it is a Right or a Left and returns the result.\n */\n abstract fold<U1, U2>(leftFn: (l: L) => U1, rightFn: (r: R) => U2): U1 | U2;\n\n /**\n * Allows to deconstruct the Either using:\n *\n * @example\n *\n * ```ts\n * declare const e: Either<string, number>;\n *\n * const [left, right] = e.pair();\n * ```\n *\n */\n pair(): [Maybe<L>, Maybe<R>] {\n return [this.getLeft(), this.get()];\n }\n\n /**\n * Returns true if this Either is a Right, false otherwise.\n */\n isRight(): this is Right<R> {\n return this.fold(\n () => false,\n () => true,\n );\n }\n\n /**\n * Returns true if this Either is a Left, false otherwise.\n */\n isLeft(): this is Left<L> {\n return this.fold(\n () => true,\n () => false,\n );\n }\n\n /**\n * Gets the right value if this is a Right or undefined if it's a Left.\n */\n get(): Maybe<R> {\n // Overridden in Right#get\n return undefined;\n }\n\n /**\n * Returns the left value if this is a Left or undefined if it's a Right.\n */\n getLeft(): Maybe<L> {\n // Overridden in Left#getLeft\n return undefined;\n }\n\n /**\n * Gets the right value if this is a Right or the result of the provided function if it's a Left.\n */\n getOrElse<T>(defaultValue: (l: L) => T): R | T {\n return this.fold(\n (l) => defaultValue(l),\n (r) => r,\n );\n }\n}\n\nfunction toEitherPromise<L, R>(e: EitherBase<L, R>): Promise<Either<L, R>> {\n // EitherBase is abstract with only Left/Right as concrete subclasses; the cast is always valid.\n return Promise.resolve(e as unknown as Either<L, R>);\n}\n\nexport class Left<L> extends EitherBase<L, never> {\n constructor(private readonly value: L) {\n super();\n }\n\n fold<U1, U2>(leftFn: (l: L) => U1, _rightFn: (r: never) => U2): U1 | U2 {\n return leftFn(this.value);\n }\n\n override getLeft(): L {\n return this.value;\n }\n\n override toString(): string {\n return `Left(${String(this.value)})`;\n }\n\n get [Symbol.toStringTag](): string {\n return 'Left';\n }\n}\n\nexport class Right<R> extends EitherBase<never, R> {\n constructor(private readonly value: R) {\n super();\n }\n\n fold<U1, U2>(_leftFn: (l: never) => U1, rightFn: (r: R) => U2): U1 | U2 {\n return rightFn(this.value);\n }\n\n override get(): R {\n return this.value;\n }\n\n override toString(): string {\n return `Right(${String(this.value)})`;\n }\n\n get [Symbol.toStringTag](): string {\n return 'Right';\n }\n}\n\n/**\n * Either<L, R> is a union of Left<L> and Right<R>, so narrowing works in both directions:\n *\n * ```ts\n * declare const e: Either<string, number>;\n *\n * if (e.isLeft()) {\n * e; // Left<string>\n * } else {\n * e; // Right<number>\n * }\n * ```\n */\nexport type Either<L, R> = Left<L> | Right<R>;\n\nexport namespace Either {\n /**\n * Creates a new Left Either with the provided value.\n */\n export function left<L>(value: L): Either<L, never> {\n return new Left(value);\n }\n\n /**\n * Creates a new Right Either with the provided value.\n */\n export function right<R>(value: R): Either<never, R> {\n return new Right(value);\n }\n\n /**\n * Creates a Right Either from a Maybe if it is defined, or a Left Either from the result of the provided function otherwise.\n */\n export function fromMaybe<L, R>(value: Maybe<R>, leftValue: () => L): Either<L, R> {\n return isDefined(value) ? Either.right(value) : Either.left(leftValue());\n }\n\n /**\n * Creates a Right Either from the result of `rightFn` if `bool` is true, or a Left Either from the result of `leftFn` otherwise.\n */\n export function cond<L, R>(bool: boolean, leftFn: () => L, rightFn: () => R): Either<L, R> {\n return bool ? Either.right(rightFn()) : Either.left(leftFn());\n }\n}\n\n/**\n * Asynchronous version of @{link Either}, allowing for asynchronous operations on the values of the Either.\n *\n * ```ts\n * declare const e: EitherP<string, number>;\n *\n * const result = await e.get(); // result is of type Maybe<number>\n */\nexport class EitherP<L, R> implements PromiseLike<Either<L, R>> {\n private constructor(private readonly value: PromiseLike<Either<L, R>>) {}\n\n /**\n * Maps the value of this Either if it is a Right, performs no operation if this is a Left.\n */\n map<R2>(fn: (t: R) => R2): EitherP<L, R2> {\n return new EitherP(this.value.then((e) => e.map(fn)));\n }\n\n /**\n * Maps the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.\n */\n mapAsync<R2>(fn: (t: R) => Promise<R2>): EitherP<L, R2> {\n return this.flatMapAsync(async (value) => Either.right(await fn(value)));\n }\n\n /**\n * Maps the value of this Either if it is a Left, performs no operation if this is a Right.\n */\n leftMap<L2>(fn: (t: L) => L2): EitherP<L2, R> {\n return new EitherP(this.value.then((e) => e.leftMap(fn)));\n }\n\n /**\n * Maps the value of this Either if it is a Left, performs no operation if this is a Right, asynchronously.\n */\n leftMapAsync<L2>(fn: (t: L) => Promise<L2>): EitherP<L2, R> {\n return new EitherP(\n this.value.then(\n async (e) =>\n await e.fold(\n async (l) => Either.left(await fn(l)),\n async (r) => Either.right(r),\n ),\n ),\n );\n }\n\n /**\n * Flat maps the value of this Either if it is a Left, performs no operation if this is a Right.\n */\n leftFlatMap<L2, R2>(fn: (t: L) => Either<L2, R2>): EitherP<L2, R | R2> {\n return new EitherP(this.value.then((e) => e.leftFlatMap(fn)));\n }\n\n /**\n * Flat maps the value of this Either if it is a Left, performs no operation if this is a Right, asynchronously.\n */\n leftFlatMapAsync<L2, R2>(fn: (t: L) => PromiseLike<Either<L2, R2>>): EitherP<L2, R | R2> {\n return new EitherP(\n this.value.then<Either<L2, R | R2>>(\n async (e) =>\n await e.fold(\n async (left) => await fn(left),\n async (right) => Either.right(right),\n ),\n ),\n );\n }\n\n /**\n * Applies the provided functions to the value of this Either, depending on whether it is a Right or a Left and returns a new Either.\n */\n bimap<L2, R2>(leftFn: (l: L) => L2, rightFn: (r: R) => R2): EitherP<L2, R2> {\n return new EitherP(this.value.then((e) => e.bimap(leftFn, rightFn)));\n }\n\n /**\n * Applies the provided functions to the value of this Either, depending on whether it is a Right or a Left and returns a new Either, asynchronously.\n */\n bimapAsync<L2, R2>(\n leftFn: (l: L) => Promise<L2>,\n rightFn: (r: R) => Promise<R2>,\n ): EitherP<L2, R2> {\n return new EitherP(\n this.value.then(\n async (e) =>\n await e.fold(\n async (l) => Either.left(await leftFn(l)),\n async (r) => Either.right(await rightFn(r)),\n ),\n ),\n );\n }\n\n /**\n * Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left.\n */\n tap(fn: (t: R) => void): EitherP<L, R> {\n return new EitherP(this.value.then((e) => e.tap(fn)));\n }\n\n /**\n * Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.\n */\n tapAsync(fn: (t: R) => Promise<void>): EitherP<L, R> {\n return this.flatMapAsync(async (value) => {\n await fn(value);\n return Either.right(value);\n });\n }\n\n /**\n * Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left.\n * If the result of the function is a Left, it will be returned, otherwise the original Right value will be returned.\n */\n flatTap<L2>(fn: (t: R) => Either<L2, void>): EitherP<L | L2, R> {\n return new EitherP(this.value.then((e) => e.flatTap(fn)));\n }\n\n /**\n * Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.\n * If the result of the function is a Left, it will be returned, otherwise the original Right value will be returned.\n */\n flatTapAsync<L2>(fn: (t: R) => PromiseLike<Either<L2, void>>): EitherP<L | L2, R> {\n return this.flatMapAsync(async (value) => (await fn(value)).map(() => value));\n }\n\n /**\n * Flat maps the value of this Either if it is a Right, performs no operation if this is a Left.\n */\n flatMap<L2, R2>(fn: (t: R) => Either<L2, R2>): EitherP<L | L2, R2> {\n return new EitherP(this.value.then((e) => e.flatMap(fn)));\n }\n\n /**\n * Flat maps the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.\n */\n flatMapAsync<L2, R2>(fn: (t: R) => PromiseLike<Either<L2, R2>>): EitherP<L | L2, R2> {\n return new EitherP(\n this.value.then<Either<L | L2, R2>>((e) =>\n e.fold(\n async (left) => Either.left(left),\n (right) => fn(right),\n ),\n ),\n );\n }\n\n /**\n * Applies the provided functions to the value of this Either, depending on whether it is a Right or a Left and returns the result.\n */\n async fold<U1, U2>(leftFn: (l: L) => U1, rightFn: (r: R) => U2): Promise<U1 | U2> {\n return (await this.value).fold(leftFn, rightFn);\n }\n\n /**\n * Allows to deconstruct the Either using:\n *\n * @example\n *\n * ```ts\n * declare const e: EitherP<string, number>;\n *\n * const [left, right] = await e.pair();\n * ```\n *\n */\n async pair(): Promise<[Maybe<L>, Maybe<R>]> {\n return [await this.getLeft(), await this.get()];\n }\n\n /**\n * Returns true if this Either is a Right, false otherwise.\n */\n async isRight(): Promise<boolean> {\n return (await this.value).isRight();\n }\n\n /**\n * Returns true if this Either is a Left, false otherwise.\n */\n async isLeft(): Promise<boolean> {\n return !(await this.isRight());\n }\n\n /**\n * Gets the right value if this is a Right or undefined if it's a Left.\n */\n async get(): Promise<Maybe<R>> {\n return (await this.value).get();\n }\n\n /**\n * Returns the left value if this is a Left or undefined if it's a Right.\n */\n async getLeft(): Promise<Maybe<L>> {\n return (await this.value).getLeft();\n }\n\n /**\n * Gets the right value if this is a Right or the result of the provided function if it's a Left.\n */\n async getOrElse<T>(defaultValue: (l: L) => T): Promise<R | T> {\n return (await this.value).getOrElse(defaultValue);\n }\n\n /**\n * Creates a new Left EitherP with the provided value.\n */\n static left<L>(value: Promise<L>): EitherP<L, never> {\n return new EitherP(value.then((v) => Either.left(v)));\n }\n\n /**\n * Creates a new Right EitherP with the provided value.\n */\n static right<R>(value: Promise<R>): EitherP<never, R> {\n return new EitherP(value.then((v) => Either.right(v)));\n }\n\n /**\n * Creates a Right EitherP from a Promise of a Maybe if it resolves to a defined value, or a Left EitherP from the result of the provided function otherwise.\n */\n static fromMaybe<L, R>(value: Promise<Maybe<R>>, leftValue: () => Promise<L>): EitherP<L, R> {\n return new EitherP(\n value.then(async (v) => (isDefined(v) ? Either.right(v) : Either.left(await leftValue()))),\n );\n }\n\n /**\n * Creates a new EitherP from a Promise of an Either.\n */\n static fromPromise<L, R>(either: PromiseLike<Either<L, R>>): EitherP<L, R> {\n return new EitherP(either);\n }\n\n /**\n * Creates a new Right EitherP if the provided Promise resolves to true, or a new Left EitherP otherwise.\n */\n static cond<L, R>(\n bool: Promise<boolean>,\n leftFn: () => Promise<L>,\n rightFn: () => Promise<R>,\n ): EitherP<L, R> {\n return new EitherP(\n bool.then(async (b) => (b ? Either.right(await rightFn()) : Either.left(await leftFn()))),\n );\n }\n\n /**\n * Resolves this EitherP to its underlying Either, allowing `await` usage on EitherP instances.\n */\n // oxlint-disable-next-line unicorn/no-thenable -- Deliberately implementing PromiseLike to allow for `await` usage on EitherP instances.\n then<U>(onfulfilled?: (value: Either<L, R>) => U | PromiseLike<U>): PromiseLike<U> {\n return this.value.then(onfulfilled);\n }\n}\n"],"mappings":"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"}
package/dist/index.d.mts CHANGED
@@ -1,3 +1,3 @@
1
1
  import { Maybe, flattenMaybe, ifFalse, ifTrue, isDefined, mapMaybe, matchPair } from "./maybe.mjs";
2
- import { Either, EitherP, Left, Right } from "./either.mjs";
3
- export { Either, EitherP, Left, Maybe, Right, flattenMaybe, ifFalse, ifTrue, isDefined, mapMaybe, matchPair };
2
+ import { Either, EitherBase, EitherP, Left, Right } from "./either.mjs";
3
+ export { Either, EitherBase, EitherP, Left, Maybe, Right, flattenMaybe, ifFalse, ifTrue, isDefined, mapMaybe, matchPair };
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
1
  import { flattenMaybe, ifFalse, ifTrue, isDefined, mapMaybe, matchPair } from "./maybe.mjs";
2
- import { Either, EitherP, Left, Right } from "./either.mjs";
2
+ import { Either, EitherBase, EitherP, Left, Right } from "./either.mjs";
3
3
 
4
- export { Either, EitherP, Left, Right, flattenMaybe, ifFalse, ifTrue, isDefined, mapMaybe, matchPair };
4
+ export { Either, EitherBase, EitherP, Left, Right, flattenMaybe, ifFalse, ifTrue, isDefined, mapMaybe, matchPair };
package/dist/maybe.d.mts CHANGED
@@ -1,10 +1,74 @@
1
1
  //#region src/maybe.d.ts
2
+ /**
3
+ * Represents a value that may be absent.
4
+ */
2
5
  type Maybe<T> = T | undefined;
6
+ /**
7
+ * Maps the value if it is defined, performs no operation if it is undefined.
8
+ *
9
+ * @example
10
+ *
11
+ * ```ts
12
+ * const value: Maybe<number> = 5;
13
+ * const result: Maybe<string> = mapMaybe(value, (v) => `Value is ${v}`); // "Value is 5"
14
+ *
15
+ * const undefinedValue: Maybe<number> = undefined;
16
+ * const undefinedResult: Maybe<string> = mapMaybe(undefinedValue, (v) => `Value is ${v}`); // undefined
17
+ * ```
18
+ */
3
19
  declare function mapMaybe<T, U>(value: Maybe<T>, fn: (value: T) => U): Maybe<U>;
20
+ /**
21
+ * Returns true if the value is defined, false if it is undefined.
22
+ *
23
+ * @example
24
+ *
25
+ * ```ts
26
+ * const definedValue: Maybe<number> = 5;
27
+ *
28
+ * if (isDefined(definedValue)) {
29
+ * console.log(definedValue + 1); // Output: 6
30
+ * }
31
+ * ```
32
+ */
4
33
  declare function isDefined<T>(value: Maybe<T>): value is T;
34
+ /**
35
+ * Flattens a nested Maybe into a single Maybe.
36
+ *
37
+ * @example
38
+ *
39
+ * ```ts
40
+ * const nested: Maybe<Maybe<number>> = 5;
41
+ * const flattened: Maybe<number> = flattenMaybe(nested); // 5
42
+ * ```
43
+ */
5
44
  declare function flattenMaybe<T>(value: Maybe<Maybe<T>>): Maybe<T>;
45
+ /**
46
+ * Returns the result of the provided function if the value is true, undefined otherwise.
47
+ */
6
48
  declare function ifTrue<T>(value: boolean, fn: () => T): Maybe<T>;
49
+ /**
50
+ * Returns the result of the provided function if the value is false, undefined otherwise.
51
+ */
7
52
  declare function ifFalse<T>(value: boolean, fn: () => T): Maybe<T>;
53
+ /**
54
+ * Matches a pair of Maybe values against the provided cases, depending on which of them are defined.
55
+ *
56
+ * @example
57
+ *
58
+ * ```ts
59
+ * const a: Maybe<number> = 5;
60
+ * const b: Maybe<string> = undefined;
61
+ *
62
+ * const result = matchPair([a, b], {
63
+ * neither: () => 'neither',
64
+ * a: (a) => `a is ${a}`,
65
+ * b: (b) => `b is ${b}`,
66
+ * both: (a, b) => `both are ${a} and ${b}`,
67
+ * });
68
+ *
69
+ * console.log(result); // Output: "a is 5"
70
+ * ```
71
+ */
8
72
  declare function matchPair<A, B, R>([a, b]: [Maybe<A>, Maybe<B>], cases: {
9
73
  neither: () => R;
10
74
  a: (a: A) => R;
@@ -1 +1 @@
1
- {"version":3,"file":"maybe.d.mts","names":[],"sources":["../src/maybe.ts"],"mappings":";KAAY,MAAM,KAAK;iBAEP,SAAS,GAAG,GAAG,OAAO,MAAM,IAAI,KAAK,OAAO,MAAM,IAAI,MAAM;iBAI5D,UAAU,GAAG,OAAO,MAAM,KAAK,SAAS;iBAIxC,aAAa,GAAG,OAAO,MAAM,MAAM,MAAM,MAAM;iBAI/C,OAAO,GAAG,gBAAgB,UAAU,IAAI,MAAM;iBAI9C,QAAQ,GAAG,gBAAgB,UAAU,IAAI,MAAM;iBAI/C,UAAU,GAAG,GAAG,IAC7B,GAAG,KAAK,MAAM,IAAI,MAAM,KACzB;EACE,eAAe;EACf,IAAI,GAAG,MAAM;EACb,IAAI,GAAG,MAAM;EACb,OAAO,GAAG,GAAG,GAAG,MAAM;IAEvB"}
1
+ {"version":3,"file":"maybe.d.mts","names":[],"sources":["../src/maybe.ts"],"mappings":";;;;KAGY,MAAM,KAAK;;;;;;;;;;;;;;iBAeP,SAAS,GAAG,GAAG,OAAO,MAAM,IAAI,KAAK,OAAO,MAAM,IAAI,MAAM;;;;;;;;;;;;;;iBAiB5D,UAAU,GAAG,OAAO,MAAM,KAAK,SAAS;;;;;;;;;;;iBAcxC,aAAa,GAAG,OAAO,MAAM,MAAM,MAAM,MAAM;;;;iBAO/C,OAAO,GAAG,gBAAgB,UAAU,IAAI,MAAM;;;;iBAO9C,QAAQ,GAAG,gBAAgB,UAAU,IAAI,MAAM;;;;;;;;;;;;;;;;;;;;iBAuB/C,UAAU,GAAG,GAAG,IAC7B,GAAG,KAAK,MAAM,IAAI,MAAM,KACzB;EACE,eAAe;EACf,IAAI,GAAG,MAAM;EACb,IAAI,GAAG,MAAM;EACb,OAAO,GAAG,GAAG,GAAG,MAAM;IAEvB"}
package/dist/maybe.mjs CHANGED
@@ -1,19 +1,80 @@
1
1
  //#region src/maybe.ts
2
+ /**
3
+ * Maps the value if it is defined, performs no operation if it is undefined.
4
+ *
5
+ * @example
6
+ *
7
+ * ```ts
8
+ * const value: Maybe<number> = 5;
9
+ * const result: Maybe<string> = mapMaybe(value, (v) => `Value is ${v}`); // "Value is 5"
10
+ *
11
+ * const undefinedValue: Maybe<number> = undefined;
12
+ * const undefinedResult: Maybe<string> = mapMaybe(undefinedValue, (v) => `Value is ${v}`); // undefined
13
+ * ```
14
+ */
2
15
  function mapMaybe(value, fn) {
3
16
  return value === void 0 ? void 0 : fn(value);
4
17
  }
18
+ /**
19
+ * Returns true if the value is defined, false if it is undefined.
20
+ *
21
+ * @example
22
+ *
23
+ * ```ts
24
+ * const definedValue: Maybe<number> = 5;
25
+ *
26
+ * if (isDefined(definedValue)) {
27
+ * console.log(definedValue + 1); // Output: 6
28
+ * }
29
+ * ```
30
+ */
5
31
  function isDefined(value) {
6
32
  return value !== void 0;
7
33
  }
34
+ /**
35
+ * Flattens a nested Maybe into a single Maybe.
36
+ *
37
+ * @example
38
+ *
39
+ * ```ts
40
+ * const nested: Maybe<Maybe<number>> = 5;
41
+ * const flattened: Maybe<number> = flattenMaybe(nested); // 5
42
+ * ```
43
+ */
8
44
  function flattenMaybe(value) {
9
45
  return mapMaybe(value, (v) => v);
10
46
  }
47
+ /**
48
+ * Returns the result of the provided function if the value is true, undefined otherwise.
49
+ */
11
50
  function ifTrue(value, fn) {
12
51
  return value ? fn() : void 0;
13
52
  }
53
+ /**
54
+ * Returns the result of the provided function if the value is false, undefined otherwise.
55
+ */
14
56
  function ifFalse(value, fn) {
15
57
  return !value ? fn() : void 0;
16
58
  }
59
+ /**
60
+ * Matches a pair of Maybe values against the provided cases, depending on which of them are defined.
61
+ *
62
+ * @example
63
+ *
64
+ * ```ts
65
+ * const a: Maybe<number> = 5;
66
+ * const b: Maybe<string> = undefined;
67
+ *
68
+ * const result = matchPair([a, b], {
69
+ * neither: () => 'neither',
70
+ * a: (a) => `a is ${a}`,
71
+ * b: (b) => `b is ${b}`,
72
+ * both: (a, b) => `both are ${a} and ${b}`,
73
+ * });
74
+ *
75
+ * console.log(result); // Output: "a is 5"
76
+ * ```
77
+ */
17
78
  function matchPair([a, b], cases) {
18
79
  if (!isDefined(a)) {
19
80
  if (!isDefined(b)) return cases.neither();
@@ -1 +1 @@
1
- {"version":3,"file":"maybe.mjs","names":[],"sources":["../src/maybe.ts"],"sourcesContent":["export type Maybe<T> = T | undefined;\n\nexport function mapMaybe<T, U>(value: Maybe<T>, fn: (value: T) => U): Maybe<U> {\n return value === undefined ? undefined : fn(value);\n}\n\nexport function isDefined<T>(value: Maybe<T>): value is T {\n return value !== undefined;\n}\n\nexport function flattenMaybe<T>(value: Maybe<Maybe<T>>): Maybe<T> {\n return mapMaybe(value, (v) => v);\n}\n\nexport function ifTrue<T>(value: boolean, fn: () => T): Maybe<T> {\n return value ? fn() : undefined;\n}\n\nexport function ifFalse<T>(value: boolean, fn: () => T): Maybe<T> {\n return !value ? fn() : undefined;\n}\n\nexport function matchPair<A, B, R>(\n [a, b]: [Maybe<A>, Maybe<B>],\n cases: {\n neither: () => R;\n a: (a: A) => R;\n b: (b: B) => R;\n both: (a: A, b: B) => R;\n },\n): R {\n if (!isDefined(a)) {\n if (!isDefined(b)) {\n return cases.neither();\n }\n\n return cases.b(b);\n }\n\n if (!isDefined(b)) {\n return cases.a(a);\n }\n\n return cases.both(a, b);\n}\n"],"mappings":";AAEA,SAAgB,SAAe,OAAiB,IAA+B;CAC7E,OAAO,UAAU,SAAY,SAAY,GAAG,KAAK;AACnD;AAEA,SAAgB,UAAa,OAA6B;CACxD,OAAO,UAAU;AACnB;AAEA,SAAgB,aAAgB,OAAkC;CAChE,OAAO,SAAS,QAAQ,MAAM,CAAC;AACjC;AAEA,SAAgB,OAAU,OAAgB,IAAuB;CAC/D,OAAO,QAAQ,GAAG,IAAI;AACxB;AAEA,SAAgB,QAAW,OAAgB,IAAuB;CAChE,OAAO,CAAC,QAAQ,GAAG,IAAI;AACzB;AAEA,SAAgB,UACd,CAAC,GAAG,IACJ,OAMG;CACH,IAAI,CAAC,UAAU,CAAC,GAAG;EACjB,IAAI,CAAC,UAAU,CAAC,GACd,OAAO,MAAM,QAAQ;EAGvB,OAAO,MAAM,EAAE,CAAC;CAClB;CAEA,IAAI,CAAC,UAAU,CAAC,GACd,OAAO,MAAM,EAAE,CAAC;CAGlB,OAAO,MAAM,KAAK,GAAG,CAAC;AACxB"}
1
+ {"version":3,"file":"maybe.mjs","names":[],"sources":["../src/maybe.ts"],"sourcesContent":["/**\n * Represents a value that may be absent.\n */\nexport type Maybe<T> = T | undefined;\n\n/**\n * Maps the value if it is defined, performs no operation if it is undefined.\n *\n * @example\n *\n * ```ts\n * const value: Maybe<number> = 5;\n * const result: Maybe<string> = mapMaybe(value, (v) => `Value is ${v}`); // \"Value is 5\"\n *\n * const undefinedValue: Maybe<number> = undefined;\n * const undefinedResult: Maybe<string> = mapMaybe(undefinedValue, (v) => `Value is ${v}`); // undefined\n * ```\n */\nexport function mapMaybe<T, U>(value: Maybe<T>, fn: (value: T) => U): Maybe<U> {\n return value === undefined ? undefined : fn(value);\n}\n\n/**\n * Returns true if the value is defined, false if it is undefined.\n *\n * @example\n *\n * ```ts\n * const definedValue: Maybe<number> = 5;\n *\n * if (isDefined(definedValue)) {\n * console.log(definedValue + 1); // Output: 6\n * }\n * ```\n */\nexport function isDefined<T>(value: Maybe<T>): value is T {\n return value !== undefined;\n}\n\n/**\n * Flattens a nested Maybe into a single Maybe.\n *\n * @example\n *\n * ```ts\n * const nested: Maybe<Maybe<number>> = 5;\n * const flattened: Maybe<number> = flattenMaybe(nested); // 5\n * ```\n */\nexport function flattenMaybe<T>(value: Maybe<Maybe<T>>): Maybe<T> {\n return mapMaybe(value, (v) => v);\n}\n\n/**\n * Returns the result of the provided function if the value is true, undefined otherwise.\n */\nexport function ifTrue<T>(value: boolean, fn: () => T): Maybe<T> {\n return value ? fn() : undefined;\n}\n\n/**\n * Returns the result of the provided function if the value is false, undefined otherwise.\n */\nexport function ifFalse<T>(value: boolean, fn: () => T): Maybe<T> {\n return !value ? fn() : undefined;\n}\n\n/**\n * Matches a pair of Maybe values against the provided cases, depending on which of them are defined.\n *\n * @example\n *\n * ```ts\n * const a: Maybe<number> = 5;\n * const b: Maybe<string> = undefined;\n *\n * const result = matchPair([a, b], {\n * neither: () => 'neither',\n * a: (a) => `a is ${a}`,\n * b: (b) => `b is ${b}`,\n * both: (a, b) => `both are ${a} and ${b}`,\n * });\n *\n * console.log(result); // Output: \"a is 5\"\n * ```\n */\nexport function matchPair<A, B, R>(\n [a, b]: [Maybe<A>, Maybe<B>],\n cases: {\n neither: () => R;\n a: (a: A) => R;\n b: (b: B) => R;\n both: (a: A, b: B) => R;\n },\n): R {\n if (!isDefined(a)) {\n if (!isDefined(b)) {\n return cases.neither();\n }\n\n return cases.b(b);\n }\n\n if (!isDefined(b)) {\n return cases.a(a);\n }\n\n return cases.both(a, b);\n}\n"],"mappings":";;;;;;;;;;;;;;AAkBA,SAAgB,SAAe,OAAiB,IAA+B;CAC7E,OAAO,UAAU,SAAY,SAAY,GAAG,KAAK;AACnD;;;;;;;;;;;;;;AAeA,SAAgB,UAAa,OAA6B;CACxD,OAAO,UAAU;AACnB;;;;;;;;;;;AAYA,SAAgB,aAAgB,OAAkC;CAChE,OAAO,SAAS,QAAQ,MAAM,CAAC;AACjC;;;;AAKA,SAAgB,OAAU,OAAgB,IAAuB;CAC/D,OAAO,QAAQ,GAAG,IAAI;AACxB;;;;AAKA,SAAgB,QAAW,OAAgB,IAAuB;CAChE,OAAO,CAAC,QAAQ,GAAG,IAAI;AACzB;;;;;;;;;;;;;;;;;;;;AAqBA,SAAgB,UACd,CAAC,GAAG,IACJ,OAMG;CACH,IAAI,CAAC,UAAU,CAAC,GAAG;EACjB,IAAI,CAAC,UAAU,CAAC,GACd,OAAO,MAAM,QAAQ;EAGvB,OAAO,MAAM,EAAE,CAAC;CAClB;CAEA,IAAI,CAAC,UAAU,CAAC,GACd,OAAO,MAAM,EAAE,CAAC;CAGlB,OAAO,MAAM,KAAK,GAAG,CAAC;AACxB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jeengbe/prelude",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "A small, dependency-free functional programming toolkit for TypeScript.",
5
5
  "keywords": [
6
6
  "either",
package/src/either.ts CHANGED
@@ -7,7 +7,7 @@ import { isDefined } from './maybe.js';
7
7
  // And conversely, xxx implementations in EitherP all look like:
8
8
  // new EitherP(this.value.then(e => e.xxx(...)))
9
9
 
10
- abstract class EitherBase<L, R> {
10
+ export abstract class EitherBase<L, R> {
11
11
  /**
12
12
  * Maps the value of this Either if it is a Right, performs no operation if this is a Left.
13
13
  */
@@ -15,6 +15,9 @@ abstract class EitherBase<L, R> {
15
15
  return this.flatMap((value) => Either.right(fn(value)));
16
16
  }
17
17
 
18
+ /**
19
+ * Maps the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
20
+ */
18
21
  mapAsync<R2>(fn: (t: R) => Promise<R2>): EitherP<L, R2> {
19
22
  return EitherP.fromPromise(toEitherPromise(this)).mapAsync(fn);
20
23
  }
@@ -29,6 +32,9 @@ abstract class EitherBase<L, R> {
29
32
  );
30
33
  }
31
34
 
35
+ /**
36
+ * Flat maps the value of this Either if it is a Left, performs no operation if this is a Right, asynchronously.
37
+ */
32
38
  leftFlatMapAsync<L2, R2>(fn: (t: L) => PromiseLike<Either<L2, R2>>): EitherP<L2, R | R2> {
33
39
  return EitherP.fromPromise(toEitherPromise(this)).leftFlatMapAsync(fn);
34
40
  }
@@ -43,6 +49,9 @@ abstract class EitherBase<L, R> {
43
49
  );
44
50
  }
45
51
 
52
+ /**
53
+ * Maps the value of this Either if it is a Left, performs no operation if this is a Right, asynchronously.
54
+ */
46
55
  leftMapAsync<L2>(fn: (t: L) => Promise<L2>): EitherP<L2, R> {
47
56
  return EitherP.fromPromise(toEitherPromise(this)).leftMapAsync(fn);
48
57
  }
@@ -57,6 +66,9 @@ abstract class EitherBase<L, R> {
57
66
  );
58
67
  }
59
68
 
69
+ /**
70
+ * Applies the provided functions to the value of this Either, depending on whether it is a Right or a Left and returns a new Either, asynchronously.
71
+ */
60
72
  bimapAsync<L2, R2>(
61
73
  leftFn: (l: L) => Promise<L2>,
62
74
  rightFn: (r: R) => Promise<R2>,
@@ -74,6 +86,9 @@ abstract class EitherBase<L, R> {
74
86
  });
75
87
  }
76
88
 
89
+ /**
90
+ * Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
91
+ */
77
92
  tapAsync(fn: (t: R) => Promise<void>): EitherP<L, R> {
78
93
  return EitherP.fromPromise(toEitherPromise(this)).tapAsync(fn);
79
94
  }
@@ -86,6 +101,10 @@ abstract class EitherBase<L, R> {
86
101
  return this.flatMap((value) => fn(value).map(() => value));
87
102
  }
88
103
 
104
+ /**
105
+ * Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
106
+ * If the result of the function is a Left, it will be returned, otherwise the original Right value will be returned.
107
+ */
89
108
  flatTapAsync<L2>(fn: (t: R) => PromiseLike<Either<L2, void>>): EitherP<L | L2, R> {
90
109
  return EitherP.fromPromise(toEitherPromise(this)).flatTapAsync(fn);
91
110
  }
@@ -100,6 +119,9 @@ abstract class EitherBase<L, R> {
100
119
  );
101
120
  }
102
121
 
122
+ /**
123
+ * Flat maps the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
124
+ */
103
125
  flatMapAsync<L2, R2>(fn: (t: R) => PromiseLike<Either<L2, R2>>): EitherP<L | L2, R2> {
104
126
  return EitherP.fromPromise(toEitherPromise(this)).flatMapAsync(fn);
105
127
  }
@@ -149,20 +171,16 @@ abstract class EitherBase<L, R> {
149
171
  * Gets the right value if this is a Right or undefined if it's a Left.
150
172
  */
151
173
  get(): Maybe<R> {
152
- return this.fold(
153
- () => undefined,
154
- (r) => r,
155
- );
174
+ // Overridden in Right#get
175
+ return undefined;
156
176
  }
157
177
 
158
178
  /**
159
179
  * Returns the left value if this is a Left or undefined if it's a Right.
160
180
  */
161
181
  getLeft(): Maybe<L> {
162
- return this.fold(
163
- (l) => l,
164
- () => undefined,
165
- );
182
+ // Overridden in Left#getLeft
183
+ return undefined;
166
184
  }
167
185
 
168
186
  /**
@@ -176,8 +194,8 @@ abstract class EitherBase<L, R> {
176
194
  }
177
195
  }
178
196
 
179
- // EitherBase is abstract with only Left/Right as concrete subclasses; the cast is always valid.
180
197
  function toEitherPromise<L, R>(e: EitherBase<L, R>): Promise<Either<L, R>> {
198
+ // EitherBase is abstract with only Left/Right as concrete subclasses; the cast is always valid.
181
199
  return Promise.resolve(e as unknown as Either<L, R>);
182
200
  }
183
201
 
@@ -193,6 +211,14 @@ export class Left<L> extends EitherBase<L, never> {
193
211
  override getLeft(): L {
194
212
  return this.value;
195
213
  }
214
+
215
+ override toString(): string {
216
+ return `Left(${String(this.value)})`;
217
+ }
218
+
219
+ get [Symbol.toStringTag](): string {
220
+ return 'Left';
221
+ }
196
222
  }
197
223
 
198
224
  export class Right<R> extends EitherBase<never, R> {
@@ -207,11 +233,17 @@ export class Right<R> extends EitherBase<never, R> {
207
233
  override get(): R {
208
234
  return this.value;
209
235
  }
236
+
237
+ override toString(): string {
238
+ return `Right(${String(this.value)})`;
239
+ }
240
+
241
+ get [Symbol.toStringTag](): string {
242
+ return 'Right';
243
+ }
210
244
  }
211
245
 
212
246
  /**
213
- * Mimics the [Cats Either[L, R]](https://typelevel.org/cats/datatypes/either.html) type.
214
- *
215
247
  * Either<L, R> is a union of Left<L> and Right<R>, so narrowing works in both directions:
216
248
  *
217
249
  * ```ts
@@ -241,17 +273,28 @@ export namespace Either {
241
273
  return new Right(value);
242
274
  }
243
275
 
276
+ /**
277
+ * Creates a Right Either from a Maybe if it is defined, or a Left Either from the result of the provided function otherwise.
278
+ */
244
279
  export function fromMaybe<L, R>(value: Maybe<R>, leftValue: () => L): Either<L, R> {
245
280
  return isDefined(value) ? Either.right(value) : Either.left(leftValue());
246
281
  }
247
282
 
283
+ /**
284
+ * Creates a Right Either from the result of `rightFn` if `bool` is true, or a Left Either from the result of `leftFn` otherwise.
285
+ */
248
286
  export function cond<L, R>(bool: boolean, leftFn: () => L, rightFn: () => R): Either<L, R> {
249
287
  return bool ? Either.right(rightFn()) : Either.left(leftFn());
250
288
  }
251
289
  }
252
290
 
253
291
  /**
254
- * Mimics the [Cats EitherT[Future, L, R]](https://typelevel.org/cats/datatypes/eithert.html) type.
292
+ * Asynchronous version of @{link Either}, allowing for asynchronous operations on the values of the Either.
293
+ *
294
+ * ```ts
295
+ * declare const e: EitherP<string, number>;
296
+ *
297
+ * const result = await e.get(); // result is of type Maybe<number>
255
298
  */
256
299
  export class EitherP<L, R> implements PromiseLike<Either<L, R>> {
257
300
  private constructor(private readonly value: PromiseLike<Either<L, R>>) {}
@@ -263,6 +306,9 @@ export class EitherP<L, R> implements PromiseLike<Either<L, R>> {
263
306
  return new EitherP(this.value.then((e) => e.map(fn)));
264
307
  }
265
308
 
309
+ /**
310
+ * Maps the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
311
+ */
266
312
  mapAsync<R2>(fn: (t: R) => Promise<R2>): EitherP<L, R2> {
267
313
  return this.flatMapAsync(async (value) => Either.right(await fn(value)));
268
314
  }
@@ -274,6 +320,9 @@ export class EitherP<L, R> implements PromiseLike<Either<L, R>> {
274
320
  return new EitherP(this.value.then((e) => e.leftMap(fn)));
275
321
  }
276
322
 
323
+ /**
324
+ * Maps the value of this Either if it is a Left, performs no operation if this is a Right, asynchronously.
325
+ */
277
326
  leftMapAsync<L2>(fn: (t: L) => Promise<L2>): EitherP<L2, R> {
278
327
  return new EitherP(
279
328
  this.value.then(
@@ -293,6 +342,9 @@ export class EitherP<L, R> implements PromiseLike<Either<L, R>> {
293
342
  return new EitherP(this.value.then((e) => e.leftFlatMap(fn)));
294
343
  }
295
344
 
345
+ /**
346
+ * Flat maps the value of this Either if it is a Left, performs no operation if this is a Right, asynchronously.
347
+ */
296
348
  leftFlatMapAsync<L2, R2>(fn: (t: L) => PromiseLike<Either<L2, R2>>): EitherP<L2, R | R2> {
297
349
  return new EitherP(
298
350
  this.value.then<Either<L2, R | R2>>(
@@ -312,6 +364,9 @@ export class EitherP<L, R> implements PromiseLike<Either<L, R>> {
312
364
  return new EitherP(this.value.then((e) => e.bimap(leftFn, rightFn)));
313
365
  }
314
366
 
367
+ /**
368
+ * Applies the provided functions to the value of this Either, depending on whether it is a Right or a Left and returns a new Either, asynchronously.
369
+ */
315
370
  bimapAsync<L2, R2>(
316
371
  leftFn: (l: L) => Promise<L2>,
317
372
  rightFn: (r: R) => Promise<R2>,
@@ -334,6 +389,9 @@ export class EitherP<L, R> implements PromiseLike<Either<L, R>> {
334
389
  return new EitherP(this.value.then((e) => e.tap(fn)));
335
390
  }
336
391
 
392
+ /**
393
+ * Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
394
+ */
337
395
  tapAsync(fn: (t: R) => Promise<void>): EitherP<L, R> {
338
396
  return this.flatMapAsync(async (value) => {
339
397
  await fn(value);
@@ -349,6 +407,10 @@ export class EitherP<L, R> implements PromiseLike<Either<L, R>> {
349
407
  return new EitherP(this.value.then((e) => e.flatTap(fn)));
350
408
  }
351
409
 
410
+ /**
411
+ * Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
412
+ * If the result of the function is a Left, it will be returned, otherwise the original Right value will be returned.
413
+ */
352
414
  flatTapAsync<L2>(fn: (t: R) => PromiseLike<Either<L2, void>>): EitherP<L | L2, R> {
353
415
  return this.flatMapAsync(async (value) => (await fn(value)).map(() => value));
354
416
  }
@@ -360,6 +422,9 @@ export class EitherP<L, R> implements PromiseLike<Either<L, R>> {
360
422
  return new EitherP(this.value.then((e) => e.flatMap(fn)));
361
423
  }
362
424
 
425
+ /**
426
+ * Flat maps the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
427
+ */
363
428
  flatMapAsync<L2, R2>(fn: (t: R) => PromiseLike<Either<L2, R2>>): EitherP<L | L2, R2> {
364
429
  return new EitherP(
365
430
  this.value.then<Either<L | L2, R2>>((e) =>
@@ -443,6 +508,9 @@ export class EitherP<L, R> implements PromiseLike<Either<L, R>> {
443
508
  return new EitherP(value.then((v) => Either.right(v)));
444
509
  }
445
510
 
511
+ /**
512
+ * Creates a Right EitherP from a Promise of a Maybe if it resolves to a defined value, or a Left EitherP from the result of the provided function otherwise.
513
+ */
446
514
  static fromMaybe<L, R>(value: Promise<Maybe<R>>, leftValue: () => Promise<L>): EitherP<L, R> {
447
515
  return new EitherP(
448
516
  value.then(async (v) => (isDefined(v) ? Either.right(v) : Either.left(await leftValue()))),
@@ -450,16 +518,15 @@ export class EitherP<L, R> implements PromiseLike<Either<L, R>> {
450
518
  }
451
519
 
452
520
  /**
453
- * @deprecated
521
+ * Creates a new EitherP from a Promise of an Either.
454
522
  */
455
- static fromEither<L, R>(either: PromiseLike<Either<L, R>>): EitherP<L, R> {
456
- return new EitherP(either);
457
- }
458
-
459
523
  static fromPromise<L, R>(either: PromiseLike<Either<L, R>>): EitherP<L, R> {
460
524
  return new EitherP(either);
461
525
  }
462
526
 
527
+ /**
528
+ * Creates a new Right EitherP if the provided Promise resolves to true, or a new Left EitherP otherwise.
529
+ */
463
530
  static cond<L, R>(
464
531
  bool: Promise<boolean>,
465
532
  leftFn: () => Promise<L>,
@@ -470,6 +537,9 @@ export class EitherP<L, R> implements PromiseLike<Either<L, R>> {
470
537
  );
471
538
  }
472
539
 
540
+ /**
541
+ * Resolves this EitherP to its underlying Either, allowing `await` usage on EitherP instances.
542
+ */
473
543
  // oxlint-disable-next-line unicorn/no-thenable -- Deliberately implementing PromiseLike to allow for `await` usage on EitherP instances.
474
544
  then<U>(onfulfilled?: (value: Either<L, R>) => U | PromiseLike<U>): PromiseLike<U> {
475
545
  return this.value.then(onfulfilled);
package/src/maybe.ts CHANGED
@@ -1,25 +1,89 @@
1
+ /**
2
+ * Represents a value that may be absent.
3
+ */
1
4
  export type Maybe<T> = T | undefined;
2
5
 
6
+ /**
7
+ * Maps the value if it is defined, performs no operation if it is undefined.
8
+ *
9
+ * @example
10
+ *
11
+ * ```ts
12
+ * const value: Maybe<number> = 5;
13
+ * const result: Maybe<string> = mapMaybe(value, (v) => `Value is ${v}`); // "Value is 5"
14
+ *
15
+ * const undefinedValue: Maybe<number> = undefined;
16
+ * const undefinedResult: Maybe<string> = mapMaybe(undefinedValue, (v) => `Value is ${v}`); // undefined
17
+ * ```
18
+ */
3
19
  export function mapMaybe<T, U>(value: Maybe<T>, fn: (value: T) => U): Maybe<U> {
4
20
  return value === undefined ? undefined : fn(value);
5
21
  }
6
22
 
23
+ /**
24
+ * Returns true if the value is defined, false if it is undefined.
25
+ *
26
+ * @example
27
+ *
28
+ * ```ts
29
+ * const definedValue: Maybe<number> = 5;
30
+ *
31
+ * if (isDefined(definedValue)) {
32
+ * console.log(definedValue + 1); // Output: 6
33
+ * }
34
+ * ```
35
+ */
7
36
  export function isDefined<T>(value: Maybe<T>): value is T {
8
37
  return value !== undefined;
9
38
  }
10
39
 
40
+ /**
41
+ * Flattens a nested Maybe into a single Maybe.
42
+ *
43
+ * @example
44
+ *
45
+ * ```ts
46
+ * const nested: Maybe<Maybe<number>> = 5;
47
+ * const flattened: Maybe<number> = flattenMaybe(nested); // 5
48
+ * ```
49
+ */
11
50
  export function flattenMaybe<T>(value: Maybe<Maybe<T>>): Maybe<T> {
12
51
  return mapMaybe(value, (v) => v);
13
52
  }
14
53
 
54
+ /**
55
+ * Returns the result of the provided function if the value is true, undefined otherwise.
56
+ */
15
57
  export function ifTrue<T>(value: boolean, fn: () => T): Maybe<T> {
16
58
  return value ? fn() : undefined;
17
59
  }
18
60
 
61
+ /**
62
+ * Returns the result of the provided function if the value is false, undefined otherwise.
63
+ */
19
64
  export function ifFalse<T>(value: boolean, fn: () => T): Maybe<T> {
20
65
  return !value ? fn() : undefined;
21
66
  }
22
67
 
68
+ /**
69
+ * Matches a pair of Maybe values against the provided cases, depending on which of them are defined.
70
+ *
71
+ * @example
72
+ *
73
+ * ```ts
74
+ * const a: Maybe<number> = 5;
75
+ * const b: Maybe<string> = undefined;
76
+ *
77
+ * const result = matchPair([a, b], {
78
+ * neither: () => 'neither',
79
+ * a: (a) => `a is ${a}`,
80
+ * b: (b) => `b is ${b}`,
81
+ * both: (a, b) => `both are ${a} and ${b}`,
82
+ * });
83
+ *
84
+ * console.log(result); // Output: "a is 5"
85
+ * ```
86
+ */
23
87
  export function matchPair<A, B, R>(
24
88
  [a, b]: [Maybe<A>, Maybe<B>],
25
89
  cases: {