Squashed 'cms/core/' content from commit 59b9e20

git-subtree-dir: cms/core
git-subtree-split: 59b9e2075ac48cf017db38009d54dbe56a98fffc
This commit is contained in:
2026-06-30 01:46:20 +02:00
commit bba1df32cb
59 changed files with 7398 additions and 0 deletions
+39
View File
@@ -0,0 +1,39 @@
// Serialisiert asynchrone Aufgaben je `key` und koalesziert Wartende:
// - Es läuft nie mehr als eine Aufgabe pro Key gleichzeitig.
// - Kommen während eines Laufs weitere Aufrufe rein, wird GENAU EIN weiterer
// Durchlauf nachgelagert (egal wie viele warten) — sie teilen sich dessen
// Ergebnis. So sehen alle den jüngsten Stand, ohne einen Lauf-Sturm.
//
// Einsatz: teure, idempotente Vorgänge wie der Hugo-Build (siehe hugo.js).
const state = new Map();
export function coalesce(key, fn) {
let s = state.get(key);
if (!s) { s = { running: false, rerun: false, fn, waiters: [] }; state.set(key, s); }
s.fn = fn; // jüngste Variante gewinnt für den nächsten Lauf
return new Promise((resolve, reject) => {
s.waiters.push({ resolve, reject });
if (!s.running) drain(key);
else s.rerun = true;
});
}
async function drain(key) {
const s = state.get(key);
s.running = true;
try {
do {
s.rerun = false;
const waiters = s.waiters;
s.waiters = [];
try {
const r = await s.fn();
waiters.forEach((w) => w.resolve(r));
} catch (e) {
waiters.forEach((w) => w.reject(e));
}
} while (s.rerun);
} finally {
s.running = false;
}
}