TypeScript99.5%
JavaScript0.5%

Commit activity

Last 12 weeks · 13 commits

Full graph →

Community health

4 of 6 standards met

Community profile →
100
✓README✓License✓Contributing✓Code of Conduct○Issue Template○PR Template

Recent PRs & issues

Active · Last activity 4d ago
See all on GitHub →
sansynx

Bug report Description / Observed Behavior Two distinct object keys can produce the same SWR cache key when a property name contains the delimiters used by . In a local React/Jest reproduction, the first fetcher ran once, the second fetcher did not run, and both hooks displayed the first response. Expected Behavior Different object keys should have separate cache entries. Both fetchers should run, and each hook should display its own response. Repro Steps / Code Example On the current revision, render this component inside an with a fresh cache provider: The page displays . A focused Jest reproduction confirmed that the first fetcher was called once and the second was called zero times. A separate assertion that the two results differ also fails; both are . Additional Context SWR source version: , at . Environment: Windows, Node.js , React , pnpm . The collision comes from raw property names being joined with and , then used as the cache key by . Encoding property names unambiguously (for example, quoting them with or using length prefixes) would keep these shapes distinct. Regression coverage belongs in and . The existing passes on this checkout.

sansynx · 1d ago
VG31OP

Description Closes #4359. Currently, useSWRHandler's mount effect unconditionally executes: Every call to setCache triggers the cache setter, notifying all registered subscribers of that key (onStoreUpdate). In component trees where many components share a key (such as virtualized tables, grids, and lists), mounting $N$ components produces $O(N^2)$ subscriber notifications and comparison evaluations even though _k does not change after the initial mount. Solution Guard the mount-effect write to check whether the cached _k already matches the current serialized key: If _k is missing (first mount or cleared cache), it writes normally. If multiple components mount on an already-cached key, redundant writes and subscriber wakes are eliminated (dropping mount overhead from $O(N^2)$ to $O(1)$). If the key changes or _k differs, it updates appropriately. Verification Added unit test in est/use-swr-cache.test.tsx verifying that mounting multiple hooks sharing a key only writes _k once on initial mount instead of waking subscribers on every mount. Verified linting (oxlint), formatting (oxfmt), and types ( sc --noEmit). All 21 cache unit tests passed.

VG31OP · 1d ago
RaphaelFakhri

Description deletes every cache entry, including the original key () that the mount effect writes for each mounted hook. When a mounted hook revalidates afterwards, it writes its state back without , and the mount effect does not run again because the key is unchanged. The global passes to key filters, so after a filter receives for every mounted key. silently skips the hook, and a filter such as throws a . This also happens after once a hook revalidates later, for example on focus. Changes When a request starts and the cache entry has no , the revalidation writes the original key together with the initial state. still leaves the cache empty until a hook revalidates. Tests Two tests in : A key filter matches a mounted hook after . A key filter matches a mounted hook that revalidates after . Both fail on and pass with this change. , , , and pass. Fixes #4367

RaphaelFakhri · 1d ago
vaibhavmashal

Summary In #4208, \immutable\ middleware was updated to set \config.refreshInterval = 0\ to prevent inheriting global \SWRConfig\ \ efreshInterval\. However, because this was unconditionally executed inside the middleware, it ignored explicit hook-level \ efreshInterval\ options passed directly to \useSWRImmutable\ (e.g. \useSWRImmutable(key, fetcher, { refreshInterval: 100 })\). Changes Removed unconditional \config.refreshInterval = 0\ from the \immutable\ middleware in \src/immutable/index.ts\. Defined \useSWRImmutable\ with default \ efreshInterval: 0\ in \hookConfig\ (\{ refreshInterval: 0, ...config, use: (config.use []).concat(immutable) }\) so that global config polling is ignored while explicit hook options are preserved. Added a unit test in \ est/use-swr-immutable.test.tsx\ verifying hook-level \ efreshInterval\ revalidations. Closes #4322

vaibhavmashal · 1d ago
vaibhavmashal

Problem: When using \mutate\ with both \optimisticData\ and an async data function that return structurally identical data (but different array references), SWR populates the cache with the new reference. Even though \useSWR\ evaluates that the snapshots are deeply equal and initially returns the old \memorizedSnapshot\ object, it updates the snapshot's \data\ field to the new cache reference via \memorizedSnapshot.data = newSnapshot.data\. This breaks referential equality of the returned \data\, causing React child components (like \React.memo\ lists) to unnecessarily re-render the whole array, despite the content remaining exactly the same. Solution: In \src/index/use-swr.ts\, when \compareResult\ is evaluated as true (indicating structural equality), we conditionally preserve \memorizedSnapshot.data\ if it wasn't a tracked field that we should ignore. If they are structurally identical, we skip assigning the new data reference to \memorizedSnapshot.data\, thereby preserving referential equality. This ensures that mutations won't inadvertently break object references in the active hook instances. Changes Made: \src/index/use-swr.ts\: Updated the snapshot assignment inside \if (compareResult)\ to only update \memorizedSnapshot.data\ if \stateDependencies.data\ is false. \ est/test-issue-4180.test.tsx\: Added a test specifically reproducing the \mutate\ sequence on \useSWRInfinite\ to assert that the \data\ array reference does not change when the asynchronously fetched payload is structurally identical to the optimistic payload. Testing: Checked out the issue #4180 reproduction using \useSWRInfinite\ with an array payload in the new Jest test (\ est-issue-4180.test.tsx\). Verified that without the fix, the \data\ reference changed when the mutate promise resolved. Verified that with the fix, the \data\ array reference remains stable and the component only re-renders twice instead of three times for identical data. Ran all tests with \pnpm test\ to ensure no side effects on existing revalidation or subscription logic. Fixes #4180

vaibhavmashal · 1d ago
pengshenghai

Summary currently points at , but the published package contains instead. This updates the export target to match the emitted file name used in the package tarball. Reproduction Before this change, the react-server condition resolves to the missing file: The tarball contains: Validation Locally patched and verified the same resolution now points at the existing file: No package scripts were run for this check.

pengshenghai · 3d ago
Structured data for AI agents

Repository: vercel/swr. Description: React Hooks for Data Fetching Stars: 32496, Forks: 1401. Primary language: TypeScript. Languages: TypeScript (99.5%), JavaScript (0.5%). License: MIT. Homepage: https://swr.vercel.app Topics: cache, data, data-fetching, fetch, hook, hooks, nextjs, react, react-native, stale-while-revalidate, suspense, swr, vercel. Latest release: v2.5.1 (2mo ago). Open PRs: 89, open issues: 152. Last activity: 4d ago. Community health: 100%. Top contributors: shuding, huozhi, promer94, koba04, vercel-release-bot, dependabot[bot], sergiodxa, cryptiklemur, matamatanot, anothertempore and others.