retuple 1.0.0-next.2 → 1.0.0-next.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/dist/index.cjs CHANGED
@@ -12,13 +12,20 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
12
12
  };
13
13
  var _ResultAsync_inner;
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.Result = exports.RetupleThrownValueError = exports.RetupleExpectFailed = exports.RetupleUnwrapErrFailed = exports.RetupleUnwrapFailed = void 0;
15
+ exports.RetupleInvalidResultError = exports.RetupleThrownValueError = exports.RetupleExpectFailed = exports.RetupleUnwrapErrFailed = exports.RetupleUnwrapFailed = void 0;
16
+ exports.Result = Result;
16
17
  exports.Ok = Ok;
17
18
  exports.Err = Err;
18
- exports.from = from;
19
+ exports.nonNullable = nonNullable;
20
+ exports.truthy = truthy;
19
21
  exports.safe = safe;
20
22
  exports.safeAsync = safeAsync;
21
23
  exports.safePromise = safePromise;
24
+ /**
25
+ * ## Retuple Unwrap Failed
26
+ *
27
+ * An error which occurs when calling `$unwrap` on `Err`.
28
+ */
22
29
  class RetupleUnwrapFailed extends Error {
23
30
  constructor(value, msg = "Unwrap failed") {
24
31
  super(msg, value instanceof Error ? { cause: value } : undefined);
@@ -26,6 +33,11 @@ class RetupleUnwrapFailed extends Error {
26
33
  }
27
34
  }
28
35
  exports.RetupleUnwrapFailed = RetupleUnwrapFailed;
36
+ /**
37
+ * ## Retuple Unwrap Err Failed
38
+ *
39
+ * An error which occurs when calling `$unwrapErr` on `Ok`.
40
+ */
29
41
  class RetupleUnwrapErrFailed extends Error {
30
42
  constructor(value, msg = "Unwrap error failed") {
31
43
  super(msg);
@@ -33,6 +45,12 @@ class RetupleUnwrapErrFailed extends Error {
33
45
  }
34
46
  }
35
47
  exports.RetupleUnwrapErrFailed = RetupleUnwrapErrFailed;
48
+ /**
49
+ * ## Retuple Expect Failed
50
+ *
51
+ * An error which occurs when calling `$expect` on `Err`, and when the value
52
+ * contained in the `Err` is not an instance of `Error`.
53
+ */
36
54
  class RetupleExpectFailed extends Error {
37
55
  constructor(value) {
38
56
  super("Expect failed");
@@ -40,6 +58,13 @@ class RetupleExpectFailed extends Error {
40
58
  }
41
59
  }
42
60
  exports.RetupleExpectFailed = RetupleExpectFailed;
61
+ /**
62
+ * ## Retuple Thrown Value Error
63
+ *
64
+ * An error constructed when a safe function call throws or rejects, when the
65
+ * thrown error or rejected value is not an instance of `Error`, and when no
66
+ * map error function is provided.
67
+ */
43
68
  class RetupleThrownValueError extends Error {
44
69
  constructor(value) {
45
70
  super("Caught value was not an instance of Error");
@@ -47,50 +72,76 @@ class RetupleThrownValueError extends Error {
47
72
  }
48
73
  }
49
74
  exports.RetupleThrownValueError = RetupleThrownValueError;
75
+ /**
76
+ * ## Retuple Invalid Result Error
77
+ *
78
+ * An error thrown when attempting to construct a `Result` from a native tuple,
79
+ * when neither index 0 or 1 are null or undefined. In this case, it is impossible
80
+ * to determine whether the result should be `Ok` or `Err`.
81
+ */
82
+ class RetupleInvalidResultError extends Error {
83
+ constructor(value) {
84
+ super("Constructing a Result from native tuple failed, at least one of the values at index 0 or 1 should be null or undefined");
85
+ this.value = value;
86
+ }
87
+ }
88
+ exports.RetupleInvalidResultError = RetupleInvalidResultError;
50
89
  /**
51
90
  * ## Result
52
91
  *
53
92
  * @TODO
54
93
  */
55
- exports.Result = {
56
- Ok,
57
- Err,
58
- from,
59
- safe,
60
- safeAsync,
61
- safePromise,
62
- };
63
- exports.default = exports.Result;
94
+ function Result(resultLike) {
95
+ const [err, ok] = resultLike;
96
+ if (err === null || err === undefined) {
97
+ return new ResultOk(ok);
98
+ }
99
+ if (ok === null || ok === undefined) {
100
+ return new ResultErr(err);
101
+ }
102
+ throw new RetupleInvalidResultError(resultLike);
103
+ }
104
+ Result.Ok = Ok;
105
+ Result.Err = Err;
106
+ Result.nonNullable = nonNullable;
107
+ Result.truthy = truthy;
108
+ Result.safe = safe;
109
+ Result.safeAsync = safeAsync;
110
+ Result.safePromise = safePromise;
111
+ Object.freeze(Result);
64
112
  function Ok(val) {
65
113
  return new ResultOk(val);
66
114
  }
67
115
  function Err(err) {
68
116
  return new ResultErr(err);
69
117
  }
70
- function from(value, error) {
71
- if (value) {
118
+ function nonNullable(value, error = mapTrue) {
119
+ if (value !== null && value !== undefined) {
72
120
  return new ResultOk(value);
73
121
  }
74
- if (error) {
75
- return new ResultErr(error());
122
+ return new ResultErr(error());
123
+ }
124
+ function truthy(value, error = mapTrue) {
125
+ if (value) {
126
+ return new ResultOk(value);
76
127
  }
77
- return new ResultErr(true);
128
+ return new ResultErr(error());
78
129
  }
79
130
  function safe(f, mapError = ensureError) {
80
131
  try {
81
- return Ok(f());
132
+ return new ResultOk(f());
82
133
  }
83
134
  catch (err) {
84
- return Err(mapError(err));
135
+ return new ResultErr(mapError(err));
85
136
  }
86
137
  }
87
138
  function safeAsync(f, mapError = ensureError) {
88
139
  return new ResultAsync((async () => {
89
140
  try {
90
- return Ok(await f());
141
+ return new ResultOk(await f());
91
142
  }
92
143
  catch (err) {
93
- return Err(await mapError(err));
144
+ return new ResultErr(await mapError(err));
94
145
  }
95
146
  })());
96
147
  }
@@ -108,14 +159,23 @@ class ResultOk extends Array {
108
159
  this[0] = undefined;
109
160
  this[1] = value;
110
161
  }
162
+ toJSON() {
163
+ return this[1];
164
+ }
165
+ $toNativeTuple() {
166
+ return [undefined, this[1]];
167
+ }
111
168
  $value() {
112
169
  return this[1];
113
170
  }
171
+ $ok() {
172
+ return this[1];
173
+ }
114
174
  $isOk() {
115
175
  return true;
116
176
  }
117
177
  $isOkAnd(f) {
118
- return f(this[1]);
178
+ return !!f(this[1]);
119
179
  }
120
180
  $isErr() {
121
181
  return false;
@@ -150,6 +210,12 @@ class ResultOk extends Array {
150
210
  $mapOrElse(_def, f) {
151
211
  return new ResultOk(f(this[1]));
152
212
  }
213
+ $assertOr(def, condition = isTruthy) {
214
+ return condition(this[1]) ? this : def;
215
+ }
216
+ $assertOrElse(def, condition = isTruthy) {
217
+ return condition(this[1]) ? this : def();
218
+ }
153
219
  $or() {
154
220
  return this;
155
221
  }
@@ -209,9 +275,18 @@ class ResultErr extends Array {
209
275
  this[0] = err;
210
276
  this[1] = undefined;
211
277
  }
278
+ toJSON() {
279
+ return null;
280
+ }
281
+ $toNativeTuple() {
282
+ return [this[0], undefined];
283
+ }
212
284
  $value() {
213
285
  return this[0];
214
286
  }
287
+ $ok() {
288
+ undefined;
289
+ }
215
290
  $isOk() {
216
291
  return false;
217
292
  }
@@ -222,7 +297,7 @@ class ResultErr extends Array {
222
297
  return true;
223
298
  }
224
299
  $isErrAnd(f) {
225
- return f(this[0]);
300
+ return !!f(this[0]);
226
301
  }
227
302
  $expect() {
228
303
  if (this[0] instanceof Error) {
@@ -254,6 +329,12 @@ class ResultErr extends Array {
254
329
  $mapOrElse(def) {
255
330
  return new ResultOk(def(this[0]));
256
331
  }
332
+ $assertOr() {
333
+ return this;
334
+ }
335
+ $assertOrElse() {
336
+ return this;
337
+ }
257
338
  $or(or) {
258
339
  return or;
259
340
  }
@@ -314,12 +395,24 @@ class ResultAsync {
314
395
  then(onfulfilled, onrejected) {
315
396
  return __classPrivateFieldGet(this, _ResultAsync_inner, "f").then(onfulfilled, onrejected);
316
397
  }
398
+ /**
399
+ * @TODO
400
+ */
401
+ async $toNativeTuple() {
402
+ return (await __classPrivateFieldGet(this, _ResultAsync_inner, "f")).$toNativeTuple();
403
+ }
317
404
  /**
318
405
  * @TODO
319
406
  */
320
407
  async $value() {
321
408
  return (await __classPrivateFieldGet(this, _ResultAsync_inner, "f")).$value();
322
409
  }
410
+ /**
411
+ * @TODO
412
+ */
413
+ async $ok() {
414
+ return (await __classPrivateFieldGet(this, _ResultAsync_inner, "f")).$ok();
415
+ }
323
416
  /**
324
417
  * @TODO
325
418
  */
@@ -391,6 +484,22 @@ class ResultAsync {
391
484
  : new ResultOk(def(res[0]));
392
485
  }));
393
486
  }
487
+ $assertOr(def, condition = isTruthy) {
488
+ return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
489
+ if (res instanceof ResultErr || condition(res[1])) {
490
+ return res;
491
+ }
492
+ return await def;
493
+ }));
494
+ }
495
+ $assertOrElse(def, condition = isTruthy) {
496
+ return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
497
+ if (res instanceof ResultErr || condition(res[1])) {
498
+ return res;
499
+ }
500
+ return await def();
501
+ }));
502
+ }
394
503
  /**
395
504
  * @TODO
396
505
  */
@@ -407,9 +516,6 @@ class ResultAsync {
407
516
  return res instanceof ResultErr ? await f(res[0]) : res;
408
517
  }));
409
518
  }
410
- /**
411
- * @TODO
412
- */
413
519
  $orSafe(f, mapError = ensureError) {
414
520
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
415
521
  if (res instanceof ResultOk) {
@@ -453,9 +559,6 @@ class ResultAsync {
453
559
  return res;
454
560
  }));
455
561
  }
456
- /**
457
- * @TODO
458
- */
459
562
  $andSafe(f, mapError = ensureError) {
460
563
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
461
564
  if (res instanceof ResultErr) {
@@ -514,18 +617,9 @@ function ensureError(err) {
514
617
  }
515
618
  return new RetupleThrownValueError(err);
516
619
  }
517
- Object.freeze(exports.Result);
518
- Object.freeze(ResultOk);
519
- Object.freeze(ResultErr);
520
- Object.freeze(ResultAsync);
521
- Object.freeze(RetupleUnwrapFailed);
522
- Object.freeze(RetupleUnwrapErrFailed);
523
- Object.freeze(RetupleExpectFailed);
524
- Object.freeze(RetupleThrownValueError);
525
- Object.freeze(ResultOk.prototype);
526
- Object.freeze(ResultErr.prototype);
527
- Object.freeze(ResultAsync.prototype);
528
- Object.freeze(RetupleUnwrapFailed.prototype);
529
- Object.freeze(RetupleUnwrapErrFailed.prototype);
530
- Object.freeze(RetupleExpectFailed.prototype);
531
- Object.freeze(RetupleThrownValueError.prototype);
620
+ function mapTrue() {
621
+ return true;
622
+ }
623
+ function isTruthy(val) {
624
+ return !!val;
625
+ }
package/dist/index.d.cts CHANGED
@@ -1,57 +1,103 @@
1
+ export type nonNullable = typeof nonNullable;
2
+ export type truthy = typeof truthy;
3
+ export type safe = typeof safe;
4
+ export type safeAsync = typeof safeAsync;
5
+ export type safePromise = typeof safePromise;
1
6
  export type Ok<T> = OkTuple<T> & Retuple<T, never>;
2
7
  export type Err<E> = ErrTuple<E> & Retuple<never, E>;
3
8
  export type Result<T, E> = (OkTuple<T> | ErrTuple<E>) & Retuple<T, E>;
4
9
  export { type ResultAsync };
5
- export declare class RetupleUnwrapFailed<E = unknown> extends Error {
10
+ /**
11
+ * ## Retuple Unwrap Failed
12
+ *
13
+ * An error which occurs when calling `$unwrap` on `Err`.
14
+ */
15
+ export declare class RetupleUnwrapFailed<const E = unknown> extends Error {
6
16
  value: E;
7
17
  constructor(value: E, msg?: string);
8
18
  }
9
- export declare class RetupleUnwrapErrFailed<T = unknown> extends Error {
19
+ /**
20
+ * ## Retuple Unwrap Err Failed
21
+ *
22
+ * An error which occurs when calling `$unwrapErr` on `Ok`.
23
+ */
24
+ export declare class RetupleUnwrapErrFailed<const T = unknown> extends Error {
10
25
  value: T;
11
26
  constructor(value: T, msg?: string);
12
27
  }
13
- export declare class RetupleExpectFailed<E = unknown> extends Error {
28
+ /**
29
+ * ## Retuple Expect Failed
30
+ *
31
+ * An error which occurs when calling `$expect` on `Err`, and when the value
32
+ * contained in the `Err` is not an instance of `Error`.
33
+ */
34
+ export declare class RetupleExpectFailed<const E = unknown> extends Error {
14
35
  value: E;
15
36
  constructor(value: E);
16
37
  }
38
+ /**
39
+ * ## Retuple Thrown Value Error
40
+ *
41
+ * An error constructed when a safe function call throws or rejects, when the
42
+ * thrown error or rejected value is not an instance of `Error`, and when no
43
+ * map error function is provided.
44
+ */
17
45
  export declare class RetupleThrownValueError extends Error {
18
46
  value: unknown;
19
47
  constructor(value: unknown);
20
48
  }
49
+ /**
50
+ * ## Retuple Invalid Result Error
51
+ *
52
+ * An error thrown when attempting to construct a `Result` from a native tuple,
53
+ * when neither index 0 or 1 are null or undefined. In this case, it is impossible
54
+ * to determine whether the result should be `Ok` or `Err`.
55
+ */
56
+ export declare class RetupleInvalidResultError extends Error {
57
+ value: unknown[];
58
+ constructor(value: unknown[]);
59
+ }
21
60
  /**
22
61
  * ## Result
23
62
  *
24
63
  * @TODO
25
64
  */
26
- export declare const Result: {
27
- Ok: typeof Ok;
28
- Err: typeof Err;
29
- from: typeof from;
30
- safe: typeof safe;
31
- safeAsync: typeof safeAsync;
32
- safePromise: typeof safePromise;
33
- };
34
- export default Result;
65
+ export declare function Result<R extends [err: null | undefined, value: unknown] | [err: unknown, value: null | undefined]>(resultLike: R): (R extends [null | undefined, infer T] ? Ok<T> : R extends [infer E, null | undefined] ? Err<E> : never) extends Ok<infer T> | Err<infer E> ? Result<T, NonNullable<E>> : never;
66
+ export declare namespace Result {
67
+ var Ok: typeof import(".").Ok;
68
+ var Err: typeof import(".").Err;
69
+ var nonNullable: typeof import(".").nonNullable;
70
+ var truthy: typeof import(".").truthy;
71
+ var safe: typeof import(".").safe;
72
+ var safeAsync: typeof import(".").safeAsync;
73
+ var safePromise: typeof import(".").safePromise;
74
+ }
35
75
  /**
36
76
  * ## Ok
37
77
  *
38
78
  * @TODO
39
79
  */
40
80
  export declare function Ok(): Ok<void>;
41
- export declare function Ok<T>(val: T): Ok<T>;
81
+ export declare function Ok<const T>(val: T): Ok<T>;
42
82
  /**
43
83
  * ## Err
44
84
  *
45
85
  * @TODO
46
86
  */
47
87
  export declare function Err(): Err<void>;
48
- export declare function Err<E>(err: E): Err<E>;
88
+ export declare function Err<const E>(err: E): Err<E>;
89
+ /**
90
+ * Construct a {@link Result} from a value. If the value is neither null or
91
+ * undefined, the result is `Ok`.
92
+ */
93
+ export declare function nonNullable<const T>(value: T): Result<NonNullable<T>, true>;
94
+ export declare function nonNullable<const T, const E>(value: T, error: () => E): Result<NonNullable<T>, E>;
49
95
  /**
50
96
  * Construct a {@link Result} from a value. If the value is truthy, the result
51
97
  * is `Ok`.
52
98
  */
53
- export declare function from<T>(value: T): Result<Truthy<T>, true>;
54
- export declare function from<T, E>(value: T, error: () => E): Result<Truthy<T>, E>;
99
+ export declare function truthy<const T>(value: T): Result<Truthy<T>, true>;
100
+ export declare function truthy<const T, const E>(value: T, error: () => E): Result<Truthy<T>, E>;
55
101
  /**
56
102
  * Construct a {@link Result} from a synchronous function call. If the function
57
103
  * returns without throwing, the result is `Ok`.
@@ -78,11 +124,19 @@ export declare function safePromise<T, E>(promise: PromiseLike<T>, mapError: (er
78
124
  declare class ResultAsync<T, E> {
79
125
  #private;
80
126
  constructor(inner: PromiseLike<Result<T, E>>);
81
- then<TResult1 = Result<T, E>, TResult2 = never>(onfulfilled?: ((result: Result<T, E>) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: (reason: any) => TResult2 | PromiseLike<TResult2>): PromiseLike<TResult1 | TResult2>;
127
+ then<U = Result<T, E>, F = never>(onfulfilled?: ((value: Result<T, E>) => U | PromiseLike<U>) | null | undefined, onrejected?: ((reason: any) => F | PromiseLike<F>) | null | undefined): PromiseLike<U | F>;
128
+ /**
129
+ * @TODO
130
+ */
131
+ $toNativeTuple(this: ResultAsync<T, E>): Promise<OkTuple<T> | ErrTuple<E>>;
82
132
  /**
83
133
  * @TODO
84
134
  */
85
135
  $value(this: ResultAsync<T, E>): Promise<T | E>;
136
+ /**
137
+ * @TODO
138
+ */
139
+ $ok(this: ResultAsync<T, E>): Promise<T | undefined>;
86
140
  /**
87
141
  * @TODO
88
142
  */
@@ -102,7 +156,7 @@ declare class ResultAsync<T, E> {
102
156
  /**
103
157
  * @TODO
104
158
  */
105
- $unwrapOrElse<U = T>(this: ResultAsync<T, E>, f: () => U): Promise<T | U>;
159
+ $unwrapOrElse<U>(this: ResultAsync<T, E>, f: () => U): Promise<T | U>;
106
160
  /**
107
161
  * @TODO
108
162
  */
@@ -114,39 +168,52 @@ declare class ResultAsync<T, E> {
114
168
  /**
115
169
  * @TODO
116
170
  */
117
- $mapOr<U>(this: ResultAsync<T, E>, def: U, f: (val: T) => U): ResultAsync<U, E>;
171
+ $mapOr<U, V>(this: ResultAsync<T, E>, def: U, f: (val: T) => V): ResultAsync<U | V, E>;
118
172
  /**
119
173
  * @TODO
120
174
  */
121
- $mapOrElse<U>(this: ResultAsync<T, E>, def: (err: E) => U, f: (val: T) => U): ResultAsync<U, E>;
175
+ $mapOrElse<U, V>(this: ResultAsync<T, E>, def: (err: E) => U, f: (val: T) => V): ResultAsync<U | V, E>;
176
+ /**
177
+ * ## $assertOr
178
+ *
179
+ * {@link Retuple.$assertOr|$assertOr}
180
+ */
181
+ $assertOr<U, F>(this: ResultAsync<T, E>, def: Result<U, F> | PromiseLike<Result<U, F>>): ResultAsync<Truthy<T>, E | F>;
182
+ $assertOr<U, F, A extends T>(this: ResultAsync<T, E>, def: Result<U, F> | PromiseLike<Result<U, F>>, predicate: (val: T) => val is A): ResultAsync<U | A, E | F>;
183
+ $assertOr<U, F>(this: ResultAsync<T, E>, def: Result<U, F> | PromiseLike<Result<U, F>>, condition: (val: T) => unknown): ResultAsync<T | U, E | F>;
184
+ $assertOrElse<U, F>(this: ResultAsync<T, E>, def: () => Result<U, F> | PromiseLike<Result<U, F>>): ResultAsync<Truthy<T>, E | F>;
185
+ $assertOrElse<U, F, A extends T>(this: ResultAsync<T, E>, def: () => Result<U, F> | PromiseLike<Result<U, F>>, predicate: (val: T) => val is A): ResultAsync<U | A, E | F>;
186
+ $assertOrElse<U, F>(this: ResultAsync<T, E>, def: () => Result<U, F> | PromiseLike<Result<U, F>>, condition: (val: T) => unknown): ResultAsync<T | U, E | F>;
122
187
  /**
123
188
  * @TODO
124
189
  */
125
- $or<U = T, F = E>(this: ResultAsync<T, E>, or: Result<U, F> | PromiseLike<Result<U, F>>): ResultAsync<T | U, E | F>;
190
+ $or<U, F>(this: ResultAsync<T, E>, or: Result<U, F> | PromiseLike<Result<U, F>>): ResultAsync<T | U, E | F>;
126
191
  /**
127
192
  * @TODO
128
193
  */
129
- $orElse<U = T, F = E>(this: ResultAsync<T, E>, f: (err: E) => Result<U, F> | PromiseLike<Result<U, F>>): ResultAsync<T | U, E | F>;
194
+ $orElse<U, F>(this: ResultAsync<T, E>, f: (err: E) => Result<U, F> | PromiseLike<Result<U, F>>): ResultAsync<T | U, E | F>;
130
195
  /**
131
196
  * @TODO
132
197
  */
133
- $orSafe<U = T, F = Error>(this: ResultAsync<T, E>, f: (err: E) => U | PromiseLike<U>, mapError?: (err: unknown) => F): ResultAsync<T | U, E | F>;
198
+ $orSafe<U>(this: ResultAsync<T, E>, f: (err: E) => U | PromiseLike<U>): ResultAsync<T | U, E | Error>;
199
+ $orSafe<U, F>(this: ResultAsync<T, E>, f: (err: E) => U | PromiseLike<U>, mapError: (err: unknown) => F): ResultAsync<T | U, E | F>;
134
200
  /**
135
201
  * @TODO
136
202
  */
137
- $and<U = T, F = E>(this: ResultAsync<T, E>, and: Result<U, F> | PromiseLike<Result<U, F>>): ResultAsync<U, E | F>;
203
+ $and<U, F>(this: ResultAsync<T, E>, and: Result<U, F> | PromiseLike<Result<U, F>>): ResultAsync<U, E | F>;
138
204
  /**
139
205
  * @TODO
140
206
  */
141
- $andThen<U = T, F = E>(this: ResultAsync<T, E>, f: (val: T) => Result<U, F> | PromiseLike<Result<U, F>>): ResultAsync<U, E | F>;
207
+ $andThen<U, F>(this: ResultAsync<T, E>, f: (val: T) => Result<U, F> | PromiseLike<Result<U, F>>): ResultAsync<U, E | F>;
142
208
  /**
143
209
  * @TODO
144
210
  */
145
- $andThrough<F = E>(this: ResultAsync<T, E>, f: (val: T) => Result<any, F> | PromiseLike<Result<any, F>>): ResultAsync<T, E | F>;
211
+ $andThrough<F>(this: ResultAsync<T, E>, f: (val: T) => Result<any, F> | PromiseLike<Result<any, F>>): ResultAsync<T, E | F>;
146
212
  /**
147
213
  * @TODO
148
214
  */
149
- $andSafe<U = T, F = Error>(this: ResultAsync<T, E>, f: (val: T) => U | PromiseLike<U>, mapError?: (err: unknown) => F): ResultAsync<U, E | F>;
215
+ $andSafe<U>(this: ResultAsync<T, E>, f: (val: T) => U | PromiseLike<U>): ResultAsync<T | U, E | Error>;
216
+ $andSafe<U, F>(this: ResultAsync<T, E>, f: (val: T) => U | PromiseLike<U>, mapError: (err: unknown) => F): ResultAsync<T | U, E | F>;
150
217
  /**
151
218
  * @TODO
152
219
  */
@@ -174,23 +241,33 @@ interface Retuple<T, E> {
174
241
  /**
175
242
  * @TODO
176
243
  */
177
- $isOk(this: Result<T, E>): this is Ok<T>;
244
+ $toNativeTuple(this: Result<T, E>): OkTuple<T> | ErrTuple<E>;
178
245
  /**
179
246
  * @TODO
180
247
  */
181
- $isOkAnd<U extends T = T>(this: Result<T, E>, f: ((val: T) => val is U) | ((val: T) => boolean)): this is Ok<U>;
248
+ $value(this: Result<T, E>): T | E;
182
249
  /**
183
250
  * @TODO
184
251
  */
185
- $isErr(this: Result<T, E>): this is Err<E>;
252
+ $ok(this: Result<T, E>): T | undefined;
186
253
  /**
187
254
  * @TODO
188
255
  */
189
- $isErrAnd<F extends E = E>(this: Result<T, E>, f: ((err: E) => err is F) | ((err: E) => boolean)): this is Err<F>;
256
+ $isOk(this: Result<T, E>): this is Ok<T>;
190
257
  /**
191
258
  * @TODO
192
259
  */
193
- $value(this: Result<T, E>): T | E;
260
+ $isOkAnd<U extends T>(this: Result<T, E>, predicate: (val: T) => val is U): this is Ok<U>;
261
+ $isOkAnd(this: Result<T, E>, predicate: (val: T) => unknown): this is Ok<T>;
262
+ /**
263
+ * @TODO
264
+ */
265
+ $isErr(this: Result<T, E>): this is Err<E>;
266
+ /**
267
+ * @TODO
268
+ */
269
+ $isErrAnd<F extends E>(this: Result<T, E>, prediacte: (val: E) => val is F): this is Err<F>;
270
+ $isErrAnd(this: Result<T, E>, predicate: (val: E) => unknown): this is Err<E>;
194
271
  /**
195
272
  * @TODO
196
273
  */
@@ -206,11 +283,11 @@ interface Retuple<T, E> {
206
283
  /**
207
284
  * @TODO
208
285
  */
209
- $unwrapOr<U = T>(this: Result<T, E>, def: U): T | U;
286
+ $unwrapOr<const U>(this: Result<T, E>, def: U): T | U;
210
287
  /**
211
288
  * @TODO
212
289
  */
213
- $unwrapOrElse<U = T>(this: Result<T, E>, f: () => U): T | U;
290
+ $unwrapOrElse<U>(this: Result<T, E>, f: () => U): T | U;
214
291
  /**
215
292
  * @TODO
216
293
  */
@@ -222,43 +299,53 @@ interface Retuple<T, E> {
222
299
  /**
223
300
  * @TODO
224
301
  */
225
- $mapOr<U>(this: Result<T, E>, def: U, f: (val: T) => U): Result<U, E>;
302
+ $mapOr<U, V = U>(this: Result<T, E>, def: U, f: (val: T) => V): Result<U | V, E>;
303
+ /**
304
+ * @TODO
305
+ */
306
+ $mapOrElse<U, V = U>(this: Result<T, E>, def: (err: E) => U, f: (val: T) => V): Result<U | V, E>;
307
+ /**
308
+ * @TODO
309
+ */
310
+ $or<U, F>(this: Result<T, E>, or: Result<U, F>): Result<T | U, E | F>;
226
311
  /**
227
312
  * @TODO
228
313
  */
229
- $mapOrElse<U>(this: Result<T, E>, def: (err: E) => U, f: (val: T) => U): Result<U, E>;
314
+ $orElse<U, F>(this: Result<T, E>, f: (err: E) => Result<U, F>): Result<T | U, E | F>;
230
315
  /**
231
316
  * @TODO
232
317
  */
233
- $or<U = T, F = E>(this: Result<T, E>, or: Result<U, F>): Result<T | U, E | F>;
318
+ $orSafe<U>(this: Result<T, E>, f: (err: E) => U): Result<T | U, E | Error>;
319
+ $orSafe<U, F>(this: Result<T, E>, f: (err: E) => U, mapError: (err: unknown) => F): Result<T | U, E | F>;
234
320
  /**
235
321
  * @TODO
236
322
  */
237
- $orElse<U = never, F = never>(this: Result<T, E>, f: (err: E) => Result<U, F>): Result<T | U, E | F>;
323
+ $and<U, F>(this: Result<T, E>, and: Result<U, F>): Result<U, E | F>;
238
324
  /**
239
325
  * @TODO
240
326
  */
241
- $orSafe<U = T>(this: Result<T, E>, f: (err: E) => U): Result<T | U, E | Error>;
242
- $orSafe<U = T, F = E>(this: Result<T, E>, f: (err: E) => U, mapError: (err: unknown) => F): Result<T | U, E | F>;
243
- $orSafe<U = T, F = Error>(this: Result<T, E>, f: (err: E) => U, mapError: (err: unknown) => F): Result<T | U, E | F>;
327
+ $andThen<U, F>(this: Result<T, E>, f: (val: T) => Result<U, F>): Result<U, E | F>;
244
328
  /**
245
329
  * @TODO
246
330
  */
247
- $and<U = T, F = E>(this: Result<T, E>, and: Result<U, F>): Result<U, E | F>;
331
+ $andThrough<F>(this: Result<T, E>, f: (val: T) => Result<any, F>): Result<T, E | F>;
248
332
  /**
249
333
  * @TODO
250
334
  */
251
- $andThen<U = never, F = never>(this: Result<T, E>, f: (val: T) => Result<U, F>): Result<U, E | F>;
335
+ $andSafe<U>(this: Result<T, E>, f: (val: T) => U): Result<T | U, E | Error>;
336
+ $andSafe<U, F>(this: Result<T, E>, f: (val: T) => U, mapError: (err: unknown) => F): Result<T | U, E | F>;
252
337
  /**
253
338
  * @TODO
254
339
  */
255
- $andThrough<F = never>(this: Result<T, E>, f: (val: T) => Result<any, F>): Result<T, E | F>;
340
+ $assertOr<U, F>(this: Result<T, E>, def: Result<U, F>): Result<Truthy<T>, E | F>;
341
+ $assertOr<U, F, A extends T>(this: Result<T, E>, def: Result<U, F>, predicate: (val: T) => val is A): Result<U | A, E | F>;
342
+ $assertOr<U, F>(this: Result<T, E>, def: Result<U, F>, condition: (val: T) => unknown): Result<T | U, E | F>;
256
343
  /**
257
344
  * @TODO
258
345
  */
259
- $andSafe<U = T>(this: Result<T, E>, f: (val: T) => U): Result<T | U, E | Error>;
260
- $andSafe<U = T, F = E>(this: Result<T, E>, f: (val: T) => U, mapError: (err: unknown) => F): Result<T | U, E | F>;
261
- $andSafe<U, F = Error>(this: Result<T, E>, f: (val: T) => U, mapError: (err: unknown) => F): Result<T | U, E | F>;
346
+ $assertOrElse<U, F>(this: Result<T, E>, def: () => Result<U, F>): Result<Truthy<T>, E | F>;
347
+ $assertOrElse<U, F, A extends T>(this: Result<T, E>, def: () => Result<U, F>, predicate: (val: T) => val is A): Result<U | A, E | F>;
348
+ $assertOrElse<U, F>(this: Result<T, E>, def: () => Result<U, F>, condition: (val: T) => unknown): Result<T | U, E | F>;
262
349
  /**
263
350
  * @TODO
264
351
  */
package/dist/index.d.ts CHANGED
@@ -1,57 +1,103 @@
1
+ export type nonNullable = typeof nonNullable;
2
+ export type truthy = typeof truthy;
3
+ export type safe = typeof safe;
4
+ export type safeAsync = typeof safeAsync;
5
+ export type safePromise = typeof safePromise;
1
6
  export type Ok<T> = OkTuple<T> & Retuple<T, never>;
2
7
  export type Err<E> = ErrTuple<E> & Retuple<never, E>;
3
8
  export type Result<T, E> = (OkTuple<T> | ErrTuple<E>) & Retuple<T, E>;
4
9
  export { type ResultAsync };
5
- export declare class RetupleUnwrapFailed<E = unknown> extends Error {
10
+ /**
11
+ * ## Retuple Unwrap Failed
12
+ *
13
+ * An error which occurs when calling `$unwrap` on `Err`.
14
+ */
15
+ export declare class RetupleUnwrapFailed<const E = unknown> extends Error {
6
16
  value: E;
7
17
  constructor(value: E, msg?: string);
8
18
  }
9
- export declare class RetupleUnwrapErrFailed<T = unknown> extends Error {
19
+ /**
20
+ * ## Retuple Unwrap Err Failed
21
+ *
22
+ * An error which occurs when calling `$unwrapErr` on `Ok`.
23
+ */
24
+ export declare class RetupleUnwrapErrFailed<const T = unknown> extends Error {
10
25
  value: T;
11
26
  constructor(value: T, msg?: string);
12
27
  }
13
- export declare class RetupleExpectFailed<E = unknown> extends Error {
28
+ /**
29
+ * ## Retuple Expect Failed
30
+ *
31
+ * An error which occurs when calling `$expect` on `Err`, and when the value
32
+ * contained in the `Err` is not an instance of `Error`.
33
+ */
34
+ export declare class RetupleExpectFailed<const E = unknown> extends Error {
14
35
  value: E;
15
36
  constructor(value: E);
16
37
  }
38
+ /**
39
+ * ## Retuple Thrown Value Error
40
+ *
41
+ * An error constructed when a safe function call throws or rejects, when the
42
+ * thrown error or rejected value is not an instance of `Error`, and when no
43
+ * map error function is provided.
44
+ */
17
45
  export declare class RetupleThrownValueError extends Error {
18
46
  value: unknown;
19
47
  constructor(value: unknown);
20
48
  }
49
+ /**
50
+ * ## Retuple Invalid Result Error
51
+ *
52
+ * An error thrown when attempting to construct a `Result` from a native tuple,
53
+ * when neither index 0 or 1 are null or undefined. In this case, it is impossible
54
+ * to determine whether the result should be `Ok` or `Err`.
55
+ */
56
+ export declare class RetupleInvalidResultError extends Error {
57
+ value: unknown[];
58
+ constructor(value: unknown[]);
59
+ }
21
60
  /**
22
61
  * ## Result
23
62
  *
24
63
  * @TODO
25
64
  */
26
- export declare const Result: {
27
- Ok: typeof Ok;
28
- Err: typeof Err;
29
- from: typeof from;
30
- safe: typeof safe;
31
- safeAsync: typeof safeAsync;
32
- safePromise: typeof safePromise;
33
- };
34
- export default Result;
65
+ export declare function Result<R extends [err: null | undefined, value: unknown] | [err: unknown, value: null | undefined]>(resultLike: R): (R extends [null | undefined, infer T] ? Ok<T> : R extends [infer E, null | undefined] ? Err<E> : never) extends Ok<infer T> | Err<infer E> ? Result<T, NonNullable<E>> : never;
66
+ export declare namespace Result {
67
+ var Ok: typeof import(".").Ok;
68
+ var Err: typeof import(".").Err;
69
+ var nonNullable: typeof import(".").nonNullable;
70
+ var truthy: typeof import(".").truthy;
71
+ var safe: typeof import(".").safe;
72
+ var safeAsync: typeof import(".").safeAsync;
73
+ var safePromise: typeof import(".").safePromise;
74
+ }
35
75
  /**
36
76
  * ## Ok
37
77
  *
38
78
  * @TODO
39
79
  */
40
80
  export declare function Ok(): Ok<void>;
41
- export declare function Ok<T>(val: T): Ok<T>;
81
+ export declare function Ok<const T>(val: T): Ok<T>;
42
82
  /**
43
83
  * ## Err
44
84
  *
45
85
  * @TODO
46
86
  */
47
87
  export declare function Err(): Err<void>;
48
- export declare function Err<E>(err: E): Err<E>;
88
+ export declare function Err<const E>(err: E): Err<E>;
89
+ /**
90
+ * Construct a {@link Result} from a value. If the value is neither null or
91
+ * undefined, the result is `Ok`.
92
+ */
93
+ export declare function nonNullable<const T>(value: T): Result<NonNullable<T>, true>;
94
+ export declare function nonNullable<const T, const E>(value: T, error: () => E): Result<NonNullable<T>, E>;
49
95
  /**
50
96
  * Construct a {@link Result} from a value. If the value is truthy, the result
51
97
  * is `Ok`.
52
98
  */
53
- export declare function from<T>(value: T): Result<Truthy<T>, true>;
54
- export declare function from<T, E>(value: T, error: () => E): Result<Truthy<T>, E>;
99
+ export declare function truthy<const T>(value: T): Result<Truthy<T>, true>;
100
+ export declare function truthy<const T, const E>(value: T, error: () => E): Result<Truthy<T>, E>;
55
101
  /**
56
102
  * Construct a {@link Result} from a synchronous function call. If the function
57
103
  * returns without throwing, the result is `Ok`.
@@ -78,11 +124,19 @@ export declare function safePromise<T, E>(promise: PromiseLike<T>, mapError: (er
78
124
  declare class ResultAsync<T, E> {
79
125
  #private;
80
126
  constructor(inner: PromiseLike<Result<T, E>>);
81
- then<TResult1 = Result<T, E>, TResult2 = never>(onfulfilled?: ((result: Result<T, E>) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: (reason: any) => TResult2 | PromiseLike<TResult2>): PromiseLike<TResult1 | TResult2>;
127
+ then<U = Result<T, E>, F = never>(onfulfilled?: ((value: Result<T, E>) => U | PromiseLike<U>) | null | undefined, onrejected?: ((reason: any) => F | PromiseLike<F>) | null | undefined): PromiseLike<U | F>;
128
+ /**
129
+ * @TODO
130
+ */
131
+ $toNativeTuple(this: ResultAsync<T, E>): Promise<OkTuple<T> | ErrTuple<E>>;
82
132
  /**
83
133
  * @TODO
84
134
  */
85
135
  $value(this: ResultAsync<T, E>): Promise<T | E>;
136
+ /**
137
+ * @TODO
138
+ */
139
+ $ok(this: ResultAsync<T, E>): Promise<T | undefined>;
86
140
  /**
87
141
  * @TODO
88
142
  */
@@ -102,7 +156,7 @@ declare class ResultAsync<T, E> {
102
156
  /**
103
157
  * @TODO
104
158
  */
105
- $unwrapOrElse<U = T>(this: ResultAsync<T, E>, f: () => U): Promise<T | U>;
159
+ $unwrapOrElse<U>(this: ResultAsync<T, E>, f: () => U): Promise<T | U>;
106
160
  /**
107
161
  * @TODO
108
162
  */
@@ -114,39 +168,52 @@ declare class ResultAsync<T, E> {
114
168
  /**
115
169
  * @TODO
116
170
  */
117
- $mapOr<U>(this: ResultAsync<T, E>, def: U, f: (val: T) => U): ResultAsync<U, E>;
171
+ $mapOr<U, V>(this: ResultAsync<T, E>, def: U, f: (val: T) => V): ResultAsync<U | V, E>;
118
172
  /**
119
173
  * @TODO
120
174
  */
121
- $mapOrElse<U>(this: ResultAsync<T, E>, def: (err: E) => U, f: (val: T) => U): ResultAsync<U, E>;
175
+ $mapOrElse<U, V>(this: ResultAsync<T, E>, def: (err: E) => U, f: (val: T) => V): ResultAsync<U | V, E>;
176
+ /**
177
+ * ## $assertOr
178
+ *
179
+ * {@link Retuple.$assertOr|$assertOr}
180
+ */
181
+ $assertOr<U, F>(this: ResultAsync<T, E>, def: Result<U, F> | PromiseLike<Result<U, F>>): ResultAsync<Truthy<T>, E | F>;
182
+ $assertOr<U, F, A extends T>(this: ResultAsync<T, E>, def: Result<U, F> | PromiseLike<Result<U, F>>, predicate: (val: T) => val is A): ResultAsync<U | A, E | F>;
183
+ $assertOr<U, F>(this: ResultAsync<T, E>, def: Result<U, F> | PromiseLike<Result<U, F>>, condition: (val: T) => unknown): ResultAsync<T | U, E | F>;
184
+ $assertOrElse<U, F>(this: ResultAsync<T, E>, def: () => Result<U, F> | PromiseLike<Result<U, F>>): ResultAsync<Truthy<T>, E | F>;
185
+ $assertOrElse<U, F, A extends T>(this: ResultAsync<T, E>, def: () => Result<U, F> | PromiseLike<Result<U, F>>, predicate: (val: T) => val is A): ResultAsync<U | A, E | F>;
186
+ $assertOrElse<U, F>(this: ResultAsync<T, E>, def: () => Result<U, F> | PromiseLike<Result<U, F>>, condition: (val: T) => unknown): ResultAsync<T | U, E | F>;
122
187
  /**
123
188
  * @TODO
124
189
  */
125
- $or<U = T, F = E>(this: ResultAsync<T, E>, or: Result<U, F> | PromiseLike<Result<U, F>>): ResultAsync<T | U, E | F>;
190
+ $or<U, F>(this: ResultAsync<T, E>, or: Result<U, F> | PromiseLike<Result<U, F>>): ResultAsync<T | U, E | F>;
126
191
  /**
127
192
  * @TODO
128
193
  */
129
- $orElse<U = T, F = E>(this: ResultAsync<T, E>, f: (err: E) => Result<U, F> | PromiseLike<Result<U, F>>): ResultAsync<T | U, E | F>;
194
+ $orElse<U, F>(this: ResultAsync<T, E>, f: (err: E) => Result<U, F> | PromiseLike<Result<U, F>>): ResultAsync<T | U, E | F>;
130
195
  /**
131
196
  * @TODO
132
197
  */
133
- $orSafe<U = T, F = Error>(this: ResultAsync<T, E>, f: (err: E) => U | PromiseLike<U>, mapError?: (err: unknown) => F): ResultAsync<T | U, E | F>;
198
+ $orSafe<U>(this: ResultAsync<T, E>, f: (err: E) => U | PromiseLike<U>): ResultAsync<T | U, E | Error>;
199
+ $orSafe<U, F>(this: ResultAsync<T, E>, f: (err: E) => U | PromiseLike<U>, mapError: (err: unknown) => F): ResultAsync<T | U, E | F>;
134
200
  /**
135
201
  * @TODO
136
202
  */
137
- $and<U = T, F = E>(this: ResultAsync<T, E>, and: Result<U, F> | PromiseLike<Result<U, F>>): ResultAsync<U, E | F>;
203
+ $and<U, F>(this: ResultAsync<T, E>, and: Result<U, F> | PromiseLike<Result<U, F>>): ResultAsync<U, E | F>;
138
204
  /**
139
205
  * @TODO
140
206
  */
141
- $andThen<U = T, F = E>(this: ResultAsync<T, E>, f: (val: T) => Result<U, F> | PromiseLike<Result<U, F>>): ResultAsync<U, E | F>;
207
+ $andThen<U, F>(this: ResultAsync<T, E>, f: (val: T) => Result<U, F> | PromiseLike<Result<U, F>>): ResultAsync<U, E | F>;
142
208
  /**
143
209
  * @TODO
144
210
  */
145
- $andThrough<F = E>(this: ResultAsync<T, E>, f: (val: T) => Result<any, F> | PromiseLike<Result<any, F>>): ResultAsync<T, E | F>;
211
+ $andThrough<F>(this: ResultAsync<T, E>, f: (val: T) => Result<any, F> | PromiseLike<Result<any, F>>): ResultAsync<T, E | F>;
146
212
  /**
147
213
  * @TODO
148
214
  */
149
- $andSafe<U = T, F = Error>(this: ResultAsync<T, E>, f: (val: T) => U | PromiseLike<U>, mapError?: (err: unknown) => F): ResultAsync<U, E | F>;
215
+ $andSafe<U>(this: ResultAsync<T, E>, f: (val: T) => U | PromiseLike<U>): ResultAsync<T | U, E | Error>;
216
+ $andSafe<U, F>(this: ResultAsync<T, E>, f: (val: T) => U | PromiseLike<U>, mapError: (err: unknown) => F): ResultAsync<T | U, E | F>;
150
217
  /**
151
218
  * @TODO
152
219
  */
@@ -174,23 +241,33 @@ interface Retuple<T, E> {
174
241
  /**
175
242
  * @TODO
176
243
  */
177
- $isOk(this: Result<T, E>): this is Ok<T>;
244
+ $toNativeTuple(this: Result<T, E>): OkTuple<T> | ErrTuple<E>;
178
245
  /**
179
246
  * @TODO
180
247
  */
181
- $isOkAnd<U extends T = T>(this: Result<T, E>, f: ((val: T) => val is U) | ((val: T) => boolean)): this is Ok<U>;
248
+ $value(this: Result<T, E>): T | E;
182
249
  /**
183
250
  * @TODO
184
251
  */
185
- $isErr(this: Result<T, E>): this is Err<E>;
252
+ $ok(this: Result<T, E>): T | undefined;
186
253
  /**
187
254
  * @TODO
188
255
  */
189
- $isErrAnd<F extends E = E>(this: Result<T, E>, f: ((err: E) => err is F) | ((err: E) => boolean)): this is Err<F>;
256
+ $isOk(this: Result<T, E>): this is Ok<T>;
190
257
  /**
191
258
  * @TODO
192
259
  */
193
- $value(this: Result<T, E>): T | E;
260
+ $isOkAnd<U extends T>(this: Result<T, E>, predicate: (val: T) => val is U): this is Ok<U>;
261
+ $isOkAnd(this: Result<T, E>, predicate: (val: T) => unknown): this is Ok<T>;
262
+ /**
263
+ * @TODO
264
+ */
265
+ $isErr(this: Result<T, E>): this is Err<E>;
266
+ /**
267
+ * @TODO
268
+ */
269
+ $isErrAnd<F extends E>(this: Result<T, E>, prediacte: (val: E) => val is F): this is Err<F>;
270
+ $isErrAnd(this: Result<T, E>, predicate: (val: E) => unknown): this is Err<E>;
194
271
  /**
195
272
  * @TODO
196
273
  */
@@ -206,11 +283,11 @@ interface Retuple<T, E> {
206
283
  /**
207
284
  * @TODO
208
285
  */
209
- $unwrapOr<U = T>(this: Result<T, E>, def: U): T | U;
286
+ $unwrapOr<const U>(this: Result<T, E>, def: U): T | U;
210
287
  /**
211
288
  * @TODO
212
289
  */
213
- $unwrapOrElse<U = T>(this: Result<T, E>, f: () => U): T | U;
290
+ $unwrapOrElse<U>(this: Result<T, E>, f: () => U): T | U;
214
291
  /**
215
292
  * @TODO
216
293
  */
@@ -222,43 +299,53 @@ interface Retuple<T, E> {
222
299
  /**
223
300
  * @TODO
224
301
  */
225
- $mapOr<U>(this: Result<T, E>, def: U, f: (val: T) => U): Result<U, E>;
302
+ $mapOr<U, V = U>(this: Result<T, E>, def: U, f: (val: T) => V): Result<U | V, E>;
303
+ /**
304
+ * @TODO
305
+ */
306
+ $mapOrElse<U, V = U>(this: Result<T, E>, def: (err: E) => U, f: (val: T) => V): Result<U | V, E>;
307
+ /**
308
+ * @TODO
309
+ */
310
+ $or<U, F>(this: Result<T, E>, or: Result<U, F>): Result<T | U, E | F>;
226
311
  /**
227
312
  * @TODO
228
313
  */
229
- $mapOrElse<U>(this: Result<T, E>, def: (err: E) => U, f: (val: T) => U): Result<U, E>;
314
+ $orElse<U, F>(this: Result<T, E>, f: (err: E) => Result<U, F>): Result<T | U, E | F>;
230
315
  /**
231
316
  * @TODO
232
317
  */
233
- $or<U = T, F = E>(this: Result<T, E>, or: Result<U, F>): Result<T | U, E | F>;
318
+ $orSafe<U>(this: Result<T, E>, f: (err: E) => U): Result<T | U, E | Error>;
319
+ $orSafe<U, F>(this: Result<T, E>, f: (err: E) => U, mapError: (err: unknown) => F): Result<T | U, E | F>;
234
320
  /**
235
321
  * @TODO
236
322
  */
237
- $orElse<U = never, F = never>(this: Result<T, E>, f: (err: E) => Result<U, F>): Result<T | U, E | F>;
323
+ $and<U, F>(this: Result<T, E>, and: Result<U, F>): Result<U, E | F>;
238
324
  /**
239
325
  * @TODO
240
326
  */
241
- $orSafe<U = T>(this: Result<T, E>, f: (err: E) => U): Result<T | U, E | Error>;
242
- $orSafe<U = T, F = E>(this: Result<T, E>, f: (err: E) => U, mapError: (err: unknown) => F): Result<T | U, E | F>;
243
- $orSafe<U = T, F = Error>(this: Result<T, E>, f: (err: E) => U, mapError: (err: unknown) => F): Result<T | U, E | F>;
327
+ $andThen<U, F>(this: Result<T, E>, f: (val: T) => Result<U, F>): Result<U, E | F>;
244
328
  /**
245
329
  * @TODO
246
330
  */
247
- $and<U = T, F = E>(this: Result<T, E>, and: Result<U, F>): Result<U, E | F>;
331
+ $andThrough<F>(this: Result<T, E>, f: (val: T) => Result<any, F>): Result<T, E | F>;
248
332
  /**
249
333
  * @TODO
250
334
  */
251
- $andThen<U = never, F = never>(this: Result<T, E>, f: (val: T) => Result<U, F>): Result<U, E | F>;
335
+ $andSafe<U>(this: Result<T, E>, f: (val: T) => U): Result<T | U, E | Error>;
336
+ $andSafe<U, F>(this: Result<T, E>, f: (val: T) => U, mapError: (err: unknown) => F): Result<T | U, E | F>;
252
337
  /**
253
338
  * @TODO
254
339
  */
255
- $andThrough<F = never>(this: Result<T, E>, f: (val: T) => Result<any, F>): Result<T, E | F>;
340
+ $assertOr<U, F>(this: Result<T, E>, def: Result<U, F>): Result<Truthy<T>, E | F>;
341
+ $assertOr<U, F, A extends T>(this: Result<T, E>, def: Result<U, F>, predicate: (val: T) => val is A): Result<U | A, E | F>;
342
+ $assertOr<U, F>(this: Result<T, E>, def: Result<U, F>, condition: (val: T) => unknown): Result<T | U, E | F>;
256
343
  /**
257
344
  * @TODO
258
345
  */
259
- $andSafe<U = T>(this: Result<T, E>, f: (val: T) => U): Result<T | U, E | Error>;
260
- $andSafe<U = T, F = E>(this: Result<T, E>, f: (val: T) => U, mapError: (err: unknown) => F): Result<T | U, E | F>;
261
- $andSafe<U, F = Error>(this: Result<T, E>, f: (val: T) => U, mapError: (err: unknown) => F): Result<T | U, E | F>;
346
+ $assertOrElse<U, F>(this: Result<T, E>, def: () => Result<U, F>): Result<Truthy<T>, E | F>;
347
+ $assertOrElse<U, F, A extends T>(this: Result<T, E>, def: () => Result<U, F>, predicate: (val: T) => val is A): Result<U | A, E | F>;
348
+ $assertOrElse<U, F>(this: Result<T, E>, def: () => Result<U, F>, condition: (val: T) => unknown): Result<T | U, E | F>;
262
349
  /**
263
350
  * @TODO
264
351
  */
package/dist/index.js CHANGED
@@ -10,74 +10,122 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
10
10
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
11
  };
12
12
  var _ResultAsync_inner;
13
+ /**
14
+ * ## Retuple Unwrap Failed
15
+ *
16
+ * An error which occurs when calling `$unwrap` on `Err`.
17
+ */
13
18
  export class RetupleUnwrapFailed extends Error {
14
19
  constructor(value, msg = "Unwrap failed") {
15
20
  super(msg, value instanceof Error ? { cause: value } : undefined);
16
21
  this.value = value;
17
22
  }
18
23
  }
24
+ /**
25
+ * ## Retuple Unwrap Err Failed
26
+ *
27
+ * An error which occurs when calling `$unwrapErr` on `Ok`.
28
+ */
19
29
  export class RetupleUnwrapErrFailed extends Error {
20
30
  constructor(value, msg = "Unwrap error failed") {
21
31
  super(msg);
22
32
  this.value = value;
23
33
  }
24
34
  }
35
+ /**
36
+ * ## Retuple Expect Failed
37
+ *
38
+ * An error which occurs when calling `$expect` on `Err`, and when the value
39
+ * contained in the `Err` is not an instance of `Error`.
40
+ */
25
41
  export class RetupleExpectFailed extends Error {
26
42
  constructor(value) {
27
43
  super("Expect failed");
28
44
  this.value = value;
29
45
  }
30
46
  }
47
+ /**
48
+ * ## Retuple Thrown Value Error
49
+ *
50
+ * An error constructed when a safe function call throws or rejects, when the
51
+ * thrown error or rejected value is not an instance of `Error`, and when no
52
+ * map error function is provided.
53
+ */
31
54
  export class RetupleThrownValueError extends Error {
32
55
  constructor(value) {
33
56
  super("Caught value was not an instance of Error");
34
57
  this.value = value;
35
58
  }
36
59
  }
60
+ /**
61
+ * ## Retuple Invalid Result Error
62
+ *
63
+ * An error thrown when attempting to construct a `Result` from a native tuple,
64
+ * when neither index 0 or 1 are null or undefined. In this case, it is impossible
65
+ * to determine whether the result should be `Ok` or `Err`.
66
+ */
67
+ export class RetupleInvalidResultError extends Error {
68
+ constructor(value) {
69
+ super("Constructing a Result from native tuple failed, at least one of the values at index 0 or 1 should be null or undefined");
70
+ this.value = value;
71
+ }
72
+ }
37
73
  /**
38
74
  * ## Result
39
75
  *
40
76
  * @TODO
41
77
  */
42
- export const Result = {
43
- Ok,
44
- Err,
45
- from,
46
- safe,
47
- safeAsync,
48
- safePromise,
49
- };
50
- export default Result;
78
+ export function Result(resultLike) {
79
+ const [err, ok] = resultLike;
80
+ if (err === null || err === undefined) {
81
+ return new ResultOk(ok);
82
+ }
83
+ if (ok === null || ok === undefined) {
84
+ return new ResultErr(err);
85
+ }
86
+ throw new RetupleInvalidResultError(resultLike);
87
+ }
88
+ Result.Ok = Ok;
89
+ Result.Err = Err;
90
+ Result.nonNullable = nonNullable;
91
+ Result.truthy = truthy;
92
+ Result.safe = safe;
93
+ Result.safeAsync = safeAsync;
94
+ Result.safePromise = safePromise;
95
+ Object.freeze(Result);
51
96
  export function Ok(val) {
52
97
  return new ResultOk(val);
53
98
  }
54
99
  export function Err(err) {
55
100
  return new ResultErr(err);
56
101
  }
57
- export function from(value, error) {
58
- if (value) {
102
+ export function nonNullable(value, error = mapTrue) {
103
+ if (value !== null && value !== undefined) {
59
104
  return new ResultOk(value);
60
105
  }
61
- if (error) {
62
- return new ResultErr(error());
106
+ return new ResultErr(error());
107
+ }
108
+ export function truthy(value, error = mapTrue) {
109
+ if (value) {
110
+ return new ResultOk(value);
63
111
  }
64
- return new ResultErr(true);
112
+ return new ResultErr(error());
65
113
  }
66
114
  export function safe(f, mapError = ensureError) {
67
115
  try {
68
- return Ok(f());
116
+ return new ResultOk(f());
69
117
  }
70
118
  catch (err) {
71
- return Err(mapError(err));
119
+ return new ResultErr(mapError(err));
72
120
  }
73
121
  }
74
122
  export function safeAsync(f, mapError = ensureError) {
75
123
  return new ResultAsync((async () => {
76
124
  try {
77
- return Ok(await f());
125
+ return new ResultOk(await f());
78
126
  }
79
127
  catch (err) {
80
- return Err(await mapError(err));
128
+ return new ResultErr(await mapError(err));
81
129
  }
82
130
  })());
83
131
  }
@@ -95,14 +143,23 @@ class ResultOk extends Array {
95
143
  this[0] = undefined;
96
144
  this[1] = value;
97
145
  }
146
+ toJSON() {
147
+ return this[1];
148
+ }
149
+ $toNativeTuple() {
150
+ return [undefined, this[1]];
151
+ }
98
152
  $value() {
99
153
  return this[1];
100
154
  }
155
+ $ok() {
156
+ return this[1];
157
+ }
101
158
  $isOk() {
102
159
  return true;
103
160
  }
104
161
  $isOkAnd(f) {
105
- return f(this[1]);
162
+ return !!f(this[1]);
106
163
  }
107
164
  $isErr() {
108
165
  return false;
@@ -137,6 +194,12 @@ class ResultOk extends Array {
137
194
  $mapOrElse(_def, f) {
138
195
  return new ResultOk(f(this[1]));
139
196
  }
197
+ $assertOr(def, condition = isTruthy) {
198
+ return condition(this[1]) ? this : def;
199
+ }
200
+ $assertOrElse(def, condition = isTruthy) {
201
+ return condition(this[1]) ? this : def();
202
+ }
140
203
  $or() {
141
204
  return this;
142
205
  }
@@ -196,9 +259,18 @@ class ResultErr extends Array {
196
259
  this[0] = err;
197
260
  this[1] = undefined;
198
261
  }
262
+ toJSON() {
263
+ return null;
264
+ }
265
+ $toNativeTuple() {
266
+ return [this[0], undefined];
267
+ }
199
268
  $value() {
200
269
  return this[0];
201
270
  }
271
+ $ok() {
272
+ undefined;
273
+ }
202
274
  $isOk() {
203
275
  return false;
204
276
  }
@@ -209,7 +281,7 @@ class ResultErr extends Array {
209
281
  return true;
210
282
  }
211
283
  $isErrAnd(f) {
212
- return f(this[0]);
284
+ return !!f(this[0]);
213
285
  }
214
286
  $expect() {
215
287
  if (this[0] instanceof Error) {
@@ -241,6 +313,12 @@ class ResultErr extends Array {
241
313
  $mapOrElse(def) {
242
314
  return new ResultOk(def(this[0]));
243
315
  }
316
+ $assertOr() {
317
+ return this;
318
+ }
319
+ $assertOrElse() {
320
+ return this;
321
+ }
244
322
  $or(or) {
245
323
  return or;
246
324
  }
@@ -301,12 +379,24 @@ class ResultAsync {
301
379
  then(onfulfilled, onrejected) {
302
380
  return __classPrivateFieldGet(this, _ResultAsync_inner, "f").then(onfulfilled, onrejected);
303
381
  }
382
+ /**
383
+ * @TODO
384
+ */
385
+ async $toNativeTuple() {
386
+ return (await __classPrivateFieldGet(this, _ResultAsync_inner, "f")).$toNativeTuple();
387
+ }
304
388
  /**
305
389
  * @TODO
306
390
  */
307
391
  async $value() {
308
392
  return (await __classPrivateFieldGet(this, _ResultAsync_inner, "f")).$value();
309
393
  }
394
+ /**
395
+ * @TODO
396
+ */
397
+ async $ok() {
398
+ return (await __classPrivateFieldGet(this, _ResultAsync_inner, "f")).$ok();
399
+ }
310
400
  /**
311
401
  * @TODO
312
402
  */
@@ -378,6 +468,22 @@ class ResultAsync {
378
468
  : new ResultOk(def(res[0]));
379
469
  }));
380
470
  }
471
+ $assertOr(def, condition = isTruthy) {
472
+ return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
473
+ if (res instanceof ResultErr || condition(res[1])) {
474
+ return res;
475
+ }
476
+ return await def;
477
+ }));
478
+ }
479
+ $assertOrElse(def, condition = isTruthy) {
480
+ return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
481
+ if (res instanceof ResultErr || condition(res[1])) {
482
+ return res;
483
+ }
484
+ return await def();
485
+ }));
486
+ }
381
487
  /**
382
488
  * @TODO
383
489
  */
@@ -394,9 +500,6 @@ class ResultAsync {
394
500
  return res instanceof ResultErr ? await f(res[0]) : res;
395
501
  }));
396
502
  }
397
- /**
398
- * @TODO
399
- */
400
503
  $orSafe(f, mapError = ensureError) {
401
504
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
402
505
  if (res instanceof ResultOk) {
@@ -440,9 +543,6 @@ class ResultAsync {
440
543
  return res;
441
544
  }));
442
545
  }
443
- /**
444
- * @TODO
445
- */
446
546
  $andSafe(f, mapError = ensureError) {
447
547
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
448
548
  if (res instanceof ResultErr) {
@@ -501,18 +601,9 @@ function ensureError(err) {
501
601
  }
502
602
  return new RetupleThrownValueError(err);
503
603
  }
504
- Object.freeze(Result);
505
- Object.freeze(ResultOk);
506
- Object.freeze(ResultErr);
507
- Object.freeze(ResultAsync);
508
- Object.freeze(RetupleUnwrapFailed);
509
- Object.freeze(RetupleUnwrapErrFailed);
510
- Object.freeze(RetupleExpectFailed);
511
- Object.freeze(RetupleThrownValueError);
512
- Object.freeze(ResultOk.prototype);
513
- Object.freeze(ResultErr.prototype);
514
- Object.freeze(ResultAsync.prototype);
515
- Object.freeze(RetupleUnwrapFailed.prototype);
516
- Object.freeze(RetupleUnwrapErrFailed.prototype);
517
- Object.freeze(RetupleExpectFailed.prototype);
518
- Object.freeze(RetupleThrownValueError.prototype);
604
+ function mapTrue() {
605
+ return true;
606
+ }
607
+ function isTruthy(val) {
608
+ return !!val;
609
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "retuple",
3
- "version": "1.0.0-next.2",
3
+ "version": "1.0.0-next.4",
4
4
  "scripts": {
5
5
  "test": "vitest",
6
6
  "lint": "eslint . --ext .ts -c eslint.config.mjs --fix",