uhm/src/app.js

78 lines
2.1 KiB
JavaScript
Raw Normal View History

2024-05-22 15:40:08 +00:00
/**
* App Builder
*
* Composes data, views, actions together as
* mountable ui
*
* @param {Object} opts options
* @param {Object} opts.state initial app object state
* @param {Function} opts.view function that returns dom. state and actions are passed in
* @param {Object} opts.actions object functions includes and return state
* @param {String} opts.mount querySelector value
* @returns
*/
2024-05-05 13:07:17 +00:00
export default function app(opts) {
2024-05-05 00:34:27 +00:00
// initial setup
2024-05-05 13:07:17 +00:00
let data = check(opts.state, {});
let view = check(opts.view, () => null);
let actions = check(opts.actions, {});
let mount = opts.mount || "body";
2024-05-22 15:40:08 +00:00
/**
* simple type validation check
*
* @param {*} value
* @param {String} type
* @returns value|String
*/
2024-05-05 13:07:17 +00:00
function check(value, type) {
return typeof value === typeof type ? value : type;
}
2024-05-05 00:34:27 +00:00
// state helper
const state = (state) => {
if(typeof state === "object") {
data = {...data, ...state};
}
// update ui
update();
2024-05-05 00:34:27 +00:00
// return current state
return data;
}
2024-05-22 15:40:08 +00:00
/**
* Assigns Dispatch-able Actions into App
*
* @param {Object} input state used by actions
* @param {Object} actions functions that update state
*/
2024-05-05 19:04:45 +00:00
function dispatch(input, actions) {
Object.entries(actions).forEach(([name, action]) => {
if (typeof action === "function") {
actions[name] = (...args) => {
// update date from action return
Object.assign(data, action(input, ...args));
// call update
update();
};
}
});
update();
}
2024-05-22 15:40:08 +00:00
/** update dom */
const update = () => {
2024-05-05 13:07:17 +00:00
document.querySelector(mount).replaceChildren(view(data, actions));
2024-05-05 00:34:27 +00:00
}
// mount view
2024-05-05 13:07:17 +00:00
if (opts.view && mount) {
2024-05-05 19:04:45 +00:00
dispatch(data, actions);
2024-05-05 00:34:27 +00:00
}
2024-05-05 19:04:45 +00:00
return {state}
2024-05-05 13:07:17 +00:00
}