UNPKG

@muryp/router-dom

Version:
107 lines (106 loc) 3.22 kB
function convertRoutes(t) { let n = {}; for (let r in t) { if (!Object.prototype.hasOwnProperty.call(t, r)) continue; let i = t[r]; if (r.startsWith("@")) { n[r] = typeof i == "object" && i ? convertRoutes(i) : i; continue; } let a = r.replace(/^\//, "").split("/").filter(Boolean); if (a.length <= 1) { let t = a[0] || r; typeof i == "object" && i ? n[t] = { ...n[t], ...convertRoutes(i) } : n[t] = i; continue; } let o = n; a.forEach((t, n) => { if (o[t] || (o[t] = {}), n === a.length - 1) { let n = typeof i == "object" && i ? convertRoutes(i) : { component: i }; o[t] = { ...o[t], ...n }; } o = o[t]; }); } return n; } function matchRouteLogic(e, t) { let n = t, r = {}, i = []; if ((n.middleware || n.layout) && i.push({ middleware: n.middleware, layout: n.layout }), e.length === 0) return t["@home"] && i.push(t["@home"]), { configs: i, params: r }; for (let t of e) { if (!n || typeof n != "object") break; let e = n[t]; if (!e) { let i = Object.keys(n).find((e) => e.startsWith(":")); if (i) r[i.slice(1)] = t, e = n[i]; else return { configs: [], params: {} }; } n = e, (n.layout || n.component || n.middleware) && i.push(n); } return { configs: i, params: r }; } function parseUrlLogic(e, t, n = "/") { let r = n.replace(/\/$/, "") + "/", i = new URL(e).pathname.replace(r, ""), [a, o] = t.replace(/^#/, "").split("#"), [s, c] = a.split("?"), l = `${i}/${s}`.split("/").filter(Boolean), u = {}; return c && new URLSearchParams(c).forEach((e, t) => { u[t] = e; }), { segments: l, query: u, anchor: o }; } async function executeComponent(e, t, n) { return typeof e == "string" ? e : await e(t, n) || ""; } async function render({ routes: e, settings: i }) { let s = window.location.href, c = window.location.hash, { segments: l, query: u, anchor: d } = parseUrlLogic(s, c, i.rootUrl), { configs: f, params: p } = matchRouteLogic(l, e), m = { params: p, query: u, url: s, id: i.id }, h = f.length === 0 || !f.some((e) => e.component) ? [e["@404"]] : f; if (i.middleware && i.middleware(m) === !1) return redirectToHome(); for (let e of h) if (e.middleware && await e.middleware(m) === !1) return redirectToHome(); let g = "", _ = [...h].reverse(), v = _.find((e) => e.component); v?.component && (g = await executeComponent(v.component, m)); for (let e of _) e.layout && (g = await executeComponent(e.layout, m, g)); let y = document.getElementById(i.id); y && (y.innerHTML = g), updateTitle(_, m), h.forEach((e) => e.script?.(m)), i.script?.(m), d && document.getElementById(d)?.scrollIntoView(); } function redirectToHome() { window.location.hash = "#/"; } async function updateTitle(e, t) { let n = e.find((e) => e.title); if (n?.title) { let e = typeof n.title == "function" ? await n.title(t) : n.title; e && (document.title = e); } } function onChange(e) { window.onpopstate = async () => { render(e); }; } function MurypRoutesDom(t) { t.routes = convertRoutes(t.routes), t.routes["@home"] = t.routes["/"], delete t.routes["/"], t.settings.isFirstRender !== !1 && render(t), onChange(t); } export { MurypRoutesDom as default };