@shirudo/result 0.0.3 → 0.0.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 +2 -0
- package/dist/index.cjs +132 -34
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +47 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +47 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +117 -35
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -263,6 +263,8 @@ const result = await matchAsync({
|
|
|
263
263
|
- `.serialize()`: Convert to `{ isSuccess, data?, error? }`.
|
|
264
264
|
- `.toUserFriendly()`: User-friendly serialization with error messages.
|
|
265
265
|
|
|
266
|
+
**Error types:** Methods that throw (e.g., `.unwrap()`, `.unwrapErr()`, `.expect()`, `.expectErr()`, and invalid-state checks) now use custom error classes with stable `code` values like `ERR_UNWRAP_ON_ERR` and `ERR_INVALID_STATE`. These classes and constants are exported from the package for programmatic handling.
|
|
267
|
+
|
|
266
268
|
### Utilities
|
|
267
269
|
|
|
268
270
|
Type guards and helper functions:
|
package/dist/index.cjs
CHANGED
|
@@ -13,6 +13,88 @@ var Pipeable = class {
|
|
|
13
13
|
}
|
|
14
14
|
};
|
|
15
15
|
|
|
16
|
+
//#endregion
|
|
17
|
+
//#region src/errors.ts
|
|
18
|
+
const ERR_INVALID_STATE = "ERR_INVALID_STATE";
|
|
19
|
+
const ERR_TASK_YIELD_NOT_RESULT = "ERR_TASK_YIELD_NOT_RESULT";
|
|
20
|
+
const ERR_MATCH_ON_OK = "ERR_MATCH_ON_OK";
|
|
21
|
+
const ERR_UNWRAP_ON_ERR = "ERR_UNWRAP_ON_ERR";
|
|
22
|
+
const ERR_UNWRAP_ERR_ON_OK = "ERR_UNWRAP_ERR_ON_OK";
|
|
23
|
+
const ERR_EXPECT_OK = "ERR_EXPECT_OK";
|
|
24
|
+
const ERR_EXPECT_ERR = "ERR_EXPECT_ERR";
|
|
25
|
+
const formatResultErrorMessage = (code, message, context) => {
|
|
26
|
+
if (context) return `${code}: ${message} (context: ${context})`;
|
|
27
|
+
return `${code}: ${message}`;
|
|
28
|
+
};
|
|
29
|
+
var ResultError = class extends Error {
|
|
30
|
+
code;
|
|
31
|
+
context;
|
|
32
|
+
constructor(message, code, context) {
|
|
33
|
+
super(formatResultErrorMessage(code, message, context));
|
|
34
|
+
this.code = code;
|
|
35
|
+
this.context = context;
|
|
36
|
+
this.name = new.target.name;
|
|
37
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
var ResultTypeError = class extends TypeError {
|
|
41
|
+
code;
|
|
42
|
+
context;
|
|
43
|
+
constructor(message, code, context) {
|
|
44
|
+
super(formatResultErrorMessage(code, message, context));
|
|
45
|
+
this.code = code;
|
|
46
|
+
this.context = context;
|
|
47
|
+
this.name = new.target.name;
|
|
48
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
const INVALID_RESULT_STATE_MESSAGE = "Unreachable: Result is neither Ok nor Err";
|
|
52
|
+
var InvalidResultStateError = class extends ResultError {
|
|
53
|
+
constructor(context) {
|
|
54
|
+
super(INVALID_RESULT_STATE_MESSAGE, ERR_INVALID_STATE, context);
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
var TaskYieldNotResultError = class extends ResultTypeError {
|
|
58
|
+
yieldedValue;
|
|
59
|
+
constructor(yieldedValue) {
|
|
60
|
+
super("task() expected yielded values to be Result. Use `yield*` on a Result.", ERR_TASK_YIELD_NOT_RESULT);
|
|
61
|
+
this.yieldedValue = yieldedValue;
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
var MatchOnOkError = class extends ResultTypeError {
|
|
65
|
+
constructor() {
|
|
66
|
+
super("match() can only be called on Err results. Use `if (result.isErr()) { ... }` first.", ERR_MATCH_ON_OK);
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
var UnwrapOnErrError = class extends ResultTypeError {
|
|
70
|
+
errorValue;
|
|
71
|
+
constructor(errorValue) {
|
|
72
|
+
super(`Called unwrap() on Err: ${String(errorValue)}`, ERR_UNWRAP_ON_ERR);
|
|
73
|
+
this.errorValue = errorValue;
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
var UnwrapErrOnOkError = class extends ResultTypeError {
|
|
77
|
+
okValue;
|
|
78
|
+
constructor(okValue) {
|
|
79
|
+
super(`Called unwrapErr() on Ok: ${String(okValue)}`, ERR_UNWRAP_ERR_ON_OK);
|
|
80
|
+
this.okValue = okValue;
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
var ExpectOkError = class extends ResultError {
|
|
84
|
+
expectedMessage;
|
|
85
|
+
constructor(expectedMessage) {
|
|
86
|
+
super(expectedMessage, ERR_EXPECT_OK);
|
|
87
|
+
this.expectedMessage = expectedMessage;
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
var ExpectErrError = class extends ResultError {
|
|
91
|
+
expectedMessage;
|
|
92
|
+
constructor(expectedMessage) {
|
|
93
|
+
super(expectedMessage, ERR_EXPECT_ERR);
|
|
94
|
+
this.expectedMessage = expectedMessage;
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
|
|
16
98
|
//#endregion
|
|
17
99
|
//#region src/core/matcher.ts
|
|
18
100
|
/**
|
|
@@ -75,7 +157,7 @@ var ErrMatchBuilder = class ErrMatchBuilder {
|
|
|
75
157
|
static fromResult(result, makeErr) {
|
|
76
158
|
if (result.isOk()) return new ErrMatchBuilder(makeErr, void 0, result);
|
|
77
159
|
if (result.isErr()) return new ErrMatchBuilder(makeErr, result.error);
|
|
78
|
-
throw new
|
|
160
|
+
throw new InvalidResultStateError("ErrMatchBuilder.fromResult");
|
|
79
161
|
}
|
|
80
162
|
when(ctor, handler) {
|
|
81
163
|
if (this.#resolved) return this;
|
|
@@ -143,7 +225,7 @@ function mapBoth(mapOk, mapErr$1) {
|
|
|
143
225
|
return (source) => {
|
|
144
226
|
if (source.isOk()) return ok(mapOk(source.value));
|
|
145
227
|
if (source.isErr()) return err(mapErr$1(source.error));
|
|
146
|
-
throw new
|
|
228
|
+
throw new InvalidResultStateError("mapBoth");
|
|
147
229
|
};
|
|
148
230
|
}
|
|
149
231
|
/**
|
|
@@ -170,7 +252,7 @@ function zipImpl(left, right) {
|
|
|
170
252
|
if (left.isErr()) return left;
|
|
171
253
|
if (right.isErr()) return right;
|
|
172
254
|
if (left.isOk() && right.isOk()) return ok([left.value, right.value]);
|
|
173
|
-
throw new
|
|
255
|
+
throw new InvalidResultStateError("zip");
|
|
174
256
|
}
|
|
175
257
|
function zip(...args) {
|
|
176
258
|
if (args.length === 1) {
|
|
@@ -236,7 +318,7 @@ function match(handlers) {
|
|
|
236
318
|
return (source) => {
|
|
237
319
|
if (source.isOk()) return handlers.ok(source.value);
|
|
238
320
|
if (source.isErr()) return handlers.err(source.error);
|
|
239
|
-
throw new
|
|
321
|
+
throw new InvalidResultStateError("match");
|
|
240
322
|
};
|
|
241
323
|
}
|
|
242
324
|
|
|
@@ -250,7 +332,7 @@ function recover(defaultValue) {
|
|
|
250
332
|
return (source) => {
|
|
251
333
|
if (source.isOk()) return source;
|
|
252
334
|
if (source.isErr()) return ok(defaultValue);
|
|
253
|
-
throw new
|
|
335
|
+
throw new InvalidResultStateError("recover");
|
|
254
336
|
};
|
|
255
337
|
}
|
|
256
338
|
/**
|
|
@@ -260,7 +342,7 @@ function recoverWith(fn) {
|
|
|
260
342
|
return (source) => {
|
|
261
343
|
if (source.isOk()) return source;
|
|
262
344
|
if (source.isErr()) return ok(fn(source.error));
|
|
263
|
-
throw new
|
|
345
|
+
throw new InvalidResultStateError("recoverWith");
|
|
264
346
|
};
|
|
265
347
|
}
|
|
266
348
|
|
|
@@ -273,7 +355,7 @@ function recoverWith(fn) {
|
|
|
273
355
|
function swap(result) {
|
|
274
356
|
if (result.isOk()) return err(result.value);
|
|
275
357
|
if (result.isErr()) return ok(result.error);
|
|
276
|
-
throw new
|
|
358
|
+
throw new InvalidResultStateError("swap");
|
|
277
359
|
}
|
|
278
360
|
|
|
279
361
|
//#endregion
|
|
@@ -304,7 +386,7 @@ function tryMap(project, errorMapper) {
|
|
|
304
386
|
if (source.isErr()) return source;
|
|
305
387
|
try {
|
|
306
388
|
if (source.isOk()) return ok(project(source.value));
|
|
307
|
-
throw new
|
|
389
|
+
throw new InvalidResultStateError("tryMap");
|
|
308
390
|
} catch (error) {
|
|
309
391
|
return err(errorMapper ? errorMapper(error) : error);
|
|
310
392
|
}
|
|
@@ -326,7 +408,7 @@ function collectFirstOk(results) {
|
|
|
326
408
|
errors.push(result.error);
|
|
327
409
|
continue;
|
|
328
410
|
}
|
|
329
|
-
throw new
|
|
411
|
+
throw new InvalidResultStateError("collectFirstOk");
|
|
330
412
|
}
|
|
331
413
|
return err(errors);
|
|
332
414
|
}
|
|
@@ -404,7 +486,7 @@ function matchAsync(handlers) {
|
|
|
404
486
|
return async (source) => {
|
|
405
487
|
if (source.isOk()) return await handlers.ok(source.value);
|
|
406
488
|
if (source.isErr()) return await handlers.err(source.error);
|
|
407
|
-
throw new
|
|
489
|
+
throw new InvalidResultStateError("matchAsync");
|
|
408
490
|
};
|
|
409
491
|
}
|
|
410
492
|
|
|
@@ -434,7 +516,7 @@ function tryMapAsync(project, errorMapper) {
|
|
|
434
516
|
if (source.isErr()) return source;
|
|
435
517
|
try {
|
|
436
518
|
if (source.isOk()) return ok(await project(source.value));
|
|
437
|
-
throw new
|
|
519
|
+
throw new InvalidResultStateError("tryMapAsync");
|
|
438
520
|
} catch (error) {
|
|
439
521
|
return err(errorMapper ? errorMapper(error) : error);
|
|
440
522
|
}
|
|
@@ -459,7 +541,7 @@ var ResultBase = class extends Pipeable {
|
|
|
459
541
|
fold(onOk, onErr) {
|
|
460
542
|
if (this._tag === "Ok") return onOk(this.value);
|
|
461
543
|
if (this._tag === "Err") return onErr(this.error);
|
|
462
|
-
throw new
|
|
544
|
+
throw new InvalidResultStateError("Result.fold");
|
|
463
545
|
}
|
|
464
546
|
/**
|
|
465
547
|
* Enables `yield* result` in generators (Do-notation).
|
|
@@ -479,7 +561,7 @@ var ResultBase = class extends Pipeable {
|
|
|
479
561
|
*/
|
|
480
562
|
match() {
|
|
481
563
|
if (this._tag === "Err") return new ErrorMatchBuilder(this.error);
|
|
482
|
-
throw new
|
|
564
|
+
throw new MatchOnOkError();
|
|
483
565
|
}
|
|
484
566
|
/**
|
|
485
567
|
* Matcht auf den Err-Wert, aber normalisiert jeden Branch zu einem `Result`:
|
|
@@ -614,7 +696,7 @@ async function task(makeGenerator, onThrow) {
|
|
|
614
696
|
return err(onThrow(caught));
|
|
615
697
|
}
|
|
616
698
|
const yielded = step.value;
|
|
617
|
-
if (!isResult(yielded)) throw new
|
|
699
|
+
if (!isResult(yielded)) throw new TaskYieldNotResultError(yielded);
|
|
618
700
|
if (yielded.isOk()) {
|
|
619
701
|
input = yielded.value;
|
|
620
702
|
continue;
|
|
@@ -628,7 +710,7 @@ async function task(makeGenerator, onThrow) {
|
|
|
628
710
|
}
|
|
629
711
|
return yielded;
|
|
630
712
|
}
|
|
631
|
-
throw new
|
|
713
|
+
throw new InvalidResultStateError("task");
|
|
632
714
|
}
|
|
633
715
|
}
|
|
634
716
|
const gen = task;
|
|
@@ -645,7 +727,7 @@ function fold(handlers) {
|
|
|
645
727
|
return (source) => {
|
|
646
728
|
if (source.isOk()) return handlers.ok(source.value);
|
|
647
729
|
if (source.isErr()) return handlers.err(source.error);
|
|
648
|
-
throw new
|
|
730
|
+
throw new InvalidResultStateError("fold");
|
|
649
731
|
};
|
|
650
732
|
}
|
|
651
733
|
|
|
@@ -661,7 +743,7 @@ function foldAsync(handlers) {
|
|
|
661
743
|
return async (source) => {
|
|
662
744
|
if (source.isOk()) return await handlers.ok(source.value);
|
|
663
745
|
if (source.isErr()) return await handlers.err(source.error);
|
|
664
|
-
throw new
|
|
746
|
+
throw new InvalidResultStateError("foldAsync");
|
|
665
747
|
};
|
|
666
748
|
}
|
|
667
749
|
|
|
@@ -673,8 +755,8 @@ function foldAsync(handlers) {
|
|
|
673
755
|
*/
|
|
674
756
|
function unwrap(result) {
|
|
675
757
|
if (result.isOk()) return result.value;
|
|
676
|
-
if (result.isErr()) throw new
|
|
677
|
-
throw new
|
|
758
|
+
if (result.isErr()) throw new UnwrapOnErrError(result.error);
|
|
759
|
+
throw new InvalidResultStateError("unwrap");
|
|
678
760
|
}
|
|
679
761
|
|
|
680
762
|
//#endregion
|
|
@@ -697,7 +779,7 @@ function unwrapOr(result, defaultValue) {
|
|
|
697
779
|
function unwrapOrElse(result, fn) {
|
|
698
780
|
if (result.isOk()) return result.value;
|
|
699
781
|
if (result.isErr()) return fn(result.error);
|
|
700
|
-
throw new
|
|
782
|
+
throw new InvalidResultStateError("unwrapOrElse");
|
|
701
783
|
}
|
|
702
784
|
|
|
703
785
|
//#endregion
|
|
@@ -719,7 +801,7 @@ function unwrapOrDefault(result, defaultValue) {
|
|
|
719
801
|
function unwrapOrThrow(result) {
|
|
720
802
|
if (result.isOk()) return result.value;
|
|
721
803
|
if (result.isErr()) throw result.error;
|
|
722
|
-
throw new
|
|
804
|
+
throw new InvalidResultStateError("unwrapOrThrow");
|
|
723
805
|
}
|
|
724
806
|
|
|
725
807
|
//#endregion
|
|
@@ -730,8 +812,8 @@ function unwrapOrThrow(result) {
|
|
|
730
812
|
*/
|
|
731
813
|
function unwrapErr(result) {
|
|
732
814
|
if (result.isErr()) return result.error;
|
|
733
|
-
if (result.isOk()) throw new
|
|
734
|
-
throw new
|
|
815
|
+
if (result.isOk()) throw new UnwrapErrOnOkError(result.value);
|
|
816
|
+
throw new InvalidResultStateError("unwrapErr");
|
|
735
817
|
}
|
|
736
818
|
|
|
737
819
|
//#endregion
|
|
@@ -742,7 +824,7 @@ function unwrapErr(result) {
|
|
|
742
824
|
*/
|
|
743
825
|
function expectResult(result, message) {
|
|
744
826
|
if (result.isOk()) return result.value;
|
|
745
|
-
throw new
|
|
827
|
+
throw new ExpectOkError(message);
|
|
746
828
|
}
|
|
747
829
|
|
|
748
830
|
//#endregion
|
|
@@ -753,7 +835,7 @@ function expectResult(result, message) {
|
|
|
753
835
|
*/
|
|
754
836
|
function expectErr(result, message) {
|
|
755
837
|
if (result.isErr()) return result.error;
|
|
756
|
-
throw new
|
|
838
|
+
throw new ExpectErrError(message);
|
|
757
839
|
}
|
|
758
840
|
|
|
759
841
|
//#endregion
|
|
@@ -785,7 +867,7 @@ function or(result, other) {
|
|
|
785
867
|
function orElse(result, fn) {
|
|
786
868
|
if (result.isOk()) return result;
|
|
787
869
|
if (result.isErr()) return fn(result.error);
|
|
788
|
-
throw new
|
|
870
|
+
throw new InvalidResultStateError("orElse");
|
|
789
871
|
}
|
|
790
872
|
|
|
791
873
|
//#endregion
|
|
@@ -808,7 +890,7 @@ function mapOr(result, defaultValue, fn) {
|
|
|
808
890
|
function mapOrElse(result, defaultFn, fn) {
|
|
809
891
|
if (result.isOk()) return fn(result.value);
|
|
810
892
|
if (result.isErr()) return defaultFn(result.error);
|
|
811
|
-
throw new
|
|
893
|
+
throw new InvalidResultStateError("mapOrElse");
|
|
812
894
|
}
|
|
813
895
|
|
|
814
896
|
//#endregion
|
|
@@ -826,7 +908,7 @@ function sequence(results) {
|
|
|
826
908
|
continue;
|
|
827
909
|
}
|
|
828
910
|
if (result.isErr()) return result;
|
|
829
|
-
throw new
|
|
911
|
+
throw new InvalidResultStateError("sequence");
|
|
830
912
|
}
|
|
831
913
|
return ok(values);
|
|
832
914
|
}
|
|
@@ -853,7 +935,7 @@ function sequenceRecord(record) {
|
|
|
853
935
|
continue;
|
|
854
936
|
}
|
|
855
937
|
if (result.isErr()) return result;
|
|
856
|
-
throw new
|
|
938
|
+
throw new InvalidResultStateError("sequenceRecord");
|
|
857
939
|
}
|
|
858
940
|
return ok(out);
|
|
859
941
|
}
|
|
@@ -876,7 +958,7 @@ async function collectFirstOkAsync(inputs) {
|
|
|
876
958
|
errors.push(result.error);
|
|
877
959
|
continue;
|
|
878
960
|
}
|
|
879
|
-
throw new
|
|
961
|
+
throw new InvalidResultStateError("collectFirstOkAsync");
|
|
880
962
|
} catch (error) {
|
|
881
963
|
errors.push(error);
|
|
882
964
|
}
|
|
@@ -909,7 +991,7 @@ async function collectFirstOkParallelAsync(inputs) {
|
|
|
909
991
|
for (const entry of settled) if (entry.status === "fulfilled") {
|
|
910
992
|
const result = entry.value;
|
|
911
993
|
if (result.isErr()) errors.push(result.error);
|
|
912
|
-
else if (!result.isOk()) errors.push(
|
|
994
|
+
else if (!result.isOk()) errors.push(new InvalidResultStateError("collectFirstOkParallelAsync"));
|
|
913
995
|
} else errors.push(entry.reason);
|
|
914
996
|
return err(errors);
|
|
915
997
|
});
|
|
@@ -934,7 +1016,7 @@ function collectAllErrors(results) {
|
|
|
934
1016
|
errors.push(result.error);
|
|
935
1017
|
continue;
|
|
936
1018
|
}
|
|
937
|
-
throw new
|
|
1019
|
+
throw new InvalidResultStateError("collectAllErrors");
|
|
938
1020
|
}
|
|
939
1021
|
return errors.length === 0 ? ok(values) : err(errors);
|
|
940
1022
|
}
|
|
@@ -956,7 +1038,7 @@ function partition(results) {
|
|
|
956
1038
|
errs.push(result.error);
|
|
957
1039
|
continue;
|
|
958
1040
|
}
|
|
959
|
-
throw new
|
|
1041
|
+
throw new InvalidResultStateError("partition");
|
|
960
1042
|
}
|
|
961
1043
|
return [oks, errs];
|
|
962
1044
|
}
|
|
@@ -982,7 +1064,7 @@ function flatten(result) {
|
|
|
982
1064
|
function toPromise(result) {
|
|
983
1065
|
if (result.isOk()) return Promise.resolve(result.value);
|
|
984
1066
|
if (result.isErr()) return Promise.reject(result.error);
|
|
985
|
-
throw new
|
|
1067
|
+
throw new InvalidResultStateError("toPromise");
|
|
986
1068
|
}
|
|
987
1069
|
|
|
988
1070
|
//#endregion
|
|
@@ -1039,9 +1121,25 @@ function containsErr(result, error) {
|
|
|
1039
1121
|
}
|
|
1040
1122
|
|
|
1041
1123
|
//#endregion
|
|
1124
|
+
exports.ERR_EXPECT_ERR = ERR_EXPECT_ERR;
|
|
1125
|
+
exports.ERR_EXPECT_OK = ERR_EXPECT_OK;
|
|
1126
|
+
exports.ERR_INVALID_STATE = ERR_INVALID_STATE;
|
|
1127
|
+
exports.ERR_MATCH_ON_OK = ERR_MATCH_ON_OK;
|
|
1128
|
+
exports.ERR_TASK_YIELD_NOT_RESULT = ERR_TASK_YIELD_NOT_RESULT;
|
|
1129
|
+
exports.ERR_UNWRAP_ERR_ON_OK = ERR_UNWRAP_ERR_ON_OK;
|
|
1130
|
+
exports.ERR_UNWRAP_ON_ERR = ERR_UNWRAP_ON_ERR;
|
|
1042
1131
|
exports.Err = Err;
|
|
1132
|
+
exports.ExpectErrError = ExpectErrError;
|
|
1133
|
+
exports.ExpectOkError = ExpectOkError;
|
|
1134
|
+
exports.InvalidResultStateError = InvalidResultStateError;
|
|
1135
|
+
exports.MatchOnOkError = MatchOnOkError;
|
|
1043
1136
|
exports.Ok = Ok;
|
|
1044
1137
|
exports.Result = Result;
|
|
1138
|
+
exports.ResultError = ResultError;
|
|
1139
|
+
exports.ResultTypeError = ResultTypeError;
|
|
1140
|
+
exports.TaskYieldNotResultError = TaskYieldNotResultError;
|
|
1141
|
+
exports.UnwrapErrOnOkError = UnwrapErrOnOkError;
|
|
1142
|
+
exports.UnwrapOnErrError = UnwrapOnErrError;
|
|
1045
1143
|
exports.all = all;
|
|
1046
1144
|
exports.and = and;
|
|
1047
1145
|
exports.bimap = bimap;
|