UNPKG

typescript-monads

Version:
333 lines 12.8 kB
var __values = (this && this.__values) || function(o) { var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); }; var __read = (this && this.__read) || function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; }; var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { if (ar || !(i in from)) { if (!ar) ar = Array.prototype.slice.call(from, 0, i); ar[i] = from[i]; } } return to.concat(ar || Array.prototype.slice.call(from)); }; import { FailResult, OkResult } from '../result/result'; var Maybe = /** @class */ (function () { function Maybe(value) { this.value = value; } Maybe.prototype.of = function (value) { return new Maybe(value); }; Maybe.none = function () { return new Maybe(); }; Maybe.some = function (value) { return new Maybe(value); }; /** * Creates a Maybe from a Promise. * * Creates a Maybe that will resolve to: * - Some containing the resolved value if the promise resolves successfully * - None if the promise rejects or resolves to null/undefined * * @param promise The promise to convert to a Maybe * @returns A Promise that resolves to a Maybe containing the result * * @example * // Convert a promise to a Maybe * Maybe.fromPromise(api.fetchUser(userId)) * .then(userMaybe => userMaybe.match({ * some: user => console.log(user.name), * none: () => console.log('User not found') * })); */ /** * Creates a Maybe from a Promise. * * Creates a Promise that will resolve to a Maybe that is: * - Some containing the resolved value if the promise resolves successfully to a non-nullish value * - None if the promise rejects or resolves to null/undefined * * Note on resolution preservation: This static method maps the Promise resolution semantics * to the Maybe context in a natural way: * - Promise resolution (success) becomes Some (presence of value) * - Promise rejection (failure) becomes None (absence of value) * * This provides a clean way to convert from error-based to optional-based handling, * which is often more appropriate for values that might legitimately be missing. * * @param promise The promise to convert to a Maybe * @returns A Promise that resolves to a Maybe containing the result * * @example * // Convert a promise to a Maybe and use in a chain * Maybe.fromPromise(api.fetchUser(userId)) * .then(userMaybe => userMaybe.match({ * some: user => renderUser(user), * none: () => showUserNotFound() * })); */ Maybe.fromPromise = function (promise) { return promise .then(function (value) { return new Maybe(value); }) .catch(function () { return new Maybe(); }); }; /** * Creates a Maybe from an Observable. * * Creates a Promise that will resolve to a Maybe that is: * - Some containing the first emitted value if the observable emits a non-nullish value * - None if the observable completes without emitting, errors, or emits a nullish value * * Note on resolution transformation: This method transforms the reactive semantics of * an Observable to the optional semantics of a Maybe: * - Observable emissions (data) become Some values (presence) * - Observable completion without emissions (empty success) becomes None (absence) * - Observable errors (failure) become None (absence) * * Note on timing model: This transformation changes from a continuous/reactive model * to a one-time asynchronous result. Only the first emission is captured, and the * reactive nature of the Observable is lost after transformation. * * @param observable The observable to convert to a Maybe * @returns A Promise that resolves to a Maybe containing the first emitted value * * @requires rxjs@^7.0 * @example * // Convert an observable to a Maybe and use in a chain * Maybe.fromObservable(userService.getUser(userId)) * .then(userMaybe => userMaybe * .map(user => user.name) * .valueOr('Guest')) * .then(name => displayUserName(name)); */ Maybe.fromObservable = function (observable) { return import('rxjs').then(function (_a) { var firstValueFrom = _a.firstValueFrom, EMPTY = _a.EMPTY, take = _a.take, map = _a.map, catchError = _a.catchError; return firstValueFrom(observable.pipe(take(1), map(function (value) { return new Maybe(value); }), catchError(function () { return EMPTY; }))).then(function (maybeValue) { return maybeValue; }, function () { return new Maybe(); }); }); }; /** * Transforms an array of Maybe values into a Maybe containing an array of values. * * If all Maybes in the input array are Some, returns a Some containing an array of all values. * If any Maybe in the input array is None, returns None. * * @param maybes An array of Maybe values * @returns A Maybe containing an array of all values if all inputs are Some, otherwise None * * @example * // All Maybes are Some * const result1 = Maybe.sequence([maybe(1), maybe(2), maybe(3)]); * // result1 is Some([1, 2, 3]) * * // One Maybe is None * const result2 = Maybe.sequence([maybe(1), maybe(null), maybe(3)]); * // result2 is None */ Maybe.sequence = function (maybes) { var e_1, _a; if (maybes.length === 0) { return new Maybe([]); } var values = []; try { for (var maybes_1 = __values(maybes), maybes_1_1 = maybes_1.next(); !maybes_1_1.done; maybes_1_1 = maybes_1.next()) { var m = maybes_1_1.value; if (m.isNone()) { return new Maybe(); } values.push(m.valueOrThrow()); } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (maybes_1_1 && !maybes_1_1.done && (_a = maybes_1.return)) _a.call(maybes_1); } finally { if (e_1) throw e_1.error; } } return new Maybe(values); }; Maybe.prototype.isSome = function () { return !this.isNone(); }; Maybe.prototype.isNone = function () { return this.value === null || this.value === undefined; }; Maybe.prototype.valueOr = function (value) { return this.isSome() ? this.value : value; }; Maybe.prototype.valueOrUndefined = function () { return this.isSome() ? this.value : undefined; }; Maybe.prototype.valueOrNull = function () { return this.isSome() ? this.value : null; }; Maybe.prototype.valueOrCompute = function (fn) { return this.isSome() ? this.value : fn(); }; Maybe.prototype.valueOrThrow = function (msg) { return this.isNone() ? (function () { throw new Error(msg); })() : this.value; }; Maybe.prototype.valueOrThrowErr = function (err) { return this.isNone() ? (function () { return err instanceof Error ? (function () { throw err; })() : (function () { throw new Error(); })(); })() : this.value; }; Maybe.prototype.tap = function (obj) { this.isNone() ? typeof obj.none === 'function' && obj.none() : typeof obj.some === 'function' && obj.some(this.value); }; Maybe.prototype.tapNone = function (fn) { (this.isNone()) && fn(); }; Maybe.prototype.tapSome = function (fn) { (this.isSome()) && fn(this.value); }; Maybe.prototype.tapThru = function (val) { this.tap(val); return this; }; Maybe.prototype.tapThruNone = function (fn) { this.tapNone(fn); return this; }; Maybe.prototype.tapThruSome = function (fn) { this.tapSome(fn); return this; }; Maybe.prototype.match = function (pattern) { return this.isNone() ? pattern.none() : pattern.some(this.value); }; Maybe.prototype.toArray = function () { return this.isNone() ? [] : Array.isArray(this.value) ? this.value : [this.value]; }; Maybe.prototype.map = function (fn) { return this.isSome() ? new Maybe(fn(this.value)) : new Maybe(); }; Maybe.prototype.mapTo = function (t) { return this.isSome() ? new Maybe(t) : new Maybe(); }; Maybe.prototype.flatMap = function (fn) { return this.isNone() ? new Maybe() : fn(this.value); }; Maybe.prototype.flatMapAuto = function (fn) { return this.isNone() ? new Maybe() : new Maybe(fn(this.value)); }; Maybe.prototype.project = function (fn) { return this.flatMapAuto(fn); }; Maybe.prototype.filter = function (fn) { return this.isNone() ? new Maybe() : fn(this.value) ? new Maybe(this.value) : new Maybe(); }; Maybe.prototype.apply = function (maybeFn) { return this.flatMap(function (v) { return maybeFn.flatMapAuto(function (f) { return f(v); }); }); }; Maybe.prototype.toResult = function (error) { return this .map(function (b) { return new OkResult(b); }) .valueOr(new FailResult(error)); }; Maybe.prototype.flatMapPromise = function (fn) { if (this.isNone()) { return Promise.resolve(new Maybe()); } return fn(this.value) .then(function (value) { return new Maybe(value); }) .catch(function () { return new Maybe(); }); }; Maybe.prototype.flatMapObservable = function (fn) { var _this = this; if (this.isNone()) { return Promise.resolve(new Maybe()); } return import('rxjs').then(function (_a) { var firstValueFrom = _a.firstValueFrom, EMPTY = _a.EMPTY, take = _a.take, map = _a.map, catchError = _a.catchError; return firstValueFrom(fn(_this.value).pipe(take(1), map(function (value) { return new Maybe(value); }), catchError(function () { return EMPTY; }))).then(function (maybeValue) { return maybeValue; }, function () { return new Maybe(); }); }); }; Maybe.prototype.flatMapMany = function (fn) { if (this.isNone()) { return Promise.resolve(new Maybe()); } return Promise.all(fn(this.value)) .then(function (values) { return new Maybe(values); }) .catch(function () { return new Maybe(); }); }; Maybe.prototype.zipWith = function () { var e_2, _a; var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } if (this.isNone()) { return new Maybe(); } var fn = args[args.length - 1]; var maybes = args.slice(0, -1); var values = [this.value]; try { for (var maybes_2 = __values(maybes), maybes_2_1 = maybes_2.next(); !maybes_2_1.done; maybes_2_1 = maybes_2.next()) { var m = maybes_2_1.value; if (m.isNone()) { return new Maybe(); } values.push(m.valueOrThrow()); } } catch (e_2_1) { e_2 = { error: e_2_1 }; } finally { try { if (maybes_2_1 && !maybes_2_1.done && (_a = maybes_2.return)) _a.call(maybes_2); } finally { if (e_2) throw e_2.error; } } return new Maybe(fn.apply(void 0, __spreadArray([], __read(values), false))); }; return Maybe; }()); export { Maybe }; //# sourceMappingURL=maybe.js.map