@tempots/std
Version:
Std library for TypeScript. Natural complement to the Tempo libraries.
196 lines (195 loc) • 6.08 kB
JavaScript
const u = {
/**
* Creates a loading state.
* @param previousValue - The previous value.
* @returns A loading state.
* @public
*/
notAsked: { type: "NotAsked" },
/**
* Creates a loading state.
* @param previousValue - The previous value.
* @returns A loading state.
* @public
*/
loading(e = void 0) {
return { type: "Loading", previousValue: e };
},
/**
* Creates a successful state.
* @param value - The value.
* @returns A successful state.
* @public
*/
success(e) {
return { type: "AsyncSuccess", value: e };
},
/**
* Creates a failure state.
* @param error - The error.
* @returns A failure state.
* @public
*/
failure(e) {
return { type: "AsyncFailure", error: e };
},
/**
* Checks if the result is a success.
* @param r - The result.
* @returns `true` if the result is a success; otherwise, `false`.
* @public
*/
isSuccess(e) {
return e.type === "AsyncSuccess";
},
/**
* Checks if the result is a failure.
* @param r - The result.
* @returns `true` if the result is a failure; otherwise, `false`.
* @public
*/
isFailure(e) {
return e.type === "AsyncFailure";
},
/**
* Checks if the result is a not-asked.
* @param r - The result.
* @returns `true` if the result is not-asked; otherwise, `false`.
* @public
*/
isNotAsked(e) {
return e.type === "NotAsked";
},
/**
* Checks if the result is a loading.
* @param r - The result.
* @returns `true` if the result is loading; otherwise, `false`.
* @public
*/
isLoading(e) {
return e.type === "Loading";
},
/**
* Gets the value if the result is a success; otherwise, returns the alternative value.
* @param r - The result.
* @param alt - The alternative value.
* @returns The value if the result is a success; otherwise, the alternative value.
* @public
*/
getOrElse(e, s) {
return u.isSuccess(e) ? e.value : s;
},
/**
* Gets the value if the result is a success; otherwise, returns the value from the alternative function.
* @param r - The result.
* @param altf - The alternative function.
* @returns The value if the result is a success; otherwise, the value from the alternative
* @public
* function.
*/
getOrElseLazy(e, s) {
return u.isSuccess(e) ? e.value : s();
},
/**
* Gets the value if the result is a success; otherwise, returns `null`.
* @param r - The result.
* @returns The value if the result is a success; otherwise, `null`.
* @public
*/
getOrNull(e) {
return u.isSuccess(e) ? e.value : null;
},
/**
* Gets the value if the result is a success; otherwise, returns `undefined`.
* @param r - The result.
* @returns The value if the result is a success; otherwise, `undefined`.
* @public
*/
getOrUndefined(e) {
return u.isSuccess(e) ? e.value : void 0;
},
/**
* Gets the value of a `AsyncResult` if it is a `Success`, otherwise it throws the error contained in the `Failure`.
* @param r - The `AsyncResult` to get the value from.
* @returns The value of the `AsyncResult` if it is a `Success`.
*/
getUnsafe: (e) => {
if (u.isSuccess(e))
return e.value;
throw u.isFailure(e) ? e.error : new Error("Cannot get value from a not-asked or loading result");
},
/**
* Based on the state of the result, it picks the appropriate function to call and returns the result.
* @param success - The function to call if the result is a success.
* @param failure - The function to call if the result is a failure.
* @param loading - The function to call if the result is loading.
* @param notAsked - The function to call if the result is not-asked.
* @returns The result of calling the appropriate function based on the state of the result.
* @public
*/
match: (e, {
success: s,
failure: r,
loading: t,
notAsked: n = t
}) => u.isSuccess(e) ? s(e.value) : u.isFailure(e) ? r(e.error) : u.isNotAsked(e) ? n() : t(e.previousValue),
/**
* When the result is a success, it applies the function to the value.
*
* @param r - The result.
* @param apply - The function to apply.
* @returns The result that was passed in.
* @public
*/
whenSuccess: (e, s) => (u.isSuccess(e) && s(e.value), e),
/**
* When the result is a failure, it applies the function to the error.
*
* @param r - The result.
* @param apply - The function to apply.
* @returns The result that was passed in.
* @public
*/
whenFailure: (e, s) => (u.isFailure(e) && s(e.error), e),
/**
* Compares two results for equality.
* @param r1 - The first result.
* @param r2 - The second result.
* @param options - The options to use for comparison. By default, uses strict equality.
* @returns `true` if the results are equal, `false` otherwise.
*/
equals: (e, s, r = {
valueEquals: (t, n) => t === n,
errorEquals: (t, n) => t === n
}) => e.type === "AsyncSuccess" && s.type === "AsyncSuccess" ? r.valueEquals(e.value, s.value) : e.type === "AsyncFailure" && s.type === "AsyncFailure" ? r.errorEquals(e.error, s.error) : e.type === "Loading" && s.type === "Loading" ? r.valueEquals(e.previousValue, s.previousValue) : e.type === "NotAsked" && s.type === "NotAsked",
/**
* Combines multiple results into a single result.
* @param results - The results to combine.
* @returns A single result that is a success if all the input results are successes, otherwise a failure.
*/
all: (e) => {
const s = [];
for (const r of e)
if (u.isSuccess(r))
s.push(r.value);
else
return r;
return u.success(s);
},
/**
* Converts a Promise to an AsyncResult.
* @param p - The Promise to convert.
* @returns A Promise that resolves to an AsyncResult.
*/
ofPromise: async (e) => {
try {
const s = await e;
return u.success(s);
} catch (s) {
return u.failure(s instanceof Error ? s : new Error(String(s)));
}
}
};
export {
u as AsyncResult
};