Actualizar sigworkPro.js

This commit is contained in:
2026-04-12 23:54:56 +02:00
parent dcc669d6fe
commit d8ab8c75d8

View File

@@ -100,7 +100,7 @@ const getComponentContext = () => {
export const removeNode = node => { export const removeNode = node => {
if (!node) return; if (!node) return;
if (node.childNodes) { if (node.childNodes) {
node.childNodes.forEach(child => removeNode(child)); [...node.childNodes].forEach(removeNode);
} }
const disposers = nodeDisposers.get(node); const disposers = nodeDisposers.get(node);
if (disposers) { if (disposers) {
@@ -108,7 +108,7 @@ export const removeNode = node => {
nodeDisposers.delete(node); nodeDisposers.delete(node);
} }
if (node._raf) cancelAnimationFrame(node._raf); if (node._raf) cancelAnimationFrame(node._raf);
if (node.componentStop) node.componentStop(); if (node._stop) node._stop();
const ctx = node.componentContext; const ctx = node.componentContext;
if (ctx) { if (ctx) {
ctx.unmount.forEach(fn => fn()); ctx.unmount.forEach(fn => fn());
@@ -117,7 +117,7 @@ export const removeNode = node => {
if (node.leaveTransition) { if (node.leaveTransition) {
node.leaveTransition(() => node.remove()); node.leaveTransition(() => node.remove());
} else { } else {
node.remove(); node.remove?.();
} }
}; };
@@ -186,6 +186,35 @@ export const $ = (initialValue, storageKey) => {
return signal; return signal;
}; };
export const computed = fn => {
let dirty = true;
let cache;
const subs = new Set();
const evaluate = () => {
if (!dirty) return cache;
const prev = activeEffect;
activeEffect = null;
try {
cache = fn();
} finally {
activeEffect = prev;
}
dirty = false;
trigger(subs);
return cache;
};
const signal = () => {
track(subs);
return evaluate();
};
const effect = createEffect(() => {
fn();
dirty = true;
trigger(subs);
});
return signal;
};
export const set = (signal, path, value) => { export const set = (signal, path, value) => {
if (value === undefined) { if (value === undefined) {
signal(isFunction(path) ? path(signal()) : path); signal(isFunction(path) ? path(signal()) : path);
@@ -218,6 +247,7 @@ export const onMount = fn => {
const ctx = getComponentContext(); const ctx = getComponentContext();
if (ctx) ctx.mount.push(fn); if (ctx) ctx.mount.push(fn);
}; };
export const onUnmount = fn => { export const onUnmount = fn => {
const ctx = getComponentContext(); const ctx = getComponentContext();
if (ctx) ctx.unmount.push(fn); if (ctx) ctx.unmount.push(fn);
@@ -275,23 +305,30 @@ const appendChildNode = (parent, child) => {
let currentNodes = []; let currentNodes = [];
const stop = Watch(() => { const stop = Watch(() => {
const raw = child(); const raw = child();
const next = (Array.isArray(raw) ? raw : [raw]) if (raw?._isFor) {
.flat(Infinity) raw._reconcile(parent);
.filter(v => v != null) currentNodes = raw();
.map(v => isNode(v) ? v : doc.createTextNode(String(v))); } else {
for (const n of currentNodes) { const next = (Array.isArray(raw) ? raw : [raw])
if (!next.includes(n)) removeNode(n); .flat(Infinity)
} .filter(v => v != null)
let ref = anchor; .map(v => isNode(v) ? v : doc.createTextNode(String(v)));
for (let i = next.length - 1; i >= 0; i--) { for (const n of currentNodes) {
const n = next[i]; if (!next.includes(n)) removeNode(n);
if (n.parentNode !== parent) {
parent.insertBefore(n, ref);
if (n.componentContext) n.componentContext.mount.forEach(f => f());
} }
ref = n; let ref = anchor;
for (let i = next.length - 1; i >= 0; i--) {
const n = next[i];
if (n.parentNode !== parent) {
parent.insertBefore(n, ref);
} else if (n.nextSibling !== next[i + 1]) {
parent.insertBefore(n, ref);
}
if (n.componentContext) n.componentContext.mount.forEach(f => f());
ref = n;
}
currentNodes = next;
} }
currentNodes = next;
}); });
registerNodeCleanup(anchor, stop); registerNodeCleanup(anchor, stop);
} else if (isNode(child)) { } else if (isNode(child)) {
@@ -318,7 +355,16 @@ export const Tag = (tag, props = {}, ...children) => {
}); });
if (isNode(rendered)) { if (isNode(rendered)) {
rendered.componentContext = ctx; rendered.componentContext = ctx;
rendered.componentStop = stop; rendered._stop = stop;
queueMicrotask(() => ctx.mount.forEach(fn => fn()));
} else if (Array.isArray(rendered)) {
rendered.forEach(node => {
if (isNode(node)) {
node.componentContext = ctx;
node._stop = stop;
}
});
queueMicrotask(() => ctx.mount.forEach(fn => fn()));
} }
return rendered; return rendered;
} }
@@ -348,52 +394,69 @@ export const Tag = (tag, props = {}, ...children) => {
export const If = (cond, thenFn, elseFn = null, hooks = {}) => { export const If = (cond, thenFn, elseFn = null, hooks = {}) => {
let lastResult = null; let lastResult = null;
let node = null; let nodes = [];
let exitPromise = null; let exitPromise = null;
return () => { return () => {
const condition = !!(isFunction(cond) ? cond() : cond); const condition = !!(isFunction(cond) ? cond() : cond);
if (condition === lastResult) return node; if (condition === lastResult) return nodes.length === 1 ? nodes[0] : nodes;
if (node) { if (nodes.length) {
if (hooks.leave) { if (hooks.leave) {
if (exitPromise && exitPromise.cancel) exitPromise.cancel(); if (exitPromise && exitPromise.cancel) exitPromise.cancel();
const anim = hooks.leave(node); const anim = hooks.leave(nodes);
exitPromise = anim; exitPromise = anim;
if (anim && anim.finished) { if (anim && anim.finished) {
anim.finished.then(() => removeNode(node)); anim.finished.then(() => nodes.forEach(n => removeNode(n)));
} else { } else {
removeNode(node); nodes.forEach(n => removeNode(n));
} }
} else { } else {
removeNode(node); nodes.forEach(n => removeNode(n));
} }
} }
lastResult = condition; lastResult = condition;
const newNode = condition ? thenFn() : elseFn?.(); const newNodes = condition ? thenFn() : elseFn?.() ?? [];
node = newNode; const newArr = (Array.isArray(newNodes) ? newNodes : [newNodes]).flat(Infinity).filter(v => v != null);
if (node && hooks.enter) hooks.enter(node); nodes = newArr;
return node; if (nodes.length && hooks.enter) hooks.enter(nodes);
return nodes.length === 1 ? nodes[0] : nodes;
}; };
}; };
export const For = ({ each, key, children }) => { export const For = ({ each, key, children }) => {
let cache = new Map(); let cache = new Map();
return () => { let order = [];
const reconcile = (parent) => {
const items = isFunction(each) ? each() : each || []; const items = isFunction(each) ? each() : each || [];
const newCache = new Map(); const newMap = new Map();
const nodes = []; const newOrder = [];
const getKey = (item, i) => key ? (isFunction(key) ? key(item, i) : item[key]) : i;
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 itemKey = key ? (isFunction(key) ? key(item, i) : item[key]) : i; const k = getKey(item, i);
let node = cache.get(itemKey); let node = cache.get(k);
if (!node) node = Tag(children[0], { item, index: i }); if (!node) node = Tag(children[0], { item, index: i });
newCache.set(itemKey, node); newMap.set(k, node);
nodes.push(node); newOrder.push(node);
cache.delete(itemKey); cache.delete(k);
}
if (parent) {
let ref = null;
for (let i = newOrder.length - 1; i >= 0; i--) {
const node = newOrder[i];
if (node.nextSibling !== newOrder[i + 1]) {
parent.insertBefore(node, ref);
}
ref = node;
}
} }
for (const node of cache.values()) removeNode(node); for (const node of cache.values()) removeNode(node);
cache = newCache; cache = newMap;
return nodes; order = newOrder;
}; };
const renderFn = () => order;
renderFn._isFor = true;
renderFn._reconcile = reconcile;
return renderFn;
}; };
export const Router = ({ routes }) => { export const Router = ({ routes }) => {
@@ -402,7 +465,7 @@ export const Router = ({ routes }) => {
const path = $(getHash()); const path = $(getHash());
const handler = () => { path(getHash()); }; const handler = () => { path(getHash()); };
window.addEventListener('hashchange', handler); window.addEventListener('hashchange', handler);
onUnmount(() => window.removeEventListener('hashchange', handler)); registerNodeCleanup(outlet, () => window.removeEventListener('hashchange', handler));
Watch(() => { Watch(() => {
const current = path(); const current = path();
const matched = routes.find(r => { const matched = routes.find(r => {
@@ -444,4 +507,4 @@ export const createApp = (Root, rootProps = {}) => selector => {
globalThis[tag[0].toUpperCase() + tag.slice(1)] = (props, ...children) => Tag(tag, props, ...children); globalThis[tag[0].toUpperCase() + tag.slice(1)] = (props, ...children) => Tag(tag, props, ...children);
}); });
export default { $, set, Watch, watch, untrack, Tag, If, For, Router, createApp, removeNode, navigate, currentPath, onMount, onUnmount }; export default { $, set, Watch, watch, computed, untrack, Tag, If, For, Router, createApp, removeNode, navigate, currentPath, onMount, onUnmount };