Merge branch 'tomerge'

This commit is contained in:
2026-08-29 20:11:13 +02:00
5 changed files with 319 additions and 14 deletions
+46
View File
@@ -10,6 +10,8 @@
let highScoreRequestInFlight = false;
let highScoreGeneration = 0;
let highScoreSubmissionWarningShown = false;
let highScoreRetryDelayMs = highScoreRetryInitialDelayMs;
let highScoreRetryAt = 0;
function browserStorage() {
try {
@@ -86,10 +88,50 @@
}
}
function retryAfterDelay(response) {
if (response.status !== 429 && response.status !== 503) {
return null;
}
const value = response.headers.get("Retry-After")?.trim();
if (!value) {
return null;
}
const seconds = Number(value);
if (Number.isFinite(seconds) && seconds >= 0) {
const delay = seconds * 1000;
return Number.isFinite(delay) ? delay : null;
}
const timestamp = Date.parse(value);
return Number.isFinite(timestamp)
? Math.max(0, timestamp - Date.now())
: null;
}
function scheduleHighScoreRetry(retryAfterMs) {
const jitteredDelay = highScoreRetryDelayMs * (0.5 + Math.random());
const delay =
retryAfterMs === null ? jitteredDelay : retryAfterMs + jitteredDelay;
highScoreRetryAt = Date.now() + delay;
highScoreRetryDelayMs = Math.min(
highScoreRetryDelayMs * 2,
highScoreRetryMaxDelayMs,
);
}
function resetHighScoreRetry() {
highScoreRetryDelayMs = highScoreRetryInitialDelayMs;
highScoreRetryAt = 0;
}
async function flushHighScoreSubmission() {
if (highScoreRequestInFlight) {
return;
}
if (Date.now() < highScoreRetryAt) {
return;
}
const revision = wasm_exports.tdkpin_browser_high_score_revision();
if (revision === lastHighScoreRevision) {
return;
@@ -102,6 +144,7 @@
}
highScoreRequestInFlight = true;
let retryAfterMs = null;
try {
const response = await fetch(highScoreApi, {
method: "POST",
@@ -110,6 +153,7 @@
keepalive: true,
});
if (!response.ok) {
retryAfterMs = retryAfterDelay(response);
throw new Error(`high-score submission failed (${response.status})`);
}
const json = await response.text();
@@ -118,7 +162,9 @@
wasm_exports.tdkpin_browser_high_score_ack(revision);
lastHighScoreRevision = revision;
highScoreSubmissionWarningShown = false;
resetHighScoreRetry();
} catch (error) {
scheduleHighScoreRetry(retryAfterMs);
if (!highScoreSubmissionWarningShown) {
console.warn("shared high-score submission failed; will retry", error);
highScoreSubmissionWarningShown = true;