Actualizar src/sigpro.js

This commit is contained in:
2026-04-06 03:15:26 +02:00
parent 4bc640b2c3
commit d68b5a74e0

View File

@@ -1,473 +1,433 @@
/**
* SigPro Core
*/
let activeEffect = null; let activeEffect = null;
let currentOwner = null; let currentOwner = null;
const effectQueue = new Set(); const effectQueue = new Set();
let isFlushing = false; let isFlushing = false;
const MOUNTED_NODES = new WeakMap(); const MOUNTED_NODES = new WeakMap();
const flush = () => { const doc = document;
const isArr = Array.isArray;
const assign = Object.assign;
const createEl = (t) => doc.createElement(t);
const createText = (t) => doc.createTextNode(String(t ?? ""));
const isFunc = (f) => typeof f === "function";
const isObj = (o) => typeof o === "object" && o !== null;
const runWithContext = (effect, callback) => {
const previousEffect = activeEffect;
activeEffect = effect;
try { return callback(); }
finally { activeEffect = previousEffect; }
};
const cleanupNode = (node) => {
if (node._cleanups) {
node._cleanups.forEach((dispose) => dispose());
node._cleanups.clear();
}
node.childNodes?.forEach(cleanupNode);
};
const flushEffects = () => {
if (isFlushing) return; if (isFlushing) return;
isFlushing = true; isFlushing = true;
while (effectQueue.size > 0) { while (effectQueue.size > 0) {
const sorted = Array.from(effectQueue).sort((a, b) => (a.depth || 0) - (b.depth || 0)); const sortedEffects = Array.from(effectQueue).sort((a, b) => (a.depth || 0) - (b.depth || 0));
effectQueue.clear(); effectQueue.clear();
for (const eff of sorted) if (!eff._deleted) eff(); for (const effect of sortedEffects) {
if (!effect._deleted) effect();
}
} }
isFlushing = false; isFlushing = false;
}; };
const track = (subs) => { const trackSubscription = (subscribers) => {
if (activeEffect && !activeEffect._deleted) { if (activeEffect && !activeEffect._deleted) {
subs.add(activeEffect); subscribers.add(activeEffect);
activeEffect._deps.add(subs); activeEffect._deps.add(subscribers);
} }
}; };
const trigger = (subs) => { const triggerUpdate = (subscribers) => {
for (const eff of subs) { subscribers.forEach((effect) => {
if (eff === activeEffect || eff._deleted) continue; if (effect === activeEffect || effect._deleted) return;
if (eff._isComputed) { if (effect._isComputed) {
eff.markDirty(); effect.markDirty();
if (eff._subs) trigger(eff._subs); if (effect._subs) triggerUpdate(effect._subs);
} else { } else {
effectQueue.add(eff); effectQueue.add(effect);
} }
} });
if (!isFlushing) queueMicrotask(flush); if (!isFlushing) queueMicrotask(flushEffects);
}; };
const sweep = (node) => { const Render = (renderFn) => {
if (node._cleanups) {
node._cleanups.forEach((f) => f());
node._cleanups.clear();
}
node.childNodes?.forEach(sweep);
};
const _view = (fn) => {
const cleanups = new Set(); const cleanups = new Set();
const prev = currentOwner; const previousOwner = currentOwner;
const container = document.createElement("div"); const container = createEl("div");
container.style.display = "contents"; container.style.display = "contents";
currentOwner = { cleanups }; currentOwner = { cleanups };
try {
const res = fn({ onCleanup: (f) => cleanups.add(f) }); const processResult = (result) => {
const process = (n) => { if (!result) return;
if (!n) return; if (result._isRuntime) {
if (n._isRuntime) { cleanups.add(result.destroy);
cleanups.add(n.destroy); container.appendChild(result.container);
container.appendChild(n.container); } else if (isArr(result)) {
} else if (Array.isArray(n)) n.forEach(process); result.forEach(processResult);
else container.appendChild(n instanceof Node ? n : document.createTextNode(String(n))); } else {
container.appendChild(result instanceof Node ? result : createText(result));
}
}; };
process(res);
} finally { currentOwner = prev; } try {
processResult(renderFn({ onCleanup: (fn) => cleanups.add(fn) }));
} finally { currentOwner = previousOwner; }
return { return {
_isRuntime: true, _isRuntime: true,
container, container,
destroy: () => { destroy: () => {
cleanups.forEach((f) => f()); cleanups.forEach((fn) => fn());
sweep(container); cleanupNode(container);
container.remove(); container.remove();
}, },
}; };
}; };
const $ = (initial, key = null) => { const $ = (initialValue, storageKey = null) => {
if (typeof initial === "function") { const subscribers = new Set();
const subs = new Set();
let cached, dirty = true; if (isFunc(initialValue)) {
let cachedValue, isDirty = true;
const effect = () => { const effect = () => {
if (effect._deleted) return; if (effect._deleted) return;
effect._deps.forEach((s) => s.delete(effect)); effect._deps.forEach((dep) => dep.delete(effect));
effect._deps.clear(); effect._deps.clear();
const prev = activeEffect;
activeEffect = effect; runWithContext(effect, () => {
try { const newValue = initialValue();
const val = initial(); if (!Object.is(cachedValue, newValue) || isDirty) {
if (!Object.is(cached, val) || dirty) { cachedValue = newValue;
cached = val; isDirty = false;
dirty = false; triggerUpdate(subscribers);
trigger(subs);
} }
} finally { activeEffect = prev; } });
}; };
effect._deps = new Set();
effect._isComputed = true; assign(effect, {
effect._subs = subs; _deps: new Set(),
effect._deleted = false; _isComputed: true,
effect.markDirty = () => (dirty = true); _subs: subscribers,
effect.stop = () => { _deleted: false,
markDirty: () => (isDirty = true),
stop: () => {
effect._deleted = true; effect._deleted = true;
effect._deps.forEach((s) => s.delete(effect)); effect._deps.forEach((dep) => dep.delete(effect));
subs.clear(); subscribers.clear();
}; }
});
if (currentOwner) currentOwner.cleanups.add(effect.stop); if (currentOwner) currentOwner.cleanups.add(effect.stop);
return () => { if (dirty) effect(); track(subs); return cached; }; return () => { if (isDirty) effect(); trackSubscription(subscribers); return cachedValue; };
} }
let value = initial; let value = initialValue;
if (key) { if (storageKey) {
try { try {
const saved = localStorage.getItem(key); const saved = localStorage.getItem(storageKey);
if (saved !== null) value = JSON.parse(saved); if (saved !== null) value = JSON.parse(saved);
} catch (e) { } catch (e) { console.warn("SigPro Storage Lock", e); }
console.warn("SigPro: LocalStorage locked", e);
} }
}
const subs = new Set();
return (...args) => { return (...args) => {
if (args.length) { if (args.length) {
const next = typeof args[0] === "function" ? args[0](value) : args[0]; const nextValue = isFunc(args[0]) ? args[0](value) : args[0];
if (!Object.is(value, next)) { if (!Object.is(value, nextValue)) {
value = next; value = nextValue;
if (key) localStorage.setItem(key, JSON.stringify(value)); if (storageKey) localStorage.setItem(storageKey, JSON.stringify(value));
trigger(subs); triggerUpdate(subscribers);
} }
} }
track(subs); trackSubscription(subscribers);
return value; return value;
}; };
}; };
const $$ = (obj, cache = new WeakMap()) => { const $$ = (object, cache = new WeakMap()) => {
if (typeof obj !== "object" || obj === null) return obj; if (!isObj(object)) return object;
if (cache.has(obj)) return cache.get(obj); if (cache.has(object)) return cache.get(object);
const subs = {}; const keySubscribers = {};
const proxy = new Proxy(object, {
const proxy = new Proxy(obj, {
get(target, key) { get(target, key) {
if (activeEffect) if (activeEffect) trackSubscription(keySubscribers[key] ??= new Set());
track(subs[key] ??= new Set());
const value = Reflect.get(target, key); const value = Reflect.get(target, key);
return isObj(value) ? $$(value, cache) : value;
return (typeof value === "object" && value !== null)
? $$(value, cache)
: value;
}, },
set(target, key, value) { set(target, key, value) {
if (Object.is(target[key], value)) return true; if (Object.is(target[key], value)) return true;
const success = Reflect.set(target, key, value);
const res = Reflect.set(target, key, value); if (keySubscribers[key]) triggerUpdate(keySubscribers[key]);
return success;
if (subs[key])
trigger(subs[key]);
return res;
} }
}); });
cache.set(obj, proxy); cache.set(object, proxy);
return proxy; return proxy;
}; };
const $watch = (target, fn) => { const Watch = (target, callbackFn) => {
const isExplicit = Array.isArray(target); const isExplicit = isArr(target);
const callback = isExplicit ? fn : target; const callback = isExplicit ? callbackFn : target;
const depsInput = isExplicit ? target : null; if (!isFunc(callback)) return () => {};
if (typeof callback !== "function") return () => { };
const owner = currentOwner; const owner = currentOwner;
const runner = () => { const runner = () => {
if (runner._deleted) return; if (runner._deleted) return;
runner._deps.forEach((s) => s.delete(runner)); runner._deps.forEach((dep) => dep.delete(runner));
runner._deps.clear(); runner._deps.clear();
runner._cleanups.forEach((c) => c()); runner._cleanups.forEach((cleanup) => cleanup());
runner._cleanups.clear(); runner._cleanups.clear();
const prevEffect = activeEffect; const previousOwner = currentOwner;
const prevOwner = currentOwner; runner.depth = activeEffect ? activeEffect.depth + 1 : 0;
activeEffect = runner;
currentOwner = { cleanups: runner._cleanups };
runner.depth = prevEffect ? prevEffect.depth + 1 : 0;
try { runWithContext(runner, () => {
currentOwner = { cleanups: runner._cleanups };
if (isExplicit) { if (isExplicit) {
activeEffect = null; runWithContext(null, callback);
callback(); target.forEach((dep) => isFunc(dep) && dep());
activeEffect = runner;
depsInput.forEach(d => typeof d === "function" && d());
} else { } else {
callback(); callback();
} }
} finally { currentOwner = previousOwner;
activeEffect = prevEffect; });
currentOwner = prevOwner;
}
}; };
runner._deps = new Set(); assign(runner, {
runner._cleanups = new Set(); _deps: new Set(),
runner._deleted = false; _cleanups: new Set(),
runner.stop = () => { _deleted: false,
stop: () => {
if (runner._deleted) return; if (runner._deleted) return;
runner._deleted = true; runner._deleted = true;
effectQueue.delete(runner); effectQueue.delete(runner);
runner._deps.forEach((s) => s.delete(runner)); runner._deps.forEach((dep) => dep.delete(runner));
runner._cleanups.forEach((c) => c()); runner._cleanups.forEach((cleanup) => cleanup());
if (owner) owner.cleanups.delete(runner.stop); if (owner) owner.cleanups.delete(runner.stop);
}; }
});
if (owner) owner.cleanups.add(runner.stop); if (owner) owner.cleanups.add(runner.stop);
runner(); runner();
return runner.stop; return runner.stop;
}; };
const $html = (tag, props = {}, content = []) => { const Tag = (tag, props = {}, children = []) => {
if (props instanceof Node || Array.isArray(props) || typeof props !== "object") { if (props instanceof Node || isArr(props) || !isObj(props)) {
content = props; props = {}; children = props; props = {};
} }
const svgTags = ["svg", "path", "circle", "rect", "line", "polyline", "polygon", "g", "defs", "text", "tspan", "use"]; const isSVG = /^(svg|path|circle|rect|line|polyline|polygon|g|defs|text|tspan|use)$/.test(tag);
const isSVG = svgTags.includes(tag); const element = isSVG
const el = isSVG ? doc.createElementNS("http://www.w3.org/2000/svg", tag)
? document.createElementNS("http://www.w3.org/2000/svg", tag) : createEl(tag);
: document.createElement(tag);
const _sanitize = (key, val) => (key === 'src' || key === 'href') && String(val).toLowerCase().includes('javascript:') ? '#' : val; element._cleanups = new Set();
el._cleanups = new Set(); element.onUnmount = (fn) => element._cleanups.add(fn);
const booleanAttributes = ["disabled", "checked", "required", "readonly", "selected", "multiple", "autofocus"];
const boolAttrs = ["disabled", "checked", "required", "readonly", "selected", "multiple", "autofocus"]; const updateAttribute = (name, value) => {
const sanitized = (name === 'src' || name === 'href') && String(value).toLowerCase().includes('javascript:') ? '#' : value;
for (let [key, val] of Object.entries(props)) { if (booleanAttributes.includes(name)) {
if (key === "ref") { (typeof val === "function" ? val(el) : (val.current = el)); continue; } element[name] = !!sanitized;
const isSignal = typeof val === "function", isInput = ["INPUT", "TEXTAREA", "SELECT"].includes(el.tagName), isBindAttr = (key === "value" || key === "checked"); sanitized ? element.setAttribute(name, "") : element.removeAttribute(name);
if (isInput && isBindAttr && isSignal) {
el._cleanups.add($watch(() => { const currentVal = val(); if (el[key] !== currentVal) el[key] = currentVal; }));
const eventName = key === "checked" ? "change" : "input", handler = (event) => val(event.target[key]);
el.addEventListener(eventName, handler);
el._cleanups.add(() => el.removeEventListener(eventName, handler));
} else if (key.startsWith("on")) {
const eventName = key.slice(2).toLowerCase().split(".")[0], handler = (event) => val(event);
el.addEventListener(eventName, handler);
el._cleanups.add(() => el.removeEventListener(eventName, handler));
} else if (isSignal) {
el._cleanups.add($watch(() => {
const currentVal = _sanitize(key, val());
if (key === "class") {
el.className = currentVal || "";
} else if (boolAttrs.includes(key)) {
if (currentVal) {
el.setAttribute(key, "");
el[key] = true;
} else { } else {
el.removeAttribute(key); sanitized == null ? element.removeAttribute(name) : element.setAttribute(name, sanitized);
el[key] = false;
} }
} else {
if (currentVal == null) {
el.removeAttribute(key);
} else if (isSVG && typeof currentVal === 'number') {
el.setAttribute(key, currentVal);
} else {
el.setAttribute(key, currentVal);
}
}
}));
} else {
if (boolAttrs.includes(key)) {
if (val) {
el.setAttribute(key, "");
el[key] = true;
} else {
el.removeAttribute(key);
el[key] = false;
}
} else {
el.setAttribute(key, _sanitize(key, val));
}
}
}
const append = (child) => {
if (Array.isArray(child)) return child.forEach(append);
if (child instanceof Node) {
el.appendChild(child);
} else if (typeof child === "function") {
const marker = document.createTextNode("");
el.appendChild(marker);
let nodes = [];
el._cleanups.add($watch(() => {
const res = child(), next = (Array.isArray(res) ? res : [res]).map((i) =>
i?._isRuntime ? i.container : i instanceof Node ? i : document.createTextNode(i ?? "")
);
nodes.forEach((n) => { sweep?.(n); n.remove(); });
next.forEach((n) => marker.parentNode?.insertBefore(n, marker));
nodes = next;
}));
} else el.appendChild(document.createTextNode(child ?? ""));
}; };
append(content);
return el; for (let [key, value] of Object.entries(props)) {
if (key === "ref") { (isFunc(value) ? value(element) : (value.current = element)); continue; }
const isSignal = isFunc(value);
if (key.startsWith("on")) {
const eventName = key.slice(2).toLowerCase().split(".")[0];
element.addEventListener(eventName, value);
element._cleanups.add(() => element.removeEventListener(eventName, value));
} else if (isSignal) {
element._cleanups.add(Watch(() => {
const currentVal = value();
key === "class" ? (element.className = currentVal || "") : updateAttribute(key, currentVal);
}));
if (["INPUT", "TEXTAREA", "SELECT"].includes(element.tagName) && (key === "value" || key === "checked")) {
const event = key === "checked" ? "change" : "input";
const handler = (e) => value(e.target[key]);
element.addEventListener(event, handler);
element._cleanups.add(() => element.removeEventListener(event, handler));
}
} else {
updateAttribute(key, value);
}
}
const appendChildNode = (child) => {
if (isArr(child)) return child.forEach(appendChildNode);
if (isFunc(child)) {
const marker = createText("");
element.appendChild(marker);
let currentNodes = [];
element._cleanups.add(Watch(() => {
const result = child();
const nextNodes = (isArr(result) ? result : [result]).map((node) =>
node?._isRuntime ? node.container : node instanceof Node ? node : createText(node)
);
currentNodes.forEach((node) => { cleanupNode(node); node.remove(); });
nextNodes.forEach((node) => marker.parentNode?.insertBefore(node, marker));
currentNodes = nextNodes;
}));
} else {
element.appendChild(child instanceof Node ? child : createText(child));
}
};
appendChildNode(children);
return element;
}; };
const $if = (condition, thenVal, otherwiseVal = null, transition = null) => { const If = (condition, thenVal, otherwiseVal = null, transition = null) => {
const marker = document.createTextNode(""); const marker = createText("");
const container = $html("div", { style: "display:contents" }, [marker]); const container = Tag("div", { style: "display:contents" }, [marker]);
let current = null, last = null; let currentView = null, lastState = null;
$watch(() => { Watch(() => {
const state = !!(typeof condition === "function" ? condition() : condition); const state = !!(isFunc(condition) ? condition() : condition);
if (state === last) return; if (state === lastState) return;
last = state; lastState = state;
if (current && !state && transition?.out) { const dispose = () => { if (currentView) currentView.destroy(); currentView = null; };
transition.out(current.container, () => {
current.destroy(); if (currentView && !state && transition?.out) {
current = null; transition.out(currentView.container, dispose);
});
} else { } else {
if (current) current.destroy(); dispose();
current = null;
} }
if (state || (!state && otherwiseVal)) {
const branch = state ? thenVal : otherwiseVal; const branch = state ? thenVal : otherwiseVal;
if (branch) { if (branch) {
current = _view(() => typeof branch === "function" ? branch() : branch); currentView = Render(() => isFunc(branch) ? branch() : branch);
container.insertBefore(current.container, marker); container.insertBefore(currentView.container, marker);
if (state && transition?.in) transition.in(current.container); if (state && transition?.in) transition.in(currentView.container);
}
} }
}); });
return container; return container;
}; };
$if.not = (condition, thenVal, otherwiseVal) => $if(() => !(typeof condition === "function" ? condition() : condition), thenVal, otherwiseVal); const For = (source, renderFn, keyFn, tag = "div", props = { style: "display:contents" }) => {
const marker = createText("");
const container = Tag(tag, props, [marker]);
let viewCache = new Map();
const $for = (source, render, keyFn, tag = "div", props = { style: "display:contents" }) => { Watch(() => {
const marker = document.createTextNode(""); const items = (isFunc(source) ? source() : source) || [];
const container = $html(tag, props, [marker]); const nextCache = new Map();
let cache = new Map(); const order = [];
$watch(() => {
const items = (typeof source === "function" ? source() : source) || [];
const newCache = new Map();
const newOrder = [];
for (let i = 0; i < items.length; i++) { for (let i = 0; i < items.length; i++) {
const item = items[i]; const item = items[i];
const key = keyFn ? keyFn(item, i) : i; const key = keyFn ? keyFn(item, i) : i;
let view = viewCache.get(key) || Render(() => renderFn(item, i));
let run = cache.get(key); viewCache.delete(key);
if (!run) { nextCache.set(key, view);
run = _view(() => render(item, i)); order.push(key);
} else {
cache.delete(key);
} }
newCache.set(key, run); viewCache.forEach((view) => { view.destroy(); view.container.remove(); });
newOrder.push(key);
}
cache.forEach(run => {
run.destroy();
run.container.remove();
});
let anchor = marker; let anchor = marker;
for (let i = newOrder.length - 1; i >= 0; i--) { for (let i = order.length - 1; i >= 0; i--) {
const run = newCache.get(newOrder[i]); const view = nextCache.get(order[i]);
if (run.container.nextSibling !== anchor) { if (view.container.nextSibling !== anchor) {
container.insertBefore(run.container, anchor); container.insertBefore(view.container, anchor);
} }
anchor = run.container; anchor = view.container;
} }
viewCache = nextCache;
cache = newCache;
}); });
return container; return container;
}; };
const $router = (routes) => { const Router = (routes) => {
const sPath = $(window.location.hash.replace(/^#/, "") || "/"); const currentPath = $(window.location.hash.replace(/^#/, "") || "/");
window.addEventListener("hashchange", () => sPath(window.location.hash.replace(/^#/, "") || "/")); window.addEventListener("hashchange", () => currentPath(window.location.hash.replace(/^#/, "") || "/"));
const outlet = $html("div", { class: "router-outlet" }); const outlet = Tag("div", { class: "router-outlet" });
let current = null; let currentView = null;
$watch([sPath], async () => { Watch([currentPath], async () => {
const path = sPath(); const path = currentPath();
const route = routes.find(r => { const route = routes.find(r => {
const rp = r.path.split("/").filter(Boolean), pp = path.split("/").filter(Boolean); const routeParts = r.path.split("/").filter(Boolean);
return rp.length === pp.length && rp.every((p, i) => p.startsWith(":") || p === pp[i]); const pathParts = path.split("/").filter(Boolean);
return routeParts.length === pathParts.length && routeParts.every((part, i) => part.startsWith(":") || part === pathParts[i]);
}) || routes.find(r => r.path === "*"); }) || routes.find(r => r.path === "*");
if (route) { if (route) {
let comp = route.component; let component = route.component;
if (typeof comp === "function" && comp.toString().includes('import')) { if (isFunc(component) && component.toString().includes('import')) {
comp = (await comp()).default || (await comp()); component = (await component()).default || (await component());
} }
const params = {}; const params = {};
route.path.split("/").filter(Boolean).forEach((p, i) => { route.path.split("/").filter(Boolean).forEach((part, i) => {
if (p.startsWith(":")) params[p.slice(1)] = path.split("/").filter(Boolean)[i]; if (part.startsWith(":")) params[part.slice(1)] = path.split("/").filter(Boolean)[i];
}); });
if (current) current.destroy(); if (currentView) currentView.destroy();
if ($router.params) $router.params(params); if (Router.params) Router.params(params);
current = _view(() => { currentView = Render(() => {
try { try {
return typeof comp === "function" ? comp(params) : comp; return isFunc(component) ? component(params) : component;
} catch (e) { } catch (e) {
return $html("div", { class: "p-4 text-error" }, "Error loading view"); return Tag("div", { class: "p-4 text-error" }, "Error loading view");
} }
}); });
outlet.appendChild(current.container); outlet.appendChild(currentView.container);
} }
}); });
return outlet; return outlet;
}; };
$router.params = $({}); Router.params = $({});
$router.to = (path) => (window.location.hash = path.replace(/^#?\/?/, "#/")); Router.to = (path) => (window.location.hash = path.replace(/^#?\/?/, "#/"));
$router.back = () => window.history.back(); Router.back = () => window.history.back();
$router.path = () => window.location.hash.replace(/^#/, "") || "/"; Router.path = () => window.location.hash.replace(/^#/, "") || "/";
const $mount = (component, target) => { const Mount = (component, target) => {
const el = typeof target === "string" ? document.querySelector(target) : target; const targetEl = typeof target === "string" ? doc.querySelector(target) : target;
if (!el) return; if (!targetEl) return;
if (MOUNTED_NODES.has(el)) MOUNTED_NODES.get(el).destroy(); if (MOUNTED_NODES.has(targetEl)) MOUNTED_NODES.get(targetEl).destroy();
const instance = _view(typeof component === "function" ? component : () => component); const instance = Render(isFunc(component) ? component : () => component);
el.replaceChildren(instance.container); targetEl.replaceChildren(instance.container);
MOUNTED_NODES.set(el, instance); MOUNTED_NODES.set(targetEl, instance);
return instance; return instance;
}; };
export const Fragment = ({ children }) => children; export const Fragment = ({ children }) => children;
const SigProCore = { $, $watch, $html, $if, $for, $router, $mount, Fragment }; const SigPro = { $, $$, Render, Watch, Tag, If, For, Router, Mount, Fragment };
if (typeof window !== "undefined") { if (typeof window !== "undefined") {
const install = (registry) => { assign(window, SigPro);
Object.keys(registry).forEach(key => { const tags = `div span p h1 h2 h3 h4 h5 h6 br hr section article aside nav main header footer address ul ol li dl dt dd a em strong small i b u mark time sub sup pre code blockquote details summary dialog form label input textarea select button option fieldset legend table thead tbody tfoot tr th td caption img video audio canvas svg iframe picture source progress meter`.split(" ");
window[key] = registry[key]; tags.forEach((tag) => {
const helper = tag[0].toUpperCase() + tag.slice(1);
if (!(helper in window)) window[helper] = (p, c) => Tag(tag, p, c);
}); });
window.SigPro = Object.freeze(SigPro);
const tags = `div span p h1 h2 h3 h4 h5 h6 br hr section article aside nav main header footer address ul ol li dl dt dd a em strong small i b u mark time sub sup pre code blockquote details summary dialog form label input textarea select button option fieldset legend table thead tbody tfoot tr th td caption img video audio canvas svg iframe picture source progress meter`.split(/\s+/);
tags.forEach((tagName) => {
const helperName = tagName.charAt(0).toUpperCase() + tagName.slice(1);
if (!(helperName in window)) {
window[helperName] = (props, content) => $html(tagName, props, content);
}
});
window.Fragment = Fragment;
window.SigPro = Object.freeze(registry);
};
install(SigProCore);
} }
export { $, $watch, $html, $if, $for, $router, $mount }; export { $, $$, Render, Watch, Tag, If, For, Router, Mount };
export default SigPro;
export default SigProCore;