resultar 2.0.0 → 3.0.0-alpha.1

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.
@@ -1,698 +0,0 @@
1
- //#region src/error.ts
2
- const defaultErrorConfig = { withStackTrace: false };
3
- const createResultarError = (message, result, config = defaultErrorConfig) => {
4
- const data = result.isOk() ? {
5
- type: "Ok",
6
- value: result.value
7
- } : {
8
- type: "Err",
9
- value: result.error
10
- };
11
- const maybeStack = config.withStackTrace ? (/* @__PURE__ */ new Error()).stack : void 0;
12
- const error = {
13
- name: "ResultarError",
14
- data,
15
- message
16
- };
17
- return maybeStack === void 0 ? error : Object.assign(error, { stack: maybeStack });
18
- };
19
- //#endregion
20
- //#region src/utils.ts
21
- /**
22
- * Short circuits on the FIRST Err value that we find
23
- */
24
- const combineResultList = (resultList) => {
25
- const values = [];
26
- for (const result of resultList) {
27
- if (result.isErr()) return err(result.error);
28
- values.push(result.value);
29
- }
30
- return ok(values);
31
- };
32
- const combineResultAsyncList = (asyncResultList) => ResultAsync.fromSafePromise(Promise.all(asyncResultList)).andThen(combineResultList);
33
- /**
34
- * Give a list of all the errors we find
35
- */
36
- const combineResultListWithAllErrors = (resultList) => {
37
- let acc = ok([]);
38
- for (const result of resultList) if (result.isErr() && acc.isErr()) acc.error.push(result.error);
39
- else if (result.isErr() && acc.isOk()) acc = err([result.error]);
40
- else if (result.isOk() && acc.isOk()) acc.value.push(result.value);
41
- return acc;
42
- };
43
- const combineResultAsyncListWithAllErrors = (asyncResultList) => ResultAsync.fromSafePromise(Promise.all(asyncResultList)).andThen(combineResultListWithAllErrors);
44
- //#endregion
45
- //#region src/tagged-match.ts
46
- const isTaggedValue = (value) => typeof value === "object" && value !== null && "_tag" in value;
47
- const hasTag = (value, tag) => isTaggedValue(value) && value._tag === tag;
48
- const callTaggedHandler = (value, handlers) => {
49
- if (!isTaggedValue(value)) return { matched: false };
50
- const handler = handlers[value._tag];
51
- if (handler === void 0) return { matched: false };
52
- return {
53
- matched: true,
54
- value: handler(value)
55
- };
56
- };
57
- const callErrorHandler = (error, handlers) => {
58
- if (handlers.Error === void 0) return { matched: false };
59
- return {
60
- matched: true,
61
- value: handlers.Error(error)
62
- };
63
- };
64
- //#endregion
65
- //#region src/result.ts
66
- /**
67
- * Runtime namespace for Result constructors and static helpers.
68
- */
69
- var ResultNamespace = class {
70
- static [Symbol.hasInstance](value) {
71
- return value instanceof Ok || value instanceof Err;
72
- }
73
- /**
74
- * Creates a `Result` by running a function that might throw.
75
- * If the function throws, the error will be caught and returned as an `Err`.
76
- * If the function succeeds, the value will be wrapped in an `Ok`.
77
- *
78
- * @param fn - The function to execute, which might throw an error
79
- * @param errorFn - Optional function to transform the thrown error before wrapping in `Err`
80
- * @returns A `Result` containing either the function's return value or the caught error
81
- */
82
- static tryCatch(fn, errorFn) {
83
- try {
84
- return ok(fn());
85
- } catch (error) {
86
- if (errorFn) return err(errorFn(error));
87
- return err(error);
88
- }
89
- }
90
- /**
91
- * Wraps a function with a try catch, creating a new function with the same
92
- * arguments but returning `Ok` if successful, `Err` if the function throws
93
- *
94
- * @param fn function to wrap with ok on success or err on failure
95
- * @param errorFn when an error is thrown, this will wrap the error result if provided
96
- */
97
- static fromThrowable(fn, errorFn) {
98
- return (...args) => {
99
- try {
100
- return ok(fn(...args));
101
- } catch (error) {
102
- if (errorFn) return err(errorFn(error));
103
- return err(error);
104
- }
105
- };
106
- }
107
- static ok(value) {
108
- return ok(value);
109
- }
110
- /**
111
- * Creates a new `Result` instance representing a successful operation with an undefined value.
112
- *
113
- * @return {Result<undefined, E>} A new `Result` instance with an undefined value.
114
- */
115
- static unit() {
116
- return unit();
117
- }
118
- static err(error) {
119
- return err(error);
120
- }
121
- static combine(resultList) {
122
- return combineResultList(resultList);
123
- }
124
- static combineWithAllErrors(resultList) {
125
- return combineResultListWithAllErrors(resultList);
126
- }
127
- };
128
- const Result = ResultNamespace;
129
- var Ok = class {
130
- value;
131
- constructor(value) {
132
- this.value = value;
133
- }
134
- isOk() {
135
- this;
136
- return true;
137
- }
138
- isErr() {
139
- this;
140
- return false;
141
- }
142
- map(f) {
143
- return ok(f(this.value));
144
- }
145
- filterOrElse(predicate, onFalse) {
146
- if (predicate(this.value)) return ok(this.value);
147
- return err(onFalse(this.value));
148
- }
149
- mapErr(_fn) {
150
- return ok(this.value);
151
- }
152
- andThen(f) {
153
- return f(this.value);
154
- }
155
- if(fCondition) {
156
- return { true: (fTrue) => ({ false: (fFalse) => fCondition(this.value) ? fTrue(this.value) : fFalse(this.value) }) };
157
- }
158
- orElse(_f) {
159
- return ok(this.value);
160
- }
161
- catchTag(_tag, _f) {
162
- return ok(this.value);
163
- }
164
- catchTags(_handlers) {
165
- return ok(this.value);
166
- }
167
- asyncAndThen(f) {
168
- return f(this.value);
169
- }
170
- asyncMap(f) {
171
- return ResultAsync.fromSafePromise(f(this.value));
172
- }
173
- unwrapOr(_defaultValue) {
174
- return this.value;
175
- }
176
- match(fnOk, _fnErr) {
177
- return fnOk(this.value);
178
- }
179
- matchTags(fnOk, _handlers) {
180
- return fnOk(this.value);
181
- }
182
- matchTagsPartial(fnOk, _handlers, _fallback) {
183
- return fnOk(this.value);
184
- }
185
- pipe(...fns) {
186
- const first = fns[0];
187
- if (!first) return this;
188
- let input = first(this);
189
- for (const fn of fns.slice(1)) input = fn(input);
190
- return input;
191
- }
192
- log(fn) {
193
- try {
194
- fn(this.value, void 0);
195
- } catch {}
196
- return this;
197
- }
198
- tap(fn) {
199
- try {
200
- fn(this.value);
201
- } catch {}
202
- return this;
203
- }
204
- tapError(_fn) {
205
- return this;
206
- }
207
- toDisposable(f) {
208
- return new DisposableResult(this, f);
209
- }
210
- unwrapOrThrow() {
211
- return this.value;
212
- }
213
- _unsafeUnwrap(_config) {
214
- return this.value;
215
- }
216
- _unsafeUnwrapErr(config) {
217
- throw createResultarError("Called `_unsafeUnwrapErr` on an Ok", this, config);
218
- }
219
- *[Symbol.iterator]() {
220
- return this.value;
221
- }
222
- safeUnwrap() {
223
- const { value } = this;
224
- return (function* () {
225
- return value;
226
- })();
227
- }
228
- };
229
- var Err = class {
230
- error;
231
- constructor(error) {
232
- this.error = error;
233
- }
234
- isOk() {
235
- this;
236
- return false;
237
- }
238
- isErr() {
239
- this;
240
- return true;
241
- }
242
- map(_f) {
243
- return err(this.error);
244
- }
245
- filterOrElse(_predicate, _onFalse) {
246
- return err(this.error);
247
- }
248
- mapErr(fn) {
249
- return err(fn(this.error));
250
- }
251
- andThen(_f) {
252
- return err(this.error);
253
- }
254
- if(_fCondition) {
255
- return { true: (_fTrue) => ({ false: (_fFalse) => err(this.error) }) };
256
- }
257
- orElse(f) {
258
- return f(this.error);
259
- }
260
- catchTag(tag, f) {
261
- if (hasTag(this.error, tag)) return f(this.error);
262
- return err(this.error);
263
- }
264
- catchTags(handlers) {
265
- const error = this.error;
266
- const handled = callTaggedHandler(error, handlers);
267
- if (handled.matched) return handled.value;
268
- return err(error);
269
- }
270
- asyncAndThen(_f) {
271
- return errAsync(this.error);
272
- }
273
- asyncMap(_f) {
274
- return errAsync(this.error);
275
- }
276
- unwrapOr(defaultValue) {
277
- this;
278
- return defaultValue;
279
- }
280
- match(_fnOk, fnErr) {
281
- return fnErr(this.error);
282
- }
283
- matchTags(_fnOk, handlers) {
284
- const error = this.error;
285
- const tagged = callTaggedHandler(error, handlers);
286
- if (tagged.matched) return tagged.value;
287
- const errorHandler = callErrorHandler(error, handlers);
288
- if (errorHandler.matched) return errorHandler.value;
289
- throw error;
290
- }
291
- matchTagsPartial(_fnOk, handlers, fallback) {
292
- const error = this.error;
293
- const tagged = callTaggedHandler(error, handlers);
294
- if (tagged.matched) return tagged.value;
295
- const errorHandler = callErrorHandler(error, handlers);
296
- if (errorHandler.matched) return errorHandler.value;
297
- return fallback(error);
298
- }
299
- pipe(...fns) {
300
- const first = fns[0];
301
- if (!first) return this;
302
- let input = first(this);
303
- for (const fn of fns.slice(1)) input = fn(input);
304
- return input;
305
- }
306
- log(fn) {
307
- try {
308
- fn(void 0, this.error);
309
- } catch {}
310
- return this;
311
- }
312
- tap(_fn) {
313
- return this;
314
- }
315
- tapError(fn) {
316
- try {
317
- fn(this.error);
318
- } catch {}
319
- return this;
320
- }
321
- toDisposable(f) {
322
- return new DisposableResult(this, f);
323
- }
324
- unwrapOrThrow() {
325
- throw this.error;
326
- }
327
- _unsafeUnwrap(config) {
328
- throw createResultarError("Called `_unsafeUnwrap` on an Err", this, config);
329
- }
330
- _unsafeUnwrapErr(_config) {
331
- return this.error;
332
- }
333
- *[Symbol.iterator]() {
334
- yield this;
335
- return this;
336
- }
337
- safeUnwrap() {
338
- const { error } = this;
339
- return (function* () {
340
- yield err(error);
341
- throw new Error("Do not use this generator out of `safeTry`");
342
- })();
343
- }
344
- };
345
- /**
346
- * A `Disposable` is an object that has a `dispose` method that can be used to
347
- * clean up resources.
348
- */
349
- var DisposableResult = class {
350
- disposed = false;
351
- finalizer;
352
- result;
353
- constructor(result, finalizer) {
354
- this.result = result;
355
- this.finalizer = finalizer;
356
- }
357
- get value() {
358
- return this.result.isOk() ? this.result.value : void 0;
359
- }
360
- get error() {
361
- return this.result.isErr() ? this.result.error : void 0;
362
- }
363
- _unsafeUnwrap(config) {
364
- return this.result._unsafeUnwrap(config);
365
- }
366
- _unsafeUnwrapErr(config) {
367
- return this.result._unsafeUnwrapErr(config);
368
- }
369
- isOk() {
370
- return this.result.isOk();
371
- }
372
- isErr() {
373
- return this.result.isErr();
374
- }
375
- unwrapOr(defaultValue) {
376
- return this.result.unwrapOr(defaultValue);
377
- }
378
- [Symbol.dispose]() {
379
- if (this.disposed) return;
380
- this.disposed = true;
381
- try {
382
- this.finalizer(this.result.isOk() ? this.result.value : void 0, this.result.isErr() ? this.result.error : void 0);
383
- } catch {}
384
- }
385
- };
386
- function safeTry(body) {
387
- const n = body().next();
388
- if (n instanceof Promise) return new ResultAsync(n.then((r) => r.value));
389
- return n.value;
390
- }
391
- function ok(value) {
392
- return new Ok(value);
393
- }
394
- function err(error) {
395
- return new Err(error);
396
- }
397
- const fromThrowable = Result.fromThrowable;
398
- function unit() {
399
- return ok(void 0);
400
- }
401
- const tryCatch = Result.tryCatch;
402
- //#endregion
403
- //#region src/result-async.ts
404
- var DisposableResultAsync = class {
405
- innerPromise;
406
- finalizer;
407
- disposed = false;
408
- constructor(res, finalizer) {
409
- this.innerPromise = res;
410
- this.finalizer = finalizer;
411
- }
412
- then(successCallback, failureCallback) {
413
- return this.innerPromise.then(successCallback, failureCallback);
414
- }
415
- async [Symbol.asyncDispose]() {
416
- if (this.disposed) return;
417
- this.disposed = true;
418
- const result = await this.innerPromise;
419
- try {
420
- await this.finalizer(result.isOk() ? result.value : void 0, result.isErr() ? result.error : void 0);
421
- } catch {}
422
- }
423
- };
424
- /**
425
- * Represents an asynchronous Result type that wraps a Promise of a Result<T, E>.
426
- * This class provides a way to handle asynchronous operations that may succeed with a value of type T
427
- * or fail with an error of type E.
428
- *
429
- * @template T - The type of the success value
430
- * @template E - The type of the error value
431
- *
432
- * @implements {PromiseLike<Result<T, E>>}
433
- *
434
- * @example
435
- * ```typescript
436
- * // Create a successful async result
437
- * const okAsync = ResultAsync.okAsync(42);
438
- *
439
- * // Create a failed async result
440
- * const errAsync = ResultAsync.errAsync(new Error("Something went wrong"));
441
- *
442
- * // Transform a Promise into a ResultAsync
443
- * const resultFromPromise = ResultAsync.fromPromise(
444
- * fetch("https://api.example.com/data"),
445
- * (error) => new Error(`API call failed: ${error}`)
446
- * );
447
- * ```
448
- *
449
- * @remarks
450
- * ResultAsync implements the PromiseLike interface, allowing it to be used with async/await syntax.
451
- * It provides various utility methods for transforming and combining results, similar to the Result type,
452
- * but operating in an asynchronous context.
453
- *
454
- * The class includes methods for:
455
- * - Creating ResultAsync instances (okAsync, errAsync, fromPromise)
456
- * - Transforming values (map, mapErr)
457
- * - Chaining operations (andThen, orElse)
458
- * - Error handling (tapError)
459
- * - Conditional branching (if)
460
- * - Combining multiple ResultAsync instances (combine, combineWithAllErrors)
461
- */
462
- var ResultAsync = class ResultAsync {
463
- static okAsync(value) {
464
- return new ResultAsync(Promise.resolve(Result.ok(value)));
465
- }
466
- /**
467
- * Returns a ResultAsync that is immediately resolved with a Result.ok(undefined) value.
468
- *
469
- * @return {ResultAsync<undefined, E>} A ResultAsync instance with undefined as the value type and E as the error type.
470
- */
471
- static unitAsync() {
472
- return new ResultAsync(Promise.resolve(Result.unit()));
473
- }
474
- static errAsync(error) {
475
- return new ResultAsync(Promise.resolve(Result.err(error)));
476
- }
477
- static tryCatch(fn, errorFn) {
478
- return new ResultAsync((typeof fn === "function" ? Promise.try(fn) : fn).then((value) => Result.ok(value)).catch((error) => {
479
- if (errorFn) return Result.err(errorFn(error));
480
- return Result.err(error);
481
- }));
482
- }
483
- static fromSafePromise(promise) {
484
- return new ResultAsync(promise.then((value) => Result.ok(value)));
485
- }
486
- static fromPromise(promise, errorFn) {
487
- return new ResultAsync(promise.then((value) => Result.ok(value)).catch((error) => Result.err(errorFn(error))));
488
- }
489
- static combine(asyncResultList) {
490
- return combineResultAsyncList(asyncResultList);
491
- }
492
- static combineWithAllErrors(asyncResultList) {
493
- return combineResultAsyncListWithAllErrors(asyncResultList);
494
- }
495
- /**
496
- * Wraps a async function with a try catch, creating a new function with the same
497
- * arguments but returning `Ok` if successful, `Err` if the function throws
498
- *
499
- * @param fn function to wrap with ok on success or err on failure
500
- * @param errorFn when an error is thrown, this will wrap the error result if provided
501
- * @returns a new function that returns a `ResultAsync`
502
- */
503
- static fromThrowable(fn, errorFn) {
504
- return (...args) => new ResultAsync((async () => {
505
- try {
506
- const v = await fn(...args);
507
- return Result.ok(v);
508
- } catch (error) {
509
- const e = errorFn ? errorFn(error) : error;
510
- return Result.err(e);
511
- }
512
- })());
513
- }
514
- innerPromise;
515
- constructor(res) {
516
- this.innerPromise = res;
517
- }
518
- then(successCallback, failureCallback) {
519
- return this.innerPromise.then(successCallback, failureCallback);
520
- }
521
- mapErr(f) {
522
- return new ResultAsync(this.innerPromise.then(async (res) => {
523
- if (res.isOk()) return Result.ok(res.value);
524
- return Result.err(await f(res.error));
525
- }));
526
- }
527
- map(f) {
528
- return new ResultAsync(this.innerPromise.then(async (res) => {
529
- if (res.isErr()) return Result.err(res.error);
530
- return Result.ok(await f(res.value));
531
- }));
532
- }
533
- filterOrElse(predicate, onFalse) {
534
- return new ResultAsync(this.innerPromise.then(async (res) => {
535
- if (res.isErr()) return Result.err(res.error);
536
- if (await predicate(res.value)) return Result.ok(res.value);
537
- return Result.err(await onFalse(res.value));
538
- }));
539
- }
540
- andThen(f) {
541
- return new ResultAsync(this.innerPromise.then((res) => {
542
- if (res.isErr()) return Result.err(res.error);
543
- const next = f(res.value);
544
- return next instanceof ResultAsync ? next.innerPromise : next;
545
- }));
546
- }
547
- if(fCondition) {
548
- return { true: (fTrue) => ({ false: (fFalse) => new ResultAsync(this.innerPromise.then(async (res) => {
549
- if (res.isOk()) return fCondition(res.value) ? fTrue(res.value) : fFalse(res.value);
550
- return errAsync(res.error);
551
- })) }) };
552
- }
553
- orElse(f) {
554
- return new ResultAsync(this.innerPromise.then((res) => {
555
- if (res.isErr()) {
556
- const next = f(res.error);
557
- return next instanceof ResultAsync ? next.innerPromise : next;
558
- }
559
- return Result.ok(res.value);
560
- }));
561
- }
562
- catchTag(tag, f) {
563
- return new ResultAsync(this.innerPromise.then((res) => {
564
- if (res.isOk()) return Result.ok(res.value);
565
- if (hasTag(res.error, tag)) {
566
- const next = f(res.error);
567
- return next instanceof ResultAsync ? next.innerPromise : next;
568
- }
569
- return Result.err(res.error);
570
- }));
571
- }
572
- catchTags(handlers) {
573
- return new ResultAsync(this.innerPromise.then((res) => {
574
- if (res.isOk()) return Result.ok(res.value);
575
- const error = res.error;
576
- const handled = callTaggedHandler(error, handlers);
577
- if (handled.matched) {
578
- const next = handled.value;
579
- return next instanceof ResultAsync ? next.innerPromise : next;
580
- }
581
- return Result.err(error);
582
- }));
583
- }
584
- async match(ok, fnErr) {
585
- return this.innerPromise.then((res) => res.match(ok, fnErr));
586
- }
587
- async matchTags(ok, handlers) {
588
- return this.innerPromise.then((res) => {
589
- if (res.isOk()) return ok(res.value);
590
- const error = res.error;
591
- const tagged = callTaggedHandler(error, handlers);
592
- if (tagged.matched) return tagged.value;
593
- const errorHandler = callErrorHandler(error, handlers);
594
- if (errorHandler.matched) return errorHandler.value;
595
- throw error;
596
- });
597
- }
598
- async matchTagsPartial(ok, handlers, fallback) {
599
- return this.innerPromise.then((res) => {
600
- if (res.isOk()) return ok(res.value);
601
- const error = res.error;
602
- const tagged = callTaggedHandler(error, handlers);
603
- if (tagged.matched) return tagged.value;
604
- const errorHandler = callErrorHandler(error, handlers);
605
- if (errorHandler.matched) return errorHandler.value;
606
- return fallback(error);
607
- });
608
- }
609
- async unwrapOr(t) {
610
- return this.innerPromise.then((res) => res.unwrapOr(t));
611
- }
612
- async unwrapOrThrow() {
613
- return this.innerPromise.then((res) => res.unwrapOrThrow());
614
- }
615
- pipe(...fns) {
616
- const first = fns[0];
617
- if (!first) return this;
618
- let input = first(this);
619
- for (const fn of fns.slice(1)) input = fn(input);
620
- return input;
621
- }
622
- /**
623
- * Runs a side effect for either variant and preserves the original async result.
624
- *
625
- * For `Ok`, the callback receives `(value, undefined)`.
626
- * For `Err`, the callback receives `(undefined, error)`.
627
- * Callback errors and rejected callback promises are intentionally ignored.
628
- *
629
- * Use `map`, `mapErr`, `andThen`, or `orElse` when the callback should
630
- * transform the result.
631
- */
632
- log(f) {
633
- return new ResultAsync(this.innerPromise.then(async (res) => {
634
- if (res.isOk()) {
635
- try {
636
- await f(res.value);
637
- } catch {}
638
- return okAsync(res.value);
639
- }
640
- try {
641
- await f(void 0, res.error);
642
- } catch {}
643
- return errAsync(res.error);
644
- }));
645
- }
646
- /**
647
- * Runs a side effect only for the `Ok` variant and preserves the original async result.
648
- *
649
- * Callback errors and rejected callback promises are intentionally ignored.
650
- * Use `map` or `andThen` when the callback should transform the value.
651
- */
652
- tap(f) {
653
- return new ResultAsync(this.innerPromise.then(async (res) => {
654
- if (res.isErr()) return errAsync(res.error);
655
- try {
656
- await f(res.value);
657
- } catch {}
658
- return okAsync(res.value);
659
- }));
660
- }
661
- /**
662
- * Runs a side effect only for the `Err` variant and preserves the original async result.
663
- *
664
- * Callback errors and rejected callback promises are intentionally ignored.
665
- * Use `mapErr` or `orElse` when the callback should transform the error.
666
- */
667
- tapError(f) {
668
- return new ResultAsync(this.innerPromise.then(async (res) => {
669
- if (res.isErr()) {
670
- try {
671
- await f(res.error);
672
- } catch {}
673
- return errAsync(res.error);
674
- }
675
- return okAsync(res.value);
676
- }));
677
- }
678
- toAsyncDisposable(f) {
679
- return new DisposableResultAsync(this.innerPromise, f);
680
- }
681
- async *[Symbol.asyncIterator]() {
682
- const result = await this.innerPromise;
683
- if (result.isOk()) return result.value;
684
- yield err(result.error);
685
- return void 0;
686
- }
687
- };
688
- const okAsync = ResultAsync.okAsync;
689
- const errAsync = ResultAsync.errAsync;
690
- const fromPromise = ResultAsync.fromPromise;
691
- const fromSafePromise = ResultAsync.fromSafePromise;
692
- const unitAsync = ResultAsync.unitAsync;
693
- const fromThrowableAsync = ResultAsync.fromThrowable;
694
- const tryCatchAsync = ResultAsync.tryCatch;
695
- //#endregion
696
- export { unit as _, fromSafePromise as a, tryCatchAsync as c, Result as d, err as f, tryCatch as g, safeTry as h, fromPromise as i, unitAsync as l, ok as m, ResultAsync as n, fromThrowableAsync as o, fromThrowable as p, errAsync as r, okAsync as s, DisposableResultAsync as t, DisposableResult as u };
697
-
698
- //# sourceMappingURL=result-async-CdlVdXgX.js.map