Comparing version 2.0.2 to 2.0.3
@@ -308,3 +308,3 @@ import react, { FC, PropsWithChildren, MutableRefObject } from 'react'; | ||
declare const hasRequestAnimationFrame: () => boolean; | ||
declare const createCacheHelper: <Data = any, T = State<Data, any>>(cache: Cache, key: string | undefined) => readonly [() => T, (info: T) => void, (key: string, callback: (current: any, prev: any) => void) => () => void]; | ||
declare const createCacheHelper: <Data = any, T = State<Data, any>>(cache: Cache, key: string | undefined) => readonly [() => T, (info: T) => void, (key: string, callback: (current: any, prev: any) => void) => () => void, () => any]; | ||
@@ -311,0 +311,0 @@ declare const mergeConfigs: (a: Partial<FullConfiguration>, b?: Partial<FullConfiguration>) => Partial<FullConfiguration<any, any, BareFetcher<unknown>>>; |
@@ -7,2 +7,3 @@ import React, { useEffect, useLayoutEffect, createContext, useContext, useMemo, useState, createElement, useRef, useCallback } from 'react'; | ||
const EMPTY_CACHE = {}; | ||
const INITIAL_CACHE = {}; | ||
const noop = ()=>{}; | ||
@@ -35,2 +36,7 @@ // Using noop() as the undefined value as undefined can be replaced | ||
const prev = cache.get(key); | ||
// Before writing to the store, we keep the value in the initial cache | ||
// if it's not there yet. | ||
if (!(key in INITIAL_CACHE)) { | ||
INITIAL_CACHE[key] = prev; | ||
} | ||
state[5](key, mergeObjects(prev, info), prev || EMPTY_CACHE); | ||
@@ -40,3 +46,12 @@ } | ||
// Subscriber | ||
state[6] | ||
state[6], | ||
// Get server cache snapshot | ||
()=>{ | ||
if (!isUndefined(key)) { | ||
// If the cache was updated on the client, we return the stored initial value. | ||
if (key in INITIAL_CACHE) return INITIAL_CACHE[key]; | ||
} | ||
// If we haven't done any client-side updates, we return the current value. | ||
return cache.get(key) || EMPTY_CACHE; | ||
} | ||
]; | ||
@@ -389,3 +404,3 @@ }; | ||
for(let i = subs.length; i--;){ | ||
subs[i](prev, value); | ||
subs[i](value, prev); | ||
} | ||
@@ -392,0 +407,0 @@ } |
@@ -13,2 +13,3 @@ Object.defineProperty(exports, '__esModule', { value: true }); | ||
const EMPTY_CACHE = {}; | ||
const INITIAL_CACHE = {}; | ||
const noop = ()=>{}; | ||
@@ -41,2 +42,7 @@ // Using noop() as the undefined value as undefined can be replaced | ||
const prev = cache.get(key); | ||
// Before writing to the store, we keep the value in the initial cache | ||
// if it's not there yet. | ||
if (!(key in INITIAL_CACHE)) { | ||
INITIAL_CACHE[key] = prev; | ||
} | ||
state[5](key, mergeObjects(prev, info), prev || EMPTY_CACHE); | ||
@@ -46,3 +52,12 @@ } | ||
// Subscriber | ||
state[6] | ||
state[6], | ||
// Get server cache snapshot | ||
()=>{ | ||
if (!isUndefined(key)) { | ||
// If the cache was updated on the client, we return the stored initial value. | ||
if (key in INITIAL_CACHE) return INITIAL_CACHE[key]; | ||
} | ||
// If we haven't done any client-side updates, we return the current value. | ||
return cache.get(key) || EMPTY_CACHE; | ||
} | ||
]; | ||
@@ -395,3 +410,3 @@ }; | ||
for(let i = subs.length; i--;){ | ||
subs[i](prev, value); | ||
subs[i](value, prev); | ||
} | ||
@@ -398,0 +413,0 @@ } |
@@ -10,3 +10,3 @@ import { useRef, useMemo, useCallback, useDebugValue } from 'react'; | ||
const useSWRHandler = (_key, fetcher, config)=>{ | ||
const { cache , compare , suspense , fallbackData , revalidateOnMount , refreshInterval , refreshWhenHidden , refreshWhenOffline , keepPreviousData } = config; | ||
const { cache , compare , suspense , fallbackData , revalidateOnMount , revalidateIfStale , refreshInterval , refreshWhenHidden , refreshWhenOffline , keepPreviousData } = config; | ||
const [EVENT_REVALIDATORS, MUTATION, FETCH] = SWRGlobalState.get(cache); | ||
@@ -30,5 +30,4 @@ // `key` is the identifier of the SWR `data` state, `keyInfo` holds extra | ||
const isActive = ()=>getConfig().isVisible() && getConfig().isOnline(); | ||
const [getCache, setCache, subscribeCache] = createCacheHelper(cache, key); | ||
const [getCache, setCache, subscribeCache, getInitialCache] = createCacheHelper(cache, key); | ||
const stateDependencies = useRef({}).current; | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
const fallback = isUndefined(fallbackData) ? config.fallback[key] : fallbackData; | ||
@@ -39,8 +38,14 @@ const isEqual = (prev, current)=>{ | ||
const t = _; | ||
if (!compare(current[t], prev[t])) { | ||
if (t === 'data' && isUndefined(prev[t])) { | ||
if (!compare(current[t], returnedData)) { | ||
if (t === 'data') { | ||
if (!compare(current[t], prev[t])) { | ||
if (isUndefined(prev[t])) { | ||
if (!compare(current[t], returnedData)) { | ||
equal = false; | ||
} | ||
} else { | ||
equal = false; | ||
} | ||
} else { | ||
} | ||
} else { | ||
if (current[t] !== prev[t]) { | ||
equal = false; | ||
@@ -61,6 +66,7 @@ } | ||
if (suspense) return false; | ||
if (!isUndefined(revalidateIfStale)) return revalidateIfStale; | ||
return true; | ||
})(); | ||
const getSelectedCache = ()=>{ | ||
const state = getCache(); | ||
// Get the cache and merge it with expected states. | ||
const getSelectedCache = (state)=>{ | ||
// We only select the needed fields from the state. | ||
@@ -78,7 +84,14 @@ const snapshot = mergeObjects(state); | ||
}; | ||
let memorizedSnapshot = getSelectedCache(); | ||
return ()=>{ | ||
const snapshot = getSelectedCache(); | ||
return isEqual(snapshot, memorizedSnapshot) ? memorizedSnapshot : memorizedSnapshot = snapshot; | ||
}; | ||
// To make sure that we are returning the same object reference to avoid | ||
// unnecessary re-renders, we keep the previous snapshot and use deep | ||
// comparison to check if we need to return a new one. | ||
let memorizedSnapshot = getSelectedCache(getCache()); | ||
const memorizedInitialSnapshot = getSelectedCache(getInitialCache()); | ||
return [ | ||
()=>{ | ||
const newSnapshot = getSelectedCache(getCache()); | ||
return isEqual(newSnapshot, memorizedSnapshot) ? memorizedSnapshot : memorizedSnapshot = newSnapshot; | ||
}, | ||
()=>memorizedInitialSnapshot | ||
]; | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
@@ -90,3 +103,3 @@ }, [ | ||
// Get the current state that SWR should return. | ||
const cached = useSyncExternalStore(useCallback((callback)=>subscribeCache(key, (prev, current)=>{ | ||
const cached = useSyncExternalStore(useCallback((callback)=>subscribeCache(key, (current, prev)=>{ | ||
if (!isEqual(prev, current)) callback(); | ||
@@ -97,3 +110,3 @@ }), // eslint-disable-next-line react-hooks/exhaustive-deps | ||
key | ||
]), getSnapshot, getSnapshot); | ||
]), getSnapshot[0], getSnapshot[1]); | ||
const isInitialMount = !initialMountedRef.current; | ||
@@ -120,6 +133,6 @@ const hasRevalidator = EVENT_REVALIDATORS[key] && EVENT_REVALIDATORS[key].length > 0; | ||
// If data exists, only revalidate if `revalidateIfStale` is true. | ||
if (suspense) return isUndefined(data) ? false : config.revalidateIfStale; | ||
if (suspense) return isUndefined(data) ? false : revalidateIfStale; | ||
// If there is no stale data, we need to revalidate when mount; | ||
// If `revalidateIfStale` is set to true, we will always revalidate. | ||
return isUndefined(data) || config.revalidateIfStale; | ||
return isUndefined(data) || revalidateIfStale; | ||
})(); | ||
@@ -126,0 +139,0 @@ // Resolve the default validating state: |
@@ -11,3 +11,3 @@ Object.defineProperty(exports, '__esModule', { value: true }); | ||
const useSWRHandler = (_key, fetcher, config)=>{ | ||
const { cache , compare , suspense , fallbackData , revalidateOnMount , refreshInterval , refreshWhenHidden , refreshWhenOffline , keepPreviousData } = config; | ||
const { cache , compare , suspense , fallbackData , revalidateOnMount , revalidateIfStale , refreshInterval , refreshWhenHidden , refreshWhenOffline , keepPreviousData } = config; | ||
const [EVENT_REVALIDATORS, MUTATION, FETCH] = _internal.SWRGlobalState.get(cache); | ||
@@ -31,5 +31,4 @@ // `key` is the identifier of the SWR `data` state, `keyInfo` holds extra | ||
const isActive = ()=>getConfig().isVisible() && getConfig().isOnline(); | ||
const [getCache, setCache, subscribeCache] = _internal.createCacheHelper(cache, key); | ||
const [getCache, setCache, subscribeCache, getInitialCache] = _internal.createCacheHelper(cache, key); | ||
const stateDependencies = react.useRef({}).current; | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
const fallback = _internal.isUndefined(fallbackData) ? config.fallback[key] : fallbackData; | ||
@@ -40,8 +39,14 @@ const isEqual = (prev, current)=>{ | ||
const t = _; | ||
if (!compare(current[t], prev[t])) { | ||
if (t === 'data' && _internal.isUndefined(prev[t])) { | ||
if (!compare(current[t], returnedData)) { | ||
if (t === 'data') { | ||
if (!compare(current[t], prev[t])) { | ||
if (_internal.isUndefined(prev[t])) { | ||
if (!compare(current[t], returnedData)) { | ||
equal = false; | ||
} | ||
} else { | ||
equal = false; | ||
} | ||
} else { | ||
} | ||
} else { | ||
if (current[t] !== prev[t]) { | ||
equal = false; | ||
@@ -62,6 +67,7 @@ } | ||
if (suspense) return false; | ||
if (!_internal.isUndefined(revalidateIfStale)) return revalidateIfStale; | ||
return true; | ||
})(); | ||
const getSelectedCache = ()=>{ | ||
const state = getCache(); | ||
// Get the cache and merge it with expected states. | ||
const getSelectedCache = (state)=>{ | ||
// We only select the needed fields from the state. | ||
@@ -79,7 +85,14 @@ const snapshot = _internal.mergeObjects(state); | ||
}; | ||
let memorizedSnapshot = getSelectedCache(); | ||
return ()=>{ | ||
const snapshot = getSelectedCache(); | ||
return isEqual(snapshot, memorizedSnapshot) ? memorizedSnapshot : memorizedSnapshot = snapshot; | ||
}; | ||
// To make sure that we are returning the same object reference to avoid | ||
// unnecessary re-renders, we keep the previous snapshot and use deep | ||
// comparison to check if we need to return a new one. | ||
let memorizedSnapshot = getSelectedCache(getCache()); | ||
const memorizedInitialSnapshot = getSelectedCache(getInitialCache()); | ||
return [ | ||
()=>{ | ||
const newSnapshot = getSelectedCache(getCache()); | ||
return isEqual(newSnapshot, memorizedSnapshot) ? memorizedSnapshot : memorizedSnapshot = newSnapshot; | ||
}, | ||
()=>memorizedInitialSnapshot | ||
]; | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
@@ -91,3 +104,3 @@ }, [ | ||
// Get the current state that SWR should return. | ||
const cached = index_js.useSyncExternalStore(react.useCallback((callback)=>subscribeCache(key, (prev, current)=>{ | ||
const cached = index_js.useSyncExternalStore(react.useCallback((callback)=>subscribeCache(key, (current, prev)=>{ | ||
if (!isEqual(prev, current)) callback(); | ||
@@ -98,3 +111,3 @@ }), // eslint-disable-next-line react-hooks/exhaustive-deps | ||
key | ||
]), getSnapshot, getSnapshot); | ||
]), getSnapshot[0], getSnapshot[1]); | ||
const isInitialMount = !initialMountedRef.current; | ||
@@ -121,6 +134,6 @@ const hasRevalidator = EVENT_REVALIDATORS[key] && EVENT_REVALIDATORS[key].length > 0; | ||
// If data exists, only revalidate if `revalidateIfStale` is true. | ||
if (suspense) return _internal.isUndefined(data) ? false : config.revalidateIfStale; | ||
if (suspense) return _internal.isUndefined(data) ? false : revalidateIfStale; | ||
// If there is no stale data, we need to revalidate when mount; | ||
// If `revalidateIfStale` is set to true, we will always revalidate. | ||
return _internal.isUndefined(data) || config.revalidateIfStale; | ||
return _internal.isUndefined(data) || revalidateIfStale; | ||
})(); | ||
@@ -127,0 +140,0 @@ // Resolve the default validating state: |
@@ -68,4 +68,5 @@ import { useRef, useCallback } from 'react'; | ||
// If the key has been changed, we keep the current page size if persistSize is enabled | ||
// Otherwise, we reset the page size to cached pageSize | ||
set({ | ||
_l: persistSize ? lastPageSizeRef.current : initialSize | ||
_l: persistSize ? lastPageSizeRef.current : resolvePageSize() | ||
}); | ||
@@ -72,0 +73,0 @@ } |
@@ -74,4 +74,5 @@ Object.defineProperty(exports, '__esModule', { value: true }); | ||
// If the key has been changed, we keep the current page size if persistSize is enabled | ||
// Otherwise, we reset the page size to cached pageSize | ||
set({ | ||
_l: persistSize ? lastPageSizeRef.current : initialSize | ||
_l: persistSize ? lastPageSizeRef.current : resolvePageSize() | ||
}); | ||
@@ -78,0 +79,0 @@ } |
{ | ||
"name": "swr", | ||
"version": "2.0.2", | ||
"version": "2.0.3", | ||
"description": "React Hooks library for remote data fetching", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
@@ -88,4 +88,4 @@ [![SWR](https://assets.vercel.com/image/upload/v1572289618/swr/banner.png)](https://swr.vercel.app) | ||
- Shu Ding ([@shuding\_](https://twitter.com/shuding_)) – [Vercel](https://vercel.com) | ||
- Guillermo Rauch ([@rauchg](https://twitter.com/rauchg)) – [Vercel](https://vercel.com) | ||
- Shu Ding ([@shuding\_](https://twitter.com/shuding_)) - [Vercel](https://vercel.com) | ||
- Guillermo Rauch ([@rauchg](https://twitter.com/rauchg)) - [Vercel](https://vercel.com) | ||
- Joe Haddad ([@timer150](https://twitter.com/timer150)) - [Vercel](https://vercel.com) | ||
@@ -92,0 +92,0 @@ - Paco Coursey ([@pacocoursey](https://twitter.com/pacocoursey)) - [Vercel](https://vercel.com) |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
229123
5152
0