Files
ClaudeandClaude Opus 5.5 097036c9a5 Öffnungszeiten: Speicher mit Versionen und Cache
LRU-Speicher mit Ablaufzeit (lru.js), Cache-Instanz der öffentlichen Antwort
(cache.js: 500 Einträge, 30 s) und Appwrite-Speicher mit getrennten Versionen
für Kundendaten und Team-Einstellungen (speicher.js), alle Schreibzugriffe
unter der Sperre zeiten:<projectId>.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 00:50:41 +00:00

57 lines
2.2 KiB
JavaScript

/**
* Oeffnungszeiten live: kleiner LRU-Speicher mit Ablaufzeit (rein, ohne eigene Uhr: die Zeit kommt als Millisekunden-Parameter).
*
* - hoechstens max Eintraege; ist er voll, faellt der am laengsten nicht benutzte (hole oder setze) heraus;
* - jeder Eintrag verfaellt ttlMs nach dem Setzen (genau nach ttlMs ist er weg); ein Treffer erneuert nur seinen Platz in
* der Reihe, nie die Ablaufzeit, damit auch ein oft abgefragter Eintrag spaetestens nach ttlMs neu gebaut wird;
* - hole liefert bei Fehlschlag oder Ablauf undefined; gespeichert werden darf jeder Wert (auch null, 0, '').
* Umsetzung: eine Map; ihre Einfuegereihenfolge ist die Nutzungsreihenfolge (aeltester zuerst), ein Treffer haengt den Eintrag neu an.
*/
const pruefeZeit = (nowMs, wer) => {
if (typeof nowMs !== 'number' || !Number.isFinite(nowMs)) throw new TypeError(`${wer}: nowMs muss eine Zahl (Millisekunden) sein`)
}
/**
* @param {{ max: number, ttlMs: number }} optionen max = ganze Zahl >= 1, ttlMs = Zahl > 0 (endlich)
* @returns {{ hole(key: string, nowMs: number): *, setze(key: string, wert: *, nowMs: number): void, vergiss(key: string): void, leere(): void, groesse(): number }}
*/
export function neuerLru({ max, ttlMs } = {}) {
if (!Number.isInteger(max) || max < 1) throw new TypeError('neuerLru: max muss eine ganze Zahl ab 1 sein')
if (typeof ttlMs !== 'number' || !Number.isFinite(ttlMs) || ttlMs <= 0) throw new TypeError('neuerLru: ttlMs muss eine Zahl groesser 0 sein')
/** @type {Map<string, { bis: number, wert: * }>} */
const eintraege = new Map()
return {
hole(key, nowMs) {
pruefeZeit(nowMs, 'hole')
const eintrag = eintraege.get(key)
if (!eintrag) return undefined
eintraege.delete(key)
if (eintrag.bis <= nowMs) return undefined
eintraege.set(key, eintrag)
return eintrag.wert
},
setze(key, wert, nowMs) {
pruefeZeit(nowMs, 'setze')
eintraege.delete(key)
eintraege.set(key, { bis: nowMs + ttlMs, wert })
while (eintraege.size > max) eintraege.delete(eintraege.keys().next().value)
},
vergiss(key) {
eintraege.delete(key)
},
leere() {
eintraege.clear()
},
groesse() {
return eintraege.size
},
}
}