Skip to content

feat/skeletons-async-interval-hooks-request-dedup - #402

Merged
DeFiVC merged 1 commit into
ChainLearnOfficial:mainfrom
CeceOs92:feat/skeletons-async-interval-hooks-request-dedup
Aug 31, 2026
Merged

feat/skeletons-async-interval-hooks-request-dedup#402
DeFiVC merged 1 commit into
ChainLearnOfficial:mainfrom
CeceOs92:feat/skeletons-async-interval-hooks-request-dedup

Conversation

@CeceOs92

Copy link
Copy Markdown
Contributor

What

Implements four issues in one pass — a UI polish item, two reusable hooks, and an API-client improvement.

#282 — loading-skeleton improvements

  • tailwind.config.ts: new shimmer keyframes + animate-shimmer utility (1.6s ease-in-out).
  • components/ui/skeleton.tsx: base Skeleton gains an animation prop ("shimmer" default | "pulse" | "none") rendering a moving-gradient sheen; motion-reduce falls back to a static fill; dark-mode tokens added; every block now carries data-slot="skeleton".
  • components/shared/loading-skeleton.tsx: new content-shaped variants CourseGridSkeleton, TableSkeleton (header + configurable rows/columns), FormSkeleton (label/input pairs + submit), ProfileSkeleton (avatar + detail grid). All skeleton roots expose role="status" / aria-busy with an sr-only label. Existing variants preserved.
  • Wired into app/courses/loading.tsx and new app/settings/loading.tsx for cross-page consistency.

#292 — use-async.ts hook

src/lib/hooks/use-async.tsuseAsync(fn, options) returning { execute, cancel, retry, reset, loading, error, data }. The async fn receives an AbortSignal followed by the execute args. Each execute cancels the previous call, the hook aborts on unmount, and aborted results never reach state. Built-in error capture, exponential-backoff retries, immediate, and onSuccess / onError callbacks.

#293 — use-interval.ts hook

src/lib/hooks/use-interval.tsuseInterval(callback, delay, options). delay = null pauses (and resumes on a number again), the latest callback is always invoked (ref, no stale closures), the interval clears on unmount and on delay change, plus an immediate option and overlap-guarding for async callbacks.

#298 — api/client.ts request deduplication

src/lib/api/client.ts — in-flight GETs are tracked by URL (+ JWT); concurrent callers for the same resource share one request/promise (and its retries) instead of each firing their own. Tracking is cleaned up on settle and on any mutation's cache invalidation. The shared request is owned by an internal AbortController that is aborted only once every caller has detached, so one component unmounting rejects just its own promise (via a withAbort wrapper) without cancelling the request others are still awaiting. bypassCache reads are never shared.

Tests

  • New: use-async.test.tsx, use-interval.test.tsx, request-deduplication cases in client.test.ts, new-variant coverage in loading-skeleton.test.tsx.
  • Updated skeleton.test.tsx / loading-skeleton.test.tsx to assert the shimmer default and query by data-slot="skeleton".
  • Targeted suites: 39 passing. tsc --noEmit introduces no new errors; ESLint clean on changed files.

Notes

  • Pre-existing unrelated suite failures (layout/header, sidebar, claim-button, etc.) stem from a floated vitest v4 on a clean npm install and are unchanged by this PR — verified against a stashed baseline.

Closes #282
Closes #292
Closes #293
Closes #298

@drips-wave

drips-wave Bot commented Aug 31, 2026

Copy link
Copy Markdown

@CeceOs92 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@netlify

netlify Bot commented Aug 31, 2026

Copy link
Copy Markdown

Deploy Preview for chainlearn failed.

Name Link
🔨 Latest commit 0117fbe
🔍 Latest deploy log https://app.netlify.com/projects/chainlearn/deploys/6a952f2b8bf4c30008d2f558

@DeFiVC
DeFiVC merged commit a055410 into ChainLearnOfficial:main Aug 31, 2026
0 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

. Add api/client.ts request deduplication . Add use-interval.ts hook . Add use-async.ts hook . Add loading-skeleton.tsx improvements

2 participants