Granular updates in $for

This commit is contained in:
2026-04-01 09:01:21 +02:00
parent 1107b1e929
commit 022d75e262
3 changed files with 54 additions and 38 deletions

41
dist/sigpro.js vendored
View File

@@ -316,32 +316,39 @@
return container; return container;
}; };
$if.not = (condition, thenVal, otherwiseVal) => $if(() => !(typeof condition === "function" ? condition() : condition), thenVal, otherwiseVal); $if.not = (condition, thenVal, otherwiseVal) => $if(() => !(typeof condition === "function" ? condition() : condition), thenVal, otherwiseVal);
var $for = (source, render, keyFn = (item, index) => index) => { var $for = (source, render, keyFn) => {
const marker = document.createTextNode(""); const marker = document.createTextNode("");
const container = $html("div", { style: "display:contents" }, [marker]); const container = $html("div", { style: "display:contents" }, [marker]);
const cache = new Map; let cache = new Map;
$watch(() => { $watch(() => {
const items = (typeof source === "function" ? source() : source) || []; const items = (typeof source === "function" ? source() : source) || [];
const newKeys = new Set; const newCache = new Map;
items.forEach((item, index) => { const newOrder = [];
const key = keyFn(item, index); for (let i = 0;i < items.length; i++) {
newKeys.add(key); const item = items[i];
const key = keyFn ? keyFn(item, i) : i;
let run = cache.get(key); let run = cache.get(key);
if (!run) { if (!run) {
run = _view(() => render(item, index)); run = _view(() => render(item, i));
cache.set(key, run); } else {
}
container.insertBefore(run.container, marker);
});
cache.forEach((run, key) => {
if (!newKeys.has(key)) {
run.destroy();
if (run.container && run.container.parentNode) {
run.container.remove();
}
cache.delete(key); cache.delete(key);
} }
newCache.set(key, run);
newOrder.push(key);
}
cache.forEach((run) => {
run.destroy();
run.container.remove();
}); });
let anchor = marker;
for (let i = newOrder.length - 1;i >= 0; i--) {
const run = newCache.get(newOrder[i]);
if (run.container.nextSibling !== anchor) {
container.insertBefore(run.container, anchor);
}
anchor = run.container;
}
cache = newCache;
}); });
return container; return container;
}; };

2
dist/sigpro.min.js vendored

File diff suppressed because one or more lines are too long

View File

@@ -307,37 +307,46 @@ $if.not = (condition, thenVal, otherwiseVal) => $if(() => !(typeof condition ===
* @returns {HTMLElement} A reactive container (display: contents). * @returns {HTMLElement} A reactive container (display: contents).
*/ */
const $for = (source, render, keyFn = (item, index) => index) => { const $for = (source, render, keyFn) => {
const marker = document.createTextNode(""); const marker = document.createTextNode("");
const container = $html("div", { style: "display:contents" }, [marker]); const container = $html("div", { style: "display:contents" }, [marker]);
const cache = new Map(); let cache = new Map();
$watch(() => { $watch(() => {
const items = (typeof source === "function" ? source() : source) || []; const items = (typeof source === "function" ? source() : source) || [];
const newKeys = new Set(); const newCache = new Map();
const newOrder = [];
items.forEach((item, index) => { for (let i = 0; i < items.length; i++) {
const key = keyFn(item, index); const item = items[i];
newKeys.add(key); const key = keyFn ? keyFn(item, i) : i;
let run = cache.get(key); let run = cache.get(key);
if (!run) { if (!run) {
run = _view(() => render(item, index)); run = _view(() => render(item, i));
cache.set(key, run); } else {
}
container.insertBefore(run.container, marker);
});
cache.forEach((run, key) => {
if (!newKeys.has(key)) {
run.destroy();
if (run.container && run.container.parentNode) {
run.container.remove();
}
cache.delete(key); cache.delete(key);
} }
newCache.set(key, run);
newOrder.push(key);
}
cache.forEach(run => {
run.destroy();
run.container.remove();
}); });
let anchor = marker;
for (let i = newOrder.length - 1; i >= 0; i--) {
const run = newCache.get(newOrder[i]);
if (run.container.nextSibling !== anchor) {
container.insertBefore(run.container, anchor);
}
anchor = run.container;
}
cache = newCache;
}); });
return container; return container;