@shirudo/result 0.0.1 → 0.0.2

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
@@ -1,5 +1,5 @@
1
1
 
2
- //#region src/pipeable.ts
2
+ //#region src/core/pipeable.ts
3
3
  var Pipeable = class {
4
4
  pipe(...ops) {
5
5
  let ret = this;
@@ -14,19 +14,13 @@ var Pipeable = class {
14
14
  };
15
15
 
16
16
  //#endregion
17
- //#region src/utils/isResult.ts
18
- function isResult(value) {
19
- return typeof value === "object" && value !== null && "isOk" in value && typeof value.isOk === "function" && "isErr" in value && typeof value.isErr === "function";
20
- }
21
-
22
- //#endregion
23
- //#region src/matcher.ts
17
+ //#region src/core/matcher.ts
24
18
  /**
25
- * Matcher for Err values (returns any return type, e.g. string messages).
19
+ * Matcher für Err-Values (liefert einen beliebigen Return-Type, z.B. string messages).
26
20
  *
27
21
  * - `.when(Ctor, handler)` matched via `instanceof`
28
- * - `.whenGuard(guard, handler)` matched via type guard
29
- * - `.run()` is only allowed once all error cases are handled (`E` is reduced to `never`)
22
+ * - `.whenGuard(guard, handler)` matched via Type-Guard
23
+ * - `.run()` ist nur erlaubt, wenn alle Error-Cases behandelt wurden (`E` wurde zu `never` reduziert)
30
24
  */
31
25
  var ErrorMatchBuilder = class ErrorMatchBuilder {
32
26
  #error;
@@ -58,12 +52,15 @@ var ErrorMatchBuilder = class ErrorMatchBuilder {
58
52
  throw this.#error;
59
53
  }
60
54
  };
55
+ function isResult$1(value) {
56
+ return typeof value === "object" && value !== null && "isOk" in value && typeof value.isOk === "function" && "isErr" in value && typeof value.isErr === "function";
57
+ }
61
58
  /**
62
- * Matcher for `Result` errors that always returns a `Result`.
59
+ * Matcher für `Result`-Errors, der immer wieder ein `Result` zurückgibt.
63
60
  *
64
- * Handlers may:
65
- * - return a `Result` (returned directly)
66
- * - return an error value (automatically wrapped to `Err(error)`)
61
+ * Handler dürfen:
62
+ * - ein `Result` zurückgeben (wird direkt returned)
63
+ * - einen Error-Wert zurückgeben (wird automatisch zu `Err(error)` gewrappt)
67
64
  */
68
65
  var ErrMatchBuilder = class ErrMatchBuilder {
69
66
  #makeErr;
@@ -84,7 +81,7 @@ var ErrMatchBuilder = class ErrMatchBuilder {
84
81
  if (this.#resolved) return this;
85
82
  if (this.#error instanceof ctor) {
86
83
  const out = handler(this.#error);
87
- const resolved = isResult(out) ? out : this.#makeErr(out);
84
+ const resolved = isResult$1(out) ? out : this.#makeErr(out);
88
85
  return new ErrMatchBuilder(this.#makeErr, this.#error, resolved);
89
86
  }
90
87
  return this;
@@ -94,7 +91,7 @@ var ErrMatchBuilder = class ErrMatchBuilder {
94
91
  const error = this.#error;
95
92
  if (guard(error)) {
96
93
  const out = handler(error);
97
- const resolved = isResult(out) ? out : this.#makeErr(out);
94
+ const resolved = isResult$1(out) ? out : this.#makeErr(out);
98
95
  return new ErrMatchBuilder(this.#makeErr, this.#error, resolved);
99
96
  }
100
97
  return this;
@@ -102,688 +99,19 @@ var ErrMatchBuilder = class ErrMatchBuilder {
102
99
  otherwise(handler) {
103
100
  if (this.#resolved) return this.#resolved;
104
101
  const out = handler(this.#error);
105
- return isResult(out) ? out : this.#makeErr(out);
102
+ return isResult$1(out) ? out : this.#makeErr(out);
106
103
  }
107
104
  run() {
108
105
  if (this.#resolved) return this.#resolved;
109
106
  throw this.#error;
110
107
  }
111
108
  };
112
- /**
113
- * Universal matcher for `Result` (Ok + Err in a single chain).
114
- *
115
- * - `.err(Ctor, handler)` matched via `instanceof`
116
- * - `.errVal(value, handler)` matched via `Object.is`
117
- * - `.ok(handler)` defines the success branch
118
- * - `.run()` is only allowed after `.ok()` is set
119
- *
120
- * Lazy: if the Result is `Ok`, Err cases are not evaluated in `.run()`.
121
- */
122
- var ResultMatchBuilder = class ResultMatchBuilder {
123
- #result;
124
- #errCases;
125
- #okHandler;
126
- constructor(result, errCases = [], okHandler) {
127
- this.#result = result;
128
- this.#errCases = Object.freeze([...errCases]);
129
- this.#okHandler = okHandler;
130
- Object.freeze(this);
131
- }
132
- static fromResult(result) {
133
- return new ResultMatchBuilder(result);
134
- }
135
- err(ctor, handler) {
136
- return new ResultMatchBuilder(this.#result, [...this.#errCases, {
137
- kind: "ctor",
138
- ctor,
139
- handler
140
- }], this.#okHandler);
141
- }
142
- errVal(value, handler) {
143
- return new ResultMatchBuilder(this.#result, [...this.#errCases, {
144
- kind: "val",
145
- value,
146
- handler
147
- }], this.#okHandler);
148
- }
149
- ok(handler) {
150
- return new ResultMatchBuilder(this.#result, this.#errCases, handler);
151
- }
152
- run() {
153
- const result = this.#result;
154
- if (result.isOk()) {
155
- const okHandler = this.#okHandler;
156
- if (!okHandler) throw new Error("ResultMatchBuilder.run() requires an ok() handler.");
157
- return okHandler(result.value);
158
- }
159
- if (result.isErr()) {
160
- const error = result.error;
161
- for (const c of this.#errCases) {
162
- if (c.kind === "ctor") {
163
- if (error instanceof c.ctor) return c.handler(error);
164
- continue;
165
- }
166
- if (Object.is(error, c.value)) return c.handler(error);
167
- }
168
- throw error;
169
- }
170
- throw new Error("Unreachable: Result is neither Ok nor Err");
171
- }
172
- };
173
-
174
- //#endregion
175
- //#region src/conversions/fromNullable.ts
176
- /**
177
- * Converts `null | undefined` to `Err`, everything else to `Ok`.
178
- *
179
- * **Type Safety**: The type assertion `as NonNullable<T>` is safe,
180
- * as the runtime check guarantees that the value is not null/undefined.
181
- *
182
- * @param value The value to check
183
- * @param error The error to use if value is null/undefined
184
- * @returns An Ok Result with the NonNullable value, or an Err Result with the error
185
- *
186
- * @example
187
- * ```ts
188
- * fromNullable(user, 'User not found')
189
- * // Ok(user) or Err('User not found')
190
- * ```
191
- */
192
- function fromNullable(value, error) {
193
- if (value === null || value === void 0) return Result.err(error);
194
- return Result.ok(value);
195
- }
196
-
197
- //#endregion
198
- //#region src/conversions/fromPromise.ts
199
- async function fromPromise(promise, errorMapper) {
200
- try {
201
- const value = await promise;
202
- return Result.ok(value);
203
- } catch (error) {
204
- try {
205
- return Result.err(errorMapper ? errorMapper(error) : error);
206
- } catch (mapperError) {
207
- return Result.err(mapperError);
208
- }
209
- }
210
- }
211
-
212
- //#endregion
213
- //#region src/conversions/try.ts
214
- /**
215
- * Executes a function and catches exceptions.
216
- *
217
- * @param fn The function to execute
218
- * @returns An Ok Result with the return value, or an Err Result with the caught exception
219
- *
220
- * @example
221
- * ```ts
222
- * const result = tryFn(() => JSON.parse(input));
223
- * // Ok(parsed) or Err(SyntaxError)
224
- * ```
225
- */
226
- function tryFn(fn) {
227
- try {
228
- return Result.ok(fn());
229
- } catch (error) {
230
- return Result.err(error);
231
- }
232
- }
233
-
234
- //#endregion
235
- //#region src/conversions/toPromise.ts
236
- /**
237
- * Converts a Result to a Promise.
238
- * Ok → resolves with the value, Err → rejects with the error
239
- *
240
- * @param result The Result to convert
241
- * @returns A Promise that resolves with the value if Ok, or rejects with the error if Err
242
- *
243
- * @example
244
- * ```ts
245
- * const result = ok(42);
246
- * const promise = toPromise(result);
247
- * const value = await promise; // 42
248
- * ```
249
- */
250
- function toPromise(result) {
251
- if (result.isOk()) return Promise.resolve(result.value);
252
- return Promise.reject(result.error);
253
- }
254
-
255
- //#endregion
256
- //#region src/conversions/toNullable.ts
257
- /**
258
- * Converts a Result to `T | null`.
259
- * Ok → returns the value, Err → returns null
260
- *
261
- * @param result The Result to convert
262
- * @returns The value if Ok, or null if Err
263
- *
264
- * @example
265
- * ```ts
266
- * const result = ok(42);
267
- * const value = toNullable(result); // 42
268
- *
269
- * const errResult = err('error');
270
- * const nullValue = toNullable(errResult); // null
271
- * ```
272
- */
273
- function toNullable(result) {
274
- if (result.isOk()) return result.value;
275
- return null;
276
- }
277
-
278
- //#endregion
279
- //#region src/result.ts
280
- var Result = class Result extends Pipeable {
281
- #state;
282
- constructor(state) {
283
- super();
284
- Object.freeze(state);
285
- this.#state = state;
286
- Object.freeze(this);
287
- }
288
- /**
289
- * Creates an Ok Result with the given value.
290
- *
291
- * **Note**: `null` and `undefined` are allowed as values.
292
- * If you want to convert `null`/`undefined` to an Err, use `fromNullable()`.
293
- *
294
- * @param value The value for the Ok Result
295
- * @returns An Ok Result with the given value
296
- *
297
- * @example
298
- * ```ts
299
- * const result = Result.ok(42);
300
- * const nullResult = Result.ok(null); // Allowed!
301
- * ```
302
- */
303
- static ok(value) {
304
- return new Result({
305
- _tag: "Ok",
306
- value
307
- });
308
- }
309
- /**
310
- * Creates an Err Result with the given error.
311
- *
312
- * **Note**: `null` and `undefined` are allowed as errors.
313
- *
314
- * @param error The error for the Err Result
315
- * @returns An Err Result with the given error
316
- *
317
- * @example
318
- * ```ts
319
- * const result = Result.err('error message');
320
- * const nullError = Result.err(null); // Allowed!
321
- * ```
322
- */
323
- static err(error) {
324
- return new Result({
325
- _tag: "Err",
326
- error
327
- });
328
- }
329
- /**
330
- * Converts `null | undefined` to `Err`, everything else to `Ok`.
331
- *
332
- * **Type Safety**: The type assertion `as NonNullable<T>` is safe,
333
- * as the runtime check guarantees that the value is not null/undefined.
334
- *
335
- * @param value The value to check
336
- * @param error The error to use if value is null/undefined
337
- * @returns An Ok Result with the NonNullable value, or an Err Result with the error
338
- *
339
- * @example
340
- * ```ts
341
- * Result.fromNullable(user, 'User not found')
342
- * // Ok(user) or Err('User not found')
343
- * ```
344
- */
345
- static fromNullable(value, error) {
346
- return fromNullable(value, error);
347
- }
348
- static fromPromise(promise, errorMapper) {
349
- return fromPromise(promise, errorMapper);
350
- }
351
- /**
352
- * Executes a function and catches exceptions.
353
- *
354
- * @example
355
- * ```ts
356
- * const result = Result.try(() => JSON.parse(input));
357
- * // Ok(parsed) or Err(SyntaxError)
358
- * ```
359
- */
360
- static try(fn) {
361
- return tryFn(fn);
362
- }
363
- /**
364
- * Checks if the Result is Ok.
365
- *
366
- * @returns `true` if the Result is Ok (and narrows the type)
367
- *
368
- * @example
369
- * ```ts
370
- * if (result.isOk()) {
371
- * const value: T = result.value; // TypeScript knows that value is defined
372
- * }
373
- * ```
374
- */
375
- isOk() {
376
- return this.#state._tag === "Ok";
377
- }
378
- /**
379
- * Checks if the Result is Err.
380
- *
381
- * @returns `true` if the Result is Err (and narrows the type)
382
- *
383
- * @example
384
- * ```ts
385
- * if (result.isErr()) {
386
- * const error: E = result.error; // TypeScript knows that error is defined
387
- * }
388
- * ```
389
- */
390
- isErr() {
391
- return this.#state._tag === "Err";
392
- }
393
- get value() {
394
- return this.#state._tag === "Ok" ? this.#state.value : void 0;
395
- }
396
- get error() {
397
- return this.#state._tag === "Err" ? this.#state.error : void 0;
398
- }
399
- /**
400
- * Returns the value, guaranteed to be defined after `isOk()` check.
401
- * This method provides better type narrowing than the `value` getter.
402
- *
403
- * ⚠️ **Warning**: This method throws an Error if called on an Err result.
404
- * Use this method only after a type guard (`if (result.isOk())`).
405
- * For a safer alternative with a custom message, use `expect()`.
406
- *
407
- * @throws {Error} If called on an Err result
408
- *
409
- * @example
410
- * ```ts
411
- * if (result.isOk()) {
412
- * const value = result.unwrap(); // Type is T, not T | undefined
413
- * }
414
- * ```
415
- */
416
- unwrap() {
417
- if (this.#state._tag === "Ok") return this.#state.value;
418
- const errorStr = (() => {
419
- try {
420
- const error = this.#state.error;
421
- if (error === null) return "null";
422
- if (error === void 0) return "undefined";
423
- if (typeof error === "string") return error;
424
- if (error instanceof Error) return error.message;
425
- if (typeof error === "object" && "toString" in error) try {
426
- return String(error);
427
- } catch {
428
- return "[unstringifiable error]";
429
- }
430
- return String(error);
431
- } catch {
432
- return "[unstringifiable error]";
433
- }
434
- })();
435
- throw new Error(`Called unwrap() on Err: ${errorStr}`);
436
- }
437
- /**
438
- * Returns the error, guaranteed to be defined after `isErr()` check.
439
- * This method provides better type narrowing than the `error` getter.
440
- *
441
- * ⚠️ **Warning**: This method throws an Error if called on an Ok result.
442
- * Use this method only after a type guard (`if (result.isErr())`).
443
- * For a safer alternative with a custom message, use `expectErr()`.
444
- *
445
- * @throws {Error} If called on an Ok result
446
- *
447
- * @example
448
- * ```ts
449
- * if (result.isErr()) {
450
- * const error = result.unwrapErr(); // Type is E, not E | undefined
451
- * }
452
- * ```
453
- */
454
- unwrapErr() {
455
- if (this.#state._tag === "Err") return this.#state.error;
456
- const valueStr = (() => {
457
- try {
458
- const value = this.#state.value;
459
- if (value === null) return "null";
460
- if (value === void 0) return "undefined";
461
- if (typeof value === "string") return value;
462
- if (value instanceof Error) return value.message;
463
- if (typeof value === "object" && "toString" in value) try {
464
- return String(value);
465
- } catch {
466
- return "[unstringifiable value]";
467
- }
468
- return String(value);
469
- } catch {
470
- return "[unstringifiable value]";
471
- }
472
- })();
473
- throw new Error(`Called unwrapErr() on Ok: ${valueStr}`);
474
- }
475
- /**
476
- * Returns the value with a custom error message if the result is Err.
477
- * Similar to `unwrap()`, but allows you to provide a custom error message.
478
- *
479
- * ⚠️ **Warning**: This method throws an Error if called on an Err result.
480
- * Use this method only if you are sure the Result is Ok,
481
- * or if you need a meaningful error message.
482
- *
483
- * @param message Custom error message to throw if result is Err
484
- * @returns The value if result is Ok
485
- * @throws {Error} If called on an Err result with the provided message
486
- *
487
- * @example
488
- * ```ts
489
- * const result = fetchUser(id);
490
- * const user = result.expect('User should exist'); // Throws with custom message if Err
491
- * ```
492
- */
493
- expect(message) {
494
- if (this.#state._tag === "Ok") return this.#state.value;
495
- throw new Error(message);
496
- }
497
- /**
498
- * Returns the error with a custom error message if the result is Ok.
499
- * Similar to `unwrapErr()`, but allows you to provide a custom error message.
500
- *
501
- * ⚠️ **Warning**: This method throws an Error if called on an Ok result.
502
- * Use this method only if you are sure the Result is Err,
503
- * or if you need a meaningful error message.
504
- *
505
- * @param message Custom error message to throw if result is Ok
506
- * @returns The error if result is Err
507
- * @throws {Error} If called on an Ok result with the provided message
508
- *
509
- * @example
510
- * ```ts
511
- * const result = validateInput(input);
512
- * if (result.isErr()) {
513
- * const error = result.expectErr('Validation should have failed'); // Throws if Ok
514
- * }
515
- * ```
516
- */
517
- expectErr(message) {
518
- if (this.#state._tag === "Err") return this.#state.error;
519
- throw new Error(message);
520
- }
521
- unwrapOr(defaultValue) {
522
- return this.#state._tag === "Ok" ? this.#state.value : defaultValue;
523
- }
524
- /**
525
- * Converts the Result to a Promise.
526
- * Ok → resolves with the value, Err → rejects with the error
527
- *
528
- * This instance method delegates to the standalone `toPromise()` function.
529
- *
530
- * @returns A Promise that resolves with the value if Ok, or rejects with the error if Err
531
- *
532
- * @example
533
- * ```ts
534
- * const result = ok(42);
535
- * const promise = result.toPromise();
536
- * const value = await promise; // 42
537
- *
538
- * const errResult = err('error');
539
- * try {
540
- * await errResult.toPromise();
541
- * } catch (error) {
542
- * console.log(error); // 'error'
543
- * }
544
- * ```
545
- */
546
- toPromise() {
547
- return toPromise(this);
548
- }
549
- /**
550
- * Converts the Result to `T | null`.
551
- * Ok → returns the value, Err → returns null
552
- *
553
- * This instance method delegates to the standalone `toNullable()` function.
554
- *
555
- * @returns The value if Ok, or null if Err
556
- *
557
- * @example
558
- * ```ts
559
- * const result = ok(42);
560
- * const value = result.toNullable(); // 42
561
- *
562
- * const errResult = err('error');
563
- * const nullValue = errResult.toNullable(); // null
564
- * ```
565
- */
566
- toNullable() {
567
- return toNullable(this);
568
- }
569
- /**
570
- * Enables `yield* result` in generators (Do-notation).
571
- *
572
- * The iterator yields the `Result` itself; the runner (see `task`) decides:
573
- * - Ok → sends back the Ok value (`next(value)`), `yield*` yields `T`
574
- * - Err → aborts and returns the Err Result
575
- */
576
- *[Symbol.iterator]() {
577
- return yield this;
578
- }
579
- /**
580
- * Universal pattern matcher for Ok + Err cases.
581
- *
582
- * Use this to exhaustively match on both success and error cases with type-based
583
- * and value-based pattern matching.
584
- *
585
- * @example
586
- * ```ts
587
- * const message = result
588
- * .match()
589
- * .err(NetworkError, e => `Network: ${e.message}`)
590
- * .err(ValidationError, e => `Validation: ${e.message}`)
591
- * .ok(val => `Success: ${val}`)
592
- * .run();
593
- * ```
594
- */
595
- match() {
596
- return ResultMatchBuilder.fromResult(this);
597
- }
598
- matchErr() {
599
- if (this.isErr()) return new ErrorMatchBuilder(this.error);
600
- throw new Error("matchErr() can only be called on Err results. Use `if (result.isErr()) { ... }` first.");
601
- }
602
- /**
603
- * Matches on the Err value, but normalizes every branch to a `Result`:
604
- * - Handlers may return a `Result` (returned directly)
605
- * - or an error value (wrapped to `Err(error)`)
606
- */
607
- matchErrResult() {
608
- const makeErr = (error) => Result.err(error);
609
- return ErrMatchBuilder.fromResult(this, makeErr);
610
- }
611
- /**
612
- * @deprecated Use `.match()` instead. Will be removed in next major version.
613
- */
614
- pattern() {
615
- return this.match();
616
- }
617
- /**
618
- * @deprecated Use `.match()` instead. Will be removed in next major version.
619
- */
620
- switch() {
621
- return this.match();
622
- }
623
- /**
624
- * Folds the Result into a single value by applying one of two functions.
625
- *
626
- * This is a direct method equivalent to the `match` pipe operator.
627
- * Use this when you want to handle both Ok and Err cases and return a single value.
628
- *
629
- * @param onOk Function to apply if the Result is Ok
630
- * @param onErr Function to apply if the Result is Err
631
- * @returns The result of applying the appropriate function
632
- *
633
- * @example
634
- * ```ts
635
- * const result = ok(42);
636
- * const message = result.fold(
637
- * val => `Success: ${val}`,
638
- * err => `Error: ${err}`
639
- * );
640
- * // message = "Success: 42"
641
- * ```
642
- *
643
- * @example
644
- * ```ts
645
- * // Works with discriminated unions
646
- * const result: Result<string, number> = err(404);
647
- * const response = result.fold(
648
- * data => ({ success: true as const, data }),
649
- * code => ({ success: false as const, code })
650
- * );
651
- * // response: { success: true; data: string } | { success: false; code: number }
652
- * ```
653
- */
654
- fold(onOk, onErr) {
655
- if (this.isOk()) return onOk(this.value);
656
- if (this.isErr()) return onErr(this.error);
657
- throw new Error("Unreachable: Result is neither Ok nor Err");
658
- }
659
- /**
660
- * Returns the Result as a discriminated union (`{ _tag: 'Ok', value } | { _tag: 'Err', error }`).
661
- * Useful for libraries like `ts-pattern` that match on plain object unions.
662
- */
663
- toUnion() {
664
- return this.#state;
665
- }
666
- /**
667
- * Serializes the Result into a simple object format.
668
- * Preserves the original types.
669
- */
670
- serialize() {
671
- if (this.#state._tag === "Ok") return {
672
- isSuccess: true,
673
- data: this.#state.value
674
- };
675
- return {
676
- isSuccess: false,
677
- error: this.#state.error
678
- };
679
- }
680
- /**
681
- * Serializes the Result into a user-friendly format.
682
- * Converts errors to readable strings.
683
- */
684
- toUserFriendly() {
685
- if (this.#state._tag === "Ok") return {
686
- isSuccess: true,
687
- data: this.#state.value
688
- };
689
- const error = this.#state.error;
690
- const toSafeString = (value) => {
691
- try {
692
- return String(value);
693
- } catch {
694
- return "[Unstringifiable error]";
695
- }
696
- };
697
- return {
698
- isSuccess: false,
699
- error: (() => {
700
- if (error && typeof error === "object" && "message" in error) {
701
- const message = error.message;
702
- return typeof message === "string" ? message : toSafeString(error);
703
- }
704
- return toSafeString(error);
705
- })()
706
- };
707
- }
708
- };
709
- const ok = Result.ok;
710
- const err = Result.err;
711
- /**
712
- * Helper for conditional Result creation.
713
- * Avoids type inference issues with ternary operators.
714
- *
715
- * @example
716
- * ```ts
717
- * const result = okIf(value > 5, value, 'too small');
718
- * // instead of: value > 5 ? ok(value) : err('too small')
719
- * ```
720
- */
721
- function okIf(condition, okValue, errValue) {
722
- return condition ? ok(okValue) : err(errValue);
723
- }
724
- /**
725
- * Helper for conditional Result creation with lazy evaluation.
726
- * Evaluates values only when they are needed.
727
- *
728
- * @example
729
- * ```ts
730
- * const result = okIfLazy(
731
- * value > 5,
732
- * () => expensiveComputation(value),
733
- * () => 'too small'
734
- * );
735
- * ```
736
- */
737
- function okIfLazy(condition, okFn, errFn) {
738
- return condition ? ok(okFn()) : err(errFn());
739
- }
740
-
741
- //#endregion
742
- //#region src/gen.ts
743
- async function task(makeGenerator, onThrow) {
744
- const iterator = makeGenerator();
745
- let input = void 0;
746
- while (true) {
747
- let step;
748
- try {
749
- step = await iterator.next(input);
750
- } catch (caught) {
751
- if (!onThrow) throw caught;
752
- return err(onThrow(caught));
753
- }
754
- if (step.done) try {
755
- const awaited = await step.value;
756
- if (isResult(awaited)) return awaited;
757
- return ok(awaited);
758
- } catch (caught) {
759
- if (!onThrow) throw caught;
760
- return err(onThrow(caught));
761
- }
762
- const yielded = step.value;
763
- if (!isResult(yielded)) throw new TypeError("task() expected yielded values to be Result. Use `yield*` on a Result.");
764
- if (yielded.isOk()) {
765
- input = yielded.value;
766
- continue;
767
- }
768
- if (yielded.isErr()) {
769
- try {
770
- if (typeof iterator.return === "function") await iterator.return(void 0);
771
- } catch (caught) {
772
- if (!onThrow) throw caught;
773
- return err(onThrow(caught));
774
- }
775
- return yielded;
776
- }
777
- throw new Error("Unreachable: Result is neither Ok nor Err");
778
- }
779
- }
780
- const gen = task;
781
109
 
782
110
  //#endregion
783
- //#region src/operators/map.ts
111
+ //#region src/core/map.ts
784
112
  /**
785
- * Transforms the value (Ok case).
786
- * Equivalent to Rust `map`.
113
+ * Transformiert den Wert (Ok-Fall).
114
+ * Entspricht Rust `map`.
787
115
  */
788
116
  function map(project) {
789
117
  return (source) => {
@@ -793,10 +121,10 @@ function map(project) {
793
121
  }
794
122
 
795
123
  //#endregion
796
- //#region src/operators/mapErr.ts
124
+ //#region src/core/mapErr.ts
797
125
  /**
798
- * Transforms the error (Err case).
799
- * Equivalent to Rust `map_err`.
126
+ * Transformiert den Fehler (Err-Fall).
127
+ * Entspricht Rust `map_err`.
800
128
  */
801
129
  function mapErr(project) {
802
130
  return (source) => {
@@ -806,10 +134,10 @@ function mapErr(project) {
806
134
  }
807
135
 
808
136
  //#endregion
809
- //#region src/operators/mapBoth.ts
137
+ //#region src/core/mapBoth.ts
810
138
  /**
811
- * Transforms both the Ok value and the Err error.
812
- * Equivalent to FP `bimap` / `mapBoth`.
139
+ * Transformiert sowohl den Ok-Wert als auch den Err-Fehler.
140
+ * Entspricht FP `bimap` / `mapBoth`.
813
141
  */
814
142
  function mapBoth(mapOk, mapErr$1) {
815
143
  return (source) => {
@@ -819,15 +147,15 @@ function mapBoth(mapOk, mapErr$1) {
819
147
  };
820
148
  }
821
149
  /**
822
- * Alias for `mapBoth`.
150
+ * Alias für `mapBoth`.
823
151
  */
824
152
  const bimap = mapBoth;
825
153
 
826
154
  //#endregion
827
- //#region src/operators/flatMap.ts
155
+ //#region src/core/flatMap.ts
828
156
  /**
829
- * Chains another operation that returns a Result.
830
- * Equivalent to Rust `and_then` or JS `flatMap`.
157
+ * Verkettet eine weitere Operation, die ein Result zurückgibt.
158
+ * Entspricht Rust `and_then` oder JS `flatMap`.
831
159
  */
832
160
  function flatMap(project) {
833
161
  return (source) => {
@@ -837,10 +165,42 @@ function flatMap(project) {
837
165
  }
838
166
 
839
167
  //#endregion
840
- //#region src/operators/tap.ts
168
+ //#region src/core/zip.ts
169
+ function zipImpl(left, right) {
170
+ if (left.isErr()) return left;
171
+ if (right.isErr()) return right;
172
+ if (left.isOk() && right.isOk()) return ok([left.value, right.value]);
173
+ throw new Error("Unreachable: Result is neither Ok nor Err");
174
+ }
175
+ function zip(...args) {
176
+ if (args.length === 1) {
177
+ const right$1 = args[0];
178
+ return (left$1) => zipImpl(left$1, right$1);
179
+ }
180
+ const [left, right] = args;
181
+ return zipImpl(left, right);
182
+ }
183
+ function combineImpl(left, right) {
184
+ if (left.isOk() && right.isOk()) return ok([left.value, right.value]);
185
+ const errors = [];
186
+ if (left.isErr()) errors.push(left.error);
187
+ if (right.isErr()) errors.push(right.error);
188
+ return err(errors);
189
+ }
190
+ function combine(...args) {
191
+ if (args.length === 1) {
192
+ const right$1 = args[0];
193
+ return (left$1) => combineImpl(left$1, right$1);
194
+ }
195
+ const [left, right] = args;
196
+ return combineImpl(left, right);
197
+ }
198
+
199
+ //#endregion
200
+ //#region src/core/tap.ts
841
201
  /**
842
- * Executes a side effect (logging, debugging) without changing the Result.
843
- * Equivalent to Rust `inspect` / `inspect_err`.
202
+ * Führt einen Seiteneffekt aus (Logging, Debugging), ohne das Result zu ändern.
203
+ * Entspricht Rust `inspect` / `inspect_err`.
844
204
  */
845
205
  function tap(observer) {
846
206
  return (source) => {
@@ -851,10 +211,10 @@ function tap(observer) {
851
211
  }
852
212
 
853
213
  //#endregion
854
- //#region src/operators/filter.ts
214
+ //#region src/core/filter.ts
855
215
  /**
856
- * Checks a predicate. If false, the Result becomes Err.
857
- * Partially equivalent to Rust `filter`.
216
+ * Prüft eine Bedingung. Wenn falsch, wird das Result zu Err.
217
+ * Entspricht Rust `filter` (teilweise).
858
218
  */
859
219
  function filter(predicate, errorFn) {
860
220
  return (source) => {
@@ -867,31 +227,61 @@ function filter(predicate, errorFn) {
867
227
  }
868
228
 
869
229
  //#endregion
870
- //#region src/operators/fold.ts
230
+ //#region src/core/match.ts
871
231
  /**
872
- * Folds the Result into a single value by applying one of two functions.
873
- * The end of the pipe.
874
- *
875
- * This is the pipe operator equivalent of the `.fold()` instance method.
232
+ * Löst das Result auf. Das Ende der Pipe.
233
+ * Entspricht Rust `match`.
876
234
  */
877
- function fold(handlers) {
235
+ function match(handlers) {
878
236
  return (source) => {
879
237
  if (source.isOk()) return handlers.ok(source.value);
880
238
  if (source.isErr()) return handlers.err(source.error);
881
239
  throw new Error("Unreachable: Result is neither Ok nor Err");
882
240
  };
883
241
  }
242
+
243
+ //#endregion
244
+ //#region src/core/recover.ts
245
+ /**
246
+ * Recover: wandelt Err in Ok(defaultValue) um.
247
+ * Ergebnis ist garantiert Ok → Error-Typ wird `never`.
248
+ */
249
+ function recover(defaultValue) {
250
+ return (source) => {
251
+ if (source.isOk()) return source;
252
+ if (source.isErr()) return ok(defaultValue);
253
+ throw new Error("Unreachable: Result is neither Ok nor Err");
254
+ };
255
+ }
884
256
  /**
885
- * @deprecated Use `fold` instead. Will be removed in next major version.
257
+ * Wie `recover`, aber berechnet den Default-Wert anhand des Errors.
886
258
  */
887
- const match = fold;
259
+ function recoverWith(fn) {
260
+ return (source) => {
261
+ if (source.isOk()) return source;
262
+ if (source.isErr()) return ok(fn(source.error));
263
+ throw new Error("Unreachable: Result is neither Ok nor Err");
264
+ };
265
+ }
888
266
 
889
267
  //#endregion
890
- //#region src/operators/tryCatch.ts
268
+ //#region src/core/swap.ts
891
269
  /**
892
- * Executes a function and catches exceptions.
893
- * Converts exceptions into Result<E>.
894
- * Equivalent to Rust `Result::from` for fallible operations.
270
+ * Tauscht Ok und Err.
271
+ * Result<T, E> Result<E, T>
272
+ */
273
+ function swap(result) {
274
+ if (result.isOk()) return err(result.value);
275
+ if (result.isErr()) return ok(result.error);
276
+ throw new Error("Unreachable: Result is neither Ok nor Err");
277
+ }
278
+
279
+ //#endregion
280
+ //#region src/core/tryCatch.ts
281
+ /**
282
+ * Führt eine Funktion aus und fängt Exceptions ab.
283
+ * Wandelt Exceptions in Result<E> um.
284
+ * Entspricht Rust `Result::from` für fallible Operationen.
895
285
  */
896
286
  function tryCatch(fn, errorMapper) {
897
287
  return (source) => {
@@ -905,9 +295,9 @@ function tryCatch(fn, errorMapper) {
905
295
  }
906
296
 
907
297
  //#endregion
908
- //#region src/operators/tryMap.ts
298
+ //#region src/core/tryMap.ts
909
299
  /**
910
- * Like `map`, but catches exceptions and turns them into Err.
300
+ * Wie `map`, aber fängt Exceptions ab und wandelt sie in Err um.
911
301
  */
912
302
  function tryMap(project, errorMapper) {
913
303
  return (source) => {
@@ -922,33 +312,29 @@ function tryMap(project, errorMapper) {
922
312
  }
923
313
 
924
314
  //#endregion
925
- //#region src/operators/recover.ts
315
+ //#region src/core/collectFirstOk.ts
926
316
  /**
927
- * Recover: turns Err into Ok(defaultValue).
928
- * Result is guaranteed Ok error type becomes `never`.
929
- */
930
- function recover(defaultValue) {
931
- return (source) => {
932
- if (source.isOk()) return source;
933
- if (source.isErr()) return ok(defaultValue);
934
- throw new Error("Unreachable: Result is neither Ok nor Err");
935
- };
936
- }
937
- /**
938
- * Like `recover`, but computes the default value from the error.
317
+ * Parse a set of `Result`s, short-circuits when an input value is `Ok`.
318
+ * If no `Ok` is found, returns an `Err` containing the collected error values.
319
+ * Useful for "try multiple approaches until one works" patterns.
939
320
  */
940
- function recoverWith(fn) {
941
- return (source) => {
942
- if (source.isOk()) return source;
943
- if (source.isErr()) return ok(fn(source.error));
321
+ function collectFirstOk(results) {
322
+ const errors = [];
323
+ for (const result of results) {
324
+ if (result.isOk()) return ok(result.value);
325
+ if (result.isErr()) {
326
+ errors.push(result.error);
327
+ continue;
328
+ }
944
329
  throw new Error("Unreachable: Result is neither Ok nor Err");
945
- };
330
+ }
331
+ return err(errors);
946
332
  }
947
333
 
948
334
  //#endregion
949
- //#region src/operators-async/mapAsync.ts
335
+ //#region src/core/mapAsync.ts
950
336
  /**
951
- * Async version of map.
337
+ * Async-Version von map.
952
338
  */
953
339
  function mapAsync(project) {
954
340
  return async (source) => {
@@ -958,9 +344,9 @@ function mapAsync(project) {
958
344
  }
959
345
 
960
346
  //#endregion
961
- //#region src/operators-async/mapErrAsync.ts
347
+ //#region src/core/mapErrAsync.ts
962
348
  /**
963
- * Async version of mapErr.
349
+ * Async-Version von mapErr.
964
350
  */
965
351
  function mapErrAsync(project) {
966
352
  return async (source) => {
@@ -970,10 +356,9 @@ function mapErrAsync(project) {
970
356
  }
971
357
 
972
358
  //#endregion
973
- //#region src/operators-async/flatMapAsync.ts
359
+ //#region src/core/flatMapAsync.ts
974
360
  /**
975
- * Async version of flatMap.
976
- * Allows different error types in the projected Result.
361
+ * Async-Version von flatMap.
977
362
  */
978
363
  function flatMapAsync(project) {
979
364
  return async (source) => {
@@ -983,9 +368,9 @@ function flatMapAsync(project) {
983
368
  }
984
369
 
985
370
  //#endregion
986
- //#region src/operators-async/tapAsync.ts
371
+ //#region src/core/tapAsync.ts
987
372
  /**
988
- * Async version of tap.
373
+ * Async-Version von tap.
989
374
  */
990
375
  function tapAsync(observer) {
991
376
  return async (source) => {
@@ -996,9 +381,9 @@ function tapAsync(observer) {
996
381
  }
997
382
 
998
383
  //#endregion
999
- //#region src/operators-async/filterAsync.ts
384
+ //#region src/core/filterAsync.ts
1000
385
  /**
1001
- * Async version of filter.
386
+ * Async-Version von filter.
1002
387
  */
1003
388
  function filterAsync(predicate, errorFn) {
1004
389
  return async (source) => {
@@ -1011,29 +396,22 @@ function filterAsync(predicate, errorFn) {
1011
396
  }
1012
397
 
1013
398
  //#endregion
1014
- //#region src/operators-async/foldAsync.ts
399
+ //#region src/core/matchAsync.ts
1015
400
  /**
1016
- * Async version of `fold`. Folds the Result into a single value asynchronously.
1017
- * The end of the pipe.
1018
- *
1019
- * This is the async pipe operator equivalent of the `.fold()` instance method.
401
+ * Async-Version von match.
1020
402
  */
1021
- function foldAsync(handlers) {
403
+ function matchAsync(handlers) {
1022
404
  return async (source) => {
1023
405
  if (source.isOk()) return await handlers.ok(source.value);
1024
406
  if (source.isErr()) return await handlers.err(source.error);
1025
407
  throw new Error("Unreachable: Result is neither Ok nor Err");
1026
408
  };
1027
409
  }
1028
- /**
1029
- * @deprecated Use `foldAsync` instead. Will be removed in next major version.
1030
- */
1031
- const matchAsync = foldAsync;
1032
410
 
1033
411
  //#endregion
1034
- //#region src/operators-async/tryCatchAsync.ts
412
+ //#region src/core/tryCatchAsync.ts
1035
413
  /**
1036
- * Async version of tryCatch.
414
+ * Async-Version von tryCatch.
1037
415
  */
1038
416
  function tryCatchAsync(fn, errorMapper) {
1039
417
  return async (source) => {
@@ -1047,9 +425,9 @@ function tryCatchAsync(fn, errorMapper) {
1047
425
  }
1048
426
 
1049
427
  //#endregion
1050
- //#region src/operators-async/tryMapAsync.ts
428
+ //#region src/core/tryMapAsync.ts
1051
429
  /**
1052
- * Async version of tryMap.
430
+ * Async-Version von tryMap.
1053
431
  */
1054
432
  function tryMapAsync(project, errorMapper) {
1055
433
  return async (source) => {
@@ -1064,10 +442,234 @@ function tryMapAsync(project, errorMapper) {
1064
442
  }
1065
443
 
1066
444
  //#endregion
1067
- //#region src/unwrap/unwrap.ts
445
+ //#region src/core/result.ts
446
+ var ResultBase = class extends Pipeable {
447
+ isOk() {
448
+ return this._tag === "Ok";
449
+ }
450
+ isErr() {
451
+ return this._tag === "Err";
452
+ }
453
+ unwrapOr(defaultValue) {
454
+ return this._tag === "Ok" ? this.value : defaultValue;
455
+ }
456
+ /**
457
+ * Folds the Result into a single value by applying one of two functions.
458
+ */
459
+ fold(onOk, onErr) {
460
+ if (this._tag === "Ok") return onOk(this.value);
461
+ if (this._tag === "Err") return onErr(this.error);
462
+ throw new Error("Unreachable: Result is neither Ok nor Err");
463
+ }
464
+ /**
465
+ * Enables `yield* result` in generators (Do-notation).
466
+ *
467
+ * The iterator yields the `Result` itself; the runner (see `task`) decides:
468
+ * - Ok → sends back the Ok value (`next(value)`), `yield*` yields `T`
469
+ * - Err → aborts and returns the Err Result
470
+ */
471
+ *[Symbol.iterator]() {
472
+ return yield this;
473
+ }
474
+ /**
475
+ * Matcht auf den Err-Wert via `.when(...)` Kette.
476
+ *
477
+ * Hinweis: aus Type-Safety-Gründen ist `.match()` nur auf einem bereits zu `Err` verengten Result aufrufbar,
478
+ * z.B. innerhalb von `if (result.isErr()) { ... }`.
479
+ */
480
+ match() {
481
+ if (this._tag === "Err") return new ErrorMatchBuilder(this.error);
482
+ throw new Error("match() can only be called on Err results. Use `if (result.isErr()) { ... }` first.");
483
+ }
484
+ /**
485
+ * Matcht auf den Err-Wert, aber normalisiert jeden Branch zu einem `Result`:
486
+ * - Handler dürfen ein `Result` zurückgeben (wird direkt returned)
487
+ * - oder einen Error-Wert (wird zu `Err(error)` gewrappt)
488
+ */
489
+ matchErr() {
490
+ const makeErr = (error) => err(error);
491
+ return ErrMatchBuilder.fromResult(this, makeErr);
492
+ }
493
+ /**
494
+ * Serialisiert das Result in ein einfaches Objekt-Format.
495
+ * Behält die ursprünglichen Typen bei.
496
+ */
497
+ serialize() {
498
+ if (this._tag === "Ok") return {
499
+ isSuccess: true,
500
+ data: this.value
501
+ };
502
+ return {
503
+ isSuccess: false,
504
+ error: this.error
505
+ };
506
+ }
507
+ /**
508
+ * Serialisiert das Result in ein user-friendly Format.
509
+ * Konvertiert Errors zu lesbaren Strings.
510
+ */
511
+ toUserFriendly() {
512
+ if (this._tag === "Ok") return {
513
+ isSuccess: true,
514
+ data: this.value
515
+ };
516
+ const error = this.error;
517
+ return {
518
+ isSuccess: false,
519
+ error: error && typeof error === "object" && "message" in error ? error.message : String(error)
520
+ };
521
+ }
522
+ };
523
+ var Ok = class extends ResultBase {
524
+ _tag = "Ok";
525
+ value;
526
+ error = void 0;
527
+ constructor(value) {
528
+ super();
529
+ this.value = value;
530
+ Object.freeze(this);
531
+ }
532
+ };
533
+ var Err = class extends ResultBase {
534
+ _tag = "Err";
535
+ value = void 0;
536
+ error;
537
+ constructor(error) {
538
+ super();
539
+ this.error = error;
540
+ Object.freeze(this);
541
+ }
542
+ };
543
+ function ok(value) {
544
+ return new Ok(value);
545
+ }
546
+ function err(error) {
547
+ return new Err(error);
548
+ }
549
+ function okIf(condition, okValue, errValue) {
550
+ return condition ? ok(okValue) : err(errValue);
551
+ }
552
+ function okIfLazy(condition, okFn, errFn) {
553
+ return condition ? ok(okFn()) : err(errFn());
554
+ }
555
+ function fromNullable(value, error) {
556
+ if (value === null || value === void 0) return err(error);
557
+ return ok(value);
558
+ }
559
+ async function fromPromise(promise, errorMapper) {
560
+ try {
561
+ return ok(await promise);
562
+ } catch (error) {
563
+ try {
564
+ return err(errorMapper ? errorMapper(error) : error);
565
+ } catch (mapperError) {
566
+ return err(mapperError);
567
+ }
568
+ }
569
+ }
570
+ function tryFn(fn) {
571
+ try {
572
+ return ok(fn());
573
+ } catch (error) {
574
+ return err(error);
575
+ }
576
+ }
577
+ const Result = {
578
+ ok,
579
+ err,
580
+ fromNullable,
581
+ fromPromise,
582
+ try: tryFn
583
+ };
584
+
585
+ //#endregion
586
+ //#region src/core/isResult.ts
587
+ /**
588
+ * Checks whether a value is a Result.
589
+ * Pure function alternative for runtime checks.
590
+ */
591
+ function isResult(value) {
592
+ return typeof value === "object" && value !== null && "isOk" in value && typeof value.isOk === "function" && "isErr" in value && typeof value.isErr === "function";
593
+ }
594
+
595
+ //#endregion
596
+ //#region src/gen.ts
597
+ async function task(makeGenerator, onThrow) {
598
+ const iterator = makeGenerator();
599
+ let input = void 0;
600
+ while (true) {
601
+ let step;
602
+ try {
603
+ step = await iterator.next(input);
604
+ } catch (caught) {
605
+ if (!onThrow) throw caught;
606
+ return err(onThrow(caught));
607
+ }
608
+ if (step.done) try {
609
+ const awaited = await step.value;
610
+ if (isResult(awaited)) return awaited;
611
+ return ok(awaited);
612
+ } catch (caught) {
613
+ if (!onThrow) throw caught;
614
+ return err(onThrow(caught));
615
+ }
616
+ const yielded = step.value;
617
+ if (!isResult(yielded)) throw new TypeError("task() expected yielded values to be Result. Use `yield*` on a Result.");
618
+ if (yielded.isOk()) {
619
+ input = yielded.value;
620
+ continue;
621
+ }
622
+ if (yielded.isErr()) {
623
+ try {
624
+ if (typeof iterator.return === "function") await iterator.return(void 0);
625
+ } catch (caught) {
626
+ if (!onThrow) throw caught;
627
+ return err(onThrow(caught));
628
+ }
629
+ return yielded;
630
+ }
631
+ throw new Error("Unreachable: Result is neither Ok nor Err");
632
+ }
633
+ }
634
+ const gen = task;
635
+
636
+ //#endregion
637
+ //#region src/core/fold.ts
638
+ /**
639
+ * Folds the Result into a single value by applying one of two functions.
640
+ * The end of the pipe.
641
+ *
642
+ * This is the pipe operator equivalent of the `.fold()` instance method.
643
+ */
644
+ function fold(handlers) {
645
+ return (source) => {
646
+ if (source.isOk()) return handlers.ok(source.value);
647
+ if (source.isErr()) return handlers.err(source.error);
648
+ throw new Error("Unreachable: Result is neither Ok nor Err");
649
+ };
650
+ }
651
+
652
+ //#endregion
653
+ //#region src/core/foldAsync.ts
654
+ /**
655
+ * Async version of `fold`. Folds the Result into a single value asynchronously.
656
+ * The end of the pipe.
657
+ *
658
+ * This is the async pipe operator equivalent of the `.fold()` instance method.
659
+ */
660
+ function foldAsync(handlers) {
661
+ return async (source) => {
662
+ if (source.isOk()) return await handlers.ok(source.value);
663
+ if (source.isErr()) return await handlers.err(source.error);
664
+ throw new Error("Unreachable: Result is neither Ok nor Err");
665
+ };
666
+ }
667
+
668
+ //#endregion
669
+ //#region src/core/unwrap.ts
1068
670
  /**
1069
- * Returns the value or throws an Error.
1070
- * Equivalent to Rust `unwrap`.
671
+ * Gibt den Wert zurück oder wirft einen Error.
672
+ * Entspricht Rust `unwrap`.
1071
673
  */
1072
674
  function unwrap(result) {
1073
675
  if (result.isOk()) return result.value;
@@ -1076,10 +678,10 @@ function unwrap(result) {
1076
678
  }
1077
679
 
1078
680
  //#endregion
1079
- //#region src/unwrap/unwrapOr.ts
681
+ //#region src/core/unwrapOr.ts
1080
682
  /**
1081
- * Returns the value or a default value.
1082
- * Pure function alternative to the instance method.
683
+ * Gibt den Wert zurück oder einen Default-Wert.
684
+ * Pure function Alternative zur Instanz-Methode.
1083
685
  */
1084
686
  function unwrapOr(result, defaultValue) {
1085
687
  if (result.isOk()) return result.value;
@@ -1087,10 +689,10 @@ function unwrapOr(result, defaultValue) {
1087
689
  }
1088
690
 
1089
691
  //#endregion
1090
- //#region src/unwrap/unwrapOrElse.ts
692
+ //#region src/core/unwrapOrElse.ts
1091
693
  /**
1092
- * Returns the value or computes a default value with a function.
1093
- * Equivalent to Rust `unwrap_or_else`.
694
+ * Gibt den Wert zurück oder berechnet einen Default-Wert mit einer Funktion.
695
+ * Entspricht Rust `unwrap_or_else`.
1094
696
  */
1095
697
  function unwrapOrElse(result, fn) {
1096
698
  if (result.isOk()) return result.value;
@@ -1099,20 +701,20 @@ function unwrapOrElse(result, fn) {
1099
701
  }
1100
702
 
1101
703
  //#endregion
1102
- //#region src/unwrap/unwrapOrDefault.ts
704
+ //#region src/core/unwrapOrDefault.ts
1103
705
  /**
1104
- * Alias for `unwrapOr`.
1105
- * Equivalent to Rust `unwrap_or_default` (with an explicit default value).
706
+ * Alias für `unwrapOr`.
707
+ * Entspricht Rust `unwrap_or_default` (mit explizitem Default-Wert).
1106
708
  */
1107
709
  function unwrapOrDefault(result, defaultValue) {
1108
710
  return unwrapOr(result, defaultValue);
1109
711
  }
1110
712
 
1111
713
  //#endregion
1112
- //#region src/unwrap/unwrapOrThrow.ts
714
+ //#region src/core/unwrapOrThrow.ts
1113
715
  /**
1114
- * Returns the value or throws the original Err value (not wrapped).
1115
- * Useful to keep `Error` instances with stack traces.
716
+ * Gibt den Wert zurück oder wirft den originalen Err-Wert (nicht gewrappt).
717
+ * Nützlich um `Error`-Instanzen inkl. Stacktrace zu erhalten.
1116
718
  */
1117
719
  function unwrapOrThrow(result) {
1118
720
  if (result.isOk()) return result.value;
@@ -1121,10 +723,10 @@ function unwrapOrThrow(result) {
1121
723
  }
1122
724
 
1123
725
  //#endregion
1124
- //#region src/unwrap/unwrapErr.ts
726
+ //#region src/core/unwrapErr.ts
1125
727
  /**
1126
- * Returns the error or throws an Error.
1127
- * Equivalent to Rust `unwrap_err`.
728
+ * Gibt den Fehler zurück oder wirft einen Error.
729
+ * Entspricht Rust `unwrap_err`.
1128
730
  */
1129
731
  function unwrapErr(result) {
1130
732
  if (result.isErr()) return result.error;
@@ -1133,10 +735,10 @@ function unwrapErr(result) {
1133
735
  }
1134
736
 
1135
737
  //#endregion
1136
- //#region src/unwrap/expectResult.ts
738
+ //#region src/core/expectResult.ts
1137
739
  /**
1138
- * Returns the value or throws an Error with a custom message.
1139
- * Equivalent to Rust `expect`.
740
+ * Gibt den Wert zurück oder wirft einen Error mit custom Nachricht.
741
+ * Entspricht Rust `expect`.
1140
742
  */
1141
743
  function expectResult(result, message) {
1142
744
  if (result.isOk()) return result.value;
@@ -1144,10 +746,10 @@ function expectResult(result, message) {
1144
746
  }
1145
747
 
1146
748
  //#endregion
1147
- //#region src/unwrap/expectErr.ts
749
+ //#region src/core/expectErr.ts
1148
750
  /**
1149
- * Returns the error or throws an Error with a custom message.
1150
- * Equivalent to Rust `expect_err`.
751
+ * Gibt den Fehler zurück oder wirft einen Error mit custom Nachricht.
752
+ * Entspricht Rust `expect_err`.
1151
753
  */
1152
754
  function expectErr(result, message) {
1153
755
  if (result.isErr()) return result.error;
@@ -1155,30 +757,30 @@ function expectErr(result, message) {
1155
757
  }
1156
758
 
1157
759
  //#endregion
1158
- //#region src/combinators/and.ts
760
+ //#region src/core/and.ts
1159
761
  /**
1160
- * Combines two Results. Returns the second only if the first is Ok.
1161
- * Equivalent to Rust `and`.
762
+ * Kombiniert zwei Results. Gibt den zweiten zurück nur wenn erster Ok ist.
763
+ * Entspricht Rust `and`.
1162
764
  */
1163
765
  function and(result, other) {
1164
766
  return result.isOk() ? other : result;
1165
767
  }
1166
768
 
1167
769
  //#endregion
1168
- //#region src/combinators/or.ts
770
+ //#region src/core/or.ts
1169
771
  /**
1170
- * Fallback to another Result when the first is Err.
1171
- * Equivalent to Rust `or`.
772
+ * Fallback zu einem anderen Result wenn erster Err ist.
773
+ * Entspricht Rust `or`.
1172
774
  */
1173
775
  function or(result, other) {
1174
776
  return result.isOk() ? result : other;
1175
777
  }
1176
778
 
1177
779
  //#endregion
1178
- //#region src/combinators/orElse.ts
780
+ //#region src/core/orElse.ts
1179
781
  /**
1180
- * Fallback using a function that returns a Result.
1181
- * Equivalent to Rust `or_else`.
782
+ * Fallback mit einer Funktion die ein Result zurückgibt.
783
+ * Entspricht Rust `or_else`.
1182
784
  */
1183
785
  function orElse(result, fn) {
1184
786
  if (result.isOk()) return result;
@@ -1187,10 +789,10 @@ function orElse(result, fn) {
1187
789
  }
1188
790
 
1189
791
  //#endregion
1190
- //#region src/combinators/mapOr.ts
792
+ //#region src/core/mapOr.ts
1191
793
  /**
1192
- * Transforms the value or returns a default value.
1193
- * Equivalent to Rust `map_or`.
794
+ * Transformiert den Wert oder gibt einen Default-Wert zurück.
795
+ * Entspricht Rust `map_or`.
1194
796
  */
1195
797
  function mapOr(result, defaultValue, fn) {
1196
798
  if (result.isOk()) return fn(result.value);
@@ -1198,10 +800,10 @@ function mapOr(result, defaultValue, fn) {
1198
800
  }
1199
801
 
1200
802
  //#endregion
1201
- //#region src/combinators/mapOrElse.ts
803
+ //#region src/core/mapOrElse.ts
1202
804
  /**
1203
- * Transforms the value or computes a default value with a function.
1204
- * Equivalent to Rust `map_or_else`.
805
+ * Transformiert den Wert oder berechnet einen Default-Wert mit einer Funktion.
806
+ * Entspricht Rust `map_or_else`.
1205
807
  */
1206
808
  function mapOrElse(result, defaultFn, fn) {
1207
809
  if (result.isOk()) return fn(result.value);
@@ -1210,55 +812,11 @@ function mapOrElse(result, defaultFn, fn) {
1210
812
  }
1211
813
 
1212
814
  //#endregion
1213
- //#region src/combinators/zip.ts
1214
- function zipImpl(left, right) {
1215
- if (left.isErr()) return left;
1216
- if (right.isErr()) return right;
1217
- if (left.isOk() && right.isOk()) return ok([left.value, right.value]);
1218
- throw new Error("Unreachable: Result is neither Ok nor Err");
1219
- }
1220
- function zip(...args) {
1221
- if (args.length === 1) {
1222
- const right$1 = args[0];
1223
- return (left$1) => zipImpl(left$1, right$1);
1224
- }
1225
- const [left, right] = args;
1226
- return zipImpl(left, right);
1227
- }
1228
- function combineImpl(left, right) {
1229
- if (left.isOk() && right.isOk()) return ok([left.value, right.value]);
1230
- const errors = [];
1231
- if (left.isErr()) errors.push(left.error);
1232
- if (right.isErr()) errors.push(right.error);
1233
- return err(errors);
1234
- }
1235
- function combine(...args) {
1236
- if (args.length === 1) {
1237
- const right$1 = args[0];
1238
- return (left$1) => combineImpl(left$1, right$1);
1239
- }
1240
- const [left, right] = args;
1241
- return combineImpl(left, right);
1242
- }
1243
-
1244
- //#endregion
1245
- //#region src/combinators/swap.ts
1246
- /**
1247
- * Swaps Ok and Err.
1248
- * Result<T, E> → Result<E, T>
1249
- */
1250
- function swap(result) {
1251
- if (result.isOk()) return err(result.value);
1252
- if (result.isErr()) return ok(result.error);
1253
- throw new Error("Unreachable: Result is neither Ok nor Err");
1254
- }
1255
-
1256
- //#endregion
1257
- //#region src/collections/sequence.ts
815
+ //#region src/core/sequence.ts
1258
816
  /**
1259
- * Combines a list of Results into a Result of a list.
1260
- * Short-circuits on the first Err.
1261
- * Analogous to Rust `collect::<Result<Vec<_>, _>>()`.
817
+ * Kombiniert eine Liste von Results zu einem Result einer Liste.
818
+ * Short-circuits beim ersten Err.
819
+ * Analog zu Rust `collect::<Result<Vec<_>, _>>()`.
1262
820
  */
1263
821
  function sequence(results) {
1264
822
  const values = [];
@@ -1273,23 +831,23 @@ function sequence(results) {
1273
831
  return ok(values);
1274
832
  }
1275
833
  /**
1276
- * Alias for `sequence`.
834
+ * Alias für `sequence`.
1277
835
  */
1278
836
  function all(results) {
1279
837
  return sequence(results);
1280
838
  }
1281
839
 
1282
840
  //#endregion
1283
- //#region src/collections/sequenceRecord.ts
841
+ //#region src/core/sequenceRecord.ts
1284
842
  /**
1285
- * Like `sequence`, but for records/objects.
1286
- * Short-circuits on the first Err.
843
+ * Wie `sequence`, aber für Records/Objekte.
844
+ * Short-circuits beim ersten Err.
1287
845
  */
1288
846
  function sequenceRecord(record) {
1289
847
  const out = {};
1290
848
  for (const key of Object.keys(record)) {
1291
849
  const result = record[key];
1292
- if (!result) throw new Error(`Missing Result for key "${String(key)}"`);
850
+ if (!result) continue;
1293
851
  if (result.isOk()) {
1294
852
  out[key] = result.value;
1295
853
  continue;
@@ -1301,33 +859,13 @@ function sequenceRecord(record) {
1301
859
  }
1302
860
 
1303
861
  //#endregion
1304
- //#region src/collections/collectFirstOk.ts
1305
- /**
1306
- * Parse a set of `Result`s, short-circuits when an input value is `Ok`.
1307
- * If no `Ok` is found, returns an `Err` containing the collected error values.
1308
- * Useful for "try multiple approaches until one works" patterns.
1309
- */
1310
- function collectFirstOk(results) {
1311
- const errors = [];
1312
- for (const result of results) {
1313
- if (result.isOk()) return ok(result.value);
1314
- if (result.isErr()) {
1315
- errors.push(result.error);
1316
- continue;
1317
- }
1318
- throw new Error("Unreachable: Result is neither Ok nor Err");
1319
- }
1320
- return err(errors);
1321
- }
1322
-
1323
- //#endregion
1324
- //#region src/collections/collectFirstOkAsync.ts
862
+ //#region src/core/collectFirstOkAsync.ts
1325
863
  /**
1326
- * Async version of collectFirstOk.
864
+ * Async-Version von collectFirstOk.
1327
865
  *
1328
- * - Accepts already-started promises or "thunks" (`() => Awaitable<Result<...>>`).
1329
- * - Processes inputs strictly sequentially (like `for ... of` + `await`).
1330
- * - Returns the first `Ok` and collects all errors when no `Ok` is found.
866
+ * - Nimmt entweder bereits gestartete Promises oder "Thunks" (`() => Awaitable<Result<...>>`).
867
+ * - Verarbeitet die Inputs strikt sequentiell (wie `for ... of` + `await`).
868
+ * - Gibt das erste `Ok` zurück und sammelt alle Errors wenn kein `Ok` gefunden wird.
1331
869
  */
1332
870
  async function collectFirstOkAsync(inputs) {
1333
871
  const errors = [];
@@ -1346,14 +884,13 @@ async function collectFirstOkAsync(inputs) {
1346
884
  }
1347
885
 
1348
886
  //#endregion
1349
- //#region src/collections/collectFirstOkRaceAsync.ts
887
+ //#region src/core/collectFirstOkRaceAsync.ts
1350
888
  /**
1351
- * Parallel/race variant of `collectFirstOkAsync`.
889
+ * Parallel/Race-Variante von `collectFirstOkAsync`.
1352
890
  *
1353
- * - Starts all inputs immediately (promises or thunks).
1354
- * - Returns the first `Ok` as soon as it is available.
1355
- * - If no `Ok` is found, returns an `Err` with all error values (in input order).
1356
- * - **Note**: There is no cancellation logic. All inputs keep running even after the first `Ok` is found.
891
+ * - Startet alle Inputs sofort (Promises oder Thunks).
892
+ * - Gibt das erste `Ok` zurück, sobald es verfügbar ist.
893
+ * - Wenn kein `Ok` gefunden wird, gibt ein `Err` mit allen Error-Werten (in Input-Reihenfolge) zurück.
1357
894
  */
1358
895
  async function collectFirstOkRaceAsync(inputs) {
1359
896
  if (inputs.length === 0) return err([]);
@@ -1397,10 +934,10 @@ async function collectFirstOkRaceAsync(inputs) {
1397
934
  }
1398
935
 
1399
936
  //#endregion
1400
- //#region src/collections/collectAllErrors.ts
937
+ //#region src/core/collectAllErrors.ts
1401
938
  /**
1402
- * Combines a list of Results.
1403
- * Returns Ok(values) only if all are Ok, otherwise Err([errors]).
939
+ * Kombiniert eine Liste von Results.
940
+ * Gibt Ok(values) nur zurück wenn alle Ok sind, sonst Err([errors]).
1404
941
  */
1405
942
  function collectAllErrors(results) {
1406
943
  const values = [];
@@ -1420,9 +957,9 @@ function collectAllErrors(results) {
1420
957
  }
1421
958
 
1422
959
  //#endregion
1423
- //#region src/collections/partition.ts
960
+ //#region src/core/partition.ts
1424
961
  /**
1425
- * Partitions Results into Ok values and Err errors.
962
+ * Partitioniert Results in Ok-Werte und Err-Fehler.
1426
963
  */
1427
964
  function partition(results) {
1428
965
  const oks = [];
@@ -1442,7 +979,7 @@ function partition(results) {
1442
979
  }
1443
980
 
1444
981
  //#endregion
1445
- //#region src/collections/flatten.ts
982
+ //#region src/core/flatten.ts
1446
983
  /**
1447
984
  * Flacht ein nested Result ab.
1448
985
  * Result<Result<T, E>, E> → Result<T, E>
@@ -1454,30 +991,53 @@ function flatten(result) {
1454
991
  }
1455
992
 
1456
993
  //#endregion
1457
- //#region src/utils/isOk.ts
994
+ //#region src/core/toPromise.ts
995
+ /**
996
+ * Konvertiert ein Result zu einem Promise.
997
+ * Ok → resolve(value), Err → reject(error)
998
+ */
999
+ function toPromise(result) {
1000
+ if (result.isOk()) return Promise.resolve(result.value);
1001
+ if (result.isErr()) return Promise.reject(result.error);
1002
+ throw new Error("Unreachable: Result is neither Ok nor Err");
1003
+ }
1004
+
1005
+ //#endregion
1006
+ //#region src/core/toNullable.ts
1007
+ /**
1008
+ * Konvertiert ein Result zu `T | null`.
1009
+ * Ok → value, Err → null
1010
+ */
1011
+ function toNullable(result) {
1012
+ if (result.isOk()) return result.value;
1013
+ return null;
1014
+ }
1015
+
1016
+ //#endregion
1017
+ //#region src/core/isOk.ts
1458
1018
  /**
1459
- * Checks whether a Result is Ok.
1460
- * Pure function alternative to the instance method.
1019
+ * Prüft ob ein Result Ok ist.
1020
+ * Pure function Alternative zur Instanz-Methode.
1461
1021
  */
1462
1022
  function isOk(result) {
1463
1023
  return result.isOk();
1464
1024
  }
1465
1025
 
1466
1026
  //#endregion
1467
- //#region src/utils/isErr.ts
1027
+ //#region src/core/isErr.ts
1468
1028
  /**
1469
- * Checks whether a Result is Err.
1470
- * Pure function alternative to the instance method.
1029
+ * Prüft ob ein Result Err ist.
1030
+ * Pure function Alternative zur Instanz-Methode.
1471
1031
  */
1472
1032
  function isErr(result) {
1473
1033
  return result.isErr();
1474
1034
  }
1475
1035
 
1476
1036
  //#endregion
1477
- //#region src/utils/contains.ts
1037
+ //#region src/core/contains.ts
1478
1038
  /**
1479
- * Checks whether the Result contains a specific value.
1480
- * Equivalent to Rust `contains`.
1039
+ * Prüft ob das Result einen bestimmten Wert enthält.
1040
+ * Entspricht Rust `contains`.
1481
1041
  */
1482
1042
  function contains(result, value) {
1483
1043
  if (!result.isOk()) return false;
@@ -1485,10 +1045,10 @@ function contains(result, value) {
1485
1045
  }
1486
1046
 
1487
1047
  //#endregion
1488
- //#region src/utils/containsErr.ts
1048
+ //#region src/core/containsErr.ts
1489
1049
  /**
1490
- * Checks whether the Result contains a specific error.
1491
- * Analogous to `contains` for the Err case.
1050
+ * Prüft ob das Result einen bestimmten Fehler enthält.
1051
+ * Analog zu `contains` für den Err-Fall.
1492
1052
  */
1493
1053
  function containsErr(result, error) {
1494
1054
  if (!result.isErr()) return false;
@@ -1496,6 +1056,8 @@ function containsErr(result, error) {
1496
1056
  }
1497
1057
 
1498
1058
  //#endregion
1059
+ exports.Err = Err;
1060
+ exports.Ok = Ok;
1499
1061
  exports.Result = Result;
1500
1062
  exports.all = all;
1501
1063
  exports.and = and;