Actualizar sigworkPro.js
This commit is contained in:
147
sigworkPro.js
147
sigworkPro.js
@@ -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 };
|
||||||
Reference in New Issue
Block a user