support multiple nodes (compatibility)

This commit is contained in:
Geoff Doty 2025-05-31 01:18:15 -04:00
parent 500bdbdeb6
commit 0b3a08d64e
1 changed files with 25 additions and 23 deletions

View File

@ -1,6 +1,6 @@
import diff from "./emerj.js"; import diff from './emerj.js';
/*! Uhm v0.6.0 | MIT LICENSE | https://github.com/n2geoff/uhm */ /*! Uhm v0.7.0 | MIT LICENSE | https://github.com/n2geoff/uhm */
/** /**
* App Builder * App Builder
@ -16,23 +16,12 @@ import diff from "./emerj.js";
* *
* @returns {Object} state and update() interface * @returns {Object} state and update() interface
*/ */
export default function app(opts) { export function app(opts) {
// initial setup // initial setup
const state = check(opts.state, {}); const state = opts.state || {};
const view = check(opts.view, () => null); const view = opts.view || (() => null);
const actions = check(opts.actions, {}); const actions = opts.actions || {};
const mount = opts.mount || "body"; const mount = opts.mount || 'body';
/**
* simple type validation check
*
* @param {*} value
* @param {String} type
* @returns {*}
*/
function check(value, type) {
return typeof value === typeof type ? value : type;
}
/** /**
* Assigns Dispatch-able Actions into App * Assigns Dispatch-able Actions into App
@ -42,9 +31,9 @@ export default function app(opts) {
*/ */
function dispatch(data, actions) { function dispatch(data, actions) {
Object.entries(actions).forEach(([name, action]) => { Object.entries(actions).forEach(([name, action]) => {
if (typeof action === "function") { if (typeof action === 'function') {
actions[name] = (...args) => { actions[name] = (...args) => {
// update date from action return // update date from action
Object.assign(state, action(data, ...args)); Object.assign(state, action(data, ...args));
// delay update // delay update
@ -58,13 +47,26 @@ export default function app(opts) {
/** update dom */ /** update dom */
const update = () => { const update = () => {
diff.merge(document.querySelector(mount), view(state, actions)); const parentNode = document.querySelector(mount);
} let result = view(state, actions);
// handle multiple nodes
if (Array.isArray(result)) {
const fragment = document.createDocumentFragment();
fragment.append(...result.filter(node => node != null));
result = fragment;
} else if (typeof result === 'string') {
const temp = document.createElement(parentNode.tagName);
temp.innerHTML = result;
result = temp;
}
diff.merge(parentNode, result);
};
// mount view // mount view
if (opts.view && mount) { if (opts.view && mount) {
dispatch(state, actions); dispatch(state, actions);
} }
return {state,update} return { state, update };
} }