From a823f8527db65dcfdffa4be3cd04fa3ab12040cc Mon Sep 17 00:00:00 2001 From: tiennm99 Date: Fri, 17 Apr 2026 09:48:13 +0700 Subject: [PATCH] fix: address ultrareview findings across backend and frontend Backend: - rate-limiter: retryAfter now in seconds; ms-precision lu preserves fractional regen residue across calls (C1, C2) - redis-client: throw on Upstash 200-with-error envelope; redisRaw returns body.result (NH1) - constants: MAX_BATCH_SIZE = MAX_CREDITS = 256 (was 512 vs 256) - worker: content-length cap, gzip + s-maxage=10 on /api/canvas, broadcast via executionCtx.waitUntil with r.ok check (NC2, H4, H5) - canvas-storage: warn on truncated Upstash read instead of silent zero-pad (NH2) - get-user-id: SHA-256 (16 hex chars) replaces 32-bit string hash; missing cf-connecting-ip routes to anon:dev with warn (H1, H2); function is now async - canvas-room: log unclean WS closes and errors; defensive close on unexpected client message (NH4, N5) Frontend: - pixel buffer capped at MAX_BATCH_SIZE with toast (NC2) - Submit error UX: toast for 429/413/400/5xx/network; honor retryAfter (NC1) - committedColors allocated upfront so WS updates during initial fetch no longer null-deref (NC3) - handleWheel always renders even when zoom is clamped (C1, C2) - canvas-decoder throws on truncated input instead of reading past end with || 0 (C3) - WS reconnect refetches canvas to recover missed pixels (C4) - pixel-buffer Map cache for O(1) getColorAt/pixelCount (NH1) - cancel in-progress stroke on mode switch (NH3) - canvas load error overlay with Retry button (NH5) - DPR-aware canvas sizing (H1) - onMount cleanup is now sync (no leaked resize listener) (H2) Tests: - update for async getUserId, decoder bounds check, redis error format; add Upstash error-envelope coverage --- src/client/App.svelte | 77 ++++++++++-- src/client/components/CanvasRenderer.svelte | 124 ++++++++++++++++---- src/durable-objects/canvas-room.js | 22 ++-- src/lib/canvas-decoder.js | 17 ++- src/lib/canvas-storage.js | 1 + src/lib/constants.js | 3 +- src/lib/get-user-id.js | 29 +++-- src/lib/pixel-buffer.js | 69 ++++++----- src/lib/rate-limiter.js | 41 +++++-- src/lib/redis-client.js | 19 ++- src/worker.js | 69 ++++++++--- test/lib/canvas-decoder.test.js | 37 +++--- test/lib/get-user-id.test.js | 33 +++--- test/lib/redis-client.test.js | 31 ++++- 14 files changed, 418 insertions(+), 154 deletions(-) diff --git a/src/client/App.svelte b/src/client/App.svelte index 496d801..66d220b 100644 --- a/src/client/App.svelte +++ b/src/client/App.svelte @@ -1,5 +1,5 @@ @@ -112,6 +153,7 @@ onZoomChange={(z) => zoom = z} onCursorMove={(pos) => cursorPos = pos} onBufferChange={(s) => bufferState = s} + onBufferFull={handleBufferFull} /> selectedColor = i} /> + + {#if toast} +
{toast.text}
+ {/if} diff --git a/src/client/components/CanvasRenderer.svelte b/src/client/components/CanvasRenderer.svelte index 78fddec..28d7eeb 100644 --- a/src/client/components/CanvasRenderer.svelte +++ b/src/client/components/CanvasRenderer.svelte @@ -1,19 +1,21 @@