Modular router db and locale

This commit is contained in:
2026-05-22 23:05:08 +02:00
parent 8481e339cc
commit eb1c81ec26
16 changed files with 143 additions and 107 deletions

18
src/sigpro.db.js Normal file
View File

@@ -0,0 +1,18 @@
export const db = async (url, data = {}, loading = null) => {
if (loading) loading(true);
try {
const res = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data),
credentials: 'include'
});
if (!res.ok) {
const errorText = await res.text();
throw new Error(`Error ${res.status}: ${errorText}`);
}
return await res.json();
} finally {
if (loading) loading(false);
}
};

View File

@@ -242,13 +242,13 @@ export const mount = (c, tgt) => {
t.replaceChildren(i._cnt); MOUNTED.set(t, i); return i;
};
const htmlTags = "a abbr article aside audio b blockquote br button canvas caption cite code col colgroup datalist dd del details dfn dialog div dl dt em embed fieldset figcaption figure footer form h1 h2 h3 h4 h5 h6 header hr i iframe img input ins kbd label legend li main mark meter nav object ol optgroup option output p picture pre progress section select slot small source span strong sub summary sup svg table tbody td template textarea tfoot th thead time tr u ul video";
// const htmlTags = "a abbr article aside audio b blockquote br button canvas caption cite code col colgroup datalist dd del details dfn dialog div dl dt em embed fieldset figcaption figure footer form h1 h2 h3 h4 h5 h6 header hr i iframe img input ins kbd label legend li main mark meter nav object ol optgroup option output p picture pre progress section select slot small source span strong sub summary sup svg table tbody td template textarea tfoot th thead time tr u ul video";
export const SigPro = { $, watch, batch, h, fragment, render, mount, when, each, onUnmount, val, isA, isF, isO };
if (typeof window !== "undefined") {
window.SigPro = SigPro;
htmlTags.split(" ").forEach(tag => {
window[tag] = (props, children) => h(tag, props, children);
});
// htmlTags.split(" ").forEach(tag => {
// window[tag] = (props, children) => h(tag, props, children);
// });
}

21
src/sigpro.locale.js Normal file
View File

@@ -0,0 +1,21 @@
const { $ } = window.SigPro;
const currentLocale = $("en");
const translations = {};
export const addLang = obj => {
for (const locale of Object.keys(obj)) {
if (!translations[locale]) translations[locale] = {};
Object.assign(translations[locale], obj[locale]);
}
};
export const setLocale = locale => {
if (locale && translations[locale]) {
currentLocale(locale);
}
};
export const t = key => {
return () => translations[currentLocale()]?.[key] ?? key;
};

49
src/sigpro.router.js Normal file
View File

@@ -0,0 +1,49 @@
const { $, h, watch, render, isF } = window.SigPro;
const getHash = () => window.location.hash.slice(1) || "/";
const currentPath = $(getHash());
window.addEventListener("hashchange", () => currentPath(getHash()));
export const routerParams = $({});
export const router = routes => {
const hook = h("div", { class: "router-hook" });
let currentView = null;
watch([currentPath], () => {
const cur = currentPath();
const route = routes.find(r => {
const p1 = r.path.split("/").filter(Boolean);
const p2 = cur.split("/").filter(Boolean);
return p1.length === p2.length && p1.every((p, i) => p[0] === ":" || p === p2[i]);
}) || routes.find(r => r.path === "*");
if (route) {
currentView?.destroy();
const params = {};
route.path.split("/").filter(Boolean).forEach((p, i) => {
if (p[0] === ":") params[p.slice(1)] = cur.split("/").filter(Boolean)[i];
});
routerParams(params);
currentView = render(() => isF(route.component) ? route.component(params) : route.component);
hook.replaceChildren(currentView.container);
}
});
hook.destroy = () => {
currentView?.destroy();
};
return hook;
};
router.params = routerParams;
router.to = p => window.location.hash = p.replace(/^#?\/?/, "#/");
router.back = () => window.history.back();
router.path = () => currentPath();

View File

@@ -1,90 +0,0 @@
/// <reference path="../sigpro.d.ts" />
const { $, h, watch, render, isF } = window.SigPro;
// router
export const router = routes => {
const getHash = () => window.location.hash.slice(1) || "/";
const path = $(getHash());
const handler = () => path(getHash());
window.addEventListener("hashchange", handler);
const hook = h("div", { class: "router-hook" });
let currentView = null;
watch([path], () => {
const cur = path();
const route = routes.find(r => {
const p1 = r.path.split("/").filter(Boolean);
const p2 = cur.split("/").filter(Boolean);
return p1.length === p2.length && p1.every((p, i) => p[0] === ":" || p === p2[i]);
}) || routes.find(r => r.path === "*");
if (route) {
currentView?.destroy();
const params = {};
route.path.split("/").filter(Boolean).forEach((p, i) => {
if (p[0] === ":") params[p.slice(1)] = cur.split("/").filter(Boolean)[i];
});
router.params(params);
currentView = render(() => isF(route.component) ? route.component(params) : route.component);
hook.replaceChildren(currentView.container);
}
});
hook.destroy = () => {
window.removeEventListener("hashchange", handler);
currentView?.destroy();
};
return hook;
};
router.params = $({});
router.to = p => window.location.hash = p.replace(/^#?\/?/, "#/");
router.back = () => window.history.back();
router.path = () => window.location.hash.replace(/^#/, "") || "/";
// db
export const db = async (url, data = {}, loading = null) => {
if (loading) loading(true);
try {
const res = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data),
credentials: 'include'
});
if (!res.ok) {
const errorText = await res.text();
throw new Error(`Error ${res.status}: ${errorText}`);
}
return await res.json();
} finally {
if (loading) loading(false);
}
};
const currentLocale = $('en');
const translations = {};
// addLang
export const addLang = (obj) => {
for (const locale of Object.keys(obj)) {
if (!translations[locale]) translations[locale] = {};
Object.assign(translations[locale], obj[locale]);
}
};
// setLocale
export const setLocale = (locale) => {
if (locale && translations[locale]) {
currentLocale(locale);
}
};
// t
export const t = (key) => {
return () => translations[currentLocale()]?.[key] ?? key;
};