Serverpuls: JWT-Cache, Lade-Zustand beim Umschalten, Antwort-Reihenfolge

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Opus 5.5 committed 2026-09-30 12:43:13 +00:00
1 parent ec740ca970
commit 16f3150ff1
4 files changed
+116 -8

No files matched your search

+7 -2
View File
@@ -1,4 +1,5 @@
import { account } from './appwrite'
import { createJwtCache, fetchWithRetry } from './serverpulsAuth'
/**
* Client fuer das Serverpuls-Backend (nur lesend).
@@ -6,9 +7,13 @@ import { account } from './appwrite'
*/
const BASE = '/api/serverpuls'
// JWT 10 Min. gecacht (Appwrite begrenzt das Erzeugen pro Nutzer)
const jwtCache = createJwtCache({ createJWT: () => account.createJWT() })
async function get(path) {
const { jwt } = await account.createJWT()
const res = await fetch(`${BASE}${path}`, { headers: { 'X-Appwrite-JWT': jwt } })
const res = await fetchWithRetry(jwtCache, (jwt) =>
fetch(`${BASE}${path}`, { headers: { 'X-Appwrite-JWT': jwt } })
)
const data = await res.json().catch(() => ({}))
if (!res.ok) throw new Error(data.error || `Serverpuls-Fehler ${res.status}`)
return data
+37
View File
@@ -0,0 +1,37 @@
// JWT-Cache fuer Serverpuls (rein, ohne Appwrite-Import; createJWT und Uhr werden injiziert).
export const JWT_TTL_MS = 10 * 60 * 1000
export function createJwtCache({ createJWT, now = Date.now, ttlMs = JWT_TTL_MS }) {
let entry = null // { jwt, at } oder { promise }
let pending = null
async function get() {
if (entry && now() - entry.at < ttlMs) return entry.jwt
if (pending) return pending
const p = (async () => {
try {
const { jwt } = await createJWT()
entry = { jwt, at: now() }
return jwt
} finally {
if (pending === p) pending = null
}
})()
pending = p
return p
}
function invalidate() {
entry = null
}
return { get, invalidate }
}
// doFetch(jwt) -> Response-artig ({status}); bei 401 einmal mit frischem JWT wiederholen.
export async function fetchWithRetry(cache, doFetch) {
const first = await doFetch(await cache.get())
if (first.status !== 401) return first
cache.invalidate()
return doFetch(await cache.get())
}