@valkyr/mvc
Version:
A small model view controller implementation for web frameworks.
138 lines • 6.29 kB
JavaScript
;
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var _ReactViewController_instances, _a, _ReactViewController_options, _ReactViewController_getMemoize;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ReactViewController = void 0;
const jsx_dev_runtime_1 = require("react/jsx-dev-runtime");
const _jsxFileName = "/home/runner/work/valkyr/valkyr/packages/mvc/src/React.tsx";
const react_1 = require("react");
const ViewController_1 = require("./ViewController");
/**
* Creates a model view controller layer that can wrap around functional react
* components and provides managed state from the applied controller.
*/
class ReactViewController extends ViewController_1.ViewController {
constructor() {
super(...arguments);
_ReactViewController_instances.add(this);
}
static set loading(component) {
__classPrivateFieldGet(this, _a, "f", _ReactViewController_options).loading = component;
}
static set error(component) {
__classPrivateFieldGet(this, _a, "f", _ReactViewController_options).error = component;
}
static set memo(value) {
if (typeof value === "function") {
__classPrivateFieldGet(this, _a, "f", _ReactViewController_options).memoize = value;
}
else if (value === false) {
__classPrivateFieldGet(this, _a, "f", _ReactViewController_options).memoize = false;
}
else {
__classPrivateFieldGet(this, _a, "f", _ReactViewController_options).memoize = defaultMemoizeHandler;
}
}
/**
* Register a function react component to be controller by the controller
* registered on the instance.
*
* @param component - Functional react component.
*/
view(component, options) {
const renderLoading = options?.loading ?? __classPrivateFieldGet(ReactViewController, _a, "f", _ReactViewController_options).loading;
const renderError = options?.error ?? __classPrivateFieldGet(ReactViewController, _a, "f", _ReactViewController_options).error;
const memoize = __classPrivateFieldGet(this, _ReactViewController_instances, "m", _ReactViewController_getMemoize).call(this, options?.memoize);
const wrapper = (props) => {
const [controller, setController] = (0, react_1.useState)(undefined);
const [actions, setActions] = (0, react_1.useState)();
const [state, setState] = (0, react_1.useState)(this.controller.state);
const [loading, setLoading] = (0, react_1.useState)(true);
const [error, setError] = (0, react_1.useState)();
(0, react_1.useEffect)(() => {
const controller = this.controller.make(setState);
setController(controller);
setActions(controller.toActions());
return () => {
controller.destroy();
};
}, []);
(0, react_1.useEffect)(() => {
let isMounted = true;
if (controller === undefined) {
return () => {
isMounted = false;
};
}
controller
.resolve(props)
.catch((error) => {
if (isMounted === true) {
setError(error);
}
})
.finally(() => {
if (isMounted === true) {
setLoading(false);
}
});
return () => {
isMounted = false;
};
}, [controller, props]);
if (actions === undefined || loading === true) {
return renderLoading(props);
}
if (error !== undefined) {
return renderError({ ...props, error });
}
return component({ props, state, actions });
};
wrapper.displayName = options?.name ?? component.name;
// ### Memoize
// By default run component through react memoization using stringify
// matching to determine changes to props.
if (memoize !== false) {
return (0, react_1.memo)(wrapper, memoize);
}
return wrapper;
}
}
exports.ReactViewController = ReactViewController;
_a = ReactViewController, _ReactViewController_instances = new WeakSet(), _ReactViewController_getMemoize = function _ReactViewController_getMemoize(memoize) {
if (typeof memoize === "function") {
return memoize;
}
if (memoize !== false) {
return __classPrivateFieldGet(ReactViewController, _a, "f", _ReactViewController_options).memoize;
}
return false;
};
_ReactViewController_options = { value: {
name: undefined,
loading() {
return (0, jsx_dev_runtime_1.jsxDEV)("div", { children: "Loading" }, void 0, false, { fileName: _jsxFileName, lineNumber: 13, columnNumber: 13 }, this);
},
error({ error }) {
return (0, jsx_dev_runtime_1.jsxDEV)("div", { children: error.message }, void 0, false, { fileName: _jsxFileName, lineNumber: 16, columnNumber: 13 }, this);
},
memoize: defaultMemoizeHandler
} };
/*
|--------------------------------------------------------------------------------
| Defaults
|--------------------------------------------------------------------------------
*/
function defaultMemoizeHandler(prev, next) {
if (prev.children !== undefined && next.children !== undefined) {
if (prev.children.type.type.displayName !== next.children.type.type.displayName) {
return false;
}
}
return JSON.stringify(prev) === JSON.stringify(next);
}
//# sourceMappingURL=React.js.map