react-api-adts
Version:
Helpful algebraic data types for API handling in React apps.
90 lines (89 loc) • 3.09 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.useFormState = exports.formResultPromise = exports.FormStateHandler = void 0;
const react_1 = require("react");
function success(t) {
return { kind: "success", result: t };
}
function error(msg) {
return { kind: "error", msg: msg };
}
function loading() {
return { kind: "loading" };
}
function ready() {
return { kind: "ready" };
}
function mapState(state, fun) {
if (state.kind === "success")
return success(fun(state.result));
else
return state;
}
class FormStateHandler {
constructor(state, setState) {
this.state = state;
this.isSuccess = state.kind === "success";
this.isError = state.kind === "error";
this.isLoading = state.kind === "loading";
this.isReady = state.kind === "ready";
this.errorMsg = state.kind === "error" ? state.msg : undefined;
this.result = state.kind === "success" ? state.result : undefined;
this.setState = setState;
this.handlers = [];
}
match(matchers) {
var _a, _b, _c, _d;
switch (this.state.kind) {
case "success":
return (_a = matchers.success) === null || _a === void 0 ? void 0 : _a.call(matchers, this.state.result);
case "error":
return (_b = matchers.error) === null || _b === void 0 ? void 0 : _b.call(matchers, this.state.msg);
case "loading":
return (_c = matchers.loading) === null || _c === void 0 ? void 0 : _c.call(matchers);
case "ready":
return (_d = matchers.ready) === null || _d === void 0 ? void 0 : _d.call(matchers);
}
}
success(result) {
const suc = success(result);
this.handlers.forEach(handler => handler(suc));
this.setState(suc);
}
error(msg) {
const err = error(msg);
this.handlers.forEach(handler => handler(err));
this.setState(err);
}
loading() {
const ld = loading();
this.handlers.forEach(handler => handler(ld));
this.setState(ld);
}
ready() {
const rd = ready();
this.handlers.forEach(handler => handler(rd));
this.setState(rd);
}
handleSuccess(callback) {
this.handlers.push(state => (state.kind === "success" && callback(state.result)));
}
handleError(callback) {
this.handlers.push(state => (state.kind === "error" && callback(state.msg)));
}
}
exports.FormStateHandler = FormStateHandler;
function formResultPromise(fun) {
return new Promise((resolve, reject) => {
const handler = new FormStateHandler(ready(), () => { });
handler.handleSuccess((t) => resolve(success(t)));
handler.handleError((msg) => resolve(error(msg)));
fun(handler);
});
}
exports.formResultPromise = formResultPromise;
function useFormState() {
const [state, setState] = (0, react_1.useState)(ready);
return new FormStateHandler(state, setState);
}
exports.useFormState = useFormState;