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.
package/dist/index.js CHANGED
@@ -1,9 +1,994 @@
1
- import { _ as unit, a as fromSafePromise, c as tryCatchAsync, d as Result, f as err, g as tryCatch, h as safeTry, i as fromPromise, l as unitAsync, m as ok, n as ResultAsync, o as fromThrowableAsync, p as fromThrowable, r as errAsync, s as okAsync, t as DisposableResultAsync, u as DisposableResult } from "./result-async-CdlVdXgX.js";
1
+ //#region src/pipe.ts
2
+ const runPipe = (self, fns) => {
3
+ const first = fns[0];
4
+ if (!first) return self;
5
+ let input = first(self);
6
+ for (const fn of fns.slice(1)) input = fn(input);
7
+ return input;
8
+ };
9
+ var Pipeable = class {
10
+ pipe(...fns) {
11
+ return runPipe(this, fns);
12
+ }
13
+ };
14
+ //#endregion
15
+ //#region src/result-async-adapter.ts
16
+ let resultAsyncFactory = void 0;
17
+ const registerResultAsyncFactory = (factory) => {
18
+ resultAsyncFactory = factory;
19
+ };
20
+ const createResultAsync = (promise) => {
21
+ if (resultAsyncFactory === void 0) throw new Error("ResultAsync is not registered");
22
+ return resultAsyncFactory(promise);
23
+ };
24
+ //#endregion
25
+ //#region src/error.ts
26
+ const defaultErrorConfig = { withStackTrace: false };
27
+ const createResultarError = (message, result, config = defaultErrorConfig) => {
28
+ const data = result.isOk() ? {
29
+ type: "Ok",
30
+ value: result.value
31
+ } : {
32
+ type: "Err",
33
+ value: result.error
34
+ };
35
+ const maybeStack = config.withStackTrace ? (/* @__PURE__ */ new Error()).stack : void 0;
36
+ const error = {
37
+ name: "ResultarError",
38
+ data,
39
+ message
40
+ };
41
+ return maybeStack === void 0 ? error : Object.assign(error, { stack: maybeStack });
42
+ };
43
+ //#endregion
44
+ //#region src/tagged-match.ts
45
+ const isTaggedValue = (value) => typeof value === "object" && value !== null && "_tag" in value;
46
+ const hasTag = (value, tag) => isTaggedValue(value) && value._tag === tag;
47
+ const callTaggedHandler = (value, handlers) => {
48
+ if (!isTaggedValue(value)) return { matched: false };
49
+ const handler = handlers[value._tag];
50
+ if (handler === void 0) return { matched: false };
51
+ return {
52
+ matched: true,
53
+ value: handler(value)
54
+ };
55
+ };
56
+ const callErrorHandler = (error, handlers) => {
57
+ if (handlers.Error === void 0) return { matched: false };
58
+ return {
59
+ matched: true,
60
+ value: handlers.Error(error)
61
+ };
62
+ };
63
+ const callTaggedOrErrorHandler = (error, handlers) => {
64
+ const tagged = callTaggedHandler(error, handlers);
65
+ if (tagged.matched) return tagged;
66
+ return callErrorHandler(error, handlers);
67
+ };
68
+ const matchTaggedOr = (error, handlers, fallback) => {
69
+ const handled = callTaggedOrErrorHandler(error, handlers);
70
+ return handled.matched ? handled.value : fallback(error);
71
+ };
72
+ //#endregion
73
+ //#region src/result.ts
74
+ const combineResultList = (resultList) => {
75
+ const values = [];
76
+ for (const result of resultList) {
77
+ if (result.isErr()) return err(result.error);
78
+ values.push(result.value);
79
+ }
80
+ return ok(values);
81
+ };
82
+ const combineResultListWithAllErrors = (resultList) => {
83
+ let acc = ok([]);
84
+ for (const result of resultList) if (result.isErr() && acc.isErr()) acc.error.push(result.error);
85
+ else if (result.isErr() && acc.isOk()) acc = err([result.error]);
86
+ else if (result.isOk() && acc.isOk()) acc.value.push(result.value);
87
+ return acc;
88
+ };
89
+ const validateAllResultItems = (items, f) => {
90
+ return combineResultListWithAllErrors(Array.from(items, f));
91
+ };
92
+ const createEmptyResultsCollectionError = () => {
93
+ const error = /* @__PURE__ */ new Error("Received an empty collection of results");
94
+ error.name = "IllegalArgumentException";
95
+ return error;
96
+ };
97
+ const firstSuccessOfResultCandidates = (candidates) => {
98
+ let latestError = void 0;
99
+ let hasCandidates = false;
100
+ for (const candidate of candidates) {
101
+ hasCandidates = true;
102
+ const result = candidate();
103
+ if (result.isOk()) return result;
104
+ latestError = result;
105
+ }
106
+ if (!hasCandidates || latestError === void 0) throw createEmptyResultsCollectionError();
107
+ return latestError;
108
+ };
109
+ const loopResult = (initial, options) => {
110
+ let state = initial;
111
+ const values = [];
112
+ while (options.while(state)) {
113
+ const result = options.body(state);
114
+ if (result.isErr()) return err(result.error);
115
+ if (options.discard !== true) values.push(result.value);
116
+ state = options.step(state);
117
+ }
118
+ if (options.discard === true) return ok(void 0);
119
+ return ok(values);
120
+ };
121
+ const iterateResult = (initial, options) => {
122
+ let state = initial;
123
+ while (options.while(state)) {
124
+ const result = options.body(state);
125
+ if (result.isErr()) return err(result.error);
126
+ state = result.value;
127
+ }
128
+ return ok(state);
129
+ };
130
+ const forEachResult = (items, f, options) => {
131
+ const values = [];
132
+ let index = 0;
133
+ for (const item of items) {
134
+ const result = f(item, index);
135
+ if (result.isErr()) return err(result.error);
136
+ if (options?.discard !== true) values.push(result.value);
137
+ index += 1;
138
+ }
139
+ if (options?.discard === true) return ok(void 0);
140
+ return ok(values);
141
+ };
142
+ const resolveResultBooleanCondition = (condition) => typeof condition === "function" ? condition() : condition;
143
+ const ifResult = (condition, options) => resolveResultBooleanCondition(condition) ? options.onTrue() : options.onFalse();
144
+ const ifResultWithCondition = (condition, options) => {
145
+ if (condition.isErr()) return err(condition.error);
146
+ return ifResult(condition.value, options);
147
+ };
148
+ const whenResult = (condition, body) => {
149
+ if (resolveResultBooleanCondition(condition)) return body();
150
+ return ok(void 0);
151
+ };
152
+ const whenResultWithConditionByPredicate = (condition, body, predicate) => {
153
+ if (condition.isErr()) return err(condition.error);
154
+ return whenResult(predicate(condition.value), body);
155
+ };
156
+ const whenResultWithCondition = (condition, body) => whenResultWithConditionByPredicate(condition, body, (value) => value);
157
+ const unlessResult = (condition, body) => whenResult(() => !resolveResultBooleanCondition(condition), body);
158
+ const unlessResultWithCondition = (condition, body) => whenResultWithConditionByPredicate(condition, body, (value) => !value);
159
+ const callSyncSideEffect = (effect) => {
160
+ try {
161
+ effect();
162
+ } catch {}
163
+ };
164
+ const getMatchErrorHandler = (input, fnErr) => {
165
+ if (typeof input !== "function") return input.error;
166
+ if (fnErr === void 0) throw new TypeError("Result.match requires an error handler");
167
+ return fnErr;
168
+ };
169
+ /**
170
+ * Runtime namespace for Result constructors and static helpers.
171
+ */
172
+ var ResultNamespace = class {
173
+ static [Symbol.hasInstance](value) {
174
+ return value instanceof Ok || value instanceof Err;
175
+ }
176
+ /**
177
+ * Creates a `Result` by running a function that might throw.
178
+ * If the function throws, the error will be caught and returned as an `Err`.
179
+ * If the function succeeds, the value will be wrapped in an `Ok`.
180
+ *
181
+ * Compatibility alias. Prefer the top-level `tryResult` helper in new code.
182
+ *
183
+ * @param fn - The function to execute, which might throw an error
184
+ * @param errorFn - Optional function to transform the thrown error before wrapping in `Err`
185
+ * @returns A `Result` containing either the function's return value or the caught error
186
+ */
187
+ static tryCatch(fn, errorFn) {
188
+ try {
189
+ return ok(fn());
190
+ } catch (error) {
191
+ if (errorFn) return err(errorFn(error));
192
+ return err(error);
193
+ }
194
+ }
195
+ /**
196
+ * Wraps a function with a try catch, creating a new function with the same
197
+ * arguments but returning `Ok` if successful, `Err` if the function throws
198
+ *
199
+ * @param fn function to wrap with ok on success or err on failure
200
+ * @param errorFn when an error is thrown, this will wrap the error result if provided
201
+ */
202
+ static fromThrowable(fn, errorFn) {
203
+ return (...args) => {
204
+ try {
205
+ return ok(fn(...args));
206
+ } catch (error) {
207
+ if (errorFn) return err(errorFn(error));
208
+ return err(error);
209
+ }
210
+ };
211
+ }
212
+ static ok(value) {
213
+ return ok(value);
214
+ }
215
+ /**
216
+ * Creates a new `Result` instance representing a successful operation with an undefined value.
217
+ *
218
+ * @return {Result<undefined, E>} A new `Result` instance with an undefined value.
219
+ */
220
+ static unit() {
221
+ return unit();
222
+ }
223
+ static err(error) {
224
+ return err(error);
225
+ }
226
+ static combine(resultList) {
227
+ return combineResultList(resultList);
228
+ }
229
+ static combineWithAllErrors(resultList) {
230
+ return combineResultListWithAllErrors(resultList);
231
+ }
232
+ static validateAll(resultListOrItems, f) {
233
+ if (f === void 0) return combineResultListWithAllErrors(resultListOrItems);
234
+ return validateAllResultItems(resultListOrItems, f);
235
+ }
236
+ static zip(left, right) {
237
+ return combineResultList([left, right]);
238
+ }
239
+ static firstSuccessOf(candidates) {
240
+ return firstSuccessOfResultCandidates(candidates);
241
+ }
242
+ static if(condition, options) {
243
+ if (typeof condition === "boolean" || typeof condition === "function") return ifResult(condition, options);
244
+ return ifResultWithCondition(condition, options);
245
+ }
246
+ static when(condition, body) {
247
+ return whenResult(condition, body);
248
+ }
249
+ static whenResult(condition, body) {
250
+ return whenResultWithCondition(condition, body);
251
+ }
252
+ static unless(condition, body) {
253
+ return unlessResult(condition, body);
254
+ }
255
+ static unlessResult(condition, body) {
256
+ return unlessResultWithCondition(condition, body);
257
+ }
258
+ static loop(initial, options) {
259
+ return loopResult(initial, options);
260
+ }
261
+ static iterate(initial, options) {
262
+ return iterateResult(initial, options);
263
+ }
264
+ static forEach(items, f, options) {
265
+ return forEachResult(items, f, options);
266
+ }
267
+ };
268
+ const Result = ResultNamespace;
269
+ var ResultVariant = class extends Pipeable {
270
+ filterOrElse(predicate, onFalse) {
271
+ return this.filterOrElseResult(predicate, onFalse);
272
+ }
273
+ if(fCondition) {
274
+ return { true: (fTrue) => ({ false: (fFalse) => this.branchResult(fCondition, fTrue, fFalse) }) };
275
+ }
276
+ orElse(f) {
277
+ return this.orElseResult(f);
278
+ }
279
+ };
280
+ var Ok = class extends ResultVariant {
281
+ value;
282
+ constructor(value) {
283
+ super();
284
+ this.value = value;
285
+ }
286
+ isOk() {
287
+ return true;
288
+ }
289
+ isErr() {
290
+ return false;
291
+ }
292
+ map(f) {
293
+ return ok(f(this.value));
294
+ }
295
+ as(value) {
296
+ return ok(value);
297
+ }
298
+ filterOrElseResult(predicate, onFalse) {
299
+ if (predicate(this.value)) return ok(this.value);
300
+ return err(onFalse(this.value));
301
+ }
302
+ mapErr(_fn) {
303
+ return ok(this.value);
304
+ }
305
+ andThen(f) {
306
+ return f(this.value);
307
+ }
308
+ orElseResult(_f) {
309
+ return ok(this.value);
310
+ }
311
+ catchTag(_tag, _f) {
312
+ return ok(this.value);
313
+ }
314
+ catchTags(_handlers) {
315
+ return ok(this.value);
316
+ }
317
+ branchResult(fCondition, fTrue, fFalse) {
318
+ return fCondition(this.value) ? fTrue(this.value) : fFalse(this.value);
319
+ }
320
+ asyncAndThen(f) {
321
+ return f(this.value);
322
+ }
323
+ asyncMap(f) {
324
+ return createResultAsync(Promise.resolve(f(this.value)).then((value) => ok(value)));
325
+ }
326
+ unwrapOr(_defaultValue) {
327
+ return this.value;
328
+ }
329
+ match(input, _fnErr) {
330
+ return (typeof input === "function" ? input : input.ok)(this.value);
331
+ }
332
+ matchTags(fnOk, _handlers) {
333
+ return fnOk(this.value);
334
+ }
335
+ matchTagsPartial(fnOk, _handlers, _fallback) {
336
+ return fnOk(this.value);
337
+ }
338
+ log(fn) {
339
+ callSyncSideEffect(() => {
340
+ fn(this.value, void 0);
341
+ });
342
+ return this;
343
+ }
344
+ tap(fn) {
345
+ callSyncSideEffect(() => {
346
+ fn(this.value);
347
+ });
348
+ return this;
349
+ }
350
+ tapError(_fn) {
351
+ return this;
352
+ }
353
+ toDisposable(f) {
354
+ return new DisposableResult(this, f);
355
+ }
356
+ unwrapOrThrow() {
357
+ return this.value;
358
+ }
359
+ _unsafeUnwrap(_config) {
360
+ return this.value;
361
+ }
362
+ _unsafeUnwrapErr(config) {
363
+ throw createResultarError("Called `_unsafeUnwrapErr` on an Ok", this, config);
364
+ }
365
+ *[Symbol.iterator]() {
366
+ return this.value;
367
+ }
368
+ safeUnwrap() {
369
+ const { value } = this;
370
+ return (function* () {
371
+ return value;
372
+ })();
373
+ }
374
+ };
375
+ var Err = class extends ResultVariant {
376
+ error;
377
+ constructor(error) {
378
+ super();
379
+ this.error = error;
380
+ }
381
+ isOk() {
382
+ return false;
383
+ }
384
+ isErr() {
385
+ return true;
386
+ }
387
+ map(_f) {
388
+ return err(this.error);
389
+ }
390
+ as(_value) {
391
+ return err(this.error);
392
+ }
393
+ filterOrElseResult(_predicate, _onFalse) {
394
+ return err(this.error);
395
+ }
396
+ mapErr(fn) {
397
+ return err(fn(this.error));
398
+ }
399
+ andThen(_f) {
400
+ return err(this.error);
401
+ }
402
+ orElseResult(f) {
403
+ return f(this.error);
404
+ }
405
+ branchResult(_fCondition, _fTrue, _fFalse) {
406
+ return err(this.error);
407
+ }
408
+ catchTag(tag, f) {
409
+ if (hasTag(this.error, tag)) return f(this.error);
410
+ return err(this.error);
411
+ }
412
+ catchTags(handlers) {
413
+ const error = this.error;
414
+ const handled = callTaggedHandler(error, handlers);
415
+ if (handled.matched) return handled.value;
416
+ return err(error);
417
+ }
418
+ asyncAndThen(_f) {
419
+ return createResultAsync(Promise.resolve(err(this.error)));
420
+ }
421
+ asyncMap(_f) {
422
+ return createResultAsync(Promise.resolve(err(this.error)));
423
+ }
424
+ unwrapOr(defaultValue) {
425
+ return defaultValue;
426
+ }
427
+ match(input, fnErr) {
428
+ return getMatchErrorHandler(input, fnErr)(this.error);
429
+ }
430
+ matchTags(_fnOk, handlers) {
431
+ return matchTaggedOr(this.error, handlers, (error) => {
432
+ throw error;
433
+ });
434
+ }
435
+ matchTagsPartial(_fnOk, handlers, fallback) {
436
+ return matchTaggedOr(this.error, handlers, fallback);
437
+ }
438
+ log(fn) {
439
+ callSyncSideEffect(() => {
440
+ fn(void 0, this.error);
441
+ });
442
+ return this;
443
+ }
444
+ tap(_fn) {
445
+ return this;
446
+ }
447
+ tapError(fn) {
448
+ callSyncSideEffect(() => {
449
+ fn(this.error);
450
+ });
451
+ return this;
452
+ }
453
+ toDisposable(f) {
454
+ return new DisposableResult(this, f);
455
+ }
456
+ unwrapOrThrow() {
457
+ throw this.error;
458
+ }
459
+ _unsafeUnwrap(config) {
460
+ throw createResultarError("Called `_unsafeUnwrap` on an Err", this, config);
461
+ }
462
+ _unsafeUnwrapErr(_config) {
463
+ return this.error;
464
+ }
465
+ *[Symbol.iterator]() {
466
+ yield this;
467
+ return this;
468
+ }
469
+ safeUnwrap() {
470
+ const { error } = this;
471
+ return (function* () {
472
+ yield err(error);
473
+ throw new Error("Do not use this generator out of `safeTry`");
474
+ })();
475
+ }
476
+ };
477
+ /**
478
+ * A `Disposable` is an object that has a `dispose` method that can be used to
479
+ * clean up resources.
480
+ */
481
+ var DisposableResult = class {
482
+ disposed = false;
483
+ finalizer;
484
+ result;
485
+ constructor(result, finalizer) {
486
+ this.result = result;
487
+ this.finalizer = finalizer;
488
+ }
489
+ get value() {
490
+ return this.result.isOk() ? this.result.value : void 0;
491
+ }
492
+ get error() {
493
+ return this.result.isErr() ? this.result.error : void 0;
494
+ }
495
+ _unsafeUnwrap(config) {
496
+ return this.result._unsafeUnwrap(config);
497
+ }
498
+ _unsafeUnwrapErr(config) {
499
+ return this.result._unsafeUnwrapErr(config);
500
+ }
501
+ isOk() {
502
+ return this.result.isOk();
503
+ }
504
+ isErr() {
505
+ return this.result.isErr();
506
+ }
507
+ unwrapOr(defaultValue) {
508
+ return this.result.unwrapOr(defaultValue);
509
+ }
510
+ [Symbol.dispose]() {
511
+ if (this.disposed) return;
512
+ this.disposed = true;
513
+ try {
514
+ this.finalizer(this.result.isOk() ? this.result.value : void 0, this.result.isErr() ? this.result.error : void 0);
515
+ } catch {}
516
+ }
517
+ };
518
+ function safeTry(input) {
519
+ const body = typeof input === "function" ? input : input.try;
520
+ const catchFn = typeof input === "function" ? void 0 : input.catch;
521
+ let n = void 0;
522
+ try {
523
+ n = body().next();
524
+ } catch (error) {
525
+ if (catchFn) return err(catchFn(error));
526
+ throw error;
527
+ }
528
+ if (n instanceof Promise) return createResultAsync(n.then((r) => r.value).catch((error) => {
529
+ if (catchFn) return err(catchFn(error));
530
+ throw error;
531
+ }));
532
+ return n.value;
533
+ }
534
+ function ok(value) {
535
+ return new Ok(value);
536
+ }
537
+ function err(error) {
538
+ return new Err(error);
539
+ }
540
+ const fromThrowable = Result.fromThrowable;
541
+ function tryResult(input, errorFn) {
542
+ const fn = typeof input === "function" ? input : input.try;
543
+ const catchFn = typeof input === "function" ? errorFn : input.catch;
544
+ try {
545
+ return ok(fn());
546
+ } catch (error) {
547
+ if (catchFn) return err(catchFn(error));
548
+ return err(error);
549
+ }
550
+ }
551
+ function unit() {
552
+ return ok(void 0);
553
+ }
554
+ /** Compatibility alias. Prefer `tryResult` in new code. */
555
+ const tryCatch = tryResult;
556
+ //#endregion
557
+ //#region src/result-async.ts
558
+ function isTryResultAsyncOptions(input) {
559
+ return typeof input === "object" && input !== null && "try" in input;
560
+ }
561
+ const combineResultAsyncList = (asyncResultList) => ResultAsync.fromSafePromise(Promise.all(asyncResultList)).andThen((resultList) => Result.combine(resultList));
562
+ const combineResultAsyncListWithAllErrors = (asyncResultList) => ResultAsync.fromSafePromise(Promise.all(asyncResultList)).andThen((resultList) => Result.combineWithAllErrors(resultList));
563
+ const validateAllResultAsyncItems = (items, f) => {
564
+ return combineResultAsyncListWithAllErrors(Array.from(items, f));
565
+ };
566
+ const firstSuccessOfAsyncCandidates = (candidates) => {
567
+ return new ResultAsync(Promise.try(async () => {
568
+ let latestError = void 0;
569
+ let hasCandidates = false;
570
+ for (const candidate of candidates) {
571
+ hasCandidates = true;
572
+ const result = await candidate();
573
+ if (result.isOk()) return result;
574
+ latestError = result;
575
+ }
576
+ if (!hasCandidates || latestError === void 0) throw createEmptyResultsCollectionError();
577
+ return latestError;
578
+ }));
579
+ };
580
+ const loopResultAsync = (initial, options) => {
581
+ return new ResultAsync(Promise.try(async () => {
582
+ let state = initial;
583
+ const values = [];
584
+ while (options.while(state)) {
585
+ const result = await options.body(state);
586
+ if (result.isErr()) return Result.err(result.error);
587
+ if (options.discard !== true) values.push(result.value);
588
+ state = options.step(state);
589
+ }
590
+ if (options.discard === true) return Result.ok(void 0);
591
+ return Result.ok(values);
592
+ }));
593
+ };
594
+ const iterateResultAsync = (initial, options) => {
595
+ return new ResultAsync(Promise.try(async () => {
596
+ let state = initial;
597
+ while (options.while(state)) {
598
+ const result = await options.body(state);
599
+ if (result.isErr()) return Result.err(result.error);
600
+ state = result.value;
601
+ }
602
+ return Result.ok(state);
603
+ }));
604
+ };
605
+ const forEachResultAsync = (items, f, options) => {
606
+ return new ResultAsync(Promise.try(async () => {
607
+ const values = [];
608
+ let index = 0;
609
+ for (const item of items) {
610
+ const result = await f(item, index);
611
+ if (result.isErr()) return Result.err(result.error);
612
+ if (options?.discard !== true) values.push(result.value);
613
+ index += 1;
614
+ }
615
+ if (options?.discard === true) return Result.ok(void 0);
616
+ return Result.ok(values);
617
+ }));
618
+ };
619
+ const resolveResultAsyncBooleanCondition = (condition) => typeof condition === "function" ? condition() : condition;
620
+ const toResultAsync = (result) => {
621
+ if (result instanceof ResultAsync) return result;
622
+ return new ResultAsync(Promise.resolve(result));
623
+ };
624
+ const ifResultAsync = (condition, options) => {
625
+ return new ResultAsync(Promise.try(async () => {
626
+ return await toResultAsync(resolveResultAsyncBooleanCondition(condition) ? options.onTrue() : options.onFalse());
627
+ }));
628
+ };
629
+ const ifResultAsyncWithCondition = (condition, options) => {
630
+ return new ResultAsync(Promise.try(async () => {
631
+ const conditionResult = await toResultAsync(condition);
632
+ if (conditionResult.isErr()) return Result.err(conditionResult.error);
633
+ return await toResultAsync(conditionResult.value ? options.onTrue() : options.onFalse());
634
+ }));
635
+ };
636
+ const whenResultAsync = (condition, body) => {
637
+ return new ResultAsync(Promise.try(async () => {
638
+ if (!resolveResultAsyncBooleanCondition(condition)) return Result.ok(void 0);
639
+ return await toResultAsync(body());
640
+ }));
641
+ };
642
+ const whenResultAsyncWithConditionByPredicate = (condition, body, predicate) => {
643
+ return new ResultAsync(Promise.try(async () => {
644
+ const conditionResult = await toResultAsync(condition);
645
+ if (conditionResult.isErr()) return Result.err(conditionResult.error);
646
+ if (!predicate(conditionResult.value)) return Result.ok(void 0);
647
+ return await toResultAsync(body());
648
+ }));
649
+ };
650
+ const whenResultAsyncWithCondition = (condition, body) => whenResultAsyncWithConditionByPredicate(condition, body, (value) => value);
651
+ const unlessResultAsync = (condition, body) => whenResultAsync(() => !resolveResultAsyncBooleanCondition(condition), body);
652
+ const unlessResultAsyncWithCondition = (condition, body) => whenResultAsyncWithConditionByPredicate(condition, body, (value) => !value);
653
+ const matchResolvedResultTags = ({ fallback, handlers, ok, result }) => {
654
+ if (result.isOk()) return ok(result.value);
655
+ return matchTaggedOr(result.error, handlers, fallback);
656
+ };
657
+ const callAsyncSideEffect = async (effect) => {
658
+ try {
659
+ await effect();
660
+ } catch {}
661
+ };
662
+ var DisposableResultAsync = class {
663
+ innerPromise;
664
+ finalizer;
665
+ disposed = false;
666
+ constructor(res, finalizer) {
667
+ this.innerPromise = res;
668
+ this.finalizer = finalizer;
669
+ }
670
+ then(successCallback, failureCallback) {
671
+ return this.innerPromise.then(successCallback, failureCallback);
672
+ }
673
+ async [Symbol.asyncDispose]() {
674
+ if (this.disposed) return;
675
+ this.disposed = true;
676
+ const result = await this.innerPromise;
677
+ try {
678
+ await this.finalizer(result.isOk() ? result.value : void 0, result.isErr() ? result.error : void 0);
679
+ } catch {}
680
+ }
681
+ };
682
+ /**
683
+ * Represents an asynchronous Result type that wraps a Promise of a Result<T, E>.
684
+ * This class provides a way to handle asynchronous operations that may succeed with a value of type T
685
+ * or fail with an error of type E.
686
+ *
687
+ * @template T - The type of the success value
688
+ * @template E - The type of the error value
689
+ *
690
+ * @implements {PromiseLike<Result<T, E>>}
691
+ *
692
+ * @example
693
+ * ```typescript
694
+ * // Create a successful async result
695
+ * const okAsync = ResultAsync.okAsync(42);
696
+ *
697
+ * // Create a failed async result
698
+ * const errAsync = ResultAsync.errAsync(new Error("Something went wrong"));
699
+ *
700
+ * // Transform a Promise into a ResultAsync
701
+ * const resultFromPromise = ResultAsync.fromPromise(
702
+ * fetch("https://api.example.com/data"),
703
+ * (error) => new Error(`API call failed: ${error}`)
704
+ * );
705
+ * ```
706
+ *
707
+ * @remarks
708
+ * ResultAsync implements the PromiseLike interface, allowing it to be used with async/await syntax.
709
+ * It provides various utility methods for transforming and combining results, similar to the Result type,
710
+ * but operating in an asynchronous context.
711
+ *
712
+ * The class includes methods for:
713
+ * - Creating ResultAsync instances (okAsync, errAsync, fromPromise)
714
+ * - Transforming values (map, mapErr)
715
+ * - Chaining operations (andThen, orElse)
716
+ * - Error handling (tapError)
717
+ * - Conditional branching (if)
718
+ * - Combining multiple ResultAsync instances (combine, combineWithAllErrors)
719
+ */
720
+ var ResultAsync = class ResultAsync extends Pipeable {
721
+ static okAsync(value) {
722
+ return new ResultAsync(Promise.resolve(Result.ok(value)));
723
+ }
724
+ /**
725
+ * Returns a ResultAsync that is immediately resolved with a Result.ok(undefined) value.
726
+ *
727
+ * @return {ResultAsync<undefined, E>} A ResultAsync instance with undefined as the value type and E as the error type.
728
+ */
729
+ static unitAsync() {
730
+ return new ResultAsync(Promise.resolve(Result.unit()));
731
+ }
732
+ static errAsync(error) {
733
+ return new ResultAsync(Promise.resolve(Result.err(error)));
734
+ }
735
+ static tryCatch(fn, errorFn) {
736
+ return new ResultAsync((typeof fn === "function" ? Promise.try(fn) : fn).then((value) => Result.ok(value)).catch((error) => {
737
+ if (errorFn) return Result.err(errorFn(error));
738
+ return Result.err(error);
739
+ }));
740
+ }
741
+ static fromSafePromise(promise) {
742
+ return new ResultAsync(promise.then((value) => Result.ok(value)));
743
+ }
744
+ static fromPromise(promise, errorFn) {
745
+ return new ResultAsync(promise.then((value) => Result.ok(value)).catch((error) => Result.err(errorFn(error))));
746
+ }
747
+ static combine(asyncResultList) {
748
+ return combineResultAsyncList(asyncResultList);
749
+ }
750
+ static combineWithAllErrors(asyncResultList) {
751
+ return combineResultAsyncListWithAllErrors(asyncResultList);
752
+ }
753
+ static validateAll(asyncResultListOrItems, f) {
754
+ if (f === void 0) return combineResultAsyncListWithAllErrors(asyncResultListOrItems);
755
+ return validateAllResultAsyncItems(asyncResultListOrItems, f);
756
+ }
757
+ static zip(left, right) {
758
+ return combineResultAsyncList([left, right]);
759
+ }
760
+ static firstSuccessOf(candidates) {
761
+ return firstSuccessOfAsyncCandidates(candidates);
762
+ }
763
+ static if(condition, options) {
764
+ if (typeof condition === "boolean" || typeof condition === "function") return ifResultAsync(condition, options);
765
+ return ifResultAsyncWithCondition(condition, options);
766
+ }
767
+ static when(condition, body) {
768
+ return whenResultAsync(condition, body);
769
+ }
770
+ static whenResult(condition, body) {
771
+ return whenResultAsyncWithCondition(condition, body);
772
+ }
773
+ static unless(condition, body) {
774
+ return unlessResultAsync(condition, body);
775
+ }
776
+ static unlessResult(condition, body) {
777
+ return unlessResultAsyncWithCondition(condition, body);
778
+ }
779
+ static loop(initial, options) {
780
+ return loopResultAsync(initial, options);
781
+ }
782
+ static iterate(initial, options) {
783
+ return iterateResultAsync(initial, options);
784
+ }
785
+ static forEach(items, f, options) {
786
+ return forEachResultAsync(items, f, options);
787
+ }
788
+ /**
789
+ * Wraps a async function with a try catch, creating a new function with the same
790
+ * arguments but returning `Ok` if successful, `Err` if the function throws
791
+ *
792
+ * @param fn function to wrap with ok on success or err on failure
793
+ * @param errorFn when an error is thrown, this will wrap the error result if provided
794
+ * @returns a new function that returns a `ResultAsync`
795
+ */
796
+ static fromThrowable(fn, errorFn) {
797
+ return (...args) => new ResultAsync((async () => {
798
+ try {
799
+ const v = await fn(...args);
800
+ return Result.ok(v);
801
+ } catch (error) {
802
+ const e = errorFn ? errorFn(error) : error;
803
+ return Result.err(e);
804
+ }
805
+ })());
806
+ }
807
+ innerPromise;
808
+ constructor(res) {
809
+ super();
810
+ this.innerPromise = res;
811
+ }
812
+ then(successCallback, failureCallback) {
813
+ return this.innerPromise.then(successCallback, failureCallback);
814
+ }
815
+ mapErr(f) {
816
+ return new ResultAsync(this.innerPromise.then(async (res) => {
817
+ if (res.isOk()) return Result.ok(res.value);
818
+ return Result.err(await f(res.error));
819
+ }));
820
+ }
821
+ map(f) {
822
+ return new ResultAsync(this.innerPromise.then(async (res) => {
823
+ if (res.isErr()) return Result.err(res.error);
824
+ return Result.ok(await f(res.value));
825
+ }));
826
+ }
827
+ as(value) {
828
+ return new ResultAsync(this.innerPromise.then((res) => {
829
+ if (res.isErr()) return Result.err(res.error);
830
+ return Result.ok(value);
831
+ }));
832
+ }
833
+ filterOrElse(predicate, onFalse) {
834
+ return new ResultAsync(this.innerPromise.then(async (res) => {
835
+ if (res.isErr()) return Result.err(res.error);
836
+ if (await predicate(res.value)) return Result.ok(res.value);
837
+ return Result.err(await onFalse(res.value));
838
+ }));
839
+ }
840
+ andThen(f) {
841
+ return new ResultAsync(this.innerPromise.then((res) => {
842
+ if (res.isErr()) return Result.err(res.error);
843
+ const next = f(res.value);
844
+ return next instanceof ResultAsync ? next.innerPromise : next;
845
+ }));
846
+ }
847
+ if(fCondition) {
848
+ return { true: (fTrue) => ({ false: (fFalse) => new ResultAsync(this.innerPromise.then(async (res) => {
849
+ if (res.isOk()) return fCondition(res.value) ? fTrue(res.value) : fFalse(res.value);
850
+ return errAsync(res.error);
851
+ })) }) };
852
+ }
853
+ orElse(f) {
854
+ return new ResultAsync(this.innerPromise.then((res) => {
855
+ if (res.isErr()) {
856
+ const next = f(res.error);
857
+ return next instanceof ResultAsync ? next.innerPromise : next;
858
+ }
859
+ return Result.ok(res.value);
860
+ }));
861
+ }
862
+ catchTag(tag, f) {
863
+ return new ResultAsync(this.innerPromise.then((res) => {
864
+ if (res.isOk()) return Result.ok(res.value);
865
+ if (hasTag(res.error, tag)) {
866
+ const next = f(res.error);
867
+ return next instanceof ResultAsync ? next.innerPromise : next;
868
+ }
869
+ return Result.err(res.error);
870
+ }));
871
+ }
872
+ catchTags(handlers) {
873
+ return new ResultAsync(this.innerPromise.then((res) => {
874
+ if (res.isOk()) return Result.ok(res.value);
875
+ const error = res.error;
876
+ const handled = callTaggedHandler(error, handlers);
877
+ if (handled.matched) {
878
+ const next = handled.value;
879
+ return next instanceof ResultAsync ? next.innerPromise : next;
880
+ }
881
+ return Result.err(error);
882
+ }));
883
+ }
884
+ async match(input, fnErr) {
885
+ return this.innerPromise.then((res) => typeof input === "function" ? res.match(input, getMatchErrorHandler(input, fnErr)) : res.match(input));
886
+ }
887
+ async matchTags(ok, handlers) {
888
+ return this.innerPromise.then((res) => matchResolvedResultTags({
889
+ result: res,
890
+ ok,
891
+ handlers,
892
+ fallback: (error) => {
893
+ throw error;
894
+ }
895
+ }));
896
+ }
897
+ async matchTagsPartial(ok, handlers, fallback) {
898
+ return this.innerPromise.then((res) => matchResolvedResultTags({
899
+ result: res,
900
+ ok,
901
+ handlers,
902
+ fallback
903
+ }));
904
+ }
905
+ async unwrapOr(t) {
906
+ return this.innerPromise.then((res) => res.unwrapOr(t));
907
+ }
908
+ async unwrapOrThrow() {
909
+ return this.innerPromise.then((res) => res.unwrapOrThrow());
910
+ }
911
+ /**
912
+ * Runs a side effect for either variant and preserves the original async result.
913
+ *
914
+ * For `Ok`, the callback receives `(value, undefined)`.
915
+ * For `Err`, the callback receives `(undefined, error)`.
916
+ * Callback errors and rejected callback promises are intentionally ignored.
917
+ *
918
+ * Use `map`, `mapErr`, `andThen`, or `orElse` when the callback should
919
+ * transform the result.
920
+ */
921
+ log(f) {
922
+ return new ResultAsync(this.innerPromise.then(async (res) => {
923
+ if (res.isOk()) {
924
+ await callAsyncSideEffect(() => f(res.value));
925
+ return okAsync(res.value);
926
+ }
927
+ await callAsyncSideEffect(() => f(void 0, res.error));
928
+ return errAsync(res.error);
929
+ }));
930
+ }
931
+ /**
932
+ * Runs a side effect only for the `Ok` variant and preserves the original async result.
933
+ *
934
+ * Callback errors and rejected callback promises are intentionally ignored.
935
+ * Use `map` or `andThen` when the callback should transform the value.
936
+ */
937
+ tap(f) {
938
+ return new ResultAsync(this.innerPromise.then(async (res) => {
939
+ if (res.isErr()) return errAsync(res.error);
940
+ await callAsyncSideEffect(() => f(res.value));
941
+ return okAsync(res.value);
942
+ }));
943
+ }
944
+ /**
945
+ * Runs a side effect only for the `Err` variant and preserves the original async result.
946
+ *
947
+ * Callback errors and rejected callback promises are intentionally ignored.
948
+ * Use `mapErr` or `orElse` when the callback should transform the error.
949
+ */
950
+ tapError(f) {
951
+ return new ResultAsync(this.innerPromise.then(async (res) => {
952
+ if (res.isErr()) {
953
+ await callAsyncSideEffect(() => f(res.error));
954
+ return errAsync(res.error);
955
+ }
956
+ return okAsync(res.value);
957
+ }));
958
+ }
959
+ toAsyncDisposable(f) {
960
+ return new DisposableResultAsync(this.innerPromise, f);
961
+ }
962
+ async *[Symbol.asyncIterator]() {
963
+ const result = await this.innerPromise;
964
+ if (result.isOk()) return result.value;
965
+ yield err(result.error);
966
+ return void 0;
967
+ }
968
+ };
969
+ registerResultAsyncFactory((promise) => new ResultAsync(promise));
970
+ const okAsync = ResultAsync.okAsync;
971
+ const errAsync = ResultAsync.errAsync;
972
+ const fromPromise = ResultAsync.fromPromise;
973
+ const fromSafePromise = ResultAsync.fromSafePromise;
974
+ const unitAsync = ResultAsync.unitAsync;
975
+ const fromThrowableAsync = ResultAsync.fromThrowable;
976
+ function tryResultAsync(input, errorFn) {
977
+ const promiseOrFn = isTryResultAsyncOptions(input) ? input.try : input;
978
+ const catchFn = isTryResultAsyncOptions(input) ? input.catch : errorFn;
979
+ return new ResultAsync((typeof promiseOrFn === "function" ? Promise.try(promiseOrFn) : promiseOrFn).then((value) => Result.ok(value)).catch((error) => {
980
+ if (catchFn) return Result.err(catchFn(error));
981
+ return Result.err(error);
982
+ }));
983
+ }
984
+ /** Compatibility alias. Prefer `tryResultAsync` in new code. */
985
+ const tryCatchAsync = tryResultAsync;
986
+ //#endregion
2
987
  //#region src/tagged-error.ts
3
988
  const defaultBaseError = Error;
4
989
  const defaultMessageTemplate = "$message";
5
990
  const nativeError = Error;
6
- const templateVariableMatcher = /\$([a-zA-Z_][a-zA-Z0-9_]*)/g;
991
+ const templateVariableMatcher = /\$([a-zA-Z_][a-zA-Z0-9_]*)/gu;
7
992
  const reservedTemplateVariables = new Set([
8
993
  "_tag",
9
994
  "cause",
@@ -16,14 +1001,26 @@ const reservedTemplateVariables = new Set([
16
1001
  function isError(value) {
17
1002
  return nativeError.isError?.(value) ?? value instanceof Error;
18
1003
  }
19
- const stringifyTemplateValue = (value) => {
20
- if (typeof value === "string") return value;
21
- if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") return value.toString();
22
- if (typeof value === "symbol") return value.description ?? value.toString();
23
- if (typeof value === "function") return value.name;
24
- if (typeof value === "object") return value === null ? "null" : JSON.stringify(value) ?? Object.prototype.toString.call(value);
25
- return "";
1004
+ const stringifyDirectTemplateValue = String;
1005
+ const stringifySymbolTemplateValue = (value) => {
1006
+ const symbol = value;
1007
+ return symbol.description ?? symbol.toString();
1008
+ };
1009
+ const stringifyFunctionTemplateValue = (value) => value.name;
1010
+ const stringifyObjectTemplateValue = (value) => {
1011
+ if (value === null) return "null";
1012
+ return JSON.stringify(value) ?? Object.prototype.toString.call(value);
1013
+ };
1014
+ const templateValueStringifiers = {
1015
+ bigint: stringifyDirectTemplateValue,
1016
+ boolean: stringifyDirectTemplateValue,
1017
+ function: stringifyFunctionTemplateValue,
1018
+ number: stringifyDirectTemplateValue,
1019
+ object: stringifyObjectTemplateValue,
1020
+ string: stringifyDirectTemplateValue,
1021
+ symbol: stringifySymbolTemplateValue
26
1022
  };
1023
+ const stringifyTemplateValue = (value) => templateValueStringifiers[typeof value]?.(value) ?? "";
27
1024
  const compileMessageInterpolator = (template) => (values) => template.replaceAll(templateVariableMatcher, (variable, key) => {
28
1025
  const value = values?.[key];
29
1026
  return value === void 0 ? variable : stringifyTemplateValue(value);
@@ -123,6 +1120,6 @@ const matchErrorPartial = (error, handlers, fallback) => {
123
1120
  return fallback(error);
124
1121
  };
125
1122
  //#endregion
126
- export { DisposableResult, DisposableResultAsync, Result, ResultAsync, createTaggedError, err, errAsync, findCause, fromPromise, fromSafePromise, fromThrowable, fromThrowableAsync, isError, matchError, matchErrorPartial, ok, okAsync, safeTry, tryCatch, tryCatchAsync, unit, unitAsync };
1123
+ export { DisposableResult, DisposableResultAsync, Result, ResultAsync, createTaggedError, tryResult as default, tryResult as try, tryResult, err, errAsync, findCause, fromPromise, fromSafePromise, fromThrowable, fromThrowableAsync, isError, matchError, matchErrorPartial, ok, okAsync, safeTry, tryResultAsync as tryAsync, tryResultAsync, tryCatch, tryCatchAsync, unit, unitAsync };
127
1124
 
128
1125
  //# sourceMappingURL=index.js.map