Update test framework: fix run_tests.py to support all test files, add auto-import-check for test files

This commit is contained in:
qiaoxinjiu
2026-05-09 15:11:30 +08:00
parent eb053a347f
commit eaba8328da
21739 changed files with 2236758 additions and 719 deletions

View File

@@ -0,0 +1,569 @@
'use client';
import React, { useEffect, useLayoutEffect, createContext, useContext, useMemo, useRef, createElement } from 'react';
import * as revalidateEvents from './events.mjs';
import { dequal } from 'dequal/lite';
// Global state used to deduplicate requests and store listeners
const SWRGlobalState = new WeakMap();
// Shared state between server components and client components
const noop = ()=>{};
// Using noop() as the undefined value as undefined can be replaced
// by something else. Prettier ignore and extra parentheses are necessary here
// to ensure that tsc doesn't remove the __NOINLINE__ comment.
// prettier-ignore
const UNDEFINED = /*#__NOINLINE__*/ noop();
const OBJECT = Object;
const isUndefined = (v)=>v === UNDEFINED;
const isFunction = (v)=>typeof v == 'function';
const mergeObjects = (a, b)=>({
...a,
...b
});
const isPromiseLike = (x)=>isFunction(x.then);
const EMPTY_CACHE = {};
const INITIAL_CACHE = {};
const STR_UNDEFINED = 'undefined';
// NOTE: Use the function to guarantee it's re-evaluated between jsdom and node runtime for tests.
const isWindowDefined = typeof window != STR_UNDEFINED;
const isDocumentDefined = typeof document != STR_UNDEFINED;
const isLegacyDeno = isWindowDefined && 'Deno' in window;
const hasRequestAnimationFrame = ()=>isWindowDefined && typeof window['requestAnimationFrame'] != STR_UNDEFINED;
const createCacheHelper = (cache, key)=>{
const state = SWRGlobalState.get(cache);
return [
// Getter
()=>!isUndefined(key) && cache.get(key) || EMPTY_CACHE,
// Setter
(info)=>{
if (!isUndefined(key)) {
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);
}
},
// Subscriber
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 !isUndefined(key) && cache.get(key) || EMPTY_CACHE;
}
];
} // export { UNDEFINED, OBJECT, isUndefined, isFunction, mergeObjects, isPromiseLike }
;
/**
* Due to the bug https://bugs.chromium.org/p/chromium/issues/detail?id=678075,
* it's not reliable to detect if the browser is currently online or offline
* based on `navigator.onLine`.
* As a workaround, we always assume it's online on the first load, and change
* the status upon `online` or `offline` events.
*/ let online = true;
const isOnline = ()=>online;
// For node and React Native, `add/removeEventListener` doesn't exist on window.
const [onWindowEvent, offWindowEvent] = isWindowDefined && window.addEventListener ? [
window.addEventListener.bind(window),
window.removeEventListener.bind(window)
] : [
noop,
noop
];
const isVisible = ()=>{
const visibilityState = isDocumentDefined && document.visibilityState;
return isUndefined(visibilityState) || visibilityState !== 'hidden';
};
const initFocus = (callback)=>{
// focus revalidate
if (isDocumentDefined) {
document.addEventListener('visibilitychange', callback);
}
onWindowEvent('focus', callback);
return ()=>{
if (isDocumentDefined) {
document.removeEventListener('visibilitychange', callback);
}
offWindowEvent('focus', callback);
};
};
const initReconnect = (callback)=>{
// revalidate on reconnected
const onOnline = ()=>{
online = true;
callback();
};
// nothing to revalidate, just update the status
const onOffline = ()=>{
online = false;
};
onWindowEvent('online', onOnline);
onWindowEvent('offline', onOffline);
return ()=>{
offWindowEvent('online', onOnline);
offWindowEvent('offline', onOffline);
};
};
const preset = {
isOnline,
isVisible
};
const defaultConfigOptions = {
initFocus,
initReconnect
};
const IS_REACT_LEGACY = !React.useId;
const IS_SERVER = !isWindowDefined || isLegacyDeno;
// Polyfill requestAnimationFrame
const rAF = (f)=>hasRequestAnimationFrame() ? window['requestAnimationFrame'](f) : setTimeout(f, 1);
// React currently throws a warning when using useLayoutEffect on the server.
// To get around it, we can conditionally useEffect on the server (no-op) and
// useLayoutEffect in the browser.
const useIsomorphicLayoutEffect = IS_SERVER ? useEffect : useLayoutEffect;
// This assignment is to extend the Navigator type to use effectiveType.
const navigatorConnection = typeof navigator !== 'undefined' && navigator.connection;
// Adjust the config based on slow connection status (<= 70Kbps).
const slowConnection = !IS_SERVER && navigatorConnection && ([
'slow-2g',
'2g'
].includes(navigatorConnection.effectiveType) || navigatorConnection.saveData);
// use WeakMap to store the object->key mapping
// so the objects can be garbage collected.
// WeakMap uses a hashtable under the hood, so the lookup
// complexity is almost O(1).
const table = new WeakMap();
const getTypeName = (value)=>OBJECT.prototype.toString.call(value);
const isObjectTypeName = (typeName, type)=>typeName === `[object ${type}]`;
// counter of the key
let counter = 0;
// A stable hash implementation that supports:
// - Fast and ensures unique hash properties
// - Handles unserializable values
// - Handles object key ordering
// - Generates short results
//
// This is not a serialization function, and the result is not guaranteed to be
// parsable.
const stableHash = (arg)=>{
const type = typeof arg;
const typeName = getTypeName(arg);
const isDate = isObjectTypeName(typeName, 'Date');
const isRegex = isObjectTypeName(typeName, 'RegExp');
const isPlainObject = isObjectTypeName(typeName, 'Object');
let result;
let index;
if (OBJECT(arg) === arg && !isDate && !isRegex) {
// Object/function, not null/date/regexp. Use WeakMap to store the id first.
// If it's already hashed, directly return the result.
result = table.get(arg);
if (result) return result;
// Store the hash first for circular reference detection before entering the
// recursive `stableHash` calls.
// For other objects like set and map, we use this id directly as the hash.
result = ++counter + '~';
table.set(arg, result);
if (Array.isArray(arg)) {
// Array.
result = '@';
for(index = 0; index < arg.length; index++){
result += stableHash(arg[index]) + ',';
}
table.set(arg, result);
}
if (isPlainObject) {
// Object, sort keys.
result = '#';
const keys = OBJECT.keys(arg).sort();
while(!isUndefined(index = keys.pop())){
if (!isUndefined(arg[index])) {
result += index + ':' + stableHash(arg[index]) + ',';
}
}
table.set(arg, result);
}
} else {
result = isDate ? arg.toJSON() : type == 'symbol' ? arg.toString() : type == 'string' ? JSON.stringify(arg) : '' + arg;
}
return result;
};
const serialize = (key)=>{
if (isFunction(key)) {
try {
key = key();
} catch (err) {
// dependencies not ready
key = '';
}
}
// Use the original key as the argument of fetcher. This can be a string or an
// array of values.
const args = key;
// If key is not falsy, or not an empty array, hash it.
key = typeof key == 'string' ? key : (Array.isArray(key) ? key.length : key) ? stableHash(key) : '';
return [
key,
args
];
};
// Global timestamp.
let __timestamp = 0;
const getTimestamp = ()=>++__timestamp;
async function internalMutate(...args) {
const [cache, _key, _data, _opts] = args;
// When passing as a boolean, it's explicitly used to disable/enable
// revalidation.
const options = mergeObjects({
populateCache: true,
throwOnError: true
}, typeof _opts === 'boolean' ? {
revalidate: _opts
} : _opts || {});
let populateCache = options.populateCache;
const rollbackOnErrorOption = options.rollbackOnError;
let optimisticData = options.optimisticData;
const rollbackOnError = (error)=>{
return typeof rollbackOnErrorOption === 'function' ? rollbackOnErrorOption(error) : rollbackOnErrorOption !== false;
};
const throwOnError = options.throwOnError;
// If the second argument is a key filter, return the mutation results for all
// filtered keys.
if (isFunction(_key)) {
const keyFilter = _key;
const matchedKeys = [];
const it = cache.keys();
for (const key of it){
if (// Skip the special useSWRInfinite and useSWRSubscription keys.
!/^\$(inf|sub)\$/.test(key) && keyFilter(cache.get(key)._k)) {
matchedKeys.push(key);
}
}
return Promise.all(matchedKeys.map(mutateByKey));
}
return mutateByKey(_key);
async function mutateByKey(_k) {
// Serialize key
const [key] = serialize(_k);
if (!key) return;
const [get, set] = createCacheHelper(cache, key);
const [EVENT_REVALIDATORS, MUTATION, FETCH, PRELOAD] = SWRGlobalState.get(cache);
const startRevalidate = ()=>{
const revalidators = EVENT_REVALIDATORS[key];
const revalidate = isFunction(options.revalidate) ? options.revalidate(get().data, _k) : options.revalidate !== false;
if (revalidate) {
// Invalidate the key by deleting the concurrent request markers so new
// requests will not be deduped.
delete FETCH[key];
delete PRELOAD[key];
if (revalidators && revalidators[0]) {
return revalidators[0](revalidateEvents.MUTATE_EVENT).then(()=>get().data);
}
}
return get().data;
};
// If there is no new data provided, revalidate the key with current state.
if (args.length < 3) {
// Revalidate and broadcast state.
return startRevalidate();
}
let data = _data;
let error;
let isError = false;
// Update global timestamps.
const beforeMutationTs = getTimestamp();
MUTATION[key] = [
beforeMutationTs,
0
];
const hasOptimisticData = !isUndefined(optimisticData);
const state = get();
// `displayedData` is the current value on screen. It could be the optimistic value
// that is going to be overridden by a `committedData`, or get reverted back.
// `committedData` is the validated value that comes from a fetch or mutation.
const displayedData = state.data;
const currentData = state._c;
const committedData = isUndefined(currentData) ? displayedData : currentData;
// Do optimistic data update.
if (hasOptimisticData) {
optimisticData = isFunction(optimisticData) ? optimisticData(committedData, displayedData) : optimisticData;
// When we set optimistic data, backup the current committedData data in `_c`.
set({
data: optimisticData,
_c: committedData
});
}
if (isFunction(data)) {
// `data` is a function, call it passing current cache value.
try {
data = data(committedData);
} catch (err) {
// If it throws an error synchronously, we shouldn't update the cache.
error = err;
isError = true;
}
}
// `data` is a promise/thenable, resolve the final data first.
if (data && isPromiseLike(data)) {
// This means that the mutation is async, we need to check timestamps to
// avoid race conditions.
data = await data.catch((err)=>{
error = err;
isError = true;
});
// Check if other mutations have occurred since we've started this mutation.
// If there's a race we don't update cache or broadcast the change,
// just return the data.
if (beforeMutationTs !== MUTATION[key][0]) {
if (isError) throw error;
return data;
} else if (isError && hasOptimisticData && rollbackOnError(error)) {
// Rollback. Always populate the cache in this case but without
// transforming the data.
populateCache = true;
// Reset data to be the latest committed data, and clear the `_c` value.
set({
data: committedData,
_c: UNDEFINED
});
}
}
// If we should write back the cache after request.
if (populateCache) {
if (!isError) {
// Transform the result into data.
if (isFunction(populateCache)) {
const populateCachedData = populateCache(data, committedData);
set({
data: populateCachedData,
error: UNDEFINED,
_c: UNDEFINED
});
} else {
// Only update cached data and reset the error if there's no error. Data can be `undefined` here.
set({
data,
error: UNDEFINED,
_c: UNDEFINED
});
}
}
}
// Reset the timestamp to mark the mutation has ended.
MUTATION[key][1] = getTimestamp();
// Update existing SWR Hooks' internal states:
Promise.resolve(startRevalidate()).then(()=>{
// The mutation and revalidation are ended, we can clear it since the data is
// not an optimistic value anymore.
set({
_c: UNDEFINED
});
});
// Throw error or return data
if (isError) {
if (throwOnError) throw error;
return;
}
return data;
}
}
const revalidateAllKeys = (revalidators, type)=>{
for(const key in revalidators){
if (revalidators[key][0]) revalidators[key][0](type);
}
};
const initCache = (provider, options)=>{
// The global state for a specific provider will be used to deduplicate
// requests and store listeners. As well as a mutate function that is bound to
// the cache.
// The provider's global state might be already initialized. Let's try to get the
// global state associated with the provider first.
if (!SWRGlobalState.has(provider)) {
const opts = mergeObjects(defaultConfigOptions, options);
// If there's no global state bound to the provider, create a new one with the
// new mutate function.
const EVENT_REVALIDATORS = Object.create(null);
const mutate = internalMutate.bind(UNDEFINED, provider);
let unmount = noop;
const subscriptions = Object.create(null);
const subscribe = (key, callback)=>{
const subs = subscriptions[key] || [];
subscriptions[key] = subs;
subs.push(callback);
return ()=>subs.splice(subs.indexOf(callback), 1);
};
const setter = (key, value, prev)=>{
provider.set(key, value);
const subs = subscriptions[key];
if (subs) {
for (const fn of subs){
fn(value, prev);
}
}
};
const initProvider = ()=>{
if (!SWRGlobalState.has(provider)) {
// Update the state if it's new, or if the provider has been extended.
SWRGlobalState.set(provider, [
EVENT_REVALIDATORS,
Object.create(null),
Object.create(null),
Object.create(null),
mutate,
setter,
subscribe
]);
if (!IS_SERVER) {
// When listening to the native events for auto revalidations,
// we intentionally put a delay (setTimeout) here to make sure they are
// fired after immediate JavaScript executions, which can be
// React's state updates.
// This avoids some unnecessary revalidations such as
// https://github.com/vercel/swr/issues/1680.
const releaseFocus = opts.initFocus(setTimeout.bind(UNDEFINED, revalidateAllKeys.bind(UNDEFINED, EVENT_REVALIDATORS, revalidateEvents.FOCUS_EVENT)));
const releaseReconnect = opts.initReconnect(setTimeout.bind(UNDEFINED, revalidateAllKeys.bind(UNDEFINED, EVENT_REVALIDATORS, revalidateEvents.RECONNECT_EVENT)));
unmount = ()=>{
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
releaseFocus && releaseFocus();
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
releaseReconnect && releaseReconnect();
// When un-mounting, we need to remove the cache provider from the state
// storage too because it's a side-effect. Otherwise, when re-mounting we
// will not re-register those event listeners.
SWRGlobalState.delete(provider);
};
}
}
};
initProvider();
// This is a new provider, we need to initialize it and setup DOM events
// listeners for `focus` and `reconnect` actions.
// We might want to inject an extra layer on top of `provider` in the future,
// such as key serialization, auto GC, etc.
// For now, it's just a `Map` interface without any modifications.
return [
provider,
mutate,
initProvider,
unmount
];
}
return [
provider,
SWRGlobalState.get(provider)[4]
];
};
// error retry
const onErrorRetry = (_, __, config, revalidate, opts)=>{
const maxRetryCount = config.errorRetryCount;
const currentRetryCount = opts.retryCount;
// Exponential backoff
const timeout = ~~((Math.random() + 0.5) * (1 << (currentRetryCount < 8 ? currentRetryCount : 8))) * config.errorRetryInterval;
if (!isUndefined(maxRetryCount) && currentRetryCount > maxRetryCount) {
return;
}
setTimeout(revalidate, timeout, opts);
};
const compare = dequal;
// Default cache provider
const [cache, mutate] = initCache(new Map());
// Default config
const defaultConfig = mergeObjects({
// events
onLoadingSlow: noop,
onSuccess: noop,
onError: noop,
onErrorRetry,
onDiscarded: noop,
// switches
revalidateOnFocus: true,
revalidateOnReconnect: true,
revalidateIfStale: true,
shouldRetryOnError: true,
// timeouts
errorRetryInterval: slowConnection ? 10000 : 5000,
focusThrottleInterval: 5 * 1000,
dedupingInterval: 2 * 1000,
loadingTimeout: slowConnection ? 5000 : 3000,
// providers
compare,
isPaused: ()=>false,
cache,
mutate,
fallback: {}
}, // use web preset by default
preset);
const mergeConfigs = (a, b)=>{
// Need to create a new object to avoid mutating the original here.
const v = mergeObjects(a, b);
// If two configs are provided, merge their `use` and `fallback` options.
if (b) {
const { use: u1, fallback: f1 } = a;
const { use: u2, fallback: f2 } = b;
if (u1 && u2) {
v.use = u1.concat(u2);
}
if (f1 && f2) {
v.fallback = mergeObjects(f1, f2);
}
}
return v;
};
const SWRConfigContext = createContext({});
const SWRConfig = (props)=>{
const { value } = props;
const parentConfig = useContext(SWRConfigContext);
const isFunctionalConfig = isFunction(value);
const config = useMemo(()=>isFunctionalConfig ? value(parentConfig) : value, [
isFunctionalConfig,
parentConfig,
value
]);
// Extend parent context values and middleware.
const extendedConfig = useMemo(()=>isFunctionalConfig ? config : mergeConfigs(parentConfig, config), [
isFunctionalConfig,
parentConfig,
config
]);
// Should not use the inherited provider.
const provider = config && config.provider;
// initialize the cache only on first access.
const cacheContextRef = useRef(UNDEFINED);
if (provider && !cacheContextRef.current) {
cacheContextRef.current = initCache(provider(extendedConfig.cache || cache), config);
}
const cacheContext = cacheContextRef.current;
// Override the cache if a new provider is given.
if (cacheContext) {
extendedConfig.cache = cacheContext[0];
extendedConfig.mutate = cacheContext[1];
}
// Unsubscribe events.
useIsomorphicLayoutEffect(()=>{
if (cacheContext) {
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
cacheContext[2] && cacheContext[2]();
return cacheContext[3];
}
}, []);
return createElement(SWRConfigContext.Provider, mergeObjects(props, {
value: extendedConfig
}));
};
export { noop as A, isPromiseLike as B, IS_SERVER as I, OBJECT as O, SWRConfigContext as S, UNDEFINED as U, isFunction as a, SWRGlobalState as b, cache as c, defaultConfig as d, isUndefined as e, mergeConfigs as f, SWRConfig as g, initCache as h, isWindowDefined as i, mutate as j, compare as k, stableHash as l, mergeObjects as m, internalMutate as n, getTimestamp as o, preset as p, defaultConfigOptions as q, IS_REACT_LEGACY as r, serialize as s, rAF as t, useIsomorphicLayoutEffect as u, slowConnection as v, isDocumentDefined as w, isLegacyDeno as x, hasRequestAnimationFrame as y, createCacheHelper as z };

View File

@@ -0,0 +1,623 @@
'use client';
var React = require('react');
var revalidateEvents = require('./events.js');
var lite = require('dequal/lite');
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
function _interopNamespace(e) {
if (e && e.__esModule) return e;
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return n;
}
var React__default = /*#__PURE__*/_interopDefault(React);
var revalidateEvents__namespace = /*#__PURE__*/_interopNamespace(revalidateEvents);
// Global state used to deduplicate requests and store listeners
const SWRGlobalState = new WeakMap();
// Shared state between server components and client components
const noop = ()=>{};
// Using noop() as the undefined value as undefined can be replaced
// by something else. Prettier ignore and extra parentheses are necessary here
// to ensure that tsc doesn't remove the __NOINLINE__ comment.
// prettier-ignore
const UNDEFINED = /*#__NOINLINE__*/ noop();
const OBJECT = Object;
const isUndefined = (v)=>v === UNDEFINED;
const isFunction = (v)=>typeof v == 'function';
const mergeObjects = (a, b)=>({
...a,
...b
});
const isPromiseLike = (x)=>isFunction(x.then);
const EMPTY_CACHE = {};
const INITIAL_CACHE = {};
const STR_UNDEFINED = 'undefined';
// NOTE: Use the function to guarantee it's re-evaluated between jsdom and node runtime for tests.
const isWindowDefined = typeof window != STR_UNDEFINED;
const isDocumentDefined = typeof document != STR_UNDEFINED;
const isLegacyDeno = isWindowDefined && 'Deno' in window;
const hasRequestAnimationFrame = ()=>isWindowDefined && typeof window['requestAnimationFrame'] != STR_UNDEFINED;
const createCacheHelper = (cache, key)=>{
const state = SWRGlobalState.get(cache);
return [
// Getter
()=>!isUndefined(key) && cache.get(key) || EMPTY_CACHE,
// Setter
(info)=>{
if (!isUndefined(key)) {
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);
}
},
// Subscriber
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 !isUndefined(key) && cache.get(key) || EMPTY_CACHE;
}
];
} // export { UNDEFINED, OBJECT, isUndefined, isFunction, mergeObjects, isPromiseLike }
;
/**
* Due to the bug https://bugs.chromium.org/p/chromium/issues/detail?id=678075,
* it's not reliable to detect if the browser is currently online or offline
* based on `navigator.onLine`.
* As a workaround, we always assume it's online on the first load, and change
* the status upon `online` or `offline` events.
*/ let online = true;
const isOnline = ()=>online;
// For node and React Native, `add/removeEventListener` doesn't exist on window.
const [onWindowEvent, offWindowEvent] = isWindowDefined && window.addEventListener ? [
window.addEventListener.bind(window),
window.removeEventListener.bind(window)
] : [
noop,
noop
];
const isVisible = ()=>{
const visibilityState = isDocumentDefined && document.visibilityState;
return isUndefined(visibilityState) || visibilityState !== 'hidden';
};
const initFocus = (callback)=>{
// focus revalidate
if (isDocumentDefined) {
document.addEventListener('visibilitychange', callback);
}
onWindowEvent('focus', callback);
return ()=>{
if (isDocumentDefined) {
document.removeEventListener('visibilitychange', callback);
}
offWindowEvent('focus', callback);
};
};
const initReconnect = (callback)=>{
// revalidate on reconnected
const onOnline = ()=>{
online = true;
callback();
};
// nothing to revalidate, just update the status
const onOffline = ()=>{
online = false;
};
onWindowEvent('online', onOnline);
onWindowEvent('offline', onOffline);
return ()=>{
offWindowEvent('online', onOnline);
offWindowEvent('offline', onOffline);
};
};
const preset = {
isOnline,
isVisible
};
const defaultConfigOptions = {
initFocus,
initReconnect
};
const IS_REACT_LEGACY = !React__default.default.useId;
const IS_SERVER = !isWindowDefined || isLegacyDeno;
// Polyfill requestAnimationFrame
const rAF = (f)=>hasRequestAnimationFrame() ? window['requestAnimationFrame'](f) : setTimeout(f, 1);
// React currently throws a warning when using useLayoutEffect on the server.
// To get around it, we can conditionally useEffect on the server (no-op) and
// useLayoutEffect in the browser.
const useIsomorphicLayoutEffect = IS_SERVER ? React.useEffect : React.useLayoutEffect;
// This assignment is to extend the Navigator type to use effectiveType.
const navigatorConnection = typeof navigator !== 'undefined' && navigator.connection;
// Adjust the config based on slow connection status (<= 70Kbps).
const slowConnection = !IS_SERVER && navigatorConnection && ([
'slow-2g',
'2g'
].includes(navigatorConnection.effectiveType) || navigatorConnection.saveData);
// use WeakMap to store the object->key mapping
// so the objects can be garbage collected.
// WeakMap uses a hashtable under the hood, so the lookup
// complexity is almost O(1).
const table = new WeakMap();
const getTypeName = (value)=>OBJECT.prototype.toString.call(value);
const isObjectTypeName = (typeName, type)=>typeName === `[object ${type}]`;
// counter of the key
let counter = 0;
// A stable hash implementation that supports:
// - Fast and ensures unique hash properties
// - Handles unserializable values
// - Handles object key ordering
// - Generates short results
//
// This is not a serialization function, and the result is not guaranteed to be
// parsable.
const stableHash = (arg)=>{
const type = typeof arg;
const typeName = getTypeName(arg);
const isDate = isObjectTypeName(typeName, 'Date');
const isRegex = isObjectTypeName(typeName, 'RegExp');
const isPlainObject = isObjectTypeName(typeName, 'Object');
let result;
let index;
if (OBJECT(arg) === arg && !isDate && !isRegex) {
// Object/function, not null/date/regexp. Use WeakMap to store the id first.
// If it's already hashed, directly return the result.
result = table.get(arg);
if (result) return result;
// Store the hash first for circular reference detection before entering the
// recursive `stableHash` calls.
// For other objects like set and map, we use this id directly as the hash.
result = ++counter + '~';
table.set(arg, result);
if (Array.isArray(arg)) {
// Array.
result = '@';
for(index = 0; index < arg.length; index++){
result += stableHash(arg[index]) + ',';
}
table.set(arg, result);
}
if (isPlainObject) {
// Object, sort keys.
result = '#';
const keys = OBJECT.keys(arg).sort();
while(!isUndefined(index = keys.pop())){
if (!isUndefined(arg[index])) {
result += index + ':' + stableHash(arg[index]) + ',';
}
}
table.set(arg, result);
}
} else {
result = isDate ? arg.toJSON() : type == 'symbol' ? arg.toString() : type == 'string' ? JSON.stringify(arg) : '' + arg;
}
return result;
};
const serialize = (key)=>{
if (isFunction(key)) {
try {
key = key();
} catch (err) {
// dependencies not ready
key = '';
}
}
// Use the original key as the argument of fetcher. This can be a string or an
// array of values.
const args = key;
// If key is not falsy, or not an empty array, hash it.
key = typeof key == 'string' ? key : (Array.isArray(key) ? key.length : key) ? stableHash(key) : '';
return [
key,
args
];
};
// Global timestamp.
let __timestamp = 0;
const getTimestamp = ()=>++__timestamp;
async function internalMutate(...args) {
const [cache, _key, _data, _opts] = args;
// When passing as a boolean, it's explicitly used to disable/enable
// revalidation.
const options = mergeObjects({
populateCache: true,
throwOnError: true
}, typeof _opts === 'boolean' ? {
revalidate: _opts
} : _opts || {});
let populateCache = options.populateCache;
const rollbackOnErrorOption = options.rollbackOnError;
let optimisticData = options.optimisticData;
const rollbackOnError = (error)=>{
return typeof rollbackOnErrorOption === 'function' ? rollbackOnErrorOption(error) : rollbackOnErrorOption !== false;
};
const throwOnError = options.throwOnError;
// If the second argument is a key filter, return the mutation results for all
// filtered keys.
if (isFunction(_key)) {
const keyFilter = _key;
const matchedKeys = [];
const it = cache.keys();
for (const key of it){
if (// Skip the special useSWRInfinite and useSWRSubscription keys.
!/^\$(inf|sub)\$/.test(key) && keyFilter(cache.get(key)._k)) {
matchedKeys.push(key);
}
}
return Promise.all(matchedKeys.map(mutateByKey));
}
return mutateByKey(_key);
async function mutateByKey(_k) {
// Serialize key
const [key] = serialize(_k);
if (!key) return;
const [get, set] = createCacheHelper(cache, key);
const [EVENT_REVALIDATORS, MUTATION, FETCH, PRELOAD] = SWRGlobalState.get(cache);
const startRevalidate = ()=>{
const revalidators = EVENT_REVALIDATORS[key];
const revalidate = isFunction(options.revalidate) ? options.revalidate(get().data, _k) : options.revalidate !== false;
if (revalidate) {
// Invalidate the key by deleting the concurrent request markers so new
// requests will not be deduped.
delete FETCH[key];
delete PRELOAD[key];
if (revalidators && revalidators[0]) {
return revalidators[0](revalidateEvents__namespace.MUTATE_EVENT).then(()=>get().data);
}
}
return get().data;
};
// If there is no new data provided, revalidate the key with current state.
if (args.length < 3) {
// Revalidate and broadcast state.
return startRevalidate();
}
let data = _data;
let error;
let isError = false;
// Update global timestamps.
const beforeMutationTs = getTimestamp();
MUTATION[key] = [
beforeMutationTs,
0
];
const hasOptimisticData = !isUndefined(optimisticData);
const state = get();
// `displayedData` is the current value on screen. It could be the optimistic value
// that is going to be overridden by a `committedData`, or get reverted back.
// `committedData` is the validated value that comes from a fetch or mutation.
const displayedData = state.data;
const currentData = state._c;
const committedData = isUndefined(currentData) ? displayedData : currentData;
// Do optimistic data update.
if (hasOptimisticData) {
optimisticData = isFunction(optimisticData) ? optimisticData(committedData, displayedData) : optimisticData;
// When we set optimistic data, backup the current committedData data in `_c`.
set({
data: optimisticData,
_c: committedData
});
}
if (isFunction(data)) {
// `data` is a function, call it passing current cache value.
try {
data = data(committedData);
} catch (err) {
// If it throws an error synchronously, we shouldn't update the cache.
error = err;
isError = true;
}
}
// `data` is a promise/thenable, resolve the final data first.
if (data && isPromiseLike(data)) {
// This means that the mutation is async, we need to check timestamps to
// avoid race conditions.
data = await data.catch((err)=>{
error = err;
isError = true;
});
// Check if other mutations have occurred since we've started this mutation.
// If there's a race we don't update cache or broadcast the change,
// just return the data.
if (beforeMutationTs !== MUTATION[key][0]) {
if (isError) throw error;
return data;
} else if (isError && hasOptimisticData && rollbackOnError(error)) {
// Rollback. Always populate the cache in this case but without
// transforming the data.
populateCache = true;
// Reset data to be the latest committed data, and clear the `_c` value.
set({
data: committedData,
_c: UNDEFINED
});
}
}
// If we should write back the cache after request.
if (populateCache) {
if (!isError) {
// Transform the result into data.
if (isFunction(populateCache)) {
const populateCachedData = populateCache(data, committedData);
set({
data: populateCachedData,
error: UNDEFINED,
_c: UNDEFINED
});
} else {
// Only update cached data and reset the error if there's no error. Data can be `undefined` here.
set({
data,
error: UNDEFINED,
_c: UNDEFINED
});
}
}
}
// Reset the timestamp to mark the mutation has ended.
MUTATION[key][1] = getTimestamp();
// Update existing SWR Hooks' internal states:
Promise.resolve(startRevalidate()).then(()=>{
// The mutation and revalidation are ended, we can clear it since the data is
// not an optimistic value anymore.
set({
_c: UNDEFINED
});
});
// Throw error or return data
if (isError) {
if (throwOnError) throw error;
return;
}
return data;
}
}
const revalidateAllKeys = (revalidators, type)=>{
for(const key in revalidators){
if (revalidators[key][0]) revalidators[key][0](type);
}
};
const initCache = (provider, options)=>{
// The global state for a specific provider will be used to deduplicate
// requests and store listeners. As well as a mutate function that is bound to
// the cache.
// The provider's global state might be already initialized. Let's try to get the
// global state associated with the provider first.
if (!SWRGlobalState.has(provider)) {
const opts = mergeObjects(defaultConfigOptions, options);
// If there's no global state bound to the provider, create a new one with the
// new mutate function.
const EVENT_REVALIDATORS = Object.create(null);
const mutate = internalMutate.bind(UNDEFINED, provider);
let unmount = noop;
const subscriptions = Object.create(null);
const subscribe = (key, callback)=>{
const subs = subscriptions[key] || [];
subscriptions[key] = subs;
subs.push(callback);
return ()=>subs.splice(subs.indexOf(callback), 1);
};
const setter = (key, value, prev)=>{
provider.set(key, value);
const subs = subscriptions[key];
if (subs) {
for (const fn of subs){
fn(value, prev);
}
}
};
const initProvider = ()=>{
if (!SWRGlobalState.has(provider)) {
// Update the state if it's new, or if the provider has been extended.
SWRGlobalState.set(provider, [
EVENT_REVALIDATORS,
Object.create(null),
Object.create(null),
Object.create(null),
mutate,
setter,
subscribe
]);
if (!IS_SERVER) {
// When listening to the native events for auto revalidations,
// we intentionally put a delay (setTimeout) here to make sure they are
// fired after immediate JavaScript executions, which can be
// React's state updates.
// This avoids some unnecessary revalidations such as
// https://github.com/vercel/swr/issues/1680.
const releaseFocus = opts.initFocus(setTimeout.bind(UNDEFINED, revalidateAllKeys.bind(UNDEFINED, EVENT_REVALIDATORS, revalidateEvents__namespace.FOCUS_EVENT)));
const releaseReconnect = opts.initReconnect(setTimeout.bind(UNDEFINED, revalidateAllKeys.bind(UNDEFINED, EVENT_REVALIDATORS, revalidateEvents__namespace.RECONNECT_EVENT)));
unmount = ()=>{
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
releaseFocus && releaseFocus();
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
releaseReconnect && releaseReconnect();
// When un-mounting, we need to remove the cache provider from the state
// storage too because it's a side-effect. Otherwise, when re-mounting we
// will not re-register those event listeners.
SWRGlobalState.delete(provider);
};
}
}
};
initProvider();
// This is a new provider, we need to initialize it and setup DOM events
// listeners for `focus` and `reconnect` actions.
// We might want to inject an extra layer on top of `provider` in the future,
// such as key serialization, auto GC, etc.
// For now, it's just a `Map` interface without any modifications.
return [
provider,
mutate,
initProvider,
unmount
];
}
return [
provider,
SWRGlobalState.get(provider)[4]
];
};
// error retry
const onErrorRetry = (_, __, config, revalidate, opts)=>{
const maxRetryCount = config.errorRetryCount;
const currentRetryCount = opts.retryCount;
// Exponential backoff
const timeout = ~~((Math.random() + 0.5) * (1 << (currentRetryCount < 8 ? currentRetryCount : 8))) * config.errorRetryInterval;
if (!isUndefined(maxRetryCount) && currentRetryCount > maxRetryCount) {
return;
}
setTimeout(revalidate, timeout, opts);
};
const compare = lite.dequal;
// Default cache provider
const [cache, mutate] = initCache(new Map());
// Default config
const defaultConfig = mergeObjects({
// events
onLoadingSlow: noop,
onSuccess: noop,
onError: noop,
onErrorRetry,
onDiscarded: noop,
// switches
revalidateOnFocus: true,
revalidateOnReconnect: true,
revalidateIfStale: true,
shouldRetryOnError: true,
// timeouts
errorRetryInterval: slowConnection ? 10000 : 5000,
focusThrottleInterval: 5 * 1000,
dedupingInterval: 2 * 1000,
loadingTimeout: slowConnection ? 5000 : 3000,
// providers
compare,
isPaused: ()=>false,
cache,
mutate,
fallback: {}
}, // use web preset by default
preset);
const mergeConfigs = (a, b)=>{
// Need to create a new object to avoid mutating the original here.
const v = mergeObjects(a, b);
// If two configs are provided, merge their `use` and `fallback` options.
if (b) {
const { use: u1, fallback: f1 } = a;
const { use: u2, fallback: f2 } = b;
if (u1 && u2) {
v.use = u1.concat(u2);
}
if (f1 && f2) {
v.fallback = mergeObjects(f1, f2);
}
}
return v;
};
const SWRConfigContext = React.createContext({});
const SWRConfig = (props)=>{
const { value } = props;
const parentConfig = React.useContext(SWRConfigContext);
const isFunctionalConfig = isFunction(value);
const config = React.useMemo(()=>isFunctionalConfig ? value(parentConfig) : value, [
isFunctionalConfig,
parentConfig,
value
]);
// Extend parent context values and middleware.
const extendedConfig = React.useMemo(()=>isFunctionalConfig ? config : mergeConfigs(parentConfig, config), [
isFunctionalConfig,
parentConfig,
config
]);
// Should not use the inherited provider.
const provider = config && config.provider;
// initialize the cache only on first access.
const cacheContextRef = React.useRef(UNDEFINED);
if (provider && !cacheContextRef.current) {
cacheContextRef.current = initCache(provider(extendedConfig.cache || cache), config);
}
const cacheContext = cacheContextRef.current;
// Override the cache if a new provider is given.
if (cacheContext) {
extendedConfig.cache = cacheContext[0];
extendedConfig.mutate = cacheContext[1];
}
// Unsubscribe events.
useIsomorphicLayoutEffect(()=>{
if (cacheContext) {
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
cacheContext[2] && cacheContext[2]();
return cacheContext[3];
}
}, []);
return React.createElement(SWRConfigContext.Provider, mergeObjects(props, {
value: extendedConfig
}));
};
exports.IS_REACT_LEGACY = IS_REACT_LEGACY;
exports.IS_SERVER = IS_SERVER;
exports.OBJECT = OBJECT;
exports.SWRConfig = SWRConfig;
exports.SWRConfigContext = SWRConfigContext;
exports.SWRGlobalState = SWRGlobalState;
exports.UNDEFINED = UNDEFINED;
exports.cache = cache;
exports.compare = compare;
exports.createCacheHelper = createCacheHelper;
exports.defaultConfig = defaultConfig;
exports.defaultConfigOptions = defaultConfigOptions;
exports.getTimestamp = getTimestamp;
exports.hasRequestAnimationFrame = hasRequestAnimationFrame;
exports.initCache = initCache;
exports.internalMutate = internalMutate;
exports.isDocumentDefined = isDocumentDefined;
exports.isFunction = isFunction;
exports.isLegacyDeno = isLegacyDeno;
exports.isPromiseLike = isPromiseLike;
exports.isUndefined = isUndefined;
exports.isWindowDefined = isWindowDefined;
exports.mergeConfigs = mergeConfigs;
exports.mergeObjects = mergeObjects;
exports.mutate = mutate;
exports.noop = noop;
exports.preset = preset;
exports.rAF = rAF;
exports.serialize = serialize;
exports.slowConnection = slowConnection;
exports.stableHash = stableHash;
exports.useIsomorphicLayoutEffect = useIsomorphicLayoutEffect;

3
node_modules/swr/dist/_internal/constants.d.mts generated vendored Normal file
View File

@@ -0,0 +1,3 @@
declare const INFINITE_PREFIX = "$inf$";
export { INFINITE_PREFIX };

3
node_modules/swr/dist/_internal/constants.d.ts generated vendored Normal file
View File

@@ -0,0 +1,3 @@
declare const INFINITE_PREFIX = "$inf$";
export { INFINITE_PREFIX };

5
node_modules/swr/dist/_internal/constants.js generated vendored Normal file
View File

@@ -0,0 +1,5 @@
Object.defineProperty(exports, '__esModule', { value: true });
const INFINITE_PREFIX = '$inf$';
exports.INFINITE_PREFIX = INFINITE_PREFIX;

3
node_modules/swr/dist/_internal/constants.mjs generated vendored Normal file
View File

@@ -0,0 +1,3 @@
const INFINITE_PREFIX = '$inf$';
export { INFINITE_PREFIX };

6
node_modules/swr/dist/_internal/events.d.mts generated vendored Normal file
View File

@@ -0,0 +1,6 @@
declare const FOCUS_EVENT = 0;
declare const RECONNECT_EVENT = 1;
declare const MUTATE_EVENT = 2;
declare const ERROR_REVALIDATE_EVENT = 3;
export { ERROR_REVALIDATE_EVENT, FOCUS_EVENT, MUTATE_EVENT, RECONNECT_EVENT };

6
node_modules/swr/dist/_internal/events.d.ts generated vendored Normal file
View File

@@ -0,0 +1,6 @@
declare const FOCUS_EVENT = 0;
declare const RECONNECT_EVENT = 1;
declare const MUTATE_EVENT = 2;
declare const ERROR_REVALIDATE_EVENT = 3;
export { ERROR_REVALIDATE_EVENT, FOCUS_EVENT, MUTATE_EVENT, RECONNECT_EVENT };

11
node_modules/swr/dist/_internal/events.js generated vendored Normal file
View File

@@ -0,0 +1,11 @@
Object.defineProperty(exports, '__esModule', { value: true });
const FOCUS_EVENT = 0;
const RECONNECT_EVENT = 1;
const MUTATE_EVENT = 2;
const ERROR_REVALIDATE_EVENT = 3;
exports.ERROR_REVALIDATE_EVENT = ERROR_REVALIDATE_EVENT;
exports.FOCUS_EVENT = FOCUS_EVENT;
exports.MUTATE_EVENT = MUTATE_EVENT;
exports.RECONNECT_EVENT = RECONNECT_EVENT;

6
node_modules/swr/dist/_internal/events.mjs generated vendored Normal file
View File

@@ -0,0 +1,6 @@
const FOCUS_EVENT = 0;
const RECONNECT_EVENT = 1;
const MUTATE_EVENT = 2;
const ERROR_REVALIDATE_EVENT = 3;
export { ERROR_REVALIDATE_EVENT, FOCUS_EVENT, MUTATE_EVENT, RECONNECT_EVENT };

75
node_modules/swr/dist/_internal/index.d.mts generated vendored Normal file
View File

@@ -0,0 +1,75 @@
import react, { FC, PropsWithChildren } from 'react';
import { SWRConfiguration, Cache, ProviderConfiguration, ScopedMutator, FullConfiguration, GlobalState, State, Arguments, MutatorCallback, MutatorOptions, Key, Fetcher, SWRHook, Middleware, BareFetcher, FetcherResponse } from './types.mjs';
export * from './types.mjs';
import * as events_d_mts from './events.mjs';
export { events_d_mts as revalidateEvents };
export { INFINITE_PREFIX } from './constants.mjs';
import { dequal } from 'dequal/lite';
declare const SWRConfig: FC<PropsWithChildren<{
value?: SWRConfiguration | ((parentConfig?: SWRConfiguration) => SWRConfiguration);
}>>;
declare const initCache: <Data = any>(provider: Cache<Data>, options?: Partial<ProviderConfiguration>) => [Cache<Data>, ScopedMutator, () => void, () => void] | [Cache<Data>, ScopedMutator] | undefined;
declare const compare: typeof dequal;
declare const cache: Cache<any>;
declare const mutate: ScopedMutator;
declare const defaultConfig: FullConfiguration;
declare const IS_REACT_LEGACY = false;
declare const IS_SERVER: boolean;
declare const rAF: (f: (...args: any[]) => void) => number | ReturnType<typeof setTimeout>;
declare const useIsomorphicLayoutEffect: typeof react.useEffect;
declare const slowConnection: boolean | undefined;
declare const SWRGlobalState: WeakMap<Cache<any>, GlobalState>;
declare const stableHash: (arg: any) => string;
declare const isWindowDefined: boolean;
declare const isDocumentDefined: boolean;
declare const isLegacyDeno: boolean;
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, () => any];
declare const noop: () => void;
declare const UNDEFINED: undefined;
declare const OBJECT: ObjectConstructor;
declare const isUndefined: (v: any) => v is undefined;
declare const isFunction: <T extends (...args: any[]) => any = (...args: any[]) => any>(v: unknown) => v is T;
declare const mergeObjects: (a: any, b?: any) => any;
declare const isPromiseLike: (x: unknown) => x is PromiseLike<unknown>;
declare const mergeConfigs: (a: Partial<FullConfiguration>, b?: Partial<FullConfiguration>) => Partial<FullConfiguration>;
type KeyFilter = (key?: Arguments) => boolean;
declare function internalMutate<Data>(cache: Cache, _key: KeyFilter, _data?: Data | Promise<Data | undefined> | MutatorCallback<Data>, _opts?: boolean | MutatorOptions<Data>): Promise<Array<Data | undefined>>;
declare function internalMutate<Data>(cache: Cache, _key: Arguments, _data?: Data | Promise<Data | undefined> | MutatorCallback<Data>, _opts?: boolean | MutatorOptions<Data>): Promise<Data | undefined>;
declare const normalize: <KeyType = Key, Data = any>(args: [KeyType] | [KeyType, Fetcher<Data> | null] | [KeyType, SWRConfiguration | undefined] | [KeyType, Fetcher<Data> | null, SWRConfiguration | undefined]) => [KeyType, Fetcher<Data> | null, Partial<SWRConfiguration<Data>>];
declare const withArgs: <SWRType>(hook: any) => SWRType;
declare const serialize: (key: Key) => [string, Arguments];
type Callback = (...args: any[]) => any;
declare const subscribeCallback: (key: string, callbacks: Record<string, Callback[]>, callback: Callback) => () => void;
declare const getTimestamp: () => number;
declare const useSWRConfig: () => FullConfiguration;
declare const preset: {
readonly isOnline: () => boolean;
readonly isVisible: () => boolean;
};
declare const defaultConfigOptions: ProviderConfiguration;
declare const withMiddleware: (useSWR: SWRHook, middleware: Middleware) => SWRHook;
type PreloadFetcher<Data = unknown, SWRKey extends Key = Key> = SWRKey extends () => infer Arg ? (arg: Arg) => FetcherResponse<Data> : SWRKey extends infer Arg ? (arg: Arg) => FetcherResponse<Data> : never;
declare const preload: <Data = any, SWRKey extends Key = Key, Fetcher extends BareFetcher = PreloadFetcher<Data, SWRKey>>(key_: SWRKey, fetcher: Fetcher) => ReturnType<Fetcher>;
export { IS_REACT_LEGACY, IS_SERVER, OBJECT, SWRConfig, SWRGlobalState, UNDEFINED, cache, compare, createCacheHelper, defaultConfig, defaultConfigOptions, getTimestamp, hasRequestAnimationFrame, initCache, internalMutate, isDocumentDefined, isFunction, isLegacyDeno, isPromiseLike, isUndefined, isWindowDefined, mergeConfigs, mergeObjects, mutate, noop, normalize, preload, preset, rAF, serialize, slowConnection, stableHash, subscribeCallback, useIsomorphicLayoutEffect, useSWRConfig, withArgs, withMiddleware };

75
node_modules/swr/dist/_internal/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,75 @@
import react, { FC, PropsWithChildren } from 'react';
import { SWRConfiguration, Cache, ProviderConfiguration, ScopedMutator, FullConfiguration, GlobalState, State, Arguments, MutatorCallback, MutatorOptions, Key, Fetcher, SWRHook, Middleware, BareFetcher, FetcherResponse } from './types.js';
export * from './types.js';
import * as events_d_ts from './events.js';
export { events_d_ts as revalidateEvents };
export { INFINITE_PREFIX } from './constants.js';
import { dequal } from 'dequal/lite';
declare const SWRConfig: FC<PropsWithChildren<{
value?: SWRConfiguration | ((parentConfig?: SWRConfiguration) => SWRConfiguration);
}>>;
declare const initCache: <Data = any>(provider: Cache<Data>, options?: Partial<ProviderConfiguration>) => [Cache<Data>, ScopedMutator, () => void, () => void] | [Cache<Data>, ScopedMutator] | undefined;
declare const compare: typeof dequal;
declare const cache: Cache<any>;
declare const mutate: ScopedMutator;
declare const defaultConfig: FullConfiguration;
declare const IS_REACT_LEGACY = false;
declare const IS_SERVER: boolean;
declare const rAF: (f: (...args: any[]) => void) => number | ReturnType<typeof setTimeout>;
declare const useIsomorphicLayoutEffect: typeof react.useEffect;
declare const slowConnection: boolean | undefined;
declare const SWRGlobalState: WeakMap<Cache<any>, GlobalState>;
declare const stableHash: (arg: any) => string;
declare const isWindowDefined: boolean;
declare const isDocumentDefined: boolean;
declare const isLegacyDeno: boolean;
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, () => any];
declare const noop: () => void;
declare const UNDEFINED: undefined;
declare const OBJECT: ObjectConstructor;
declare const isUndefined: (v: any) => v is undefined;
declare const isFunction: <T extends (...args: any[]) => any = (...args: any[]) => any>(v: unknown) => v is T;
declare const mergeObjects: (a: any, b?: any) => any;
declare const isPromiseLike: (x: unknown) => x is PromiseLike<unknown>;
declare const mergeConfigs: (a: Partial<FullConfiguration>, b?: Partial<FullConfiguration>) => Partial<FullConfiguration>;
type KeyFilter = (key?: Arguments) => boolean;
declare function internalMutate<Data>(cache: Cache, _key: KeyFilter, _data?: Data | Promise<Data | undefined> | MutatorCallback<Data>, _opts?: boolean | MutatorOptions<Data>): Promise<Array<Data | undefined>>;
declare function internalMutate<Data>(cache: Cache, _key: Arguments, _data?: Data | Promise<Data | undefined> | MutatorCallback<Data>, _opts?: boolean | MutatorOptions<Data>): Promise<Data | undefined>;
declare const normalize: <KeyType = Key, Data = any>(args: [KeyType] | [KeyType, Fetcher<Data> | null] | [KeyType, SWRConfiguration | undefined] | [KeyType, Fetcher<Data> | null, SWRConfiguration | undefined]) => [KeyType, Fetcher<Data> | null, Partial<SWRConfiguration<Data>>];
declare const withArgs: <SWRType>(hook: any) => SWRType;
declare const serialize: (key: Key) => [string, Arguments];
type Callback = (...args: any[]) => any;
declare const subscribeCallback: (key: string, callbacks: Record<string, Callback[]>, callback: Callback) => () => void;
declare const getTimestamp: () => number;
declare const useSWRConfig: () => FullConfiguration;
declare const preset: {
readonly isOnline: () => boolean;
readonly isVisible: () => boolean;
};
declare const defaultConfigOptions: ProviderConfiguration;
declare const withMiddleware: (useSWR: SWRHook, middleware: Middleware) => SWRHook;
type PreloadFetcher<Data = unknown, SWRKey extends Key = Key> = SWRKey extends () => infer Arg ? (arg: Arg) => FetcherResponse<Data> : SWRKey extends infer Arg ? (arg: Arg) => FetcherResponse<Data> : never;
declare const preload: <Data = any, SWRKey extends Key = Key, Fetcher extends BareFetcher = PreloadFetcher<Data, SWRKey>>(key_: SWRKey, fetcher: Fetcher) => ReturnType<Fetcher>;
export { IS_REACT_LEGACY, IS_SERVER, OBJECT, SWRConfig, SWRGlobalState, UNDEFINED, cache, compare, createCacheHelper, defaultConfig, defaultConfigOptions, getTimestamp, hasRequestAnimationFrame, initCache, internalMutate, isDocumentDefined, isFunction, isLegacyDeno, isPromiseLike, isUndefined, isWindowDefined, mergeConfigs, mergeObjects, mutate, noop, normalize, preload, preset, rAF, serialize, slowConnection, stableHash, subscribeCallback, useIsomorphicLayoutEffect, useSWRConfig, withArgs, withMiddleware };

192
node_modules/swr/dist/_internal/index.js generated vendored Normal file
View File

@@ -0,0 +1,192 @@
Object.defineProperty(exports, '__esModule', { value: true });
var configContext12s = require('./config-context-12s-DER5jwVW.js');
var revalidateEvents = require('./events.js');
var constants_js = require('./constants.js');
var React = require('react');
var types_js = require('./types.js');
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
function _interopNamespace(e) {
if (e && e.__esModule) return e;
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return n;
}
var revalidateEvents__namespace = /*#__PURE__*/_interopNamespace(revalidateEvents);
var React__default = /*#__PURE__*/_interopDefault(React);
// @ts-expect-error
const enableDevtools = configContext12s.isWindowDefined && window.__SWR_DEVTOOLS_USE__;
const use = enableDevtools ? window.__SWR_DEVTOOLS_USE__ : [];
const setupDevTools = ()=>{
if (enableDevtools) {
// @ts-expect-error
window.__SWR_DEVTOOLS_REACT__ = React__default.default;
}
};
const normalize = (args)=>{
return configContext12s.isFunction(args[1]) ? [
args[0],
args[1],
args[2] || {}
] : [
args[0],
null,
(args[1] === null ? args[2] : args[1]) || {}
];
};
const useSWRConfig = ()=>{
const parentConfig = React.useContext(configContext12s.SWRConfigContext);
const mergedConfig = React.useMemo(()=>configContext12s.mergeObjects(configContext12s.defaultConfig, parentConfig), [
parentConfig
]);
return mergedConfig;
};
const preload = (key_, fetcher)=>{
// preload should be a no-op on the server
if (configContext12s.IS_SERVER) {
return undefined;
}
const [key, fnArg] = configContext12s.serialize(key_);
const [, , , PRELOAD] = configContext12s.SWRGlobalState.get(configContext12s.cache);
// Prevent preload to be called multiple times before used.
if (PRELOAD[key]) return PRELOAD[key];
const req = fetcher(fnArg);
PRELOAD[key] = req;
return req;
};
const middleware = (useSWRNext)=>(key_, fetcher_, config)=>{
// fetcher might be a sync function, so this should not be an async function
const fetcher = fetcher_ && ((...args)=>{
const [key] = configContext12s.serialize(key_);
const [, , , PRELOAD] = configContext12s.SWRGlobalState.get(configContext12s.cache);
if (key.startsWith(constants_js.INFINITE_PREFIX)) {
// we want the infinite fetcher to be called.
// handling of the PRELOAD cache happens there.
return fetcher_(...args);
}
const req = PRELOAD[key];
if (configContext12s.isUndefined(req)) return fetcher_(...args);
delete PRELOAD[key];
return req;
});
return useSWRNext(key_, fetcher, config);
};
const BUILT_IN_MIDDLEWARE = use.concat(middleware);
// It's tricky to pass generic types as parameters, so we just directly override
// the types here.
const withArgs = (hook)=>{
return function useSWRArgs(...args) {
// Get the default and inherited configuration.
const fallbackConfig = useSWRConfig();
// Normalize arguments.
const [key, fn, _config] = normalize(args);
// Merge configurations.
const config = configContext12s.mergeConfigs(fallbackConfig, _config);
// Apply middleware
let next = hook;
const { use } = config;
const middleware = (use || []).concat(BUILT_IN_MIDDLEWARE);
for(let i = middleware.length; i--;){
next = middleware[i](next);
}
return next(key, fn || config.fetcher || null, config);
};
};
// Add a callback function to a list of keyed callback functions and return
// the unsubscribe function.
const subscribeCallback = (key, callbacks, callback)=>{
const keyedRevalidators = callbacks[key] || (callbacks[key] = []);
keyedRevalidators.push(callback);
return ()=>{
const index = keyedRevalidators.indexOf(callback);
if (index >= 0) {
// O(1): faster than splice
keyedRevalidators[index] = keyedRevalidators[keyedRevalidators.length - 1];
keyedRevalidators.pop();
}
};
};
// Create a custom hook with a middleware
const withMiddleware = (useSWR, middleware)=>{
return (...args)=>{
const [key, fn, config] = normalize(args);
const uses = (config.use || []).concat(middleware);
return useSWR(key, fn, {
...config,
use: uses
});
};
};
setupDevTools();
exports.IS_REACT_LEGACY = configContext12s.IS_REACT_LEGACY;
exports.IS_SERVER = configContext12s.IS_SERVER;
exports.OBJECT = configContext12s.OBJECT;
exports.SWRConfig = configContext12s.SWRConfig;
exports.SWRGlobalState = configContext12s.SWRGlobalState;
exports.UNDEFINED = configContext12s.UNDEFINED;
exports.cache = configContext12s.cache;
exports.compare = configContext12s.compare;
exports.createCacheHelper = configContext12s.createCacheHelper;
exports.defaultConfig = configContext12s.defaultConfig;
exports.defaultConfigOptions = configContext12s.defaultConfigOptions;
exports.getTimestamp = configContext12s.getTimestamp;
exports.hasRequestAnimationFrame = configContext12s.hasRequestAnimationFrame;
exports.initCache = configContext12s.initCache;
exports.internalMutate = configContext12s.internalMutate;
exports.isDocumentDefined = configContext12s.isDocumentDefined;
exports.isFunction = configContext12s.isFunction;
exports.isLegacyDeno = configContext12s.isLegacyDeno;
exports.isPromiseLike = configContext12s.isPromiseLike;
exports.isUndefined = configContext12s.isUndefined;
exports.isWindowDefined = configContext12s.isWindowDefined;
exports.mergeConfigs = configContext12s.mergeConfigs;
exports.mergeObjects = configContext12s.mergeObjects;
exports.mutate = configContext12s.mutate;
exports.noop = configContext12s.noop;
exports.preset = configContext12s.preset;
exports.rAF = configContext12s.rAF;
exports.serialize = configContext12s.serialize;
exports.slowConnection = configContext12s.slowConnection;
exports.stableHash = configContext12s.stableHash;
exports.useIsomorphicLayoutEffect = configContext12s.useIsomorphicLayoutEffect;
exports.revalidateEvents = revalidateEvents__namespace;
Object.defineProperty(exports, "INFINITE_PREFIX", {
enumerable: true,
get: function () { return constants_js.INFINITE_PREFIX; }
});
exports.normalize = normalize;
exports.preload = preload;
exports.subscribeCallback = subscribeCallback;
exports.useSWRConfig = useSWRConfig;
exports.withArgs = withArgs;
exports.withMiddleware = withMiddleware;
Object.keys(types_js).forEach(function (k) {
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
enumerable: true,
get: function () { return types_js[k]; }
});
});

123
node_modules/swr/dist/_internal/index.mjs generated vendored Normal file
View File

@@ -0,0 +1,123 @@
import { i as isWindowDefined, a as isFunction, S as SWRConfigContext, m as mergeObjects, d as defaultConfig, s as serialize, b as SWRGlobalState, c as cache, e as isUndefined, I as IS_SERVER, f as mergeConfigs } from './config-context-12s-CCVTDPOP.mjs';
export { r as IS_REACT_LEGACY, O as OBJECT, g as SWRConfig, U as UNDEFINED, k as compare, z as createCacheHelper, q as defaultConfigOptions, o as getTimestamp, y as hasRequestAnimationFrame, h as initCache, n as internalMutate, w as isDocumentDefined, x as isLegacyDeno, B as isPromiseLike, j as mutate, A as noop, p as preset, t as rAF, v as slowConnection, l as stableHash, u as useIsomorphicLayoutEffect } from './config-context-12s-CCVTDPOP.mjs';
import * as revalidateEvents from './events.mjs';
export { revalidateEvents };
import { INFINITE_PREFIX } from './constants.mjs';
export { INFINITE_PREFIX } from './constants.mjs';
import React, { useContext, useMemo } from 'react';
export * from './types.mjs';
// @ts-expect-error
const enableDevtools = isWindowDefined && window.__SWR_DEVTOOLS_USE__;
const use = enableDevtools ? window.__SWR_DEVTOOLS_USE__ : [];
const setupDevTools = ()=>{
if (enableDevtools) {
// @ts-expect-error
window.__SWR_DEVTOOLS_REACT__ = React;
}
};
const normalize = (args)=>{
return isFunction(args[1]) ? [
args[0],
args[1],
args[2] || {}
] : [
args[0],
null,
(args[1] === null ? args[2] : args[1]) || {}
];
};
const useSWRConfig = ()=>{
const parentConfig = useContext(SWRConfigContext);
const mergedConfig = useMemo(()=>mergeObjects(defaultConfig, parentConfig), [
parentConfig
]);
return mergedConfig;
};
const preload = (key_, fetcher)=>{
// preload should be a no-op on the server
if (IS_SERVER) {
return undefined;
}
const [key, fnArg] = serialize(key_);
const [, , , PRELOAD] = SWRGlobalState.get(cache);
// Prevent preload to be called multiple times before used.
if (PRELOAD[key]) return PRELOAD[key];
const req = fetcher(fnArg);
PRELOAD[key] = req;
return req;
};
const middleware = (useSWRNext)=>(key_, fetcher_, config)=>{
// fetcher might be a sync function, so this should not be an async function
const fetcher = fetcher_ && ((...args)=>{
const [key] = serialize(key_);
const [, , , PRELOAD] = SWRGlobalState.get(cache);
if (key.startsWith(INFINITE_PREFIX)) {
// we want the infinite fetcher to be called.
// handling of the PRELOAD cache happens there.
return fetcher_(...args);
}
const req = PRELOAD[key];
if (isUndefined(req)) return fetcher_(...args);
delete PRELOAD[key];
return req;
});
return useSWRNext(key_, fetcher, config);
};
const BUILT_IN_MIDDLEWARE = use.concat(middleware);
// It's tricky to pass generic types as parameters, so we just directly override
// the types here.
const withArgs = (hook)=>{
return function useSWRArgs(...args) {
// Get the default and inherited configuration.
const fallbackConfig = useSWRConfig();
// Normalize arguments.
const [key, fn, _config] = normalize(args);
// Merge configurations.
const config = mergeConfigs(fallbackConfig, _config);
// Apply middleware
let next = hook;
const { use } = config;
const middleware = (use || []).concat(BUILT_IN_MIDDLEWARE);
for(let i = middleware.length; i--;){
next = middleware[i](next);
}
return next(key, fn || config.fetcher || null, config);
};
};
// Add a callback function to a list of keyed callback functions and return
// the unsubscribe function.
const subscribeCallback = (key, callbacks, callback)=>{
const keyedRevalidators = callbacks[key] || (callbacks[key] = []);
keyedRevalidators.push(callback);
return ()=>{
const index = keyedRevalidators.indexOf(callback);
if (index >= 0) {
// O(1): faster than splice
keyedRevalidators[index] = keyedRevalidators[keyedRevalidators.length - 1];
keyedRevalidators.pop();
}
};
};
// Create a custom hook with a middleware
const withMiddleware = (useSWR, middleware)=>{
return (...args)=>{
const [key, fn, config] = normalize(args);
const uses = (config.use || []).concat(middleware);
return useSWR(key, fn, {
...config,
use: uses
});
};
};
setupDevTools();
export { IS_SERVER, SWRGlobalState, cache, defaultConfig, isFunction, isUndefined, isWindowDefined, mergeConfigs, mergeObjects, normalize, preload, serialize, subscribeCallback, useSWRConfig, withArgs, withMiddleware };

View File

@@ -0,0 +1,7 @@
import { Key, Arguments } from './types.mjs';
export { SWRConfig } from './index.mjs';
export { INFINITE_PREFIX } from './constants.mjs';
declare const serialize: (key: Key) => [string, Arguments];
export { serialize };

View File

@@ -0,0 +1,7 @@
import { Key, Arguments } from './types.js';
export { SWRConfig } from './index.js';
export { INFINITE_PREFIX } from './constants.js';
declare const serialize: (key: Key) => [string, Arguments];
export { serialize };

105
node_modules/swr/dist/_internal/index.react-server.js generated vendored Normal file
View File

@@ -0,0 +1,105 @@
Object.defineProperty(exports, '__esModule', { value: true });
var index_js = require('./index.js');
var constants_js = require('./constants.js');
// Shared state between server components and client components
const noop = ()=>{};
// Using noop() as the undefined value as undefined can be replaced
// by something else. Prettier ignore and extra parentheses are necessary here
// to ensure that tsc doesn't remove the __NOINLINE__ comment.
// prettier-ignore
const UNDEFINED = /*#__NOINLINE__*/ noop();
const OBJECT = Object;
const isUndefined = (v)=>v === UNDEFINED;
const isFunction = (v)=>typeof v == 'function';
// use WeakMap to store the object->key mapping
// so the objects can be garbage collected.
// WeakMap uses a hashtable under the hood, so the lookup
// complexity is almost O(1).
const table = new WeakMap();
const getTypeName = (value)=>OBJECT.prototype.toString.call(value);
const isObjectTypeName = (typeName, type)=>typeName === `[object ${type}]`;
// counter of the key
let counter = 0;
// A stable hash implementation that supports:
// - Fast and ensures unique hash properties
// - Handles unserializable values
// - Handles object key ordering
// - Generates short results
//
// This is not a serialization function, and the result is not guaranteed to be
// parsable.
const stableHash = (arg)=>{
const type = typeof arg;
const typeName = getTypeName(arg);
const isDate = isObjectTypeName(typeName, 'Date');
const isRegex = isObjectTypeName(typeName, 'RegExp');
const isPlainObject = isObjectTypeName(typeName, 'Object');
let result;
let index;
if (OBJECT(arg) === arg && !isDate && !isRegex) {
// Object/function, not null/date/regexp. Use WeakMap to store the id first.
// If it's already hashed, directly return the result.
result = table.get(arg);
if (result) return result;
// Store the hash first for circular reference detection before entering the
// recursive `stableHash` calls.
// For other objects like set and map, we use this id directly as the hash.
result = ++counter + '~';
table.set(arg, result);
if (Array.isArray(arg)) {
// Array.
result = '@';
for(index = 0; index < arg.length; index++){
result += stableHash(arg[index]) + ',';
}
table.set(arg, result);
}
if (isPlainObject) {
// Object, sort keys.
result = '#';
const keys = OBJECT.keys(arg).sort();
while(!isUndefined(index = keys.pop())){
if (!isUndefined(arg[index])) {
result += index + ':' + stableHash(arg[index]) + ',';
}
}
table.set(arg, result);
}
} else {
result = isDate ? arg.toJSON() : type == 'symbol' ? arg.toString() : type == 'string' ? JSON.stringify(arg) : '' + arg;
}
return result;
};
const serialize = (key)=>{
if (isFunction(key)) {
try {
key = key();
} catch (err) {
// dependencies not ready
key = '';
}
}
// Use the original key as the argument of fetcher. This can be a string or an
// array of values.
const args = key;
// If key is not falsy, or not an empty array, hash it.
key = typeof key == 'string' ? key : (Array.isArray(key) ? key.length : key) ? stableHash(key) : '';
return [
key,
args
];
};
Object.defineProperty(exports, "SWRConfig", {
enumerable: true,
get: function () { return index_js.SWRConfig; }
});
Object.defineProperty(exports, "INFINITE_PREFIX", {
enumerable: true,
get: function () { return constants_js.INFINITE_PREFIX; }
});
exports.serialize = serialize;

95
node_modules/swr/dist/_internal/index.react-server.mjs generated vendored Normal file
View File

@@ -0,0 +1,95 @@
export { SWRConfig } from './index.mjs';
export { INFINITE_PREFIX } from './constants.mjs';
// Shared state between server components and client components
const noop = ()=>{};
// Using noop() as the undefined value as undefined can be replaced
// by something else. Prettier ignore and extra parentheses are necessary here
// to ensure that tsc doesn't remove the __NOINLINE__ comment.
// prettier-ignore
const UNDEFINED = /*#__NOINLINE__*/ noop();
const OBJECT = Object;
const isUndefined = (v)=>v === UNDEFINED;
const isFunction = (v)=>typeof v == 'function';
// use WeakMap to store the object->key mapping
// so the objects can be garbage collected.
// WeakMap uses a hashtable under the hood, so the lookup
// complexity is almost O(1).
const table = new WeakMap();
const getTypeName = (value)=>OBJECT.prototype.toString.call(value);
const isObjectTypeName = (typeName, type)=>typeName === `[object ${type}]`;
// counter of the key
let counter = 0;
// A stable hash implementation that supports:
// - Fast and ensures unique hash properties
// - Handles unserializable values
// - Handles object key ordering
// - Generates short results
//
// This is not a serialization function, and the result is not guaranteed to be
// parsable.
const stableHash = (arg)=>{
const type = typeof arg;
const typeName = getTypeName(arg);
const isDate = isObjectTypeName(typeName, 'Date');
const isRegex = isObjectTypeName(typeName, 'RegExp');
const isPlainObject = isObjectTypeName(typeName, 'Object');
let result;
let index;
if (OBJECT(arg) === arg && !isDate && !isRegex) {
// Object/function, not null/date/regexp. Use WeakMap to store the id first.
// If it's already hashed, directly return the result.
result = table.get(arg);
if (result) return result;
// Store the hash first for circular reference detection before entering the
// recursive `stableHash` calls.
// For other objects like set and map, we use this id directly as the hash.
result = ++counter + '~';
table.set(arg, result);
if (Array.isArray(arg)) {
// Array.
result = '@';
for(index = 0; index < arg.length; index++){
result += stableHash(arg[index]) + ',';
}
table.set(arg, result);
}
if (isPlainObject) {
// Object, sort keys.
result = '#';
const keys = OBJECT.keys(arg).sort();
while(!isUndefined(index = keys.pop())){
if (!isUndefined(arg[index])) {
result += index + ':' + stableHash(arg[index]) + ',';
}
}
table.set(arg, result);
}
} else {
result = isDate ? arg.toJSON() : type == 'symbol' ? arg.toString() : type == 'string' ? JSON.stringify(arg) : '' + arg;
}
return result;
};
const serialize = (key)=>{
if (isFunction(key)) {
try {
key = key();
} catch (err) {
// dependencies not ready
key = '';
}
}
// Use the original key as the argument of fetcher. This can be a string or an
// array of values.
const args = key;
// If key is not falsy, or not an empty array, hash it.
key = typeof key == 'string' ? key : (Array.isArray(key) ? key.length : key) ? stableHash(key) : '';
return [
key,
args
];
};
export { serialize };

872
node_modules/swr/dist/_internal/types.d.mts generated vendored Normal file
View File

@@ -0,0 +1,872 @@
import { SWRGlobalConfig } from '../index/index.mjs';
import * as revalidateEvents from './events.mjs';
/**
* Global state tuple containing SWR's internal state management structures.
*
* This is the core state structure that manages all SWR operations internally.
* Each element serves a specific purpose in the SWR ecosystem.
*
* @internal
*/
type GlobalState = [
/** Event revalidators: Maps cache keys to arrays of revalidation callbacks */
Record<string, RevalidateCallback[]>,
/** Mutation timestamps: Maps cache keys to [start_timestamp, end_timestamp] tuples */
Record<string, [number, number]>,
/** Fetch cache: Maps cache keys to [data, timestamp] tuples */
Record<string, [any, number]>,
/** Preload cache: Maps cache keys to fetcher responses */
Record<string, FetcherResponse<any>>,
/** Scoped mutator function for cache updates */
ScopedMutator,
/** Cache setter function with prev/current value comparison */
(key: string, value: any, prev: any) => void,
/** Cache subscriber function that returns an unsubscribe function */
(key: string, callback: (current: any, prev: any) => void) => () => void
];
/**
* Response type that can be returned by fetcher functions.
*
* @template Data - The type of data returned by the fetcher
* @public
*/
type FetcherResponse<Data = unknown> = Data | Promise<Data>;
/**
* Basic fetcher function that accepts any arguments and returns data or a promise.
*
* This is the most permissive fetcher type, allowing any number of arguments
* of any type. Used when type safety is not required or when dealing with
* dynamic fetcher signatures.
*
* @template Data - The type of data returned by the fetcher
* @param args - Variable arguments passed to the fetcher
* @returns Data or a Promise that resolves to data
* @public
*/
type BareFetcher<Data = unknown> = (...args: any[]) => FetcherResponse<Data>;
/**
* Typed fetcher function that is constrained by the SWR key type.
*
* Provides type safety by ensuring the fetcher argument matches the key type.
* The conditional type logic ensures that:
* - If the key is a function returning a value, the fetcher receives that value
* - If the key is falsy (null, undefined, false), the fetcher is never called
* - Otherwise, the fetcher receives the key directly as its argument
*
* @template Data - The type of data returned by the fetcher
* @template SWRKey - The type of the SWR key, used to infer fetcher arguments
* @public
*/
type Fetcher<Data = unknown, SWRKey extends Key = Key> = SWRKey extends () => infer Arg | null | undefined | false ? (arg: Arg) => FetcherResponse<Data> : SWRKey extends null | undefined | false ? never : SWRKey extends infer Arg ? (arg: Arg) => FetcherResponse<Data> : never;
/**
* Determines if data should block rendering based on suspense configuration.
*
* This conditional type is used internally to determine the return type of `data`
* in SWRResponse. When suspense is enabled or fallbackData is provided, data
* will never be undefined, allowing for non-nullable return types.
*
* The type resolution follows this logic:
* 1. If global suspense is enabled → `true` (data never undefined)
* 2. If no options provided → `false` (data can be undefined)
* 3. If suspense is enabled in options → `true` (data never undefined)
* 4. If fallbackData is provided → `true` (data never undefined)
* 5. Otherwise → `false` (data can be undefined)
*
* @template Data - The data type
* @template Options - The SWR configuration options
* @returns `true` if data is guaranteed to be defined, `false` if it can be undefined
* @internal
*/
type BlockingData<Data = any, Options = SWRDefaultOptions<Data>> = SWRGlobalConfig extends {
suspense: true;
} ? true : Options extends undefined ? false : Options extends {
suspense: true;
} ? true : Options extends {
fallbackData: Data | Promise<Data>;
} ? true : false;
/**
* Configuration types that are only used internally, not exposed to the user.
*
* These options are managed internally by SWR and passed between internal
* functions. They are not part of the public API and should not be used
* directly by consumers.
*
* @internal
*/
interface InternalConfiguration {
/** The cache instance used to store SWR data and state */
cache: Cache;
/** Scoped mutator function for updating cache entries */
mutate: ScopedMutator;
}
/**
* Public configuration options for SWR.
*
* This interface defines all the configuration options that users can pass
* to customize SWR's behavior. These options can be provided globally via
* SWRConfig or per-hook via the config parameter.
*
* @template Data - The type of data returned by the fetcher
* @template Error - The type of error that can be thrown
* @template Fn - The fetcher function type
*
* @public
* @see {@link https://swr.vercel.app/docs/options | SWR Options Documentation}
*/
interface PublicConfiguration<Data = any, Error = any, Fn extends Fetcher = BareFetcher> {
/**
* error retry interval in milliseconds
* @defaultValue 5000
*/
errorRetryInterval: number;
/** max error retry count */
errorRetryCount?: number;
/**
* timeout to trigger the onLoadingSlow event in milliseconds
* @defaultValue 3000
*/
loadingTimeout: number;
/**
* only revalidate once during a time span in milliseconds
* @defaultValue 5000
*/
focusThrottleInterval: number;
/**
* dedupe requests with the same key in this time span in milliseconds
* @defaultValue 2000
*/
dedupingInterval: number;
/**
* * Disabled by default: `refreshInterval = 0`
* * If set to a number, polling interval in milliseconds
* * If set to a function, the function will receive the latest data and should return the interval in milliseconds
* @see {@link https://swr.vercel.app/docs/revalidation}
*/
refreshInterval?: number | ((latestData: Data | undefined) => number);
/**
* polling when the window is invisible (if `refreshInterval` is enabled)
* @defaultValue false
*/
refreshWhenHidden?: boolean;
/**
* polling when the browser is offline (determined by `navigator.onLine`)
*
* When enabled, SWR will continue polling even when the browser is offline.
* This can be useful for applications that need to check for connectivity
* or cache updates while offline.
*
* @defaultValue false
*/
refreshWhenOffline?: boolean;
/**
* automatically revalidate when window gets focused
*
* When enabled, SWR will automatically revalidate data when the user
* returns focus to the window/tab. This ensures data freshness when
* users switch between applications.
*
* @defaultValue true
* @see {@link https://swr.vercel.app/docs/revalidation | Revalidation Documentation}
*/
revalidateOnFocus: boolean;
/**
* automatically revalidate when the browser regains a network connection (via `navigator.onLine`)
*
* When enabled, SWR will automatically revalidate data when the browser
* goes from offline to online state, ensuring data is up-to-date when
* connectivity is restored.
*
* @defaultValue true
* @see {@link https://swr.vercel.app/docs/revalidation | Revalidation Documentation}
*/
revalidateOnReconnect: boolean;
/**
* enable or disable automatic revalidation when component is mounted
*
* Controls whether SWR should automatically fetch data when the component
* mounts. When `undefined`, the behavior depends on `revalidateIfStale`.
*
* @defaultValue undefined (inherits from revalidateIfStale)
*/
revalidateOnMount?: boolean;
/**
* automatically revalidate even if there is stale data
* @defaultValue true
* @see {@link https://swr.vercel.app/docs/revalidation#disable-automatic-revalidations}
*/
revalidateIfStale: boolean;
/**
* retry when fetcher has an error
* @defaultValue true
*/
shouldRetryOnError: boolean | ((err: Error) => boolean);
/**
* keep the previous result when key is changed but data is not ready
* @defaultValue false
*/
keepPreviousData?: boolean;
/**
* @experimental enable React Suspense mode
* @defaultValue false
* @see {@link https://swr.vercel.app/docs/suspense}
*/
suspense?: boolean;
/**
* initial data to be returned (note: ***This is per-hook***)
* @see {@link https://swr.vercel.app/docs/with-nextjs}
*/
fallbackData?: Data | Promise<Data>;
/**
* warns when preload data is missing for a given key, this includes fallback
* data, preload calls, or initial data from the cache provider
* @defaultValue false
*/
strictServerPrefetchWarning?: boolean;
/**
* the fetcher function
*/
fetcher?: Fn;
/**
* array of middleware functions
* @see {@link https://swr.vercel.app/docs/middleware}
*/
use?: Middleware[];
/**
* a key-value object of multiple fallback data
* @see {@link https://swr.vercel.app/docs/with-nextjs#pre-rendering-with-default-data}
*/
fallback: {
[key: string]: any;
};
/**
* Function to detect whether pause revalidations, will ignore fetched data and errors when it returns true. Returns false by default.
*/
isPaused: () => boolean;
/**
* callback function when a request takes too long to load (see `loadingTimeout`)
*/
onLoadingSlow: (key: string, config: Readonly<PublicConfiguration<Data, Error, Fn>>) => void;
/**
* callback function when a request finishes successfully
*/
onSuccess: (data: Data, key: string, config: Readonly<PublicConfiguration<Data, Error, Fn>>) => void;
/**
* callback function when a request returns an error
*/
onError: (err: Error, key: string, config: Readonly<PublicConfiguration<Data, Error, Fn>>) => void;
/**
* handler for error retry
*/
onErrorRetry: (err: Error, key: string, config: Readonly<PublicConfiguration<Data, Error, Fn>>, revalidate: Revalidator, revalidateOpts: Required<RevalidatorOptions>) => void;
/**
* callback function when a request is ignored due to race conditions
*/
onDiscarded: (key: string) => void;
/**
* Comparison function used to detect when returned data has changed, to avoid spurious rerenders. By default, [dequal](https://github.com/lukeed/dequal) is used.
*/
compare: (a: Data | undefined, b: Data | undefined) => boolean;
/**
* IsOnline and isVisible are functions that return a boolean, to determine if the application is "active". By default, SWR will bail out a revalidation if these conditions are not met.
* @see {@link https://swr.vercel.app/docs/advanced/react-native#customize-focus-and-reconnect-events}
*/
isOnline: () => boolean;
/**
* IsOnline and isVisible are functions that return a boolean, to determine if the application is "active". By default, SWR will bail out a revalidation if these conditions are not met.
* @see {@link https://swr.vercel.app/docs/advanced/react-native#customize-focus-and-reconnect-events}
*/
isVisible: () => boolean;
}
type FullConfiguration<Data = any, Error = any, Fn extends Fetcher = BareFetcher> = InternalConfiguration & PublicConfiguration<Data, Error, Fn>;
/**
* Provider configuration for custom focus and reconnect event handling.
*
* This configuration allows custom implementations for detecting window focus
* and network reconnection events. Useful for React Native or other environments
* where the default browser APIs are not available.
*
* @public
* @see {@link https://swr.vercel.app/docs/advanced/react-native | React Native Documentation}
*/
type ProviderConfiguration = {
/**
* Initialize focus event listener.
*
* @param callback - Function to call when window gains focus
* @returns Optional cleanup function to remove the listener
*/
initFocus: (callback: () => void) => (() => void) | void;
/**
* Initialize reconnect event listener.
*
* @param callback - Function to call when network reconnects
* @returns Optional cleanup function to remove the listener
*/
initReconnect: (callback: () => void) => (() => void) | void;
};
/**
* The main useSWR hook interface with multiple overloads for different usage patterns.
*
* This interface provides type-safe overloads for various ways to call useSWR,
* from simple key-only calls to complex configurations with custom fetchers.
* The overloads ensure proper type inference for data, error, and configuration.
*
* @public
*
* @example Basic usage
* ```ts
* const { data, error } = useSWR('/api/data', fetcher)
* ```
*
* @example With configuration
* ```ts
* const { data, error } = useSWR('/api/data', fetcher, {
* refreshInterval: 1000,
* revalidateOnFocus: false
* })
* ```
*
* @example Conditional fetching
* ```ts
* const { data, error } = useSWR(
* user.id ? `/api/user/${user.id}` : null,
* fetcher
* )
* ```
*
* @example Dynamic key with function
* ```ts
* const { data, error } = useSWR(
* () => user.id ? [`/api/user/${user.id}`, user.token] : null,
* ([url, token]) => fetcher(url, { headers: { Authorization: token } })
* )
* ```
*/
interface SWRHook {
/**
* Basic usage with just a key. Requires a global fetcher to be configured,
* or can be used for client-side state management without fetching.
*
* @example
* ```ts
* // With global fetcher
* const { data } = useSWR('/api/user')
*
* // Client state management
* const { data, mutate } = useSWR('user-settings')
* mutate({ theme: 'dark' })
* ```
*/
<Data = any, Error = any, SWRKey extends Key = StrictKey>(key: SWRKey): SWRResponse<Data, Error>;
/**
* Most common usage pattern with key and explicit fetcher function.
* The fetcher receives the key as its argument and returns the data.
*
* @example
* ```ts
* const { data, error } = useSWR('/api/user/123',
* (url) => fetch(url).then(res => res.json())
* )
* ```
*/
<Data = any, Error = any, SWRKey extends Key = StrictKey>(key: SWRKey, fetcher: Fetcher<Data, SWRKey> | null): SWRResponse<Data, Error>;
/**
* Key with fetcher using relaxed key constraints for dynamic or complex keys.
* Allows more flexible key types including functions and objects.
*
* @example
* ```ts
* const { data } = useSWR(
* () => user ? ['/api/posts', user.id] : null,
* ([url, userId]) => fetchUserPosts(url, userId)
* )
* ```
*/
<Data = any, Error = any, SWRKey extends Key = Key>(key: SWRKey, fetcher: Fetcher<Data, SWRKey> | null): SWRResponse<Data, Error>;
/**
* Key-only with advanced configuration options and strict typing.
* Useful when you need specific SWR options but rely on a global fetcher.
*
* @example
* ```ts
* const { data } = useSWR<User>('/api/user', {
* refreshInterval: 5000,
* revalidateOnFocus: false
* })
* ```
*/
<Data = any, Error = any, SWRKey extends Key = StrictKey, SWROptions extends SWRConfiguration<Data, Error, Fetcher<Data, SWRKey>> | undefined = SWRConfiguration<Data, Error, Fetcher<Data, SWRKey>> | undefined>(key: SWRKey): SWRResponse<Data, Error, SWROptions>;
/**
* Key with fetcher and advanced configuration options with strict typing.
* Provides full control over fetching behavior and SWR options.
*
* @example
* ```ts
* const { data } = useSWR('/api/data', fetcher, {
* suspense: true,
* fallbackData: initialData
* })
* ```
*/
<Data = any, Error = any, SWRKey extends Key = StrictKey, SWROptions extends SWRConfiguration<Data, Error, Fetcher<Data, SWRKey>> | undefined = SWRConfiguration<Data, Error, Fetcher<Data, SWRKey>> | undefined>(key: SWRKey, fetcher: Fetcher<Data, SWRKey> | null): SWRResponse<Data, Error, SWROptions>;
/**
* Key with configuration object but no explicit fetcher. Uses global fetcher
* or can be used for pure client state management with configuration.
*
* @example
* ```ts
* // With global fetcher and config
* const { data } = useSWR('/api/user', {
* refreshInterval: 1000
* })
*
* // Client state with config
* const { data } = useSWR('local-state', {
* fallbackData: defaultValue
* })
* ```
*/
<Data = any, Error = any, SWRKey extends Key = StrictKey, SWROptions extends SWRConfiguration<Data, Error, Fetcher<Data, SWRKey>> | undefined = SWRConfiguration<Data, Error, Fetcher<Data, SWRKey>> | undefined>(key: SWRKey, config: SWRConfigurationWithOptionalFallback<SWROptions>): SWRResponse<Data, Error, SWROptions>;
/**
* Complete signature with key, fetcher, and configuration options.
* Provides maximum flexibility and control over all SWR behavior.
*
* @example
* ```ts
* const { data, error, isLoading } = useSWR(
* '/api/user',
* async (url) => {
* const res = await fetch(url)
* if (!res.ok) throw new Error('Failed to fetch')
* return res.json()
* },
* {
* refreshInterval: 5000,
* onError: (error) => console.error('SWR Error:', error),
* fallbackData: { name: 'Loading...' }
* }
* )
* ```
*/
<Data = any, Error = any, SWRKey extends Key = StrictKey, SWROptions extends SWRConfiguration<Data, Error, Fetcher<Data, SWRKey>> | undefined = SWRConfiguration<Data, Error, Fetcher<Data, SWRKey>> | undefined>(key: SWRKey, fetcher: Fetcher<Data, SWRKey> | null, config: SWRConfigurationWithOptionalFallback<SWROptions>): SWRResponse<Data, Error, SWROptions>;
/**
* Simple key-only usage with flexible key types. Most permissive overload
* that accepts any valid key format.
*
* @example
* ```ts
* const { data } = useSWR('/api/data')
* const { data: userData } = useSWR(['user', userId])
* const { data: settings } = useSWR({ endpoint: '/settings', version: 'v1' })
* ```
*/
<Data = any, Error = any>(key: Key): SWRResponse<Data, Error>;
/**
* Key-only with configuration options using bare fetcher constraints.
* Suitable for cases where fetcher type safety is less important.
*
* @example
* ```ts
* const { data } = useSWR('/api/data', {
* dedupingInterval: 5000
* })
* ```
*/
<Data = any, Error = any, SWROptions extends SWRConfiguration<Data, Error, BareFetcher<Data>> | undefined = SWRConfiguration<Data, Error, BareFetcher<Data>> | undefined>(key: Key): SWRResponse<Data, Error, SWROptions>;
/**
* Key with bare fetcher function that accepts any arguments.
* Provides less type safety but maximum flexibility for fetcher signatures.
*
* @example
* ```ts
* const { data } = useSWR('/api/user',
* (...args) => customFetcher(...args)
* )
* ```
*/
<Data = any, Error = any, SWROptions extends SWRConfiguration<Data, Error, BareFetcher<Data>> | undefined = SWRConfiguration<Data, Error, BareFetcher<Data>> | undefined>(key: Key, fetcher: BareFetcher<Data> | null): SWRResponse<Data, Error, SWROptions>;
/**
* Key with configuration using relaxed fetcher typing constraints.
* Useful when working with dynamic or loosely-typed fetcher functions.
*
* @example
* ```ts
* const { data } = useSWR(dynamicKey, {
* fetcher: customFetcher,
* refreshInterval: 2000
* })
* ```
*/
<Data = any, Error = any, SWROptions extends SWRConfiguration<Data, Error, BareFetcher<Data>> | undefined = SWRConfiguration<Data, Error, BareFetcher<Data>> | undefined>(key: Key, config: SWRConfigurationWithOptionalFallback<SWROptions>): SWRResponse<Data, Error, SWROptions>;
/**
* Complete signature with key, bare fetcher, and configuration.
* Most flexible overload with minimal type constraints, suitable for
* complex scenarios where strict typing isn't feasible.
*
* @example
* ```ts
* const { data } = useSWR(
* complexKey,
* (...args) => legacyFetcher(...args),
* {
* refreshInterval: 10000,
* errorRetryCount: 3
* }
* )
* ```
*/
<Data = any, Error = any, SWROptions extends SWRConfiguration<Data, Error, BareFetcher<Data>> | undefined = SWRConfiguration<Data, Error, BareFetcher<Data>> | undefined>(key: Key, fetcher: BareFetcher<Data> | null, config: SWRConfigurationWithOptionalFallback<SWROptions>): SWRResponse<Data, Error, SWROptions>;
}
/**
* Middleware function type for extending SWR functionality.
*
* Middleware functions receive the next SWR hook in the chain and return
* a modified hook function. This allows for composition of multiple
* middleware functions to add features like logging, caching, or
* request/response transformation.
*
* The middleware guarantees that a SWRHook receives a key, fetcher,
* and config as arguments, providing a consistent interface for
* middleware authors.
*
* @param useSWRNext - The next SWR hook function in the middleware chain
* @returns A new SWR hook function with middleware functionality applied
*
* @template Data - The type of data returned by the fetcher
* @template Error - The type of error that can be thrown
*
* @public
* @see {@link https://swr.vercel.app/docs/middleware | Middleware Documentation}
*
* @example
* ```ts
* const logger: Middleware = (useSWRNext) => (key, fetcher, config) => {
* console.log('SWR Request:', key)
* return useSWRNext(key, fetcher, config)
* }
* ```
*/
type Middleware = (useSWRNext: SWRHook) => <Data = any, Error = any>(key: Key, fetcher: BareFetcher<Data> | null, config: SWRConfiguration<Data, Error, BareFetcher<Data>>) => SWRResponse<Data, Error>;
/**
* Represents a tuple of arguments that can be passed to a fetcher.
*
* The first element is typically the primary key (like a URL), followed
* by additional parameters that affect the request (like query parameters,
* headers, or request options).
*
*/
type ArgumentsTuple = readonly [any, ...unknown[]];
/**
* Valid types for SWR keys.
*
* SWR keys identify unique requests and can be:
* - `string`: Simple URL or identifier
* - `ArgumentsTuple`: Array with URL and additional parameters
* - `Record<any, any>`: Object that will be serialized
* - `null | undefined | false`: Falsy values disable the request
*
* When a key is falsy, SWR will not make the request, allowing for
* conditional fetching based on application state.
*
* @public
*
* @example
* ```ts
* // String key
* useSWR('/api/users', fetcher)
*
* // Array key with parameters
* useSWR(['/api/user', userId], ([url, id]) => fetcher(`${url}/${id}`))
*
* // Object key
* useSWR({ url: '/api/data', params: { page: 1 } }, fetcher)
*
* // Conditional key
* useSWR(userId ? `/api/user/${userId}` : null, fetcher)
* ```
*/
type Arguments = string | ArgumentsTuple | Record<any, any> | null | undefined | false;
/**
* SWR key that can be static or a function that returns arguments.
*
* When a function is provided, it's called on each render to determine
* the current key. This allows for dynamic keys based on component state
* or props.
*
* @public
*
* @example
* ```ts
* // Static key
* useSWR('/api/data', fetcher)
*
* // Dynamic key function
* useSWR(() => user ? `/api/user/${user.id}` : null, fetcher)
* ```
*/
type Key = Arguments | (() => Arguments);
/**
* Strict tuple key type that only allows tuples or falsy values.
*
* @internal
*/
type StrictTupleKey = ArgumentsTuple | null | undefined | false;
/**
* Strict key type for internal use.
*
* @internal
*/
type StrictKey = StrictTupleKey | (() => StrictTupleKey);
/**
* Callback function type for mutator operations.
*
* This function receives the current cached data and can return new data
* to update the cache. It can be synchronous or asynchronous, and can
* return undefined to indicate no change should be made.
*
* @template Data - The type of the cached data
* @param currentData - The current data in the cache (may be undefined)
* @returns New data to set, undefined for no change, or a Promise resolving to either
*
* @public
*
* @example
* ```ts
* // Increment a counter
* mutate(key, (current: number = 0) => current + 1)
*
* // Async update
* mutate(key, async (current) => {
* const updated = await updateData(current)
* return updated
* })
* ```
*/
type MutatorCallback<Data = any> = (currentData?: Data) => Promise<undefined | Data> | undefined | Data;
/**
* Options for configuring mutator behavior.
*
* These options control how the mutation affects the cache, revalidation,
* and error handling behavior.
*
* @template Data - The type of the data related to the key
* @template MutationData - The type of the data returned by the mutator
*
* @public
*/
type MutatorOptions<Data = any, MutationData = Data> = {
/**
* Whether to revalidate the cache after mutation.
*
* Can be a boolean or a function that receives the new data and key
* to determine whether revalidation should occur.
*
* @defaultValue true
*/
revalidate?: boolean | ((data: Data, key: Arguments) => boolean);
/**
* Whether and how to populate the cache with mutation results.
*
* - `false`: Don't update the cache
* - `true`: Update cache with mutation result directly
* - Function: Transform mutation result before caching
*
* @defaultValue true
*/
populateCache?: boolean | ((result: MutationData, currentData: Data | undefined) => Data);
/**
* Optimistic data to show immediately while mutation is pending.
*
* Can be the data directly or a function that computes it based on
* current and displayed data. Useful for immediate UI feedback.
*
* @defaultValue undefined
*/
optimisticData?: Data | ((currentData: Data | undefined, displayedData: Data | undefined) => Data);
/**
* Whether to rollback optimistic updates on error.
*
* Can be a boolean or a function that receives the error to determine
* whether rollback should occur.
*
* @defaultValue true
*/
rollbackOnError?: boolean | ((error: unknown) => boolean);
/**
* Whether to throw errors instead of returning them in the error field.
*
* When true, errors will be thrown and can be caught with try/catch.
* When false, errors are returned in the response object.
*
* @defaultValue false
*/
throwOnError?: boolean;
};
type MutatorConfig = {
revalidate?: boolean;
populateCache?: boolean;
};
type Broadcaster<Data = any, Error = any> = (cache: Cache<Data>, key: string, data: Data, error?: Error, isValidating?: boolean, revalidate?: boolean, populateCache?: boolean) => Promise<Data>;
/**
* Internal state structure stored in the cache.
*
* This represents the complete state for a cache entry, including
* data, error, and loading states. All fields are optional as they
* may not be present depending on the request lifecycle.
*
* @template Data - The type of data stored
* @template Error - The type of error that can occur
*
* @internal
*/
type State<Data = any, Error = any> = {
/** The cached data, if available */
data?: Data;
/** The error object, if an error occurred */
error?: Error;
/** Whether a revalidation is currently in progress */
isValidating?: boolean;
/** Whether this is the initial load with no cached data */
isLoading?: boolean;
};
type MutatorFn<Data = any> = (cache: Cache, key: Key, data?: Data | Promise<Data> | MutatorCallback<Data>, opts?: boolean | MutatorOptions<Data>) => Promise<Data | undefined>;
type MutatorWrapper<Fn> = Fn extends (...args: [...infer Parameters]) => infer Result ? Parameters[3] extends boolean ? Result : Parameters[3] extends Required<Pick<MutatorOptions, 'populateCache'>> ? Parameters[3]['populateCache'] extends false ? never : Result : Result : never;
type Mutator<Data = any> = MutatorWrapper<MutatorFn<Data>>;
interface ScopedMutator {
/**
* @typeParam Data - The type of the data related to the key
* @typeParam MutationData - The type of the data returned by the mutator
*/
<Data = any, MutationData = Data>(matcher: (key?: Arguments) => boolean, data?: MutationData | Promise<MutationData> | MutatorCallback<MutationData>, opts?: boolean | MutatorOptions<Data, MutationData>): Promise<Array<MutationData | undefined>>;
/**
* @typeParam Data - The type of the data related to the key
* @typeParam MutationData - The type of the data returned by the mutator
*/
<Data = any, T = Data>(key: Arguments, data?: T | Promise<T> | MutatorCallback<T>, opts?: boolean | MutatorOptions<Data, T>): Promise<T | undefined>;
}
/**
* @typeParam Data - The type of the data related to the key
* @typeParam MutationData - The type of the data returned by the mutator
*/
type KeyedMutator<Data> = <MutationData = Data>(data?: Data | Promise<Data | undefined> | MutatorCallback<Data>, opts?: boolean | MutatorOptions<Data, MutationData>) => Promise<Data | MutationData | undefined>;
type SWRConfiguration<Data = any, Error = any, Fn extends BareFetcher<any> = BareFetcher<any>> = Partial<PublicConfiguration<Data, Error, Fn>> & Partial<ProviderConfiguration> & {
provider?: (cache: Readonly<Cache>) => Cache;
};
type IsLoadingResponse<Data = any, Options = SWRDefaultOptions<Data>> = SWRGlobalConfig extends {
suspense: true;
} ? Options extends {
suspense: true;
} ? false : false : boolean;
type SWRDefaultOptions<Data> = SWRConfiguration<Data, Error, Fetcher<Data, Key>>;
type SWRConfigurationWithOptionalFallback<Options> = Options extends SWRConfiguration & Required<Pick<SWRConfiguration, 'fallbackData'>> ? Omit<Options, 'fallbackData'> & Pick<Partial<Options>, 'fallbackData'> : Options;
/**
* The response object returned by SWR hooks.
*
* This interface represents the return value of useSWR and related hooks,
* providing access to data, error state, and control functions.
*
* @template Data - The type of data returned by the fetcher
* @template Error - The type of error that can be thrown
* @template Config - The configuration type used to determine blocking behavior
*
* @public
*/
interface SWRResponse<Data = any, Error = any, Config = any> {
/**
* The data returned by the fetcher function.
*
* - When suspense is enabled or fallbackData is provided: always defined
* - Otherwise: `undefined` during initial load or when key is falsy
*/
data: BlockingData<Data, Config> extends true ? Data : Data | undefined;
/**
* The error object thrown by the fetcher function.
*
* `undefined` when there's no error or when a request is in progress.
*/
error: Error | undefined;
/**
* Function to mutate the cached data for this specific key.
*
* This is a bound version of the global mutate function that automatically
* uses the current key, providing type safety and convenience.
*/
mutate: KeyedMutator<Data>;
/**
* Whether the request is currently being validated (loading fresh data).
*
* `true` during initial load, revalidation, or when mutate is called
* with a promise or async function.
*/
isValidating: boolean;
/**
* Whether the request is in initial loading state.
*
* `true` only during the initial load when there's no cached data.
* Unlike `isValidating`, this becomes `false` once data is available.
*/
isLoading: IsLoadingResponse<Data, Config>;
}
type KeyLoader<Args extends Arguments = Arguments> = ((index: number, previousPageData: any | null) => Args) | null;
interface RevalidatorOptions {
retryCount?: number;
dedupe?: boolean;
}
type Revalidator = (revalidateOpts?: RevalidatorOptions) => Promise<boolean> | void;
type RevalidateEvent = typeof revalidateEvents.FOCUS_EVENT | typeof revalidateEvents.RECONNECT_EVENT | typeof revalidateEvents.MUTATE_EVENT | typeof revalidateEvents.ERROR_REVALIDATE_EVENT;
type RevalidateCallbackReturnType = {
[revalidateEvents.FOCUS_EVENT]: void;
[revalidateEvents.RECONNECT_EVENT]: void;
[revalidateEvents.MUTATE_EVENT]: Promise<boolean>;
[revalidateEvents.ERROR_REVALIDATE_EVENT]: void;
};
type RevalidateCallback = <K extends RevalidateEvent>(type: K, opts?: any) => RevalidateCallbackReturnType[K];
/**
* Cache interface for storing SWR state.
*
* This interface defines the contract for cache providers used by SWR.
* The default implementation uses a Map, but custom cache providers
* can implement this interface to provide different storage mechanisms.
*
* @template Data - The type of data stored in the cache
*
* @public
* @see {@link https://swr.vercel.app/docs/advanced/cache | Cache Documentation}
*/
interface Cache<Data = any> {
/**
* Get an iterator of all cache keys.
*
* @returns Iterator that yields all cache keys as strings
*/
keys(): IterableIterator<string>;
/**
* Get the cached state for a key.
*
* @param key - The cache key to look up
* @returns The cached state or undefined if not found
*/
get(key: string): State<Data> | undefined;
/**
* Set the cached state for a key.
*
* @param key - The cache key to set
* @param value - The state to cache
*/
set(key: string, value: State<Data>): void;
/**
* Delete a cached entry.
*
* @param key - The cache key to delete
*/
delete(key: string): void;
}
interface StateDependencies {
data?: boolean;
error?: boolean;
isValidating?: boolean;
isLoading?: boolean;
}
export type { Arguments, BareFetcher, BlockingData, Broadcaster, Cache, Fetcher, FetcherResponse, FullConfiguration, GlobalState, InternalConfiguration, IsLoadingResponse, Key, KeyLoader, KeyedMutator, Middleware, Mutator, MutatorCallback, MutatorConfig, MutatorFn, MutatorOptions, MutatorWrapper, ProviderConfiguration, PublicConfiguration, RevalidateCallback, RevalidateEvent, Revalidator, RevalidatorOptions, SWRConfiguration, SWRHook, SWRResponse, ScopedMutator, State, StateDependencies, StrictTupleKey };

872
node_modules/swr/dist/_internal/types.d.ts generated vendored Normal file
View File

@@ -0,0 +1,872 @@
import { SWRGlobalConfig } from '../index/index.js';
import * as revalidateEvents from './events.js';
/**
* Global state tuple containing SWR's internal state management structures.
*
* This is the core state structure that manages all SWR operations internally.
* Each element serves a specific purpose in the SWR ecosystem.
*
* @internal
*/
type GlobalState = [
/** Event revalidators: Maps cache keys to arrays of revalidation callbacks */
Record<string, RevalidateCallback[]>,
/** Mutation timestamps: Maps cache keys to [start_timestamp, end_timestamp] tuples */
Record<string, [number, number]>,
/** Fetch cache: Maps cache keys to [data, timestamp] tuples */
Record<string, [any, number]>,
/** Preload cache: Maps cache keys to fetcher responses */
Record<string, FetcherResponse<any>>,
/** Scoped mutator function for cache updates */
ScopedMutator,
/** Cache setter function with prev/current value comparison */
(key: string, value: any, prev: any) => void,
/** Cache subscriber function that returns an unsubscribe function */
(key: string, callback: (current: any, prev: any) => void) => () => void
];
/**
* Response type that can be returned by fetcher functions.
*
* @template Data - The type of data returned by the fetcher
* @public
*/
type FetcherResponse<Data = unknown> = Data | Promise<Data>;
/**
* Basic fetcher function that accepts any arguments and returns data or a promise.
*
* This is the most permissive fetcher type, allowing any number of arguments
* of any type. Used when type safety is not required or when dealing with
* dynamic fetcher signatures.
*
* @template Data - The type of data returned by the fetcher
* @param args - Variable arguments passed to the fetcher
* @returns Data or a Promise that resolves to data
* @public
*/
type BareFetcher<Data = unknown> = (...args: any[]) => FetcherResponse<Data>;
/**
* Typed fetcher function that is constrained by the SWR key type.
*
* Provides type safety by ensuring the fetcher argument matches the key type.
* The conditional type logic ensures that:
* - If the key is a function returning a value, the fetcher receives that value
* - If the key is falsy (null, undefined, false), the fetcher is never called
* - Otherwise, the fetcher receives the key directly as its argument
*
* @template Data - The type of data returned by the fetcher
* @template SWRKey - The type of the SWR key, used to infer fetcher arguments
* @public
*/
type Fetcher<Data = unknown, SWRKey extends Key = Key> = SWRKey extends () => infer Arg | null | undefined | false ? (arg: Arg) => FetcherResponse<Data> : SWRKey extends null | undefined | false ? never : SWRKey extends infer Arg ? (arg: Arg) => FetcherResponse<Data> : never;
/**
* Determines if data should block rendering based on suspense configuration.
*
* This conditional type is used internally to determine the return type of `data`
* in SWRResponse. When suspense is enabled or fallbackData is provided, data
* will never be undefined, allowing for non-nullable return types.
*
* The type resolution follows this logic:
* 1. If global suspense is enabled → `true` (data never undefined)
* 2. If no options provided → `false` (data can be undefined)
* 3. If suspense is enabled in options → `true` (data never undefined)
* 4. If fallbackData is provided → `true` (data never undefined)
* 5. Otherwise → `false` (data can be undefined)
*
* @template Data - The data type
* @template Options - The SWR configuration options
* @returns `true` if data is guaranteed to be defined, `false` if it can be undefined
* @internal
*/
type BlockingData<Data = any, Options = SWRDefaultOptions<Data>> = SWRGlobalConfig extends {
suspense: true;
} ? true : Options extends undefined ? false : Options extends {
suspense: true;
} ? true : Options extends {
fallbackData: Data | Promise<Data>;
} ? true : false;
/**
* Configuration types that are only used internally, not exposed to the user.
*
* These options are managed internally by SWR and passed between internal
* functions. They are not part of the public API and should not be used
* directly by consumers.
*
* @internal
*/
interface InternalConfiguration {
/** The cache instance used to store SWR data and state */
cache: Cache;
/** Scoped mutator function for updating cache entries */
mutate: ScopedMutator;
}
/**
* Public configuration options for SWR.
*
* This interface defines all the configuration options that users can pass
* to customize SWR's behavior. These options can be provided globally via
* SWRConfig or per-hook via the config parameter.
*
* @template Data - The type of data returned by the fetcher
* @template Error - The type of error that can be thrown
* @template Fn - The fetcher function type
*
* @public
* @see {@link https://swr.vercel.app/docs/options | SWR Options Documentation}
*/
interface PublicConfiguration<Data = any, Error = any, Fn extends Fetcher = BareFetcher> {
/**
* error retry interval in milliseconds
* @defaultValue 5000
*/
errorRetryInterval: number;
/** max error retry count */
errorRetryCount?: number;
/**
* timeout to trigger the onLoadingSlow event in milliseconds
* @defaultValue 3000
*/
loadingTimeout: number;
/**
* only revalidate once during a time span in milliseconds
* @defaultValue 5000
*/
focusThrottleInterval: number;
/**
* dedupe requests with the same key in this time span in milliseconds
* @defaultValue 2000
*/
dedupingInterval: number;
/**
* * Disabled by default: `refreshInterval = 0`
* * If set to a number, polling interval in milliseconds
* * If set to a function, the function will receive the latest data and should return the interval in milliseconds
* @see {@link https://swr.vercel.app/docs/revalidation}
*/
refreshInterval?: number | ((latestData: Data | undefined) => number);
/**
* polling when the window is invisible (if `refreshInterval` is enabled)
* @defaultValue false
*/
refreshWhenHidden?: boolean;
/**
* polling when the browser is offline (determined by `navigator.onLine`)
*
* When enabled, SWR will continue polling even when the browser is offline.
* This can be useful for applications that need to check for connectivity
* or cache updates while offline.
*
* @defaultValue false
*/
refreshWhenOffline?: boolean;
/**
* automatically revalidate when window gets focused
*
* When enabled, SWR will automatically revalidate data when the user
* returns focus to the window/tab. This ensures data freshness when
* users switch between applications.
*
* @defaultValue true
* @see {@link https://swr.vercel.app/docs/revalidation | Revalidation Documentation}
*/
revalidateOnFocus: boolean;
/**
* automatically revalidate when the browser regains a network connection (via `navigator.onLine`)
*
* When enabled, SWR will automatically revalidate data when the browser
* goes from offline to online state, ensuring data is up-to-date when
* connectivity is restored.
*
* @defaultValue true
* @see {@link https://swr.vercel.app/docs/revalidation | Revalidation Documentation}
*/
revalidateOnReconnect: boolean;
/**
* enable or disable automatic revalidation when component is mounted
*
* Controls whether SWR should automatically fetch data when the component
* mounts. When `undefined`, the behavior depends on `revalidateIfStale`.
*
* @defaultValue undefined (inherits from revalidateIfStale)
*/
revalidateOnMount?: boolean;
/**
* automatically revalidate even if there is stale data
* @defaultValue true
* @see {@link https://swr.vercel.app/docs/revalidation#disable-automatic-revalidations}
*/
revalidateIfStale: boolean;
/**
* retry when fetcher has an error
* @defaultValue true
*/
shouldRetryOnError: boolean | ((err: Error) => boolean);
/**
* keep the previous result when key is changed but data is not ready
* @defaultValue false
*/
keepPreviousData?: boolean;
/**
* @experimental enable React Suspense mode
* @defaultValue false
* @see {@link https://swr.vercel.app/docs/suspense}
*/
suspense?: boolean;
/**
* initial data to be returned (note: ***This is per-hook***)
* @see {@link https://swr.vercel.app/docs/with-nextjs}
*/
fallbackData?: Data | Promise<Data>;
/**
* warns when preload data is missing for a given key, this includes fallback
* data, preload calls, or initial data from the cache provider
* @defaultValue false
*/
strictServerPrefetchWarning?: boolean;
/**
* the fetcher function
*/
fetcher?: Fn;
/**
* array of middleware functions
* @see {@link https://swr.vercel.app/docs/middleware}
*/
use?: Middleware[];
/**
* a key-value object of multiple fallback data
* @see {@link https://swr.vercel.app/docs/with-nextjs#pre-rendering-with-default-data}
*/
fallback: {
[key: string]: any;
};
/**
* Function to detect whether pause revalidations, will ignore fetched data and errors when it returns true. Returns false by default.
*/
isPaused: () => boolean;
/**
* callback function when a request takes too long to load (see `loadingTimeout`)
*/
onLoadingSlow: (key: string, config: Readonly<PublicConfiguration<Data, Error, Fn>>) => void;
/**
* callback function when a request finishes successfully
*/
onSuccess: (data: Data, key: string, config: Readonly<PublicConfiguration<Data, Error, Fn>>) => void;
/**
* callback function when a request returns an error
*/
onError: (err: Error, key: string, config: Readonly<PublicConfiguration<Data, Error, Fn>>) => void;
/**
* handler for error retry
*/
onErrorRetry: (err: Error, key: string, config: Readonly<PublicConfiguration<Data, Error, Fn>>, revalidate: Revalidator, revalidateOpts: Required<RevalidatorOptions>) => void;
/**
* callback function when a request is ignored due to race conditions
*/
onDiscarded: (key: string) => void;
/**
* Comparison function used to detect when returned data has changed, to avoid spurious rerenders. By default, [dequal](https://github.com/lukeed/dequal) is used.
*/
compare: (a: Data | undefined, b: Data | undefined) => boolean;
/**
* IsOnline and isVisible are functions that return a boolean, to determine if the application is "active". By default, SWR will bail out a revalidation if these conditions are not met.
* @see {@link https://swr.vercel.app/docs/advanced/react-native#customize-focus-and-reconnect-events}
*/
isOnline: () => boolean;
/**
* IsOnline and isVisible are functions that return a boolean, to determine if the application is "active". By default, SWR will bail out a revalidation if these conditions are not met.
* @see {@link https://swr.vercel.app/docs/advanced/react-native#customize-focus-and-reconnect-events}
*/
isVisible: () => boolean;
}
type FullConfiguration<Data = any, Error = any, Fn extends Fetcher = BareFetcher> = InternalConfiguration & PublicConfiguration<Data, Error, Fn>;
/**
* Provider configuration for custom focus and reconnect event handling.
*
* This configuration allows custom implementations for detecting window focus
* and network reconnection events. Useful for React Native or other environments
* where the default browser APIs are not available.
*
* @public
* @see {@link https://swr.vercel.app/docs/advanced/react-native | React Native Documentation}
*/
type ProviderConfiguration = {
/**
* Initialize focus event listener.
*
* @param callback - Function to call when window gains focus
* @returns Optional cleanup function to remove the listener
*/
initFocus: (callback: () => void) => (() => void) | void;
/**
* Initialize reconnect event listener.
*
* @param callback - Function to call when network reconnects
* @returns Optional cleanup function to remove the listener
*/
initReconnect: (callback: () => void) => (() => void) | void;
};
/**
* The main useSWR hook interface with multiple overloads for different usage patterns.
*
* This interface provides type-safe overloads for various ways to call useSWR,
* from simple key-only calls to complex configurations with custom fetchers.
* The overloads ensure proper type inference for data, error, and configuration.
*
* @public
*
* @example Basic usage
* ```ts
* const { data, error } = useSWR('/api/data', fetcher)
* ```
*
* @example With configuration
* ```ts
* const { data, error } = useSWR('/api/data', fetcher, {
* refreshInterval: 1000,
* revalidateOnFocus: false
* })
* ```
*
* @example Conditional fetching
* ```ts
* const { data, error } = useSWR(
* user.id ? `/api/user/${user.id}` : null,
* fetcher
* )
* ```
*
* @example Dynamic key with function
* ```ts
* const { data, error } = useSWR(
* () => user.id ? [`/api/user/${user.id}`, user.token] : null,
* ([url, token]) => fetcher(url, { headers: { Authorization: token } })
* )
* ```
*/
interface SWRHook {
/**
* Basic usage with just a key. Requires a global fetcher to be configured,
* or can be used for client-side state management without fetching.
*
* @example
* ```ts
* // With global fetcher
* const { data } = useSWR('/api/user')
*
* // Client state management
* const { data, mutate } = useSWR('user-settings')
* mutate({ theme: 'dark' })
* ```
*/
<Data = any, Error = any, SWRKey extends Key = StrictKey>(key: SWRKey): SWRResponse<Data, Error>;
/**
* Most common usage pattern with key and explicit fetcher function.
* The fetcher receives the key as its argument and returns the data.
*
* @example
* ```ts
* const { data, error } = useSWR('/api/user/123',
* (url) => fetch(url).then(res => res.json())
* )
* ```
*/
<Data = any, Error = any, SWRKey extends Key = StrictKey>(key: SWRKey, fetcher: Fetcher<Data, SWRKey> | null): SWRResponse<Data, Error>;
/**
* Key with fetcher using relaxed key constraints for dynamic or complex keys.
* Allows more flexible key types including functions and objects.
*
* @example
* ```ts
* const { data } = useSWR(
* () => user ? ['/api/posts', user.id] : null,
* ([url, userId]) => fetchUserPosts(url, userId)
* )
* ```
*/
<Data = any, Error = any, SWRKey extends Key = Key>(key: SWRKey, fetcher: Fetcher<Data, SWRKey> | null): SWRResponse<Data, Error>;
/**
* Key-only with advanced configuration options and strict typing.
* Useful when you need specific SWR options but rely on a global fetcher.
*
* @example
* ```ts
* const { data } = useSWR<User>('/api/user', {
* refreshInterval: 5000,
* revalidateOnFocus: false
* })
* ```
*/
<Data = any, Error = any, SWRKey extends Key = StrictKey, SWROptions extends SWRConfiguration<Data, Error, Fetcher<Data, SWRKey>> | undefined = SWRConfiguration<Data, Error, Fetcher<Data, SWRKey>> | undefined>(key: SWRKey): SWRResponse<Data, Error, SWROptions>;
/**
* Key with fetcher and advanced configuration options with strict typing.
* Provides full control over fetching behavior and SWR options.
*
* @example
* ```ts
* const { data } = useSWR('/api/data', fetcher, {
* suspense: true,
* fallbackData: initialData
* })
* ```
*/
<Data = any, Error = any, SWRKey extends Key = StrictKey, SWROptions extends SWRConfiguration<Data, Error, Fetcher<Data, SWRKey>> | undefined = SWRConfiguration<Data, Error, Fetcher<Data, SWRKey>> | undefined>(key: SWRKey, fetcher: Fetcher<Data, SWRKey> | null): SWRResponse<Data, Error, SWROptions>;
/**
* Key with configuration object but no explicit fetcher. Uses global fetcher
* or can be used for pure client state management with configuration.
*
* @example
* ```ts
* // With global fetcher and config
* const { data } = useSWR('/api/user', {
* refreshInterval: 1000
* })
*
* // Client state with config
* const { data } = useSWR('local-state', {
* fallbackData: defaultValue
* })
* ```
*/
<Data = any, Error = any, SWRKey extends Key = StrictKey, SWROptions extends SWRConfiguration<Data, Error, Fetcher<Data, SWRKey>> | undefined = SWRConfiguration<Data, Error, Fetcher<Data, SWRKey>> | undefined>(key: SWRKey, config: SWRConfigurationWithOptionalFallback<SWROptions>): SWRResponse<Data, Error, SWROptions>;
/**
* Complete signature with key, fetcher, and configuration options.
* Provides maximum flexibility and control over all SWR behavior.
*
* @example
* ```ts
* const { data, error, isLoading } = useSWR(
* '/api/user',
* async (url) => {
* const res = await fetch(url)
* if (!res.ok) throw new Error('Failed to fetch')
* return res.json()
* },
* {
* refreshInterval: 5000,
* onError: (error) => console.error('SWR Error:', error),
* fallbackData: { name: 'Loading...' }
* }
* )
* ```
*/
<Data = any, Error = any, SWRKey extends Key = StrictKey, SWROptions extends SWRConfiguration<Data, Error, Fetcher<Data, SWRKey>> | undefined = SWRConfiguration<Data, Error, Fetcher<Data, SWRKey>> | undefined>(key: SWRKey, fetcher: Fetcher<Data, SWRKey> | null, config: SWRConfigurationWithOptionalFallback<SWROptions>): SWRResponse<Data, Error, SWROptions>;
/**
* Simple key-only usage with flexible key types. Most permissive overload
* that accepts any valid key format.
*
* @example
* ```ts
* const { data } = useSWR('/api/data')
* const { data: userData } = useSWR(['user', userId])
* const { data: settings } = useSWR({ endpoint: '/settings', version: 'v1' })
* ```
*/
<Data = any, Error = any>(key: Key): SWRResponse<Data, Error>;
/**
* Key-only with configuration options using bare fetcher constraints.
* Suitable for cases where fetcher type safety is less important.
*
* @example
* ```ts
* const { data } = useSWR('/api/data', {
* dedupingInterval: 5000
* })
* ```
*/
<Data = any, Error = any, SWROptions extends SWRConfiguration<Data, Error, BareFetcher<Data>> | undefined = SWRConfiguration<Data, Error, BareFetcher<Data>> | undefined>(key: Key): SWRResponse<Data, Error, SWROptions>;
/**
* Key with bare fetcher function that accepts any arguments.
* Provides less type safety but maximum flexibility for fetcher signatures.
*
* @example
* ```ts
* const { data } = useSWR('/api/user',
* (...args) => customFetcher(...args)
* )
* ```
*/
<Data = any, Error = any, SWROptions extends SWRConfiguration<Data, Error, BareFetcher<Data>> | undefined = SWRConfiguration<Data, Error, BareFetcher<Data>> | undefined>(key: Key, fetcher: BareFetcher<Data> | null): SWRResponse<Data, Error, SWROptions>;
/**
* Key with configuration using relaxed fetcher typing constraints.
* Useful when working with dynamic or loosely-typed fetcher functions.
*
* @example
* ```ts
* const { data } = useSWR(dynamicKey, {
* fetcher: customFetcher,
* refreshInterval: 2000
* })
* ```
*/
<Data = any, Error = any, SWROptions extends SWRConfiguration<Data, Error, BareFetcher<Data>> | undefined = SWRConfiguration<Data, Error, BareFetcher<Data>> | undefined>(key: Key, config: SWRConfigurationWithOptionalFallback<SWROptions>): SWRResponse<Data, Error, SWROptions>;
/**
* Complete signature with key, bare fetcher, and configuration.
* Most flexible overload with minimal type constraints, suitable for
* complex scenarios where strict typing isn't feasible.
*
* @example
* ```ts
* const { data } = useSWR(
* complexKey,
* (...args) => legacyFetcher(...args),
* {
* refreshInterval: 10000,
* errorRetryCount: 3
* }
* )
* ```
*/
<Data = any, Error = any, SWROptions extends SWRConfiguration<Data, Error, BareFetcher<Data>> | undefined = SWRConfiguration<Data, Error, BareFetcher<Data>> | undefined>(key: Key, fetcher: BareFetcher<Data> | null, config: SWRConfigurationWithOptionalFallback<SWROptions>): SWRResponse<Data, Error, SWROptions>;
}
/**
* Middleware function type for extending SWR functionality.
*
* Middleware functions receive the next SWR hook in the chain and return
* a modified hook function. This allows for composition of multiple
* middleware functions to add features like logging, caching, or
* request/response transformation.
*
* The middleware guarantees that a SWRHook receives a key, fetcher,
* and config as arguments, providing a consistent interface for
* middleware authors.
*
* @param useSWRNext - The next SWR hook function in the middleware chain
* @returns A new SWR hook function with middleware functionality applied
*
* @template Data - The type of data returned by the fetcher
* @template Error - The type of error that can be thrown
*
* @public
* @see {@link https://swr.vercel.app/docs/middleware | Middleware Documentation}
*
* @example
* ```ts
* const logger: Middleware = (useSWRNext) => (key, fetcher, config) => {
* console.log('SWR Request:', key)
* return useSWRNext(key, fetcher, config)
* }
* ```
*/
type Middleware = (useSWRNext: SWRHook) => <Data = any, Error = any>(key: Key, fetcher: BareFetcher<Data> | null, config: SWRConfiguration<Data, Error, BareFetcher<Data>>) => SWRResponse<Data, Error>;
/**
* Represents a tuple of arguments that can be passed to a fetcher.
*
* The first element is typically the primary key (like a URL), followed
* by additional parameters that affect the request (like query parameters,
* headers, or request options).
*
*/
type ArgumentsTuple = readonly [any, ...unknown[]];
/**
* Valid types for SWR keys.
*
* SWR keys identify unique requests and can be:
* - `string`: Simple URL or identifier
* - `ArgumentsTuple`: Array with URL and additional parameters
* - `Record<any, any>`: Object that will be serialized
* - `null | undefined | false`: Falsy values disable the request
*
* When a key is falsy, SWR will not make the request, allowing for
* conditional fetching based on application state.
*
* @public
*
* @example
* ```ts
* // String key
* useSWR('/api/users', fetcher)
*
* // Array key with parameters
* useSWR(['/api/user', userId], ([url, id]) => fetcher(`${url}/${id}`))
*
* // Object key
* useSWR({ url: '/api/data', params: { page: 1 } }, fetcher)
*
* // Conditional key
* useSWR(userId ? `/api/user/${userId}` : null, fetcher)
* ```
*/
type Arguments = string | ArgumentsTuple | Record<any, any> | null | undefined | false;
/**
* SWR key that can be static or a function that returns arguments.
*
* When a function is provided, it's called on each render to determine
* the current key. This allows for dynamic keys based on component state
* or props.
*
* @public
*
* @example
* ```ts
* // Static key
* useSWR('/api/data', fetcher)
*
* // Dynamic key function
* useSWR(() => user ? `/api/user/${user.id}` : null, fetcher)
* ```
*/
type Key = Arguments | (() => Arguments);
/**
* Strict tuple key type that only allows tuples or falsy values.
*
* @internal
*/
type StrictTupleKey = ArgumentsTuple | null | undefined | false;
/**
* Strict key type for internal use.
*
* @internal
*/
type StrictKey = StrictTupleKey | (() => StrictTupleKey);
/**
* Callback function type for mutator operations.
*
* This function receives the current cached data and can return new data
* to update the cache. It can be synchronous or asynchronous, and can
* return undefined to indicate no change should be made.
*
* @template Data - The type of the cached data
* @param currentData - The current data in the cache (may be undefined)
* @returns New data to set, undefined for no change, or a Promise resolving to either
*
* @public
*
* @example
* ```ts
* // Increment a counter
* mutate(key, (current: number = 0) => current + 1)
*
* // Async update
* mutate(key, async (current) => {
* const updated = await updateData(current)
* return updated
* })
* ```
*/
type MutatorCallback<Data = any> = (currentData?: Data) => Promise<undefined | Data> | undefined | Data;
/**
* Options for configuring mutator behavior.
*
* These options control how the mutation affects the cache, revalidation,
* and error handling behavior.
*
* @template Data - The type of the data related to the key
* @template MutationData - The type of the data returned by the mutator
*
* @public
*/
type MutatorOptions<Data = any, MutationData = Data> = {
/**
* Whether to revalidate the cache after mutation.
*
* Can be a boolean or a function that receives the new data and key
* to determine whether revalidation should occur.
*
* @defaultValue true
*/
revalidate?: boolean | ((data: Data, key: Arguments) => boolean);
/**
* Whether and how to populate the cache with mutation results.
*
* - `false`: Don't update the cache
* - `true`: Update cache with mutation result directly
* - Function: Transform mutation result before caching
*
* @defaultValue true
*/
populateCache?: boolean | ((result: MutationData, currentData: Data | undefined) => Data);
/**
* Optimistic data to show immediately while mutation is pending.
*
* Can be the data directly or a function that computes it based on
* current and displayed data. Useful for immediate UI feedback.
*
* @defaultValue undefined
*/
optimisticData?: Data | ((currentData: Data | undefined, displayedData: Data | undefined) => Data);
/**
* Whether to rollback optimistic updates on error.
*
* Can be a boolean or a function that receives the error to determine
* whether rollback should occur.
*
* @defaultValue true
*/
rollbackOnError?: boolean | ((error: unknown) => boolean);
/**
* Whether to throw errors instead of returning them in the error field.
*
* When true, errors will be thrown and can be caught with try/catch.
* When false, errors are returned in the response object.
*
* @defaultValue false
*/
throwOnError?: boolean;
};
type MutatorConfig = {
revalidate?: boolean;
populateCache?: boolean;
};
type Broadcaster<Data = any, Error = any> = (cache: Cache<Data>, key: string, data: Data, error?: Error, isValidating?: boolean, revalidate?: boolean, populateCache?: boolean) => Promise<Data>;
/**
* Internal state structure stored in the cache.
*
* This represents the complete state for a cache entry, including
* data, error, and loading states. All fields are optional as they
* may not be present depending on the request lifecycle.
*
* @template Data - The type of data stored
* @template Error - The type of error that can occur
*
* @internal
*/
type State<Data = any, Error = any> = {
/** The cached data, if available */
data?: Data;
/** The error object, if an error occurred */
error?: Error;
/** Whether a revalidation is currently in progress */
isValidating?: boolean;
/** Whether this is the initial load with no cached data */
isLoading?: boolean;
};
type MutatorFn<Data = any> = (cache: Cache, key: Key, data?: Data | Promise<Data> | MutatorCallback<Data>, opts?: boolean | MutatorOptions<Data>) => Promise<Data | undefined>;
type MutatorWrapper<Fn> = Fn extends (...args: [...infer Parameters]) => infer Result ? Parameters[3] extends boolean ? Result : Parameters[3] extends Required<Pick<MutatorOptions, 'populateCache'>> ? Parameters[3]['populateCache'] extends false ? never : Result : Result : never;
type Mutator<Data = any> = MutatorWrapper<MutatorFn<Data>>;
interface ScopedMutator {
/**
* @typeParam Data - The type of the data related to the key
* @typeParam MutationData - The type of the data returned by the mutator
*/
<Data = any, MutationData = Data>(matcher: (key?: Arguments) => boolean, data?: MutationData | Promise<MutationData> | MutatorCallback<MutationData>, opts?: boolean | MutatorOptions<Data, MutationData>): Promise<Array<MutationData | undefined>>;
/**
* @typeParam Data - The type of the data related to the key
* @typeParam MutationData - The type of the data returned by the mutator
*/
<Data = any, T = Data>(key: Arguments, data?: T | Promise<T> | MutatorCallback<T>, opts?: boolean | MutatorOptions<Data, T>): Promise<T | undefined>;
}
/**
* @typeParam Data - The type of the data related to the key
* @typeParam MutationData - The type of the data returned by the mutator
*/
type KeyedMutator<Data> = <MutationData = Data>(data?: Data | Promise<Data | undefined> | MutatorCallback<Data>, opts?: boolean | MutatorOptions<Data, MutationData>) => Promise<Data | MutationData | undefined>;
type SWRConfiguration<Data = any, Error = any, Fn extends BareFetcher<any> = BareFetcher<any>> = Partial<PublicConfiguration<Data, Error, Fn>> & Partial<ProviderConfiguration> & {
provider?: (cache: Readonly<Cache>) => Cache;
};
type IsLoadingResponse<Data = any, Options = SWRDefaultOptions<Data>> = SWRGlobalConfig extends {
suspense: true;
} ? Options extends {
suspense: true;
} ? false : false : boolean;
type SWRDefaultOptions<Data> = SWRConfiguration<Data, Error, Fetcher<Data, Key>>;
type SWRConfigurationWithOptionalFallback<Options> = Options extends SWRConfiguration & Required<Pick<SWRConfiguration, 'fallbackData'>> ? Omit<Options, 'fallbackData'> & Pick<Partial<Options>, 'fallbackData'> : Options;
/**
* The response object returned by SWR hooks.
*
* This interface represents the return value of useSWR and related hooks,
* providing access to data, error state, and control functions.
*
* @template Data - The type of data returned by the fetcher
* @template Error - The type of error that can be thrown
* @template Config - The configuration type used to determine blocking behavior
*
* @public
*/
interface SWRResponse<Data = any, Error = any, Config = any> {
/**
* The data returned by the fetcher function.
*
* - When suspense is enabled or fallbackData is provided: always defined
* - Otherwise: `undefined` during initial load or when key is falsy
*/
data: BlockingData<Data, Config> extends true ? Data : Data | undefined;
/**
* The error object thrown by the fetcher function.
*
* `undefined` when there's no error or when a request is in progress.
*/
error: Error | undefined;
/**
* Function to mutate the cached data for this specific key.
*
* This is a bound version of the global mutate function that automatically
* uses the current key, providing type safety and convenience.
*/
mutate: KeyedMutator<Data>;
/**
* Whether the request is currently being validated (loading fresh data).
*
* `true` during initial load, revalidation, or when mutate is called
* with a promise or async function.
*/
isValidating: boolean;
/**
* Whether the request is in initial loading state.
*
* `true` only during the initial load when there's no cached data.
* Unlike `isValidating`, this becomes `false` once data is available.
*/
isLoading: IsLoadingResponse<Data, Config>;
}
type KeyLoader<Args extends Arguments = Arguments> = ((index: number, previousPageData: any | null) => Args) | null;
interface RevalidatorOptions {
retryCount?: number;
dedupe?: boolean;
}
type Revalidator = (revalidateOpts?: RevalidatorOptions) => Promise<boolean> | void;
type RevalidateEvent = typeof revalidateEvents.FOCUS_EVENT | typeof revalidateEvents.RECONNECT_EVENT | typeof revalidateEvents.MUTATE_EVENT | typeof revalidateEvents.ERROR_REVALIDATE_EVENT;
type RevalidateCallbackReturnType = {
[revalidateEvents.FOCUS_EVENT]: void;
[revalidateEvents.RECONNECT_EVENT]: void;
[revalidateEvents.MUTATE_EVENT]: Promise<boolean>;
[revalidateEvents.ERROR_REVALIDATE_EVENT]: void;
};
type RevalidateCallback = <K extends RevalidateEvent>(type: K, opts?: any) => RevalidateCallbackReturnType[K];
/**
* Cache interface for storing SWR state.
*
* This interface defines the contract for cache providers used by SWR.
* The default implementation uses a Map, but custom cache providers
* can implement this interface to provide different storage mechanisms.
*
* @template Data - The type of data stored in the cache
*
* @public
* @see {@link https://swr.vercel.app/docs/advanced/cache | Cache Documentation}
*/
interface Cache<Data = any> {
/**
* Get an iterator of all cache keys.
*
* @returns Iterator that yields all cache keys as strings
*/
keys(): IterableIterator<string>;
/**
* Get the cached state for a key.
*
* @param key - The cache key to look up
* @returns The cached state or undefined if not found
*/
get(key: string): State<Data> | undefined;
/**
* Set the cached state for a key.
*
* @param key - The cache key to set
* @param value - The state to cache
*/
set(key: string, value: State<Data>): void;
/**
* Delete a cached entry.
*
* @param key - The cache key to delete
*/
delete(key: string): void;
}
interface StateDependencies {
data?: boolean;
error?: boolean;
isValidating?: boolean;
isLoading?: boolean;
}
export type { Arguments, BareFetcher, BlockingData, Broadcaster, Cache, Fetcher, FetcherResponse, FullConfiguration, GlobalState, InternalConfiguration, IsLoadingResponse, Key, KeyLoader, KeyedMutator, Middleware, Mutator, MutatorCallback, MutatorConfig, MutatorFn, MutatorOptions, MutatorWrapper, ProviderConfiguration, PublicConfiguration, RevalidateCallback, RevalidateEvent, Revalidator, RevalidatorOptions, SWRConfiguration, SWRHook, SWRResponse, ScopedMutator, State, StateDependencies, StrictTupleKey };

1
node_modules/swr/dist/_internal/types.js generated vendored Normal file
View File

@@ -0,0 +1 @@

1
node_modules/swr/dist/_internal/types.mjs generated vendored Normal file
View File

@@ -0,0 +1 @@

7
node_modules/swr/dist/immutable/index.d.mts generated vendored Normal file
View File

@@ -0,0 +1,7 @@
import * as ___index from '../index/index.mjs';
import { Middleware } from '../index/index.mjs';
declare const immutable: Middleware;
declare const useSWRImmutable: ___index.SWRHook;
export { useSWRImmutable as default, immutable };

7
node_modules/swr/dist/immutable/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,7 @@
import * as ___index from '../index/index.js';
import { Middleware } from '../index/index.js';
declare const immutable: Middleware;
declare const useSWRImmutable: ___index.SWRHook;
export { useSWRImmutable as default, immutable };

21
node_modules/swr/dist/immutable/index.js generated vendored Normal file
View File

@@ -0,0 +1,21 @@
Object.defineProperty(exports, '__esModule', { value: true });
var useSWR = require('../index/index.js');
var index_js = require('../_internal/index.js');
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
var useSWR__default = /*#__PURE__*/_interopDefault(useSWR);
const immutable = (useSWRNext)=>(key, fetcher, config)=>{
// Always override all revalidate options.
config.revalidateOnFocus = false;
config.revalidateIfStale = false;
config.revalidateOnReconnect = false;
config.refreshInterval = 0;
return useSWRNext(key, fetcher, config);
};
const useSWRImmutable = index_js.withMiddleware(useSWR__default.default, immutable);
exports.default = useSWRImmutable;
exports.immutable = immutable;

14
node_modules/swr/dist/immutable/index.mjs generated vendored Normal file
View File

@@ -0,0 +1,14 @@
import useSWR from '../index/index.mjs';
import { withMiddleware } from '../_internal/index.mjs';
const immutable = (useSWRNext)=>(key, fetcher, config)=>{
// Always override all revalidate options.
config.revalidateOnFocus = false;
config.revalidateIfStale = false;
config.revalidateOnReconnect = false;
config.refreshInterval = 0;
return useSWRNext(key, fetcher, config);
};
const useSWRImmutable = withMiddleware(useSWR, immutable);
export { useSWRImmutable as default, immutable };

6
node_modules/swr/dist/index/config-12s-Bi4rgVRk.mjs generated vendored Normal file
View File

@@ -0,0 +1,6 @@
'use client';
import { SWRConfig as SWRConfig$1 } from '../_internal/index.mjs';
const SWRConfig = SWRConfig$1;
export { SWRConfig as S };

32
node_modules/swr/dist/index/index.d.mts generated vendored Normal file
View File

@@ -0,0 +1,32 @@
import { Key, SWRHook, SWRConfig as SWRConfig$1, FullConfiguration } from '../_internal/index.mjs';
export { Arguments, BareFetcher, Cache, Fetcher, Key, KeyLoader, KeyedMutator, Middleware, MutatorCallback, MutatorOptions, Revalidator, RevalidatorOptions, SWRConfiguration, SWRHook, SWRResponse, ScopedMutator, State, mutate, preload, useSWRConfig } from '../_internal/index.mjs';
declare const unstable_serialize: (key: Key) => string;
declare const SWRConfig: typeof SWRConfig$1 & {
defaultValue: FullConfiguration;
};
/**
* A hook to fetch data.
*
* @see {@link https://swr.vercel.app}
*
* @example
* ```jsx
* import useSWR from 'swr'
* function Profile() {
* const { data, error, isLoading } = useSWR('/api/user', fetcher)
* if (error) return <div>failed to load</div>
* if (isLoading) return <div>loading...</div>
* return <div>hello {data.name}!</div>
* }
* ```
*/
declare const useSWR: SWRHook;
interface SWRGlobalConfig {
}
export { SWRConfig, useSWR as default, unstable_serialize };
export type { SWRGlobalConfig };

32
node_modules/swr/dist/index/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,32 @@
import { Key, SWRHook, SWRConfig as SWRConfig$1, FullConfiguration } from '../_internal/index.js';
export { Arguments, BareFetcher, Cache, Fetcher, Key, KeyLoader, KeyedMutator, Middleware, MutatorCallback, MutatorOptions, Revalidator, RevalidatorOptions, SWRConfiguration, SWRHook, SWRResponse, ScopedMutator, State, mutate, preload, useSWRConfig } from '../_internal/index.js';
declare const unstable_serialize: (key: Key) => string;
declare const SWRConfig: typeof SWRConfig$1 & {
defaultValue: FullConfiguration;
};
/**
* A hook to fetch data.
*
* @see {@link https://swr.vercel.app}
*
* @example
* ```jsx
* import useSWR from 'swr'
* function Profile() {
* const { data, error, isLoading } = useSWR('/api/user', fetcher)
* if (error) return <div>failed to load</div>
* if (isLoading) return <div>loading...</div>
* return <div>hello {data.name}!</div>
* }
* ```
*/
declare const useSWR: SWRHook;
interface SWRGlobalConfig {
}
export { SWRConfig, useSWR as default, unstable_serialize };
export type { SWRGlobalConfig };

726
node_modules/swr/dist/index/index.js generated vendored Normal file
View File

@@ -0,0 +1,726 @@
Object.defineProperty(exports, '__esModule', { value: true });
var React = require('react');
var shim = require('use-sync-external-store/shim');
var index_js = require('../_internal/index.js');
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
var React__default = /*#__PURE__*/_interopDefault(React);
// Shared state between server components and client components
const noop = ()=>{};
// Using noop() as the undefined value as undefined can be replaced
// by something else. Prettier ignore and extra parentheses are necessary here
// to ensure that tsc doesn't remove the __NOINLINE__ comment.
// prettier-ignore
const UNDEFINED = /*#__NOINLINE__*/ noop();
const OBJECT = Object;
const isUndefined = (v)=>v === UNDEFINED;
const isFunction = (v)=>typeof v == 'function';
// use WeakMap to store the object->key mapping
// so the objects can be garbage collected.
// WeakMap uses a hashtable under the hood, so the lookup
// complexity is almost O(1).
const table = new WeakMap();
const getTypeName = (value)=>OBJECT.prototype.toString.call(value);
const isObjectTypeName = (typeName, type)=>typeName === `[object ${type}]`;
// counter of the key
let counter = 0;
// A stable hash implementation that supports:
// - Fast and ensures unique hash properties
// - Handles unserializable values
// - Handles object key ordering
// - Generates short results
//
// This is not a serialization function, and the result is not guaranteed to be
// parsable.
const stableHash = (arg)=>{
const type = typeof arg;
const typeName = getTypeName(arg);
const isDate = isObjectTypeName(typeName, 'Date');
const isRegex = isObjectTypeName(typeName, 'RegExp');
const isPlainObject = isObjectTypeName(typeName, 'Object');
let result;
let index;
if (OBJECT(arg) === arg && !isDate && !isRegex) {
// Object/function, not null/date/regexp. Use WeakMap to store the id first.
// If it's already hashed, directly return the result.
result = table.get(arg);
if (result) return result;
// Store the hash first for circular reference detection before entering the
// recursive `stableHash` calls.
// For other objects like set and map, we use this id directly as the hash.
result = ++counter + '~';
table.set(arg, result);
if (Array.isArray(arg)) {
// Array.
result = '@';
for(index = 0; index < arg.length; index++){
result += stableHash(arg[index]) + ',';
}
table.set(arg, result);
}
if (isPlainObject) {
// Object, sort keys.
result = '#';
const keys = OBJECT.keys(arg).sort();
while(!isUndefined(index = keys.pop())){
if (!isUndefined(arg[index])) {
result += index + ':' + stableHash(arg[index]) + ',';
}
}
table.set(arg, result);
}
} else {
result = isDate ? arg.toJSON() : type == 'symbol' ? arg.toString() : type == 'string' ? JSON.stringify(arg) : '' + arg;
}
return result;
};
const serialize = (key)=>{
if (isFunction(key)) {
try {
key = key();
} catch (err) {
// dependencies not ready
key = '';
}
}
// Use the original key as the argument of fetcher. This can be a string or an
// array of values.
const args = key;
// If key is not falsy, or not an empty array, hash it.
key = typeof key == 'string' ? key : (Array.isArray(key) ? key.length : key) ? stableHash(key) : '';
return [
key,
args
];
};
const unstable_serialize = (key)=>serialize(key)[0];
/// <reference types="react/experimental" />
const use = React__default.default.use || // This extra generic is to avoid TypeScript mixing up the generic and JSX sytax
// and emitting an error.
// We assume that this is only for the `use(thenable)` case, not `use(context)`.
// https://github.com/facebook/react/blob/aed00dacfb79d17c53218404c52b1c7aa59c4a89/packages/react-server/src/ReactFizzThenable.js#L45
((thenable)=>{
switch(thenable.status){
case 'pending':
throw thenable;
case 'fulfilled':
return thenable.value;
case 'rejected':
throw thenable.reason;
default:
thenable.status = 'pending';
thenable.then((v)=>{
thenable.status = 'fulfilled';
thenable.value = v;
}, (e)=>{
thenable.status = 'rejected';
thenable.reason = e;
});
throw thenable;
}
});
const WITH_DEDUPE = {
dedupe: true
};
const resolvedUndef = Promise.resolve(index_js.UNDEFINED);
const sub = ()=>index_js.noop;
/**
* The core implementation of the useSWR hook.
*
* This is the main handler function that implements all SWR functionality including
* data fetching, caching, revalidation, error handling, and state management.
* It manages the complete lifecycle of SWR requests from initialization through
* cleanup.
*
* Key responsibilities:
* - Key serialization and normalization
* - Cache state management and synchronization
* - Automatic and manual revalidation
* - Error handling and retry logic
* - Suspense integration
* - Loading state management
* - Effect cleanup and memory management
*
* @template Data - The type of data returned by the fetcher
* @template Error - The type of error that can be thrown
*
* @param _key - The SWR key (string, array, object, function, or falsy)
* @param fetcher - The fetcher function to retrieve data, or null to disable fetching
* @param config - Complete SWR configuration object with both public and internal options
*
* @returns SWRResponse object containing data, error, mutate function, and loading states
*
* @internal This is the internal implementation. Use `useSWR` instead.
*/ const useSWRHandler = (_key, fetcher, config)=>{
const { cache, compare, suspense, fallbackData, revalidateOnMount, revalidateIfStale, refreshInterval, refreshWhenHidden, refreshWhenOffline, keepPreviousData, strictServerPrefetchWarning } = config;
const [EVENT_REVALIDATORS, MUTATION, FETCH, PRELOAD] = index_js.SWRGlobalState.get(cache);
// `key` is the identifier of the SWR internal state,
// `fnArg` is the argument/arguments parsed from the key, which will be passed
// to the fetcher.
// All of them are derived from `_key`.
const [key, fnArg] = index_js.serialize(_key);
// If it's the initial render of this hook.
const initialMountedRef = React.useRef(false);
// If the hook is unmounted already. This will be used to prevent some effects
// to be called after unmounting.
const unmountedRef = React.useRef(false);
// Refs to keep the key and config.
const keyRef = React.useRef(key);
const fetcherRef = React.useRef(fetcher);
const configRef = React.useRef(config);
const getConfig = ()=>configRef.current;
const isActive = ()=>getConfig().isVisible() && getConfig().isOnline();
const [getCache, setCache, subscribeCache, getInitialCache] = index_js.createCacheHelper(cache, key);
const stateDependencies = React.useRef({}).current;
// Resolve the fallback data from either the inline option, or the global provider.
// If it's a promise, we simply let React suspend and resolve it for us.
const fallback = index_js.isUndefined(fallbackData) ? index_js.isUndefined(config.fallback) ? index_js.UNDEFINED : config.fallback[key] : fallbackData;
const isEqual = (prev, current)=>{
for(const _ in stateDependencies){
const t = _;
if (t === 'data') {
if (!compare(prev[t], current[t])) {
if (!index_js.isUndefined(prev[t])) {
return false;
}
if (!compare(returnedData, current[t])) {
return false;
}
}
} else {
if (current[t] !== prev[t]) {
return false;
}
}
}
return true;
};
const isInitialMount = !initialMountedRef.current;
const getSnapshot = React.useMemo(()=>{
const cachedData = getCache();
const initialData = getInitialCache();
const getSelectedCache = (state)=>{
// We only select the needed fields from the state.
const snapshot = index_js.mergeObjects(state);
delete snapshot._k;
const shouldStartRequest = (()=>{
if (!key) return false;
if (!fetcher) return false;
// If it's paused, we skip revalidation.
if (getConfig().isPaused()) return false;
// If `revalidateOnMount` is set, we take the value directly.
if (isInitialMount && !index_js.isUndefined(revalidateOnMount)) return revalidateOnMount;
const data = !index_js.isUndefined(fallback) ? fallback : snapshot.data;
if (suspense) return index_js.isUndefined(data) || revalidateIfStale;
return index_js.isUndefined(data) || revalidateIfStale;
})();
if (!shouldStartRequest) {
return snapshot;
}
return {
isValidating: true,
isLoading: true,
...snapshot
};
};
const clientSnapshot = getSelectedCache(cachedData);
const serverSnapshot = cachedData === initialData ? clientSnapshot : getSelectedCache(initialData);
// 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 = clientSnapshot;
return [
()=>{
const newSnapshot = getSelectedCache(getCache());
const compareResult = isEqual(newSnapshot, memorizedSnapshot);
if (compareResult) {
// Mentally, we should always return the `memorizedSnapshot` here
// as there's no change between the new and old snapshots.
// However, since the `isEqual` function only compares selected fields,
// the values of the unselected fields might be changed. That's
// simply because we didn't track them.
// To support the case in https://github.com/vercel/swr/pull/2576,
// we need to update these fields in the `memorizedSnapshot` too
// with direct mutations to ensure the snapshot is always up-to-date
// even for the unselected fields, but only trigger re-renders when
// the selected fields are changed.
memorizedSnapshot.data = newSnapshot.data;
memorizedSnapshot.isLoading = newSnapshot.isLoading;
memorizedSnapshot.isValidating = newSnapshot.isValidating;
memorizedSnapshot.error = newSnapshot.error;
return memorizedSnapshot;
} else {
memorizedSnapshot = newSnapshot;
return newSnapshot;
}
},
()=>serverSnapshot
];
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [
cache,
key
]);
// Get the current state that SWR should return.
const cached = shim.useSyncExternalStore(React.useCallback((callback)=>subscribeCache(key, (current, prev)=>{
if (!isEqual(prev, current)) callback();
}), // eslint-disable-next-line react-hooks/exhaustive-deps
[
cache,
key
]), getSnapshot[0], getSnapshot[1]);
const hasRevalidator = EVENT_REVALIDATORS[key] && EVENT_REVALIDATORS[key].length > 0;
const cachedData = cached.data;
const data = index_js.isUndefined(cachedData) ? fallback && index_js.isPromiseLike(fallback) ? use(fallback) : fallback : cachedData;
const error = cached.error;
// Use a ref to store previously returned data. Use the initial data as its initial value.
const laggyDataRef = React.useRef(data);
const returnedData = keepPreviousData ? index_js.isUndefined(cachedData) ? index_js.isUndefined(laggyDataRef.current) ? data : laggyDataRef.current : cachedData : data;
const hasKeyButNoData = key && index_js.isUndefined(data);
const hydrationRef = React.useRef(null);
// Note: the conditionally hook call is fine because the environment
// `IS_SERVER` never changes.
// @ts-expect-error -- use hydrationRef directly
!index_js.IS_SERVER && // getServerSnapshot is only called during hydration
// eslint-disable-next-line react-hooks/rules-of-hooks
shim.useSyncExternalStore(sub, ()=>{
hydrationRef.current = false;
return hydrationRef;
}, ()=>{
hydrationRef.current = true;
return hydrationRef;
});
const isHydration = hydrationRef.current;
// During the initial SSR render, warn if the key has no data pre-fetched via:
// - fallback data
// - preload calls
// - initial data from the cache provider
// We only warn once for each key during Hydration.
if (strictServerPrefetchWarning && isHydration && !suspense && hasKeyButNoData) {
console.warn(`Missing pre-initiated data for serialized key "${key}" during server-side rendering. Data fetching should be initiated on the server and provided to SWR via fallback data. You can set "strictServerPrefetchWarning: false" to disable this warning.`);
}
// Resolve the default validating state:
// If it's able to validate, and it should revalidate when mount, this will be true.
// - Suspense mode and there's stale data for the initial render.
// - Not suspense mode and there is no fallback data and `revalidateIfStale` is enabled.
// - `revalidateIfStale` is enabled but `data` is not defined.
const shouldDoInitialRevalidation = (()=>{
if (!key || !fetcher) return false;
// If it's paused, we skip revalidation.
if (getConfig().isPaused()) return false;
// if a key already has revalidators and also has error, we should not trigger revalidation
if (hasRevalidator && !index_js.isUndefined(error)) return false;
// If `revalidateOnMount` is set, we take the value directly.
if (isInitialMount && !index_js.isUndefined(revalidateOnMount)) return revalidateOnMount;
// Under suspense mode, it will always fetch on render if there is no
// stale data so no need to revalidate immediately mount it again.
// If data exists, only revalidate if `revalidateIfStale` is true.
if (suspense) return index_js.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 index_js.isUndefined(data) || revalidateIfStale;
})();
const defaultValidatingState = isInitialMount && shouldDoInitialRevalidation;
const isValidating = index_js.isUndefined(cached.isValidating) ? defaultValidatingState : cached.isValidating;
const isLoading = index_js.isUndefined(cached.isLoading) ? defaultValidatingState : cached.isLoading;
// The revalidation function is a carefully crafted wrapper of the original
// `fetcher`, to correctly handle the many edge cases.
const revalidate = React.useCallback(async (revalidateOpts)=>{
const currentFetcher = fetcherRef.current;
if (!key || !currentFetcher || unmountedRef.current || getConfig().isPaused()) {
return false;
}
let newData;
let startAt;
let loading = true;
const opts = revalidateOpts || {};
// If there is no ongoing concurrent request, or `dedupe` is not set, a
// new request should be initiated.
const shouldStartNewRequest = !FETCH[key] || !opts.dedupe;
/*
For React 17
Do unmount check for calls:
If key has changed during the revalidation, or the component has been
unmounted, old dispatch and old event callbacks should not take any
effect
For React 18
only check if key has changed
https://github.com/reactwg/react-18/discussions/82
*/ const callbackSafeguard = ()=>{
if (index_js.IS_REACT_LEGACY) {
return !unmountedRef.current && key === keyRef.current && initialMountedRef.current;
}
return key === keyRef.current;
};
// The final state object when the request finishes.
const finalState = {
isValidating: false,
isLoading: false
};
const finishRequestAndUpdateState = ()=>{
setCache(finalState);
};
const cleanupState = ()=>{
// Check if it's still the same request before deleting it.
const requestInfo = FETCH[key];
if (requestInfo && requestInfo[1] === startAt) {
delete FETCH[key];
}
};
// Start fetching. Change the `isValidating` state, update the cache.
const initialState = {
isValidating: true
};
// It is in the `isLoading` state, if and only if there is no cached data.
// This bypasses fallback data and laggy data.
if (index_js.isUndefined(getCache().data)) {
initialState.isLoading = true;
}
try {
if (shouldStartNewRequest) {
setCache(initialState);
// If no cache is being rendered currently (it shows a blank page),
// we trigger the loading slow event.
if (config.loadingTimeout && index_js.isUndefined(getCache().data)) {
setTimeout(()=>{
if (loading && callbackSafeguard()) {
getConfig().onLoadingSlow(key, config);
}
}, config.loadingTimeout);
}
// Start the request and save the timestamp.
// Key must be truthy if entering here.
FETCH[key] = [
currentFetcher(fnArg),
index_js.getTimestamp()
];
}
// Wait until the ongoing request is done. Deduplication is also
// considered here.
;
[newData, startAt] = FETCH[key];
newData = await newData;
if (shouldStartNewRequest) {
// If the request isn't interrupted, clean it up after the
// deduplication interval.
setTimeout(cleanupState, config.dedupingInterval);
}
// If there're other ongoing request(s), started after the current one,
// we need to ignore the current one to avoid possible race conditions:
// req1------------------>res1 (current one)
// req2---------------->res2
// the request that fired later will always be kept.
// The timestamp maybe be `undefined` or a number
if (!FETCH[key] || FETCH[key][1] !== startAt) {
if (shouldStartNewRequest) {
if (callbackSafeguard()) {
getConfig().onDiscarded(key);
}
}
return false;
}
// Clear error.
finalState.error = index_js.UNDEFINED;
// If there're other mutations(s), that overlapped with the current revalidation:
// case 1:
// req------------------>res
// mutate------>end
// case 2:
// req------------>res
// mutate------>end
// case 3:
// req------------------>res
// mutate-------...---------->
// we have to ignore the revalidation result (res) because it's no longer fresh.
// meanwhile, a new revalidation should be triggered when the mutation ends.
const mutationInfo = MUTATION[key];
if (!index_js.isUndefined(mutationInfo) && // case 1
(startAt <= mutationInfo[0] || // case 2
startAt <= mutationInfo[1] || // case 3
mutationInfo[1] === 0)) {
finishRequestAndUpdateState();
if (shouldStartNewRequest) {
if (callbackSafeguard()) {
getConfig().onDiscarded(key);
}
}
return false;
}
// Deep compare with the latest state to avoid extra re-renders.
// For local state, compare and assign.
const cacheData = getCache().data;
// Since the compare fn could be custom fn
// cacheData might be different from newData even when compare fn returns True
finalState.data = compare(cacheData, newData) ? cacheData : newData;
// Trigger the successful callback if it's the original request.
if (shouldStartNewRequest) {
if (callbackSafeguard()) {
getConfig().onSuccess(newData, key, config);
}
}
} catch (err) {
cleanupState();
const currentConfig = getConfig();
const { shouldRetryOnError } = currentConfig;
// Not paused, we continue handling the error. Otherwise, discard it.
if (!currentConfig.isPaused()) {
// Get a new error, don't use deep comparison for errors.
finalState.error = err;
// Error event and retry logic. Only for the actual request, not
// deduped ones.
if (shouldStartNewRequest && callbackSafeguard()) {
currentConfig.onError(err, key, currentConfig);
if (shouldRetryOnError === true || index_js.isFunction(shouldRetryOnError) && shouldRetryOnError(err)) {
if (!getConfig().revalidateOnFocus || !getConfig().revalidateOnReconnect || isActive()) {
// If it's inactive, stop. It will auto-revalidate when
// refocusing or reconnecting.
// When retrying, deduplication is always enabled.
currentConfig.onErrorRetry(err, key, currentConfig, (_opts)=>{
const revalidators = EVENT_REVALIDATORS[key];
if (revalidators && revalidators[0]) {
revalidators[0](index_js.revalidateEvents.ERROR_REVALIDATE_EVENT, _opts);
}
}, {
retryCount: (opts.retryCount || 0) + 1,
dedupe: true
});
}
}
}
}
}
// Mark loading as stopped.
loading = false;
// Update the current hook's state.
finishRequestAndUpdateState();
return true;
}, // `setState` is immutable, and `eventsCallback`, `fnArg`, and
// `keyValidating` are depending on `key`, so we can exclude them from
// the deps array.
//
// FIXME:
// `fn` and `config` might be changed during the lifecycle,
// but they might be changed every render like this.
// `useSWR('key', () => fetch('/api/'), { suspense: true })`
// So we omit the values from the deps array
// even though it might cause unexpected behaviors.
// eslint-disable-next-line react-hooks/exhaustive-deps
[
key,
cache
]);
// Similar to the global mutate but bound to the current cache and key.
// `cache` isn't allowed to change during the lifecycle.
const boundMutate = React.useCallback(// Use callback to make sure `keyRef.current` returns latest result every time
(...args)=>{
return index_js.internalMutate(cache, keyRef.current, ...args);
}, // eslint-disable-next-line react-hooks/exhaustive-deps
[]);
// The logic for updating refs.
index_js.useIsomorphicLayoutEffect(()=>{
fetcherRef.current = fetcher;
configRef.current = config;
// Handle laggy data updates. If there's cached data of the current key,
// it'll be the correct reference.
if (!index_js.isUndefined(cachedData)) {
laggyDataRef.current = cachedData;
}
});
// After mounted or key changed.
index_js.useIsomorphicLayoutEffect(()=>{
if (!key) return;
const softRevalidate = revalidate.bind(index_js.UNDEFINED, WITH_DEDUPE);
let nextFocusRevalidatedAt = 0;
if (getConfig().revalidateOnFocus) {
const initNow = Date.now();
nextFocusRevalidatedAt = initNow + getConfig().focusThrottleInterval;
}
// Expose revalidators to global event listeners. So we can trigger
// revalidation from the outside.
const onRevalidate = (type, opts = {})=>{
if (type == index_js.revalidateEvents.FOCUS_EVENT) {
const now = Date.now();
if (getConfig().revalidateOnFocus && now > nextFocusRevalidatedAt && isActive()) {
nextFocusRevalidatedAt = now + getConfig().focusThrottleInterval;
softRevalidate();
}
} else if (type == index_js.revalidateEvents.RECONNECT_EVENT) {
if (getConfig().revalidateOnReconnect && isActive()) {
softRevalidate();
}
} else if (type == index_js.revalidateEvents.MUTATE_EVENT) {
return revalidate();
} else if (type == index_js.revalidateEvents.ERROR_REVALIDATE_EVENT) {
return revalidate(opts);
}
return;
};
const unsubEvents = index_js.subscribeCallback(key, EVENT_REVALIDATORS, onRevalidate);
// Mark the component as mounted and update corresponding refs.
unmountedRef.current = false;
keyRef.current = key;
initialMountedRef.current = true;
// Keep the original key in the cache.
setCache({
_k: fnArg
});
// Trigger a revalidation
if (shouldDoInitialRevalidation) {
// Performance optimization: if a request is already in progress for this key,
// skip the revalidation to avoid redundant work
if (!FETCH[key]) {
if (index_js.isUndefined(data) || index_js.IS_SERVER) {
// Revalidate immediately.
softRevalidate();
} else {
// Delay the revalidate if we have data to return so we won't block
// rendering.
index_js.rAF(softRevalidate);
}
}
}
return ()=>{
// Mark it as unmounted.
unmountedRef.current = true;
unsubEvents();
};
}, [
key
]);
// Polling
index_js.useIsomorphicLayoutEffect(()=>{
let timer;
function next() {
// Use the passed interval
// ...or invoke the function with the updated data to get the interval
const interval = index_js.isFunction(refreshInterval) ? refreshInterval(getCache().data) : refreshInterval;
// We only start the next interval if `refreshInterval` is not 0, and:
// - `force` is true, which is the start of polling
// - or `timer` is not 0, which means the effect wasn't canceled
if (interval && timer !== -1) {
timer = setTimeout(execute, interval);
}
}
function execute() {
// Check if it's OK to execute:
// Only revalidate when the page is visible, online, and not errored.
if (!getCache().error && (refreshWhenHidden || getConfig().isVisible()) && (refreshWhenOffline || getConfig().isOnline())) {
revalidate(WITH_DEDUPE).then(next);
} else {
// Schedule the next interval to check again.
next();
}
}
next();
return ()=>{
if (timer) {
clearTimeout(timer);
timer = -1;
}
};
}, [
refreshInterval,
refreshWhenHidden,
refreshWhenOffline,
key
]);
// Display debug info in React DevTools.
React.useDebugValue(returnedData);
// In Suspense mode, we can't return the empty `data` state.
// If there is an `error`, the `error` needs to be thrown to the error boundary.
// If there is no `error`, the `revalidation` promise needs to be thrown to
// the suspense boundary.
if (suspense) {
// SWR should throw when trying to use Suspense on the server with React 18,
// without providing any fallback data. This causes hydration errors. See:
// https://github.com/vercel/swr/issues/1832
if (!index_js.IS_REACT_LEGACY && index_js.IS_SERVER && hasKeyButNoData) {
throw new Error('Fallback data is required when using Suspense in SSR.');
}
// Always update fetcher and config refs even with the Suspense mode.
if (hasKeyButNoData) {
fetcherRef.current = fetcher;
configRef.current = config;
unmountedRef.current = false;
}
const req = PRELOAD[key];
const mutateReq = !index_js.isUndefined(req) && hasKeyButNoData ? boundMutate(req) : resolvedUndef;
use(mutateReq);
if (!index_js.isUndefined(error) && hasKeyButNoData) {
throw error;
}
const revalidation = hasKeyButNoData ? revalidate(WITH_DEDUPE) : resolvedUndef;
if (!index_js.isUndefined(returnedData) && hasKeyButNoData) {
// @ts-ignore modify react promise status
revalidation.status = 'fulfilled';
// @ts-ignore modify react promise value
revalidation.value = true;
}
use(revalidation);
}
const swrResponse = {
mutate: boundMutate,
get data () {
stateDependencies.data = true;
return returnedData;
},
get error () {
stateDependencies.error = true;
return error;
},
get isValidating () {
stateDependencies.isValidating = true;
return isValidating;
},
get isLoading () {
stateDependencies.isLoading = true;
return isLoading;
}
};
return swrResponse;
};
const SWRConfig = index_js.OBJECT.defineProperty(index_js.SWRConfig, 'defaultValue', {
value: index_js.defaultConfig
});
/**
* A hook to fetch data.
*
* @see {@link https://swr.vercel.app}
*
* @example
* ```jsx
* import useSWR from 'swr'
* function Profile() {
* const { data, error, isLoading } = useSWR('/api/user', fetcher)
* if (error) return <div>failed to load</div>
* if (isLoading) return <div>loading...</div>
* return <div>hello {data.name}!</div>
* }
* ```
*/ const useSWR = index_js.withArgs(useSWRHandler);
// useSWR
Object.defineProperty(exports, "mutate", {
enumerable: true,
get: function () { return index_js.mutate; }
});
Object.defineProperty(exports, "preload", {
enumerable: true,
get: function () { return index_js.preload; }
});
Object.defineProperty(exports, "useSWRConfig", {
enumerable: true,
get: function () { return index_js.useSWRConfig; }
});
exports.SWRConfig = SWRConfig;
exports.default = useSWR;
exports.unstable_serialize = unstable_serialize;

707
node_modules/swr/dist/index/index.mjs generated vendored Normal file
View File

@@ -0,0 +1,707 @@
import React, { useRef, useMemo, useCallback, useDebugValue } from 'react';
import { useSyncExternalStore } from 'use-sync-external-store/shim';
import { UNDEFINED as UNDEFINED$1, OBJECT as OBJECT$1, SWRConfig as SWRConfig$1, defaultConfig, withArgs, SWRGlobalState, serialize as serialize$1, createCacheHelper, isUndefined as isUndefined$1, isPromiseLike, IS_SERVER, noop as noop$1, getTimestamp, isFunction as isFunction$1, revalidateEvents, internalMutate, useIsomorphicLayoutEffect, subscribeCallback, rAF, IS_REACT_LEGACY, mergeObjects } from '../_internal/index.mjs';
export { mutate, preload, useSWRConfig } from '../_internal/index.mjs';
// Shared state between server components and client components
const noop = ()=>{};
// Using noop() as the undefined value as undefined can be replaced
// by something else. Prettier ignore and extra parentheses are necessary here
// to ensure that tsc doesn't remove the __NOINLINE__ comment.
// prettier-ignore
const UNDEFINED = /*#__NOINLINE__*/ noop();
const OBJECT = Object;
const isUndefined = (v)=>v === UNDEFINED;
const isFunction = (v)=>typeof v == 'function';
// use WeakMap to store the object->key mapping
// so the objects can be garbage collected.
// WeakMap uses a hashtable under the hood, so the lookup
// complexity is almost O(1).
const table = new WeakMap();
const getTypeName = (value)=>OBJECT.prototype.toString.call(value);
const isObjectTypeName = (typeName, type)=>typeName === `[object ${type}]`;
// counter of the key
let counter = 0;
// A stable hash implementation that supports:
// - Fast and ensures unique hash properties
// - Handles unserializable values
// - Handles object key ordering
// - Generates short results
//
// This is not a serialization function, and the result is not guaranteed to be
// parsable.
const stableHash = (arg)=>{
const type = typeof arg;
const typeName = getTypeName(arg);
const isDate = isObjectTypeName(typeName, 'Date');
const isRegex = isObjectTypeName(typeName, 'RegExp');
const isPlainObject = isObjectTypeName(typeName, 'Object');
let result;
let index;
if (OBJECT(arg) === arg && !isDate && !isRegex) {
// Object/function, not null/date/regexp. Use WeakMap to store the id first.
// If it's already hashed, directly return the result.
result = table.get(arg);
if (result) return result;
// Store the hash first for circular reference detection before entering the
// recursive `stableHash` calls.
// For other objects like set and map, we use this id directly as the hash.
result = ++counter + '~';
table.set(arg, result);
if (Array.isArray(arg)) {
// Array.
result = '@';
for(index = 0; index < arg.length; index++){
result += stableHash(arg[index]) + ',';
}
table.set(arg, result);
}
if (isPlainObject) {
// Object, sort keys.
result = '#';
const keys = OBJECT.keys(arg).sort();
while(!isUndefined(index = keys.pop())){
if (!isUndefined(arg[index])) {
result += index + ':' + stableHash(arg[index]) + ',';
}
}
table.set(arg, result);
}
} else {
result = isDate ? arg.toJSON() : type == 'symbol' ? arg.toString() : type == 'string' ? JSON.stringify(arg) : '' + arg;
}
return result;
};
const serialize = (key)=>{
if (isFunction(key)) {
try {
key = key();
} catch (err) {
// dependencies not ready
key = '';
}
}
// Use the original key as the argument of fetcher. This can be a string or an
// array of values.
const args = key;
// If key is not falsy, or not an empty array, hash it.
key = typeof key == 'string' ? key : (Array.isArray(key) ? key.length : key) ? stableHash(key) : '';
return [
key,
args
];
};
const unstable_serialize = (key)=>serialize(key)[0];
/// <reference types="react/experimental" />
const use = React.use || // This extra generic is to avoid TypeScript mixing up the generic and JSX sytax
// and emitting an error.
// We assume that this is only for the `use(thenable)` case, not `use(context)`.
// https://github.com/facebook/react/blob/aed00dacfb79d17c53218404c52b1c7aa59c4a89/packages/react-server/src/ReactFizzThenable.js#L45
((thenable)=>{
switch(thenable.status){
case 'pending':
throw thenable;
case 'fulfilled':
return thenable.value;
case 'rejected':
throw thenable.reason;
default:
thenable.status = 'pending';
thenable.then((v)=>{
thenable.status = 'fulfilled';
thenable.value = v;
}, (e)=>{
thenable.status = 'rejected';
thenable.reason = e;
});
throw thenable;
}
});
const WITH_DEDUPE = {
dedupe: true
};
const resolvedUndef = Promise.resolve(UNDEFINED$1);
const sub = ()=>noop$1;
/**
* The core implementation of the useSWR hook.
*
* This is the main handler function that implements all SWR functionality including
* data fetching, caching, revalidation, error handling, and state management.
* It manages the complete lifecycle of SWR requests from initialization through
* cleanup.
*
* Key responsibilities:
* - Key serialization and normalization
* - Cache state management and synchronization
* - Automatic and manual revalidation
* - Error handling and retry logic
* - Suspense integration
* - Loading state management
* - Effect cleanup and memory management
*
* @template Data - The type of data returned by the fetcher
* @template Error - The type of error that can be thrown
*
* @param _key - The SWR key (string, array, object, function, or falsy)
* @param fetcher - The fetcher function to retrieve data, or null to disable fetching
* @param config - Complete SWR configuration object with both public and internal options
*
* @returns SWRResponse object containing data, error, mutate function, and loading states
*
* @internal This is the internal implementation. Use `useSWR` instead.
*/ const useSWRHandler = (_key, fetcher, config)=>{
const { cache, compare, suspense, fallbackData, revalidateOnMount, revalidateIfStale, refreshInterval, refreshWhenHidden, refreshWhenOffline, keepPreviousData, strictServerPrefetchWarning } = config;
const [EVENT_REVALIDATORS, MUTATION, FETCH, PRELOAD] = SWRGlobalState.get(cache);
// `key` is the identifier of the SWR internal state,
// `fnArg` is the argument/arguments parsed from the key, which will be passed
// to the fetcher.
// All of them are derived from `_key`.
const [key, fnArg] = serialize$1(_key);
// If it's the initial render of this hook.
const initialMountedRef = useRef(false);
// If the hook is unmounted already. This will be used to prevent some effects
// to be called after unmounting.
const unmountedRef = useRef(false);
// Refs to keep the key and config.
const keyRef = useRef(key);
const fetcherRef = useRef(fetcher);
const configRef = useRef(config);
const getConfig = ()=>configRef.current;
const isActive = ()=>getConfig().isVisible() && getConfig().isOnline();
const [getCache, setCache, subscribeCache, getInitialCache] = createCacheHelper(cache, key);
const stateDependencies = useRef({}).current;
// Resolve the fallback data from either the inline option, or the global provider.
// If it's a promise, we simply let React suspend and resolve it for us.
const fallback = isUndefined$1(fallbackData) ? isUndefined$1(config.fallback) ? UNDEFINED$1 : config.fallback[key] : fallbackData;
const isEqual = (prev, current)=>{
for(const _ in stateDependencies){
const t = _;
if (t === 'data') {
if (!compare(prev[t], current[t])) {
if (!isUndefined$1(prev[t])) {
return false;
}
if (!compare(returnedData, current[t])) {
return false;
}
}
} else {
if (current[t] !== prev[t]) {
return false;
}
}
}
return true;
};
const isInitialMount = !initialMountedRef.current;
const getSnapshot = useMemo(()=>{
const cachedData = getCache();
const initialData = getInitialCache();
const getSelectedCache = (state)=>{
// We only select the needed fields from the state.
const snapshot = mergeObjects(state);
delete snapshot._k;
const shouldStartRequest = (()=>{
if (!key) return false;
if (!fetcher) return false;
// If it's paused, we skip revalidation.
if (getConfig().isPaused()) return false;
// If `revalidateOnMount` is set, we take the value directly.
if (isInitialMount && !isUndefined$1(revalidateOnMount)) return revalidateOnMount;
const data = !isUndefined$1(fallback) ? fallback : snapshot.data;
if (suspense) return isUndefined$1(data) || revalidateIfStale;
return isUndefined$1(data) || revalidateIfStale;
})();
if (!shouldStartRequest) {
return snapshot;
}
return {
isValidating: true,
isLoading: true,
...snapshot
};
};
const clientSnapshot = getSelectedCache(cachedData);
const serverSnapshot = cachedData === initialData ? clientSnapshot : getSelectedCache(initialData);
// 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 = clientSnapshot;
return [
()=>{
const newSnapshot = getSelectedCache(getCache());
const compareResult = isEqual(newSnapshot, memorizedSnapshot);
if (compareResult) {
// Mentally, we should always return the `memorizedSnapshot` here
// as there's no change between the new and old snapshots.
// However, since the `isEqual` function only compares selected fields,
// the values of the unselected fields might be changed. That's
// simply because we didn't track them.
// To support the case in https://github.com/vercel/swr/pull/2576,
// we need to update these fields in the `memorizedSnapshot` too
// with direct mutations to ensure the snapshot is always up-to-date
// even for the unselected fields, but only trigger re-renders when
// the selected fields are changed.
memorizedSnapshot.data = newSnapshot.data;
memorizedSnapshot.isLoading = newSnapshot.isLoading;
memorizedSnapshot.isValidating = newSnapshot.isValidating;
memorizedSnapshot.error = newSnapshot.error;
return memorizedSnapshot;
} else {
memorizedSnapshot = newSnapshot;
return newSnapshot;
}
},
()=>serverSnapshot
];
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [
cache,
key
]);
// Get the current state that SWR should return.
const cached = useSyncExternalStore(useCallback((callback)=>subscribeCache(key, (current, prev)=>{
if (!isEqual(prev, current)) callback();
}), // eslint-disable-next-line react-hooks/exhaustive-deps
[
cache,
key
]), getSnapshot[0], getSnapshot[1]);
const hasRevalidator = EVENT_REVALIDATORS[key] && EVENT_REVALIDATORS[key].length > 0;
const cachedData = cached.data;
const data = isUndefined$1(cachedData) ? fallback && isPromiseLike(fallback) ? use(fallback) : fallback : cachedData;
const error = cached.error;
// Use a ref to store previously returned data. Use the initial data as its initial value.
const laggyDataRef = useRef(data);
const returnedData = keepPreviousData ? isUndefined$1(cachedData) ? isUndefined$1(laggyDataRef.current) ? data : laggyDataRef.current : cachedData : data;
const hasKeyButNoData = key && isUndefined$1(data);
const hydrationRef = useRef(null);
// Note: the conditionally hook call is fine because the environment
// `IS_SERVER` never changes.
// @ts-expect-error -- use hydrationRef directly
!IS_SERVER && // getServerSnapshot is only called during hydration
// eslint-disable-next-line react-hooks/rules-of-hooks
useSyncExternalStore(sub, ()=>{
hydrationRef.current = false;
return hydrationRef;
}, ()=>{
hydrationRef.current = true;
return hydrationRef;
});
const isHydration = hydrationRef.current;
// During the initial SSR render, warn if the key has no data pre-fetched via:
// - fallback data
// - preload calls
// - initial data from the cache provider
// We only warn once for each key during Hydration.
if (strictServerPrefetchWarning && isHydration && !suspense && hasKeyButNoData) {
console.warn(`Missing pre-initiated data for serialized key "${key}" during server-side rendering. Data fetching should be initiated on the server and provided to SWR via fallback data. You can set "strictServerPrefetchWarning: false" to disable this warning.`);
}
// Resolve the default validating state:
// If it's able to validate, and it should revalidate when mount, this will be true.
// - Suspense mode and there's stale data for the initial render.
// - Not suspense mode and there is no fallback data and `revalidateIfStale` is enabled.
// - `revalidateIfStale` is enabled but `data` is not defined.
const shouldDoInitialRevalidation = (()=>{
if (!key || !fetcher) return false;
// If it's paused, we skip revalidation.
if (getConfig().isPaused()) return false;
// if a key already has revalidators and also has error, we should not trigger revalidation
if (hasRevalidator && !isUndefined$1(error)) return false;
// If `revalidateOnMount` is set, we take the value directly.
if (isInitialMount && !isUndefined$1(revalidateOnMount)) return revalidateOnMount;
// Under suspense mode, it will always fetch on render if there is no
// stale data so no need to revalidate immediately mount it again.
// If data exists, only revalidate if `revalidateIfStale` is true.
if (suspense) return isUndefined$1(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$1(data) || revalidateIfStale;
})();
const defaultValidatingState = isInitialMount && shouldDoInitialRevalidation;
const isValidating = isUndefined$1(cached.isValidating) ? defaultValidatingState : cached.isValidating;
const isLoading = isUndefined$1(cached.isLoading) ? defaultValidatingState : cached.isLoading;
// The revalidation function is a carefully crafted wrapper of the original
// `fetcher`, to correctly handle the many edge cases.
const revalidate = useCallback(async (revalidateOpts)=>{
const currentFetcher = fetcherRef.current;
if (!key || !currentFetcher || unmountedRef.current || getConfig().isPaused()) {
return false;
}
let newData;
let startAt;
let loading = true;
const opts = revalidateOpts || {};
// If there is no ongoing concurrent request, or `dedupe` is not set, a
// new request should be initiated.
const shouldStartNewRequest = !FETCH[key] || !opts.dedupe;
/*
For React 17
Do unmount check for calls:
If key has changed during the revalidation, or the component has been
unmounted, old dispatch and old event callbacks should not take any
effect
For React 18
only check if key has changed
https://github.com/reactwg/react-18/discussions/82
*/ const callbackSafeguard = ()=>{
if (IS_REACT_LEGACY) {
return !unmountedRef.current && key === keyRef.current && initialMountedRef.current;
}
return key === keyRef.current;
};
// The final state object when the request finishes.
const finalState = {
isValidating: false,
isLoading: false
};
const finishRequestAndUpdateState = ()=>{
setCache(finalState);
};
const cleanupState = ()=>{
// Check if it's still the same request before deleting it.
const requestInfo = FETCH[key];
if (requestInfo && requestInfo[1] === startAt) {
delete FETCH[key];
}
};
// Start fetching. Change the `isValidating` state, update the cache.
const initialState = {
isValidating: true
};
// It is in the `isLoading` state, if and only if there is no cached data.
// This bypasses fallback data and laggy data.
if (isUndefined$1(getCache().data)) {
initialState.isLoading = true;
}
try {
if (shouldStartNewRequest) {
setCache(initialState);
// If no cache is being rendered currently (it shows a blank page),
// we trigger the loading slow event.
if (config.loadingTimeout && isUndefined$1(getCache().data)) {
setTimeout(()=>{
if (loading && callbackSafeguard()) {
getConfig().onLoadingSlow(key, config);
}
}, config.loadingTimeout);
}
// Start the request and save the timestamp.
// Key must be truthy if entering here.
FETCH[key] = [
currentFetcher(fnArg),
getTimestamp()
];
}
// Wait until the ongoing request is done. Deduplication is also
// considered here.
;
[newData, startAt] = FETCH[key];
newData = await newData;
if (shouldStartNewRequest) {
// If the request isn't interrupted, clean it up after the
// deduplication interval.
setTimeout(cleanupState, config.dedupingInterval);
}
// If there're other ongoing request(s), started after the current one,
// we need to ignore the current one to avoid possible race conditions:
// req1------------------>res1 (current one)
// req2---------------->res2
// the request that fired later will always be kept.
// The timestamp maybe be `undefined` or a number
if (!FETCH[key] || FETCH[key][1] !== startAt) {
if (shouldStartNewRequest) {
if (callbackSafeguard()) {
getConfig().onDiscarded(key);
}
}
return false;
}
// Clear error.
finalState.error = UNDEFINED$1;
// If there're other mutations(s), that overlapped with the current revalidation:
// case 1:
// req------------------>res
// mutate------>end
// case 2:
// req------------>res
// mutate------>end
// case 3:
// req------------------>res
// mutate-------...---------->
// we have to ignore the revalidation result (res) because it's no longer fresh.
// meanwhile, a new revalidation should be triggered when the mutation ends.
const mutationInfo = MUTATION[key];
if (!isUndefined$1(mutationInfo) && // case 1
(startAt <= mutationInfo[0] || // case 2
startAt <= mutationInfo[1] || // case 3
mutationInfo[1] === 0)) {
finishRequestAndUpdateState();
if (shouldStartNewRequest) {
if (callbackSafeguard()) {
getConfig().onDiscarded(key);
}
}
return false;
}
// Deep compare with the latest state to avoid extra re-renders.
// For local state, compare and assign.
const cacheData = getCache().data;
// Since the compare fn could be custom fn
// cacheData might be different from newData even when compare fn returns True
finalState.data = compare(cacheData, newData) ? cacheData : newData;
// Trigger the successful callback if it's the original request.
if (shouldStartNewRequest) {
if (callbackSafeguard()) {
getConfig().onSuccess(newData, key, config);
}
}
} catch (err) {
cleanupState();
const currentConfig = getConfig();
const { shouldRetryOnError } = currentConfig;
// Not paused, we continue handling the error. Otherwise, discard it.
if (!currentConfig.isPaused()) {
// Get a new error, don't use deep comparison for errors.
finalState.error = err;
// Error event and retry logic. Only for the actual request, not
// deduped ones.
if (shouldStartNewRequest && callbackSafeguard()) {
currentConfig.onError(err, key, currentConfig);
if (shouldRetryOnError === true || isFunction$1(shouldRetryOnError) && shouldRetryOnError(err)) {
if (!getConfig().revalidateOnFocus || !getConfig().revalidateOnReconnect || isActive()) {
// If it's inactive, stop. It will auto-revalidate when
// refocusing or reconnecting.
// When retrying, deduplication is always enabled.
currentConfig.onErrorRetry(err, key, currentConfig, (_opts)=>{
const revalidators = EVENT_REVALIDATORS[key];
if (revalidators && revalidators[0]) {
revalidators[0](revalidateEvents.ERROR_REVALIDATE_EVENT, _opts);
}
}, {
retryCount: (opts.retryCount || 0) + 1,
dedupe: true
});
}
}
}
}
}
// Mark loading as stopped.
loading = false;
// Update the current hook's state.
finishRequestAndUpdateState();
return true;
}, // `setState` is immutable, and `eventsCallback`, `fnArg`, and
// `keyValidating` are depending on `key`, so we can exclude them from
// the deps array.
//
// FIXME:
// `fn` and `config` might be changed during the lifecycle,
// but they might be changed every render like this.
// `useSWR('key', () => fetch('/api/'), { suspense: true })`
// So we omit the values from the deps array
// even though it might cause unexpected behaviors.
// eslint-disable-next-line react-hooks/exhaustive-deps
[
key,
cache
]);
// Similar to the global mutate but bound to the current cache and key.
// `cache` isn't allowed to change during the lifecycle.
const boundMutate = useCallback(// Use callback to make sure `keyRef.current` returns latest result every time
(...args)=>{
return internalMutate(cache, keyRef.current, ...args);
}, // eslint-disable-next-line react-hooks/exhaustive-deps
[]);
// The logic for updating refs.
useIsomorphicLayoutEffect(()=>{
fetcherRef.current = fetcher;
configRef.current = config;
// Handle laggy data updates. If there's cached data of the current key,
// it'll be the correct reference.
if (!isUndefined$1(cachedData)) {
laggyDataRef.current = cachedData;
}
});
// After mounted or key changed.
useIsomorphicLayoutEffect(()=>{
if (!key) return;
const softRevalidate = revalidate.bind(UNDEFINED$1, WITH_DEDUPE);
let nextFocusRevalidatedAt = 0;
if (getConfig().revalidateOnFocus) {
const initNow = Date.now();
nextFocusRevalidatedAt = initNow + getConfig().focusThrottleInterval;
}
// Expose revalidators to global event listeners. So we can trigger
// revalidation from the outside.
const onRevalidate = (type, opts = {})=>{
if (type == revalidateEvents.FOCUS_EVENT) {
const now = Date.now();
if (getConfig().revalidateOnFocus && now > nextFocusRevalidatedAt && isActive()) {
nextFocusRevalidatedAt = now + getConfig().focusThrottleInterval;
softRevalidate();
}
} else if (type == revalidateEvents.RECONNECT_EVENT) {
if (getConfig().revalidateOnReconnect && isActive()) {
softRevalidate();
}
} else if (type == revalidateEvents.MUTATE_EVENT) {
return revalidate();
} else if (type == revalidateEvents.ERROR_REVALIDATE_EVENT) {
return revalidate(opts);
}
return;
};
const unsubEvents = subscribeCallback(key, EVENT_REVALIDATORS, onRevalidate);
// Mark the component as mounted and update corresponding refs.
unmountedRef.current = false;
keyRef.current = key;
initialMountedRef.current = true;
// Keep the original key in the cache.
setCache({
_k: fnArg
});
// Trigger a revalidation
if (shouldDoInitialRevalidation) {
// Performance optimization: if a request is already in progress for this key,
// skip the revalidation to avoid redundant work
if (!FETCH[key]) {
if (isUndefined$1(data) || IS_SERVER) {
// Revalidate immediately.
softRevalidate();
} else {
// Delay the revalidate if we have data to return so we won't block
// rendering.
rAF(softRevalidate);
}
}
}
return ()=>{
// Mark it as unmounted.
unmountedRef.current = true;
unsubEvents();
};
}, [
key
]);
// Polling
useIsomorphicLayoutEffect(()=>{
let timer;
function next() {
// Use the passed interval
// ...or invoke the function with the updated data to get the interval
const interval = isFunction$1(refreshInterval) ? refreshInterval(getCache().data) : refreshInterval;
// We only start the next interval if `refreshInterval` is not 0, and:
// - `force` is true, which is the start of polling
// - or `timer` is not 0, which means the effect wasn't canceled
if (interval && timer !== -1) {
timer = setTimeout(execute, interval);
}
}
function execute() {
// Check if it's OK to execute:
// Only revalidate when the page is visible, online, and not errored.
if (!getCache().error && (refreshWhenHidden || getConfig().isVisible()) && (refreshWhenOffline || getConfig().isOnline())) {
revalidate(WITH_DEDUPE).then(next);
} else {
// Schedule the next interval to check again.
next();
}
}
next();
return ()=>{
if (timer) {
clearTimeout(timer);
timer = -1;
}
};
}, [
refreshInterval,
refreshWhenHidden,
refreshWhenOffline,
key
]);
// Display debug info in React DevTools.
useDebugValue(returnedData);
// In Suspense mode, we can't return the empty `data` state.
// If there is an `error`, the `error` needs to be thrown to the error boundary.
// If there is no `error`, the `revalidation` promise needs to be thrown to
// the suspense boundary.
if (suspense) {
// SWR should throw when trying to use Suspense on the server with React 18,
// without providing any fallback data. This causes hydration errors. See:
// https://github.com/vercel/swr/issues/1832
if (!IS_REACT_LEGACY && IS_SERVER && hasKeyButNoData) {
throw new Error('Fallback data is required when using Suspense in SSR.');
}
// Always update fetcher and config refs even with the Suspense mode.
if (hasKeyButNoData) {
fetcherRef.current = fetcher;
configRef.current = config;
unmountedRef.current = false;
}
const req = PRELOAD[key];
const mutateReq = !isUndefined$1(req) && hasKeyButNoData ? boundMutate(req) : resolvedUndef;
use(mutateReq);
if (!isUndefined$1(error) && hasKeyButNoData) {
throw error;
}
const revalidation = hasKeyButNoData ? revalidate(WITH_DEDUPE) : resolvedUndef;
if (!isUndefined$1(returnedData) && hasKeyButNoData) {
// @ts-ignore modify react promise status
revalidation.status = 'fulfilled';
// @ts-ignore modify react promise value
revalidation.value = true;
}
use(revalidation);
}
const swrResponse = {
mutate: boundMutate,
get data () {
stateDependencies.data = true;
return returnedData;
},
get error () {
stateDependencies.error = true;
return error;
},
get isValidating () {
stateDependencies.isValidating = true;
return isValidating;
},
get isLoading () {
stateDependencies.isLoading = true;
return isLoading;
}
};
return swrResponse;
};
const SWRConfig = OBJECT$1.defineProperty(SWRConfig$1, 'defaultValue', {
value: defaultConfig
});
/**
* A hook to fetch data.
*
* @see {@link https://swr.vercel.app}
*
* @example
* ```jsx
* import useSWR from 'swr'
* function Profile() {
* const { data, error, isLoading } = useSWR('/api/user', fetcher)
* if (error) return <div>failed to load</div>
* if (isLoading) return <div>loading...</div>
* return <div>hello {data.name}!</div>
* }
* ```
*/ const useSWR = withArgs(useSWRHandler);
// useSWR
export { SWRConfig, useSWR as default, unstable_serialize };

96
node_modules/swr/dist/index/react-server.mjs generated vendored Normal file
View File

@@ -0,0 +1,96 @@
export { S as SWRConfig } from './config-12s-Bi4rgVRk.mjs';
// Shared state between server components and client components
const noop = ()=>{};
// Using noop() as the undefined value as undefined can be replaced
// by something else. Prettier ignore and extra parentheses are necessary here
// to ensure that tsc doesn't remove the __NOINLINE__ comment.
// prettier-ignore
const UNDEFINED = /*#__NOINLINE__*/ noop();
const OBJECT = Object;
const isUndefined = (v)=>v === UNDEFINED;
const isFunction = (v)=>typeof v == 'function';
// use WeakMap to store the object->key mapping
// so the objects can be garbage collected.
// WeakMap uses a hashtable under the hood, so the lookup
// complexity is almost O(1).
const table = new WeakMap();
const getTypeName = (value)=>OBJECT.prototype.toString.call(value);
const isObjectTypeName = (typeName, type)=>typeName === `[object ${type}]`;
// counter of the key
let counter = 0;
// A stable hash implementation that supports:
// - Fast and ensures unique hash properties
// - Handles unserializable values
// - Handles object key ordering
// - Generates short results
//
// This is not a serialization function, and the result is not guaranteed to be
// parsable.
const stableHash = (arg)=>{
const type = typeof arg;
const typeName = getTypeName(arg);
const isDate = isObjectTypeName(typeName, 'Date');
const isRegex = isObjectTypeName(typeName, 'RegExp');
const isPlainObject = isObjectTypeName(typeName, 'Object');
let result;
let index;
if (OBJECT(arg) === arg && !isDate && !isRegex) {
// Object/function, not null/date/regexp. Use WeakMap to store the id first.
// If it's already hashed, directly return the result.
result = table.get(arg);
if (result) return result;
// Store the hash first for circular reference detection before entering the
// recursive `stableHash` calls.
// For other objects like set and map, we use this id directly as the hash.
result = ++counter + '~';
table.set(arg, result);
if (Array.isArray(arg)) {
// Array.
result = '@';
for(index = 0; index < arg.length; index++){
result += stableHash(arg[index]) + ',';
}
table.set(arg, result);
}
if (isPlainObject) {
// Object, sort keys.
result = '#';
const keys = OBJECT.keys(arg).sort();
while(!isUndefined(index = keys.pop())){
if (!isUndefined(arg[index])) {
result += index + ':' + stableHash(arg[index]) + ',';
}
}
table.set(arg, result);
}
} else {
result = isDate ? arg.toJSON() : type == 'symbol' ? arg.toString() : type == 'string' ? JSON.stringify(arg) : '' + arg;
}
return result;
};
const serialize = (key)=>{
if (isFunction(key)) {
try {
key = key();
} catch (err) {
// dependencies not ready
key = '';
}
}
// Use the original key as the argument of fetcher. This can be a string or an
// array of values.
const args = key;
// If key is not falsy, or not an empty array, hash it.
key = typeof key == 'string' ? key : (Array.isArray(key) ? key.length : key) ? stableHash(key) : '';
return [
key,
args
];
};
const unstable_serialize = (key)=>serialize(key)[0];
export { unstable_serialize };

48
node_modules/swr/dist/infinite/index.d.mts generated vendored Normal file
View File

@@ -0,0 +1,48 @@
import { Arguments, StrictTupleKey, SWRResponse, MutatorCallback, MutatorOptions, BareFetcher, SWRConfiguration, Middleware } from '../_internal/index.mjs';
type FetcherResponse<Data = unknown> = Data | Promise<Data>;
type SWRInfiniteFetcher<Data = any, KeyLoader extends SWRInfiniteKeyLoader = SWRInfiniteKeyLoader> = KeyLoader extends (...args: any[]) => any ? ReturnType<KeyLoader> extends infer T | null | false | undefined ? (args: T) => FetcherResponse<Data> : never : never;
type SWRInfiniteKeyLoader<Data = any, Args extends Arguments = Arguments> = (index: number, previousPageData: Data | null) => Args;
interface SWRInfiniteCompareFn<Data = any> {
(a: Data | undefined, b: Data | undefined): boolean;
(a: Data[] | undefined, b: Data[] | undefined): boolean;
}
interface SWRInfiniteConfiguration<Data = any, Error = any, Fn extends SWRInfiniteFetcher<Data> = BareFetcher<Data>> extends Omit<SWRConfiguration<Data[], Error>, 'compare'> {
initialSize?: number;
revalidateAll?: boolean;
persistSize?: boolean;
revalidateFirstPage?: boolean;
parallel?: boolean;
fetcher?: Fn;
compare?: SWRInfiniteCompareFn<Data>;
}
interface SWRInfiniteRevalidateFn<Data = any> {
(data: Data, key: Arguments): boolean;
}
type SWRInfiniteKeyedMutator<Data> = <MutationData = Data>(data?: Data | Promise<Data | undefined> | MutatorCallback<Data>, opts?: boolean | SWRInfiniteMutatorOptions<Data, MutationData>) => Promise<Data | MutationData | undefined>;
interface SWRInfiniteMutatorOptions<Data = any, MutationData = Data> extends Omit<MutatorOptions<Data, MutationData>, 'revalidate'> {
revalidate?: boolean | SWRInfiniteRevalidateFn<Data extends unknown[] ? Data[number] : never>;
}
interface SWRInfiniteResponse<Data = any, Error = any> extends Omit<SWRResponse<Data[], Error>, 'mutate'> {
size: number;
setSize: (size: number | ((_size: number) => number)) => Promise<Data[] | undefined>;
mutate: SWRInfiniteKeyedMutator<Data[]>;
}
interface SWRInfiniteHook {
<Data = any, Error = any, KeyLoader extends SWRInfiniteKeyLoader = (index: number, previousPageData: Data | null) => StrictTupleKey>(getKey: KeyLoader): SWRInfiniteResponse<Data, Error>;
<Data = any, Error = any, KeyLoader extends SWRInfiniteKeyLoader = (index: number, previousPageData: Data | null) => StrictTupleKey>(getKey: KeyLoader, fetcher: SWRInfiniteFetcher<Data, KeyLoader> | null): SWRInfiniteResponse<Data, Error>;
<Data = any, Error = any, KeyLoader extends SWRInfiniteKeyLoader = (index: number, previousPageData: Data | null) => StrictTupleKey>(getKey: KeyLoader, config: SWRInfiniteConfiguration<Data, Error, SWRInfiniteFetcher<Data, KeyLoader>> | undefined): SWRInfiniteResponse<Data, Error>;
<Data = any, Error = any, KeyLoader extends SWRInfiniteKeyLoader = (index: number, previousPageData: Data | null) => StrictTupleKey>(getKey: KeyLoader, fetcher: SWRInfiniteFetcher<Data, KeyLoader> | null, config: SWRInfiniteConfiguration<Data, Error, SWRInfiniteFetcher<Data, KeyLoader>> | undefined): SWRInfiniteResponse<Data, Error>;
<Data = any, Error = any>(getKey: SWRInfiniteKeyLoader): SWRInfiniteResponse<Data, Error>;
<Data = any, Error = any>(getKey: SWRInfiniteKeyLoader, fetcher: BareFetcher<Data> | null): SWRInfiniteResponse<Data, Error>;
<Data = any, Error = any>(getKey: SWRInfiniteKeyLoader, config: SWRInfiniteConfiguration<Data, Error, BareFetcher<Data>> | undefined): SWRInfiniteResponse<Data, Error>;
<Data = any, Error = any>(getKey: SWRInfiniteKeyLoader, fetcher: BareFetcher<Data> | null, config: SWRInfiniteConfiguration<Data, Error, BareFetcher<Data>> | undefined): SWRInfiniteResponse<Data, Error>;
}
declare const unstable_serialize: (getKey: SWRInfiniteKeyLoader) => string;
declare const infinite: Middleware;
declare const useSWRInfinite: SWRInfiniteHook;
export { useSWRInfinite as default, infinite, unstable_serialize };
export type { SWRInfiniteCompareFn, SWRInfiniteConfiguration, SWRInfiniteFetcher, SWRInfiniteHook, SWRInfiniteKeyLoader, SWRInfiniteKeyedMutator, SWRInfiniteMutatorOptions, SWRInfiniteResponse };

48
node_modules/swr/dist/infinite/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,48 @@
import { Arguments, StrictTupleKey, SWRResponse, MutatorCallback, MutatorOptions, BareFetcher, SWRConfiguration, Middleware } from '../_internal/index.js';
type FetcherResponse<Data = unknown> = Data | Promise<Data>;
type SWRInfiniteFetcher<Data = any, KeyLoader extends SWRInfiniteKeyLoader = SWRInfiniteKeyLoader> = KeyLoader extends (...args: any[]) => any ? ReturnType<KeyLoader> extends infer T | null | false | undefined ? (args: T) => FetcherResponse<Data> : never : never;
type SWRInfiniteKeyLoader<Data = any, Args extends Arguments = Arguments> = (index: number, previousPageData: Data | null) => Args;
interface SWRInfiniteCompareFn<Data = any> {
(a: Data | undefined, b: Data | undefined): boolean;
(a: Data[] | undefined, b: Data[] | undefined): boolean;
}
interface SWRInfiniteConfiguration<Data = any, Error = any, Fn extends SWRInfiniteFetcher<Data> = BareFetcher<Data>> extends Omit<SWRConfiguration<Data[], Error>, 'compare'> {
initialSize?: number;
revalidateAll?: boolean;
persistSize?: boolean;
revalidateFirstPage?: boolean;
parallel?: boolean;
fetcher?: Fn;
compare?: SWRInfiniteCompareFn<Data>;
}
interface SWRInfiniteRevalidateFn<Data = any> {
(data: Data, key: Arguments): boolean;
}
type SWRInfiniteKeyedMutator<Data> = <MutationData = Data>(data?: Data | Promise<Data | undefined> | MutatorCallback<Data>, opts?: boolean | SWRInfiniteMutatorOptions<Data, MutationData>) => Promise<Data | MutationData | undefined>;
interface SWRInfiniteMutatorOptions<Data = any, MutationData = Data> extends Omit<MutatorOptions<Data, MutationData>, 'revalidate'> {
revalidate?: boolean | SWRInfiniteRevalidateFn<Data extends unknown[] ? Data[number] : never>;
}
interface SWRInfiniteResponse<Data = any, Error = any> extends Omit<SWRResponse<Data[], Error>, 'mutate'> {
size: number;
setSize: (size: number | ((_size: number) => number)) => Promise<Data[] | undefined>;
mutate: SWRInfiniteKeyedMutator<Data[]>;
}
interface SWRInfiniteHook {
<Data = any, Error = any, KeyLoader extends SWRInfiniteKeyLoader = (index: number, previousPageData: Data | null) => StrictTupleKey>(getKey: KeyLoader): SWRInfiniteResponse<Data, Error>;
<Data = any, Error = any, KeyLoader extends SWRInfiniteKeyLoader = (index: number, previousPageData: Data | null) => StrictTupleKey>(getKey: KeyLoader, fetcher: SWRInfiniteFetcher<Data, KeyLoader> | null): SWRInfiniteResponse<Data, Error>;
<Data = any, Error = any, KeyLoader extends SWRInfiniteKeyLoader = (index: number, previousPageData: Data | null) => StrictTupleKey>(getKey: KeyLoader, config: SWRInfiniteConfiguration<Data, Error, SWRInfiniteFetcher<Data, KeyLoader>> | undefined): SWRInfiniteResponse<Data, Error>;
<Data = any, Error = any, KeyLoader extends SWRInfiniteKeyLoader = (index: number, previousPageData: Data | null) => StrictTupleKey>(getKey: KeyLoader, fetcher: SWRInfiniteFetcher<Data, KeyLoader> | null, config: SWRInfiniteConfiguration<Data, Error, SWRInfiniteFetcher<Data, KeyLoader>> | undefined): SWRInfiniteResponse<Data, Error>;
<Data = any, Error = any>(getKey: SWRInfiniteKeyLoader): SWRInfiniteResponse<Data, Error>;
<Data = any, Error = any>(getKey: SWRInfiniteKeyLoader, fetcher: BareFetcher<Data> | null): SWRInfiniteResponse<Data, Error>;
<Data = any, Error = any>(getKey: SWRInfiniteKeyLoader, config: SWRInfiniteConfiguration<Data, Error, BareFetcher<Data>> | undefined): SWRInfiniteResponse<Data, Error>;
<Data = any, Error = any>(getKey: SWRInfiniteKeyLoader, fetcher: BareFetcher<Data> | null, config: SWRInfiniteConfiguration<Data, Error, BareFetcher<Data>> | undefined): SWRInfiniteResponse<Data, Error>;
}
declare const unstable_serialize: (getKey: SWRInfiniteKeyLoader) => string;
declare const infinite: Middleware;
declare const useSWRInfinite: SWRInfiniteHook;
export { useSWRInfinite as default, infinite, unstable_serialize };
export type { SWRInfiniteCompareFn, SWRInfiniteConfiguration, SWRInfiniteFetcher, SWRInfiniteHook, SWRInfiniteKeyLoader, SWRInfiniteKeyedMutator, SWRInfiniteMutatorOptions, SWRInfiniteResponse };

352
node_modules/swr/dist/infinite/index.js generated vendored Normal file
View File

@@ -0,0 +1,352 @@
Object.defineProperty(exports, '__esModule', { value: true });
var react = require('react');
var useSWR = require('../index/index.js');
var index_js = require('../_internal/index.js');
var shim = require('use-sync-external-store/shim');
var constants_js = require('../_internal/constants.js');
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
var useSWR__default = /*#__PURE__*/_interopDefault(useSWR);
// Shared state between server components and client components
const noop = ()=>{};
// Using noop() as the undefined value as undefined can be replaced
// by something else. Prettier ignore and extra parentheses are necessary here
// to ensure that tsc doesn't remove the __NOINLINE__ comment.
// prettier-ignore
const UNDEFINED = /*#__NOINLINE__*/ noop();
const OBJECT = Object;
const isUndefined = (v)=>v === UNDEFINED;
const isFunction = (v)=>typeof v == 'function';
// use WeakMap to store the object->key mapping
// so the objects can be garbage collected.
// WeakMap uses a hashtable under the hood, so the lookup
// complexity is almost O(1).
const table = new WeakMap();
const getTypeName = (value)=>OBJECT.prototype.toString.call(value);
const isObjectTypeName = (typeName, type)=>typeName === `[object ${type}]`;
// counter of the key
let counter = 0;
// A stable hash implementation that supports:
// - Fast and ensures unique hash properties
// - Handles unserializable values
// - Handles object key ordering
// - Generates short results
//
// This is not a serialization function, and the result is not guaranteed to be
// parsable.
const stableHash = (arg)=>{
const type = typeof arg;
const typeName = getTypeName(arg);
const isDate = isObjectTypeName(typeName, 'Date');
const isRegex = isObjectTypeName(typeName, 'RegExp');
const isPlainObject = isObjectTypeName(typeName, 'Object');
let result;
let index;
if (OBJECT(arg) === arg && !isDate && !isRegex) {
// Object/function, not null/date/regexp. Use WeakMap to store the id first.
// If it's already hashed, directly return the result.
result = table.get(arg);
if (result) return result;
// Store the hash first for circular reference detection before entering the
// recursive `stableHash` calls.
// For other objects like set and map, we use this id directly as the hash.
result = ++counter + '~';
table.set(arg, result);
if (Array.isArray(arg)) {
// Array.
result = '@';
for(index = 0; index < arg.length; index++){
result += stableHash(arg[index]) + ',';
}
table.set(arg, result);
}
if (isPlainObject) {
// Object, sort keys.
result = '#';
const keys = OBJECT.keys(arg).sort();
while(!isUndefined(index = keys.pop())){
if (!isUndefined(arg[index])) {
result += index + ':' + stableHash(arg[index]) + ',';
}
}
table.set(arg, result);
}
} else {
result = isDate ? arg.toJSON() : type == 'symbol' ? arg.toString() : type == 'string' ? JSON.stringify(arg) : '' + arg;
}
return result;
};
const serialize = (key)=>{
if (isFunction(key)) {
try {
key = key();
} catch (err) {
// dependencies not ready
key = '';
}
}
// Use the original key as the argument of fetcher. This can be a string or an
// array of values.
const args = key;
// If key is not falsy, or not an empty array, hash it.
key = typeof key == 'string' ? key : (Array.isArray(key) ? key.length : key) ? stableHash(key) : '';
return [
key,
args
];
};
const getFirstPageKey = (getKey)=>{
return serialize(getKey ? getKey(0, null) : null)[0];
};
const unstable_serialize = (getKey)=>{
return constants_js.INFINITE_PREFIX + getFirstPageKey(getKey);
};
// We have to several type castings here because `useSWRInfinite` is a special
// hook where `key` and return type are not like the normal `useSWR` types.
const EMPTY_PROMISE = Promise.resolve();
const infinite = (useSWRNext)=>(getKey, fn, config)=>{
const didMountRef = react.useRef(false);
const { cache, initialSize = 1, revalidateAll = false, persistSize = false, revalidateFirstPage = true, revalidateOnMount = false, parallel = false } = config;
const [, , , PRELOAD] = index_js.SWRGlobalState.get(index_js.cache);
// The serialized key of the first page. This key will be used to store
// metadata of this SWR infinite hook.
let infiniteKey;
try {
infiniteKey = getFirstPageKey(getKey);
if (infiniteKey) infiniteKey = index_js.INFINITE_PREFIX + infiniteKey;
} catch (err) {
// Not ready yet.
}
const [get, set, subscribeCache] = index_js.createCacheHelper(cache, infiniteKey);
const getSnapshot = react.useCallback(()=>{
const size = index_js.isUndefined(get()._l) ? initialSize : get()._l;
return size;
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [
cache,
infiniteKey,
initialSize
]);
shim.useSyncExternalStore(react.useCallback((callback)=>{
if (infiniteKey) return subscribeCache(infiniteKey, ()=>{
callback();
});
return ()=>{};
}, // eslint-disable-next-line react-hooks/exhaustive-deps
[
cache,
infiniteKey
]), getSnapshot, getSnapshot);
const resolvePageSize = react.useCallback(()=>{
const cachedPageSize = get()._l;
return index_js.isUndefined(cachedPageSize) ? initialSize : cachedPageSize;
// `cache` isn't allowed to change during the lifecycle
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [
infiniteKey,
initialSize
]);
// keep the last page size to restore it with the persistSize option
const lastPageSizeRef = react.useRef(resolvePageSize());
// When the page key changes, we reset the page size if it's not persisted
index_js.useIsomorphicLayoutEffect(()=>{
if (!didMountRef.current) {
didMountRef.current = true;
return;
}
if (infiniteKey) {
// 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 : resolvePageSize()
});
}
// `initialSize` isn't allowed to change during the lifecycle
}, [
infiniteKey,
cache
]);
// Needs to check didMountRef during mounting, not in the fetcher
const shouldRevalidateOnMount = revalidateOnMount && !didMountRef.current;
// Actual SWR hook to load all pages in one fetcher.
const swr = useSWRNext(infiniteKey, async (key)=>{
// get the revalidate context
const forceRevalidateAll = get()._i;
const shouldRevalidatePage = get()._r;
set({
_r: index_js.UNDEFINED
});
// return an array of page data
const data = [];
const pageSize = resolvePageSize();
const [getCache] = index_js.createCacheHelper(cache, key);
const cacheData = getCache().data;
const revalidators = [];
let previousPageData = null;
for(let i = 0; i < pageSize; ++i){
const [pageKey, pageArg] = index_js.serialize(getKey(i, parallel ? null : previousPageData));
if (!pageKey) {
break;
}
const [getSWRCache, setSWRCache] = index_js.createCacheHelper(cache, pageKey);
// Get the cached page data.
let pageData = getSWRCache().data;
// should fetch (or revalidate) if:
// - `revalidateAll` is enabled
// - `mutate()` called
// - the cache is missing
// - it's the first page and it's not the initial render
// - `revalidateOnMount` is enabled and it's on mount
// - cache for that page has changed
const shouldFetchPage = revalidateAll || forceRevalidateAll || index_js.isUndefined(pageData) || revalidateFirstPage && !i && !index_js.isUndefined(cacheData) || shouldRevalidateOnMount || cacheData && !index_js.isUndefined(cacheData[i]) && !config.compare(cacheData[i], pageData);
if (fn && (typeof shouldRevalidatePage === 'function' ? shouldRevalidatePage(pageData, pageArg) : shouldFetchPage)) {
const revalidate = async ()=>{
const hasPreloadedRequest = pageKey in PRELOAD;
if (!hasPreloadedRequest) {
pageData = await fn(pageArg);
} else {
const req = PRELOAD[pageKey];
// delete the preload cache key before resolving it
// in case there's an error
delete PRELOAD[pageKey];
// get the page data from the preload cache
pageData = await req;
}
setSWRCache({
data: pageData,
_k: pageArg
});
data[i] = pageData;
};
if (parallel) {
revalidators.push(revalidate);
} else {
await revalidate();
}
} else {
data[i] = pageData;
}
if (!parallel) {
previousPageData = pageData;
}
}
// flush all revalidateions in parallel
if (parallel) {
await Promise.all(revalidators.map((r)=>r()));
}
// once we executed the data fetching based on the context, clear the context
set({
_i: index_js.UNDEFINED
});
// return the data
return data;
}, config);
const mutate = react.useCallback(// eslint-disable-next-line func-names
function(data, opts) {
// When passing as a boolean, it's explicitly used to disable/enable
// revalidation.
const options = typeof opts === 'boolean' ? {
revalidate: opts
} : opts || {};
// Default to true.
const shouldRevalidate = options.revalidate !== false;
// It is possible that the key is still falsy.
if (!infiniteKey) return EMPTY_PROMISE;
if (shouldRevalidate) {
if (!index_js.isUndefined(data)) {
// We only revalidate the pages that are changed
set({
_i: false,
_r: options.revalidate
});
} else {
// Calling `mutate()`, we revalidate all pages
set({
_i: true,
_r: options.revalidate
});
}
}
return arguments.length ? swr.mutate(data, {
...options,
revalidate: shouldRevalidate
}) : swr.mutate();
}, // swr.mutate is always the same reference
// eslint-disable-next-line react-hooks/exhaustive-deps
[
infiniteKey,
cache
]);
// Extend the SWR API
const setSize = react.useCallback((arg)=>{
// It is possible that the key is still falsy.
if (!infiniteKey) return EMPTY_PROMISE;
const [, changeSize] = index_js.createCacheHelper(cache, infiniteKey);
let size;
if (index_js.isFunction(arg)) {
size = arg(resolvePageSize());
} else if (typeof arg == 'number') {
size = arg;
}
if (typeof size != 'number') return EMPTY_PROMISE;
changeSize({
_l: size
});
lastPageSizeRef.current = size;
// Calculate the page data after the size change.
const data = [];
const [getInfiniteCache] = index_js.createCacheHelper(cache, infiniteKey);
let previousPageData = null;
for(let i = 0; i < size; ++i){
const [pageKey] = index_js.serialize(getKey(i, previousPageData));
const [getCache] = index_js.createCacheHelper(cache, pageKey);
// Get the cached page data.
const pageData = pageKey ? getCache().data : index_js.UNDEFINED;
// Call `mutate` with infinte cache data if we can't get it from the page cache.
if (index_js.isUndefined(pageData)) {
return mutate(getInfiniteCache().data);
}
data.push(pageData);
previousPageData = pageData;
}
return mutate(data);
}, // exclude getKey from the dependencies, which isn't allowed to change during the lifecycle
// eslint-disable-next-line react-hooks/exhaustive-deps
[
infiniteKey,
cache,
mutate,
resolvePageSize
]);
// Use getter functions to avoid unnecessary re-renders caused by triggering
// all the getters of the returned swr object.
return {
size: resolvePageSize(),
setSize,
mutate,
get data () {
return swr.data;
},
get error () {
return swr.error;
},
get isValidating () {
return swr.isValidating;
},
get isLoading () {
return swr.isLoading;
}
};
};
const useSWRInfinite = index_js.withMiddleware(useSWR__default.default, infinite);
exports.default = useSWRInfinite;
exports.infinite = infinite;
exports.unstable_serialize = unstable_serialize;

344
node_modules/swr/dist/infinite/index.mjs generated vendored Normal file
View File

@@ -0,0 +1,344 @@
import { useRef, useCallback } from 'react';
import useSWR from '../index/index.mjs';
import { withMiddleware, SWRGlobalState, cache, INFINITE_PREFIX as INFINITE_PREFIX$1, createCacheHelper, isUndefined as isUndefined$1, useIsomorphicLayoutEffect, UNDEFINED as UNDEFINED$1, serialize as serialize$1, isFunction as isFunction$1 } from '../_internal/index.mjs';
import { useSyncExternalStore } from 'use-sync-external-store/shim';
import { INFINITE_PREFIX } from '../_internal/constants.mjs';
// Shared state between server components and client components
const noop = ()=>{};
// Using noop() as the undefined value as undefined can be replaced
// by something else. Prettier ignore and extra parentheses are necessary here
// to ensure that tsc doesn't remove the __NOINLINE__ comment.
// prettier-ignore
const UNDEFINED = /*#__NOINLINE__*/ noop();
const OBJECT = Object;
const isUndefined = (v)=>v === UNDEFINED;
const isFunction = (v)=>typeof v == 'function';
// use WeakMap to store the object->key mapping
// so the objects can be garbage collected.
// WeakMap uses a hashtable under the hood, so the lookup
// complexity is almost O(1).
const table = new WeakMap();
const getTypeName = (value)=>OBJECT.prototype.toString.call(value);
const isObjectTypeName = (typeName, type)=>typeName === `[object ${type}]`;
// counter of the key
let counter = 0;
// A stable hash implementation that supports:
// - Fast and ensures unique hash properties
// - Handles unserializable values
// - Handles object key ordering
// - Generates short results
//
// This is not a serialization function, and the result is not guaranteed to be
// parsable.
const stableHash = (arg)=>{
const type = typeof arg;
const typeName = getTypeName(arg);
const isDate = isObjectTypeName(typeName, 'Date');
const isRegex = isObjectTypeName(typeName, 'RegExp');
const isPlainObject = isObjectTypeName(typeName, 'Object');
let result;
let index;
if (OBJECT(arg) === arg && !isDate && !isRegex) {
// Object/function, not null/date/regexp. Use WeakMap to store the id first.
// If it's already hashed, directly return the result.
result = table.get(arg);
if (result) return result;
// Store the hash first for circular reference detection before entering the
// recursive `stableHash` calls.
// For other objects like set and map, we use this id directly as the hash.
result = ++counter + '~';
table.set(arg, result);
if (Array.isArray(arg)) {
// Array.
result = '@';
for(index = 0; index < arg.length; index++){
result += stableHash(arg[index]) + ',';
}
table.set(arg, result);
}
if (isPlainObject) {
// Object, sort keys.
result = '#';
const keys = OBJECT.keys(arg).sort();
while(!isUndefined(index = keys.pop())){
if (!isUndefined(arg[index])) {
result += index + ':' + stableHash(arg[index]) + ',';
}
}
table.set(arg, result);
}
} else {
result = isDate ? arg.toJSON() : type == 'symbol' ? arg.toString() : type == 'string' ? JSON.stringify(arg) : '' + arg;
}
return result;
};
const serialize = (key)=>{
if (isFunction(key)) {
try {
key = key();
} catch (err) {
// dependencies not ready
key = '';
}
}
// Use the original key as the argument of fetcher. This can be a string or an
// array of values.
const args = key;
// If key is not falsy, or not an empty array, hash it.
key = typeof key == 'string' ? key : (Array.isArray(key) ? key.length : key) ? stableHash(key) : '';
return [
key,
args
];
};
const getFirstPageKey = (getKey)=>{
return serialize(getKey ? getKey(0, null) : null)[0];
};
const unstable_serialize = (getKey)=>{
return INFINITE_PREFIX + getFirstPageKey(getKey);
};
// We have to several type castings here because `useSWRInfinite` is a special
// hook where `key` and return type are not like the normal `useSWR` types.
const EMPTY_PROMISE = Promise.resolve();
const infinite = (useSWRNext)=>(getKey, fn, config)=>{
const didMountRef = useRef(false);
const { cache: cache$1, initialSize = 1, revalidateAll = false, persistSize = false, revalidateFirstPage = true, revalidateOnMount = false, parallel = false } = config;
const [, , , PRELOAD] = SWRGlobalState.get(cache);
// The serialized key of the first page. This key will be used to store
// metadata of this SWR infinite hook.
let infiniteKey;
try {
infiniteKey = getFirstPageKey(getKey);
if (infiniteKey) infiniteKey = INFINITE_PREFIX$1 + infiniteKey;
} catch (err) {
// Not ready yet.
}
const [get, set, subscribeCache] = createCacheHelper(cache$1, infiniteKey);
const getSnapshot = useCallback(()=>{
const size = isUndefined$1(get()._l) ? initialSize : get()._l;
return size;
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [
cache$1,
infiniteKey,
initialSize
]);
useSyncExternalStore(useCallback((callback)=>{
if (infiniteKey) return subscribeCache(infiniteKey, ()=>{
callback();
});
return ()=>{};
}, // eslint-disable-next-line react-hooks/exhaustive-deps
[
cache$1,
infiniteKey
]), getSnapshot, getSnapshot);
const resolvePageSize = useCallback(()=>{
const cachedPageSize = get()._l;
return isUndefined$1(cachedPageSize) ? initialSize : cachedPageSize;
// `cache` isn't allowed to change during the lifecycle
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [
infiniteKey,
initialSize
]);
// keep the last page size to restore it with the persistSize option
const lastPageSizeRef = useRef(resolvePageSize());
// When the page key changes, we reset the page size if it's not persisted
useIsomorphicLayoutEffect(()=>{
if (!didMountRef.current) {
didMountRef.current = true;
return;
}
if (infiniteKey) {
// 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 : resolvePageSize()
});
}
// `initialSize` isn't allowed to change during the lifecycle
}, [
infiniteKey,
cache$1
]);
// Needs to check didMountRef during mounting, not in the fetcher
const shouldRevalidateOnMount = revalidateOnMount && !didMountRef.current;
// Actual SWR hook to load all pages in one fetcher.
const swr = useSWRNext(infiniteKey, async (key)=>{
// get the revalidate context
const forceRevalidateAll = get()._i;
const shouldRevalidatePage = get()._r;
set({
_r: UNDEFINED$1
});
// return an array of page data
const data = [];
const pageSize = resolvePageSize();
const [getCache] = createCacheHelper(cache$1, key);
const cacheData = getCache().data;
const revalidators = [];
let previousPageData = null;
for(let i = 0; i < pageSize; ++i){
const [pageKey, pageArg] = serialize$1(getKey(i, parallel ? null : previousPageData));
if (!pageKey) {
break;
}
const [getSWRCache, setSWRCache] = createCacheHelper(cache$1, pageKey);
// Get the cached page data.
let pageData = getSWRCache().data;
// should fetch (or revalidate) if:
// - `revalidateAll` is enabled
// - `mutate()` called
// - the cache is missing
// - it's the first page and it's not the initial render
// - `revalidateOnMount` is enabled and it's on mount
// - cache for that page has changed
const shouldFetchPage = revalidateAll || forceRevalidateAll || isUndefined$1(pageData) || revalidateFirstPage && !i && !isUndefined$1(cacheData) || shouldRevalidateOnMount || cacheData && !isUndefined$1(cacheData[i]) && !config.compare(cacheData[i], pageData);
if (fn && (typeof shouldRevalidatePage === 'function' ? shouldRevalidatePage(pageData, pageArg) : shouldFetchPage)) {
const revalidate = async ()=>{
const hasPreloadedRequest = pageKey in PRELOAD;
if (!hasPreloadedRequest) {
pageData = await fn(pageArg);
} else {
const req = PRELOAD[pageKey];
// delete the preload cache key before resolving it
// in case there's an error
delete PRELOAD[pageKey];
// get the page data from the preload cache
pageData = await req;
}
setSWRCache({
data: pageData,
_k: pageArg
});
data[i] = pageData;
};
if (parallel) {
revalidators.push(revalidate);
} else {
await revalidate();
}
} else {
data[i] = pageData;
}
if (!parallel) {
previousPageData = pageData;
}
}
// flush all revalidateions in parallel
if (parallel) {
await Promise.all(revalidators.map((r)=>r()));
}
// once we executed the data fetching based on the context, clear the context
set({
_i: UNDEFINED$1
});
// return the data
return data;
}, config);
const mutate = useCallback(// eslint-disable-next-line func-names
function(data, opts) {
// When passing as a boolean, it's explicitly used to disable/enable
// revalidation.
const options = typeof opts === 'boolean' ? {
revalidate: opts
} : opts || {};
// Default to true.
const shouldRevalidate = options.revalidate !== false;
// It is possible that the key is still falsy.
if (!infiniteKey) return EMPTY_PROMISE;
if (shouldRevalidate) {
if (!isUndefined$1(data)) {
// We only revalidate the pages that are changed
set({
_i: false,
_r: options.revalidate
});
} else {
// Calling `mutate()`, we revalidate all pages
set({
_i: true,
_r: options.revalidate
});
}
}
return arguments.length ? swr.mutate(data, {
...options,
revalidate: shouldRevalidate
}) : swr.mutate();
}, // swr.mutate is always the same reference
// eslint-disable-next-line react-hooks/exhaustive-deps
[
infiniteKey,
cache$1
]);
// Extend the SWR API
const setSize = useCallback((arg)=>{
// It is possible that the key is still falsy.
if (!infiniteKey) return EMPTY_PROMISE;
const [, changeSize] = createCacheHelper(cache$1, infiniteKey);
let size;
if (isFunction$1(arg)) {
size = arg(resolvePageSize());
} else if (typeof arg == 'number') {
size = arg;
}
if (typeof size != 'number') return EMPTY_PROMISE;
changeSize({
_l: size
});
lastPageSizeRef.current = size;
// Calculate the page data after the size change.
const data = [];
const [getInfiniteCache] = createCacheHelper(cache$1, infiniteKey);
let previousPageData = null;
for(let i = 0; i < size; ++i){
const [pageKey] = serialize$1(getKey(i, previousPageData));
const [getCache] = createCacheHelper(cache$1, pageKey);
// Get the cached page data.
const pageData = pageKey ? getCache().data : UNDEFINED$1;
// Call `mutate` with infinte cache data if we can't get it from the page cache.
if (isUndefined$1(pageData)) {
return mutate(getInfiniteCache().data);
}
data.push(pageData);
previousPageData = pageData;
}
return mutate(data);
}, // exclude getKey from the dependencies, which isn't allowed to change during the lifecycle
// eslint-disable-next-line react-hooks/exhaustive-deps
[
infiniteKey,
cache$1,
mutate,
resolvePageSize
]);
// Use getter functions to avoid unnecessary re-renders caused by triggering
// all the getters of the returned swr object.
return {
size: resolvePageSize(),
setSize,
mutate,
get data () {
return swr.data;
},
get error () {
return swr.error;
},
get isValidating () {
return swr.isValidating;
},
get isLoading () {
return swr.isLoading;
}
};
};
const useSWRInfinite = withMiddleware(useSWR, infinite);
export { useSWRInfinite as default, infinite, unstable_serialize };

101
node_modules/swr/dist/infinite/react-server.mjs generated vendored Normal file
View File

@@ -0,0 +1,101 @@
import { INFINITE_PREFIX } from '../_internal/constants.mjs';
// Shared state between server components and client components
const noop = ()=>{};
// Using noop() as the undefined value as undefined can be replaced
// by something else. Prettier ignore and extra parentheses are necessary here
// to ensure that tsc doesn't remove the __NOINLINE__ comment.
// prettier-ignore
const UNDEFINED = /*#__NOINLINE__*/ noop();
const OBJECT = Object;
const isUndefined = (v)=>v === UNDEFINED;
const isFunction = (v)=>typeof v == 'function';
// use WeakMap to store the object->key mapping
// so the objects can be garbage collected.
// WeakMap uses a hashtable under the hood, so the lookup
// complexity is almost O(1).
const table = new WeakMap();
const getTypeName = (value)=>OBJECT.prototype.toString.call(value);
const isObjectTypeName = (typeName, type)=>typeName === `[object ${type}]`;
// counter of the key
let counter = 0;
// A stable hash implementation that supports:
// - Fast and ensures unique hash properties
// - Handles unserializable values
// - Handles object key ordering
// - Generates short results
//
// This is not a serialization function, and the result is not guaranteed to be
// parsable.
const stableHash = (arg)=>{
const type = typeof arg;
const typeName = getTypeName(arg);
const isDate = isObjectTypeName(typeName, 'Date');
const isRegex = isObjectTypeName(typeName, 'RegExp');
const isPlainObject = isObjectTypeName(typeName, 'Object');
let result;
let index;
if (OBJECT(arg) === arg && !isDate && !isRegex) {
// Object/function, not null/date/regexp. Use WeakMap to store the id first.
// If it's already hashed, directly return the result.
result = table.get(arg);
if (result) return result;
// Store the hash first for circular reference detection before entering the
// recursive `stableHash` calls.
// For other objects like set and map, we use this id directly as the hash.
result = ++counter + '~';
table.set(arg, result);
if (Array.isArray(arg)) {
// Array.
result = '@';
for(index = 0; index < arg.length; index++){
result += stableHash(arg[index]) + ',';
}
table.set(arg, result);
}
if (isPlainObject) {
// Object, sort keys.
result = '#';
const keys = OBJECT.keys(arg).sort();
while(!isUndefined(index = keys.pop())){
if (!isUndefined(arg[index])) {
result += index + ':' + stableHash(arg[index]) + ',';
}
}
table.set(arg, result);
}
} else {
result = isDate ? arg.toJSON() : type == 'symbol' ? arg.toString() : type == 'string' ? JSON.stringify(arg) : '' + arg;
}
return result;
};
const serialize = (key)=>{
if (isFunction(key)) {
try {
key = key();
} catch (err) {
// dependencies not ready
key = '';
}
}
// Use the original key as the argument of fetcher. This can be a string or an
// array of values.
const args = key;
// If key is not falsy, or not an empty array, hash it.
key = typeof key == 'string' ? key : (Array.isArray(key) ? key.length : key) ? stableHash(key) : '';
return [
key,
args
];
};
const getFirstPageKey = (getKey)=>{
return serialize(getKey ? getKey(0, null) : null)[0];
};
const unstable_serialize = (getKey)=>{
return INFINITE_PREFIX + getFirstPageKey(getKey);
};
export { unstable_serialize };

159
node_modules/swr/dist/mutation/index.d.mts generated vendored Normal file
View File

@@ -0,0 +1,159 @@
import { Key, Arguments, SWRResponse } from '../index/index.mjs';
type FetcherResponse<Data> = Data | Promise<Data>;
type FetcherOptions<ExtraArg = unknown> = Readonly<{
arg: ExtraArg;
}>;
type MutationFetcher<Data = unknown, SWRKey extends Key = Key, ExtraArg = unknown> = SWRKey extends () => infer Arg | null | undefined | false ? (key: Arg, options: FetcherOptions<ExtraArg>) => FetcherResponse<Data> : SWRKey extends null | undefined | false ? never : SWRKey extends infer Arg ? (key: Arg, options: FetcherOptions<ExtraArg>) => FetcherResponse<Data> : never;
type SWRMutationConfiguration<Data, Error, SWRMutationKey extends Key = Key, ExtraArg = any, SWRData = any> = {
revalidate?: boolean | ((data: Data, key: Arguments) => boolean);
populateCache?: boolean | ((result: Data, currentData: SWRData | undefined) => SWRData);
optimisticData?: SWRData | ((currentData?: SWRData) => SWRData);
rollbackOnError?: boolean | ((error: unknown) => boolean);
fetcher?: MutationFetcher<Data, SWRMutationKey, ExtraArg>;
onSuccess?: (data: Data, key: string, config: Readonly<SWRMutationConfiguration<Data, Error, SWRMutationKey, ExtraArg, SWRData>>) => void;
onError?: (err: Error, key: string, config: Readonly<SWRMutationConfiguration<Data, Error, SWRMutationKey, ExtraArg, SWRData>>) => void;
};
type RemoveUndefined<T> = T extends undefined ? never : T;
type IsUndefinedIncluded<T> = undefined extends T ? true : false;
interface TriggerWithArgs<Data = any, Error = any, SWRMutationKey extends Key = Key, ExtraArg = never> {
<SWRData = Data>(extraArgument: ExtraArg, options?: SWRMutationConfiguration<Data, Error, SWRMutationKey, ExtraArg, SWRData>): Promise<Data>;
<SWRData = Data>(extraArgument: ExtraArg, options?: SWRMutationConfiguration<Data, Error, SWRMutationKey, ExtraArg, SWRData> & {
throwOnError: true;
}): Promise<RemoveUndefined<Data>>;
<SWRData = Data>(extraArgument: ExtraArg, options?: SWRMutationConfiguration<Data, Error, SWRMutationKey, ExtraArg, SWRData> & {
throwOnError: false;
}): Promise<Data | undefined>;
}
interface TriggerWithOptionsArgs<Data = any, Error = any, SWRMutationKey extends Key = Key, ExtraArg = never> {
<SWRData = Data>(extraArgument?: ExtraArg, options?: SWRMutationConfiguration<Data, Error, SWRMutationKey, ExtraArg, SWRData>): Promise<Data>;
<SWRData = Data>(extraArgument?: ExtraArg, options?: SWRMutationConfiguration<Data, Error, SWRMutationKey, ExtraArg, SWRData> & {
throwOnError: true;
}): Promise<RemoveUndefined<Data>>;
<SWRData = Data>(extraArgument?: ExtraArg, options?: SWRMutationConfiguration<Data, Error, SWRMutationKey, ExtraArg, SWRData> & {
throwOnError: false;
}): Promise<Data | undefined>;
}
interface TriggerWithoutArgs<Data = any, Error = any, SWRMutationKey extends Key = Key, ExtraArg = never> {
<SWRData = Data>(extraArgument?: null, options?: SWRMutationConfiguration<Data, Error, SWRMutationKey, ExtraArg, SWRData>): Promise<Data>;
<SWRData = Data>(extraArgument?: null, options?: SWRMutationConfiguration<Data, Error, SWRMutationKey, ExtraArg, SWRData> & {
throwOnError: true;
}): Promise<RemoveUndefined<Data>>;
<SWRData = Data>(extraArgument?: null, options?: SWRMutationConfiguration<Data, Error, SWRMutationKey, ExtraArg, SWRData> & {
throwOnError: false;
}): Promise<Data>;
}
interface SWRMutationResponse<Data = any, Error = any, SWRMutationKey extends Key = Key, ExtraArg = never> extends Pick<SWRResponse<Data, Error>, 'data' | 'error'> {
/**
* Indicates if the mutation is in progress.
*/
isMutating: boolean;
/**
* Function to trigger the mutation. You can also pass an extra argument to
* the fetcher, and override the options for the mutation hook.
*/
trigger: [ExtraArg] extends [never] ? TriggerWithoutArgs<Data, Error, SWRMutationKey, ExtraArg> : IsUndefinedIncluded<ExtraArg> extends true ? TriggerWithOptionsArgs<Data, Error, SWRMutationKey, ExtraArg> : TriggerWithArgs<Data, Error, SWRMutationKey, ExtraArg>;
/**
* Function to reset the mutation state (`data`, `error`, and `isMutating`).
*/
reset: () => void;
}
interface SWRMutationHook {
<Data = any, Error = any, SWRMutationKey extends Key = Key, ExtraArg = never, SWRData = Data>(
/**
* The key of the resource that will be mutated. It should be the same key
* used in the `useSWR` hook so SWR can handle revalidation and race
* conditions for that resource.
*/
key: SWRMutationKey,
/**
* The function to trigger the mutation that accepts the key, extra argument
* and options. For example:
*
* ```jsx
* (api, data) => fetch(api, {
* method: 'POST',
* body: JSON.stringify(data)
* })
* ```
*/
fetcher: MutationFetcher<Data, SWRMutationKey, ExtraArg>,
/**
* Extra options for the mutation hook.
*/
options?: SWRMutationConfiguration<Data, Error, SWRMutationKey, ExtraArg, SWRData> & {
throwOnError?: boolean;
}): SWRMutationResponse<Data, Error, SWRMutationKey, ExtraArg>;
<Data = any, Error = any, SWRMutationKey extends Key = Key, ExtraArg = never, SWRData = Data>(
/**
* The key of the resource that will be mutated. It should be the same key
* used in the `useSWR` hook so SWR can handle revalidation and race
* conditions for that resource.
*/
key: SWRMutationKey,
/**
* The function to trigger the mutation that accepts the key, extra argument
* and options. For example:
*
* ```jsx
* (api, data) => fetch(api, {
* method: 'POST',
* body: JSON.stringify(data)
* })
* ```
*/
fetcher: MutationFetcher<Data, SWRMutationKey, ExtraArg>,
/**
* Extra options for the mutation hook.
*/
options?: SWRMutationConfiguration<Data, Error, SWRMutationKey, ExtraArg, SWRData> & {
throwOnError: false;
}): SWRMutationResponse<Data | undefined, Error, SWRMutationKey, ExtraArg>;
<Data = any, Error = any, SWRMutationKey extends Key = Key, ExtraArg = never, SWRData = Data>(
/**
* The key of the resource that will be mutated. It should be the same key
* used in the `useSWR` hook so SWR can handle revalidation and race
* conditions for that resource.
*/
key: SWRMutationKey,
/**
* The function to trigger the mutation that accepts the key, extra argument
* and options. For example:
*
* ```jsx
* (api, data) => fetch(api, {
* method: 'POST',
* body: JSON.stringify(data)
* })
* ```
*/
fetcher: MutationFetcher<Data, SWRMutationKey, ExtraArg>,
/**
* Extra options for the mutation hook.
*/
options?: SWRMutationConfiguration<Data, Error, SWRMutationKey, ExtraArg, SWRData> & {
throwOnError: true;
}): SWRMutationResponse<Data, Error, SWRMutationKey, ExtraArg>;
}
/**
* A hook to define and manually trigger remote mutations like POST, PUT, DELETE and PATCH use cases.
*
* @link https://swr.vercel.app/docs/mutation
* @example
* ```jsx
* import useSWRMutation from 'swr/mutation'
*
* const {
* data,
* error,
* trigger,
* reset,
* isMutating
* } = useSWRMutation(key, fetcher, options?)
* ```
*/
declare const useSWRMutation: SWRMutationHook;
export { useSWRMutation as default };
export type { MutationFetcher, SWRMutationConfiguration, SWRMutationHook, SWRMutationResponse, TriggerWithArgs, TriggerWithOptionsArgs, TriggerWithoutArgs };

159
node_modules/swr/dist/mutation/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,159 @@
import { Key, Arguments, SWRResponse } from '../index/index.js';
type FetcherResponse<Data> = Data | Promise<Data>;
type FetcherOptions<ExtraArg = unknown> = Readonly<{
arg: ExtraArg;
}>;
type MutationFetcher<Data = unknown, SWRKey extends Key = Key, ExtraArg = unknown> = SWRKey extends () => infer Arg | null | undefined | false ? (key: Arg, options: FetcherOptions<ExtraArg>) => FetcherResponse<Data> : SWRKey extends null | undefined | false ? never : SWRKey extends infer Arg ? (key: Arg, options: FetcherOptions<ExtraArg>) => FetcherResponse<Data> : never;
type SWRMutationConfiguration<Data, Error, SWRMutationKey extends Key = Key, ExtraArg = any, SWRData = any> = {
revalidate?: boolean | ((data: Data, key: Arguments) => boolean);
populateCache?: boolean | ((result: Data, currentData: SWRData | undefined) => SWRData);
optimisticData?: SWRData | ((currentData?: SWRData) => SWRData);
rollbackOnError?: boolean | ((error: unknown) => boolean);
fetcher?: MutationFetcher<Data, SWRMutationKey, ExtraArg>;
onSuccess?: (data: Data, key: string, config: Readonly<SWRMutationConfiguration<Data, Error, SWRMutationKey, ExtraArg, SWRData>>) => void;
onError?: (err: Error, key: string, config: Readonly<SWRMutationConfiguration<Data, Error, SWRMutationKey, ExtraArg, SWRData>>) => void;
};
type RemoveUndefined<T> = T extends undefined ? never : T;
type IsUndefinedIncluded<T> = undefined extends T ? true : false;
interface TriggerWithArgs<Data = any, Error = any, SWRMutationKey extends Key = Key, ExtraArg = never> {
<SWRData = Data>(extraArgument: ExtraArg, options?: SWRMutationConfiguration<Data, Error, SWRMutationKey, ExtraArg, SWRData>): Promise<Data>;
<SWRData = Data>(extraArgument: ExtraArg, options?: SWRMutationConfiguration<Data, Error, SWRMutationKey, ExtraArg, SWRData> & {
throwOnError: true;
}): Promise<RemoveUndefined<Data>>;
<SWRData = Data>(extraArgument: ExtraArg, options?: SWRMutationConfiguration<Data, Error, SWRMutationKey, ExtraArg, SWRData> & {
throwOnError: false;
}): Promise<Data | undefined>;
}
interface TriggerWithOptionsArgs<Data = any, Error = any, SWRMutationKey extends Key = Key, ExtraArg = never> {
<SWRData = Data>(extraArgument?: ExtraArg, options?: SWRMutationConfiguration<Data, Error, SWRMutationKey, ExtraArg, SWRData>): Promise<Data>;
<SWRData = Data>(extraArgument?: ExtraArg, options?: SWRMutationConfiguration<Data, Error, SWRMutationKey, ExtraArg, SWRData> & {
throwOnError: true;
}): Promise<RemoveUndefined<Data>>;
<SWRData = Data>(extraArgument?: ExtraArg, options?: SWRMutationConfiguration<Data, Error, SWRMutationKey, ExtraArg, SWRData> & {
throwOnError: false;
}): Promise<Data | undefined>;
}
interface TriggerWithoutArgs<Data = any, Error = any, SWRMutationKey extends Key = Key, ExtraArg = never> {
<SWRData = Data>(extraArgument?: null, options?: SWRMutationConfiguration<Data, Error, SWRMutationKey, ExtraArg, SWRData>): Promise<Data>;
<SWRData = Data>(extraArgument?: null, options?: SWRMutationConfiguration<Data, Error, SWRMutationKey, ExtraArg, SWRData> & {
throwOnError: true;
}): Promise<RemoveUndefined<Data>>;
<SWRData = Data>(extraArgument?: null, options?: SWRMutationConfiguration<Data, Error, SWRMutationKey, ExtraArg, SWRData> & {
throwOnError: false;
}): Promise<Data>;
}
interface SWRMutationResponse<Data = any, Error = any, SWRMutationKey extends Key = Key, ExtraArg = never> extends Pick<SWRResponse<Data, Error>, 'data' | 'error'> {
/**
* Indicates if the mutation is in progress.
*/
isMutating: boolean;
/**
* Function to trigger the mutation. You can also pass an extra argument to
* the fetcher, and override the options for the mutation hook.
*/
trigger: [ExtraArg] extends [never] ? TriggerWithoutArgs<Data, Error, SWRMutationKey, ExtraArg> : IsUndefinedIncluded<ExtraArg> extends true ? TriggerWithOptionsArgs<Data, Error, SWRMutationKey, ExtraArg> : TriggerWithArgs<Data, Error, SWRMutationKey, ExtraArg>;
/**
* Function to reset the mutation state (`data`, `error`, and `isMutating`).
*/
reset: () => void;
}
interface SWRMutationHook {
<Data = any, Error = any, SWRMutationKey extends Key = Key, ExtraArg = never, SWRData = Data>(
/**
* The key of the resource that will be mutated. It should be the same key
* used in the `useSWR` hook so SWR can handle revalidation and race
* conditions for that resource.
*/
key: SWRMutationKey,
/**
* The function to trigger the mutation that accepts the key, extra argument
* and options. For example:
*
* ```jsx
* (api, data) => fetch(api, {
* method: 'POST',
* body: JSON.stringify(data)
* })
* ```
*/
fetcher: MutationFetcher<Data, SWRMutationKey, ExtraArg>,
/**
* Extra options for the mutation hook.
*/
options?: SWRMutationConfiguration<Data, Error, SWRMutationKey, ExtraArg, SWRData> & {
throwOnError?: boolean;
}): SWRMutationResponse<Data, Error, SWRMutationKey, ExtraArg>;
<Data = any, Error = any, SWRMutationKey extends Key = Key, ExtraArg = never, SWRData = Data>(
/**
* The key of the resource that will be mutated. It should be the same key
* used in the `useSWR` hook so SWR can handle revalidation and race
* conditions for that resource.
*/
key: SWRMutationKey,
/**
* The function to trigger the mutation that accepts the key, extra argument
* and options. For example:
*
* ```jsx
* (api, data) => fetch(api, {
* method: 'POST',
* body: JSON.stringify(data)
* })
* ```
*/
fetcher: MutationFetcher<Data, SWRMutationKey, ExtraArg>,
/**
* Extra options for the mutation hook.
*/
options?: SWRMutationConfiguration<Data, Error, SWRMutationKey, ExtraArg, SWRData> & {
throwOnError: false;
}): SWRMutationResponse<Data | undefined, Error, SWRMutationKey, ExtraArg>;
<Data = any, Error = any, SWRMutationKey extends Key = Key, ExtraArg = never, SWRData = Data>(
/**
* The key of the resource that will be mutated. It should be the same key
* used in the `useSWR` hook so SWR can handle revalidation and race
* conditions for that resource.
*/
key: SWRMutationKey,
/**
* The function to trigger the mutation that accepts the key, extra argument
* and options. For example:
*
* ```jsx
* (api, data) => fetch(api, {
* method: 'POST',
* body: JSON.stringify(data)
* })
* ```
*/
fetcher: MutationFetcher<Data, SWRMutationKey, ExtraArg>,
/**
* Extra options for the mutation hook.
*/
options?: SWRMutationConfiguration<Data, Error, SWRMutationKey, ExtraArg, SWRData> & {
throwOnError: true;
}): SWRMutationResponse<Data, Error, SWRMutationKey, ExtraArg>;
}
/**
* A hook to define and manually trigger remote mutations like POST, PUT, DELETE and PATCH use cases.
*
* @link https://swr.vercel.app/docs/mutation
* @example
* ```jsx
* import useSWRMutation from 'swr/mutation'
*
* const {
* data,
* error,
* trigger,
* reset,
* isMutating
* } = useSWRMutation(key, fetcher, options?)
* ```
*/
declare const useSWRMutation: SWRMutationHook;
export { useSWRMutation as default };
export type { MutationFetcher, SWRMutationConfiguration, SWRMutationHook, SWRMutationResponse, TriggerWithArgs, TriggerWithOptionsArgs, TriggerWithoutArgs };

201
node_modules/swr/dist/mutation/index.js generated vendored Normal file
View File

@@ -0,0 +1,201 @@
Object.defineProperty(exports, '__esModule', { value: true });
var React = require('react');
var useSWR = require('../index/index.js');
var index_js = require('../_internal/index.js');
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
var React__default = /*#__PURE__*/_interopDefault(React);
var useSWR__default = /*#__PURE__*/_interopDefault(useSWR);
const startTransition = index_js.IS_REACT_LEGACY ? (cb)=>{
cb();
} : React__default.default.startTransition;
/**
* An implementation of state with dependency-tracking.
* @param initialState - The initial state object.
*/ const useStateWithDeps = (initialState)=>{
const [, rerender] = React.useState({});
const unmountedRef = React.useRef(false);
const stateRef = React.useRef(initialState);
// If a state property (data, error, or isValidating) is accessed by the render
// function, we mark the property as a dependency so if it is updated again
// in the future, we trigger a rerender.
// This is also known as dependency-tracking.
const stateDependenciesRef = React.useRef({
data: false,
error: false,
isValidating: false
});
/**
* Updates state and triggers re-render if necessary.
* @param payload To change stateRef, pass the values explicitly to setState:
* @example
* ```js
* setState({
* isValidating: false
* data: newData // set data to newData
* error: undefined // set error to undefined
* })
*
* setState({
* isValidating: false
* data: undefined // set data to undefined
* error: err // set error to err
* })
* ```
*/ const setState = React.useCallback((payload)=>{
let shouldRerender = false;
const currentState = stateRef.current;
for(const key in payload){
if (Object.prototype.hasOwnProperty.call(payload, key)) {
const k = key;
// If the property has changed, update the state and mark rerender as
// needed.
if (currentState[k] !== payload[k]) {
currentState[k] = payload[k];
// If the property is accessed by the component, a rerender should be
// triggered.
if (stateDependenciesRef.current[k]) {
shouldRerender = true;
}
}
}
}
if (shouldRerender && !unmountedRef.current) {
rerender({});
}
}, []);
index_js.useIsomorphicLayoutEffect(()=>{
unmountedRef.current = false;
return ()=>{
unmountedRef.current = true;
};
});
return [
stateRef,
stateDependenciesRef.current,
setState
];
};
const mutation = ()=>(key, fetcher, config = {})=>{
const { mutate } = useSWR.useSWRConfig();
const keyRef = React.useRef(key);
const fetcherRef = React.useRef(fetcher);
const configRef = React.useRef(config);
// Ditch all mutation results that happened earlier than this timestamp.
const ditchMutationsUntilRef = React.useRef(0);
const [stateRef, stateDependencies, setState] = useStateWithDeps({
data: index_js.UNDEFINED,
error: index_js.UNDEFINED,
isMutating: false
});
const currentState = stateRef.current;
const trigger = React.useCallback(async (arg, opts)=>{
const [serializedKey, resolvedKey] = index_js.serialize(keyRef.current);
if (!fetcherRef.current) {
throw new Error('Cant trigger the mutation: missing fetcher.');
}
if (!serializedKey) {
throw new Error('Cant trigger the mutation: missing key.');
}
// Disable cache population by default.
const options = index_js.mergeObjects(index_js.mergeObjects({
populateCache: false,
throwOnError: true
}, configRef.current), opts);
// Trigger a mutation, and also track the timestamp. Any mutation that happened
// earlier this timestamp should be ignored.
const mutationStartedAt = index_js.getTimestamp();
ditchMutationsUntilRef.current = mutationStartedAt;
setState({
isMutating: true
});
try {
const data = await mutate(serializedKey, fetcherRef.current(resolvedKey, {
arg
}), // We must throw the error here so we can catch and update the states.
index_js.mergeObjects(options, {
throwOnError: true
}));
// If it's reset after the mutation, we don't broadcast any state change.
if (ditchMutationsUntilRef.current <= mutationStartedAt) {
startTransition(()=>setState({
data,
isMutating: false,
error: undefined
}));
options.onSuccess == null ? void 0 : options.onSuccess.call(options, data, serializedKey, options);
}
return data;
} catch (error) {
// If it's reset after the mutation, we don't broadcast any state change
// or throw because it's discarded.
if (ditchMutationsUntilRef.current <= mutationStartedAt) {
startTransition(()=>setState({
error: error,
isMutating: false
}));
options.onError == null ? void 0 : options.onError.call(options, error, serializedKey, options);
if (options.throwOnError) {
throw error;
}
}
}
}, // eslint-disable-next-line react-hooks/exhaustive-deps
[]);
const reset = React.useCallback(()=>{
ditchMutationsUntilRef.current = index_js.getTimestamp();
setState({
data: index_js.UNDEFINED,
error: index_js.UNDEFINED,
isMutating: false
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
index_js.useIsomorphicLayoutEffect(()=>{
keyRef.current = key;
fetcherRef.current = fetcher;
configRef.current = config;
});
// We don't return `mutate` here as it can be pretty confusing (e.g. people
// calling `mutate` but they actually mean `trigger`).
// And also, `mutate` relies on the useSWR hook to exist too.
return {
trigger,
reset,
get data () {
stateDependencies.data = true;
return currentState.data;
},
get error () {
stateDependencies.error = true;
return currentState.error;
},
get isMutating () {
stateDependencies.isMutating = true;
return currentState.isMutating;
}
};
};
/**
* A hook to define and manually trigger remote mutations like POST, PUT, DELETE and PATCH use cases.
*
* @link https://swr.vercel.app/docs/mutation
* @example
* ```jsx
* import useSWRMutation from 'swr/mutation'
*
* const {
* data,
* error,
* trigger,
* reset,
* isMutating
* } = useSWRMutation(key, fetcher, options?)
* ```
*/ const useSWRMutation = index_js.withMiddleware(useSWR__default.default, mutation);
exports.default = useSWRMutation;

194
node_modules/swr/dist/mutation/index.mjs generated vendored Normal file
View File

@@ -0,0 +1,194 @@
import React, { useState, useRef, useCallback } from 'react';
import useSWR, { useSWRConfig } from '../index/index.mjs';
import { IS_REACT_LEGACY, useIsomorphicLayoutEffect, withMiddleware, serialize, mergeObjects, getTimestamp, UNDEFINED } from '../_internal/index.mjs';
const startTransition = IS_REACT_LEGACY ? (cb)=>{
cb();
} : React.startTransition;
/**
* An implementation of state with dependency-tracking.
* @param initialState - The initial state object.
*/ const useStateWithDeps = (initialState)=>{
const [, rerender] = useState({});
const unmountedRef = useRef(false);
const stateRef = useRef(initialState);
// If a state property (data, error, or isValidating) is accessed by the render
// function, we mark the property as a dependency so if it is updated again
// in the future, we trigger a rerender.
// This is also known as dependency-tracking.
const stateDependenciesRef = useRef({
data: false,
error: false,
isValidating: false
});
/**
* Updates state and triggers re-render if necessary.
* @param payload To change stateRef, pass the values explicitly to setState:
* @example
* ```js
* setState({
* isValidating: false
* data: newData // set data to newData
* error: undefined // set error to undefined
* })
*
* setState({
* isValidating: false
* data: undefined // set data to undefined
* error: err // set error to err
* })
* ```
*/ const setState = useCallback((payload)=>{
let shouldRerender = false;
const currentState = stateRef.current;
for(const key in payload){
if (Object.prototype.hasOwnProperty.call(payload, key)) {
const k = key;
// If the property has changed, update the state and mark rerender as
// needed.
if (currentState[k] !== payload[k]) {
currentState[k] = payload[k];
// If the property is accessed by the component, a rerender should be
// triggered.
if (stateDependenciesRef.current[k]) {
shouldRerender = true;
}
}
}
}
if (shouldRerender && !unmountedRef.current) {
rerender({});
}
}, []);
useIsomorphicLayoutEffect(()=>{
unmountedRef.current = false;
return ()=>{
unmountedRef.current = true;
};
});
return [
stateRef,
stateDependenciesRef.current,
setState
];
};
const mutation = ()=>(key, fetcher, config = {})=>{
const { mutate } = useSWRConfig();
const keyRef = useRef(key);
const fetcherRef = useRef(fetcher);
const configRef = useRef(config);
// Ditch all mutation results that happened earlier than this timestamp.
const ditchMutationsUntilRef = useRef(0);
const [stateRef, stateDependencies, setState] = useStateWithDeps({
data: UNDEFINED,
error: UNDEFINED,
isMutating: false
});
const currentState = stateRef.current;
const trigger = useCallback(async (arg, opts)=>{
const [serializedKey, resolvedKey] = serialize(keyRef.current);
if (!fetcherRef.current) {
throw new Error('Cant trigger the mutation: missing fetcher.');
}
if (!serializedKey) {
throw new Error('Cant trigger the mutation: missing key.');
}
// Disable cache population by default.
const options = mergeObjects(mergeObjects({
populateCache: false,
throwOnError: true
}, configRef.current), opts);
// Trigger a mutation, and also track the timestamp. Any mutation that happened
// earlier this timestamp should be ignored.
const mutationStartedAt = getTimestamp();
ditchMutationsUntilRef.current = mutationStartedAt;
setState({
isMutating: true
});
try {
const data = await mutate(serializedKey, fetcherRef.current(resolvedKey, {
arg
}), // We must throw the error here so we can catch and update the states.
mergeObjects(options, {
throwOnError: true
}));
// If it's reset after the mutation, we don't broadcast any state change.
if (ditchMutationsUntilRef.current <= mutationStartedAt) {
startTransition(()=>setState({
data,
isMutating: false,
error: undefined
}));
options.onSuccess == null ? void 0 : options.onSuccess.call(options, data, serializedKey, options);
}
return data;
} catch (error) {
// If it's reset after the mutation, we don't broadcast any state change
// or throw because it's discarded.
if (ditchMutationsUntilRef.current <= mutationStartedAt) {
startTransition(()=>setState({
error: error,
isMutating: false
}));
options.onError == null ? void 0 : options.onError.call(options, error, serializedKey, options);
if (options.throwOnError) {
throw error;
}
}
}
}, // eslint-disable-next-line react-hooks/exhaustive-deps
[]);
const reset = useCallback(()=>{
ditchMutationsUntilRef.current = getTimestamp();
setState({
data: UNDEFINED,
error: UNDEFINED,
isMutating: false
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
useIsomorphicLayoutEffect(()=>{
keyRef.current = key;
fetcherRef.current = fetcher;
configRef.current = config;
});
// We don't return `mutate` here as it can be pretty confusing (e.g. people
// calling `mutate` but they actually mean `trigger`).
// And also, `mutate` relies on the useSWR hook to exist too.
return {
trigger,
reset,
get data () {
stateDependencies.data = true;
return currentState.data;
},
get error () {
stateDependencies.error = true;
return currentState.error;
},
get isMutating () {
stateDependencies.isMutating = true;
return currentState.isMutating;
}
};
};
/**
* A hook to define and manually trigger remote mutations like POST, PUT, DELETE and PATCH use cases.
*
* @link https://swr.vercel.app/docs/mutation
* @example
* ```jsx
* import useSWRMutation from 'swr/mutation'
*
* const {
* data,
* error,
* trigger,
* reset,
* isMutating
* } = useSWRMutation(key, fetcher, options?)
* ```
*/ const useSWRMutation = withMiddleware(useSWR, mutation);
export { useSWRMutation as default };

32
node_modules/swr/dist/subscription/index.d.mts generated vendored Normal file
View File

@@ -0,0 +1,32 @@
import { Key, MutatorCallback, SWRConfiguration, Middleware } from '../index/index.mjs';
type SWRSubscriptionOptions<Data = any, Error = any> = {
next: (err?: Error | null, data?: Data | MutatorCallback<Data>) => void;
};
type SWRSubscription<SWRSubKey extends Key = Key, Data = any, Error = any> = SWRSubKey extends () => infer Arg | null | undefined | false ? (key: Arg, { next }: SWRSubscriptionOptions<Data, Error>) => void : SWRSubKey extends null | undefined | false ? never : SWRSubKey extends infer Arg ? (key: Arg, { next }: SWRSubscriptionOptions<Data, Error>) => void : never;
type SWRSubscriptionResponse<Data = any, Error = any> = {
data?: Data;
error?: Error;
};
type SWRSubscriptionHook = <Data = any, Error = any, SWRSubKey extends Key = Key>(key: SWRSubKey, subscribe: SWRSubscription<SWRSubKey, Data, Error>, config?: SWRConfiguration) => SWRSubscriptionResponse<Data, Error>;
declare const subscription: Middleware;
/**
* A hook to subscribe a SWR resource to an external data source for continuous updates.
* @experimental This API is experimental and might change in the future.
* @example
* ```jsx
* import useSWRSubscription from 'swr/subscription'
*
* const { data, error } = useSWRSubscription(key, (key, { next }) => {
* const unsubscribe = dataSource.subscribe(key, (err, data) => {
* next(err, data)
* })
* return unsubscribe
* })
* ```
*/
declare const useSWRSubscription: SWRSubscriptionHook;
export { useSWRSubscription as default, subscription };
export type { SWRSubscription, SWRSubscriptionHook, SWRSubscriptionOptions, SWRSubscriptionResponse };

32
node_modules/swr/dist/subscription/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,32 @@
import { Key, MutatorCallback, SWRConfiguration, Middleware } from '../index/index.js';
type SWRSubscriptionOptions<Data = any, Error = any> = {
next: (err?: Error | null, data?: Data | MutatorCallback<Data>) => void;
};
type SWRSubscription<SWRSubKey extends Key = Key, Data = any, Error = any> = SWRSubKey extends () => infer Arg | null | undefined | false ? (key: Arg, { next }: SWRSubscriptionOptions<Data, Error>) => void : SWRSubKey extends null | undefined | false ? never : SWRSubKey extends infer Arg ? (key: Arg, { next }: SWRSubscriptionOptions<Data, Error>) => void : never;
type SWRSubscriptionResponse<Data = any, Error = any> = {
data?: Data;
error?: Error;
};
type SWRSubscriptionHook = <Data = any, Error = any, SWRSubKey extends Key = Key>(key: SWRSubKey, subscribe: SWRSubscription<SWRSubKey, Data, Error>, config?: SWRConfiguration) => SWRSubscriptionResponse<Data, Error>;
declare const subscription: Middleware;
/**
* A hook to subscribe a SWR resource to an external data source for continuous updates.
* @experimental This API is experimental and might change in the future.
* @example
* ```jsx
* import useSWRSubscription from 'swr/subscription'
*
* const { data, error } = useSWRSubscription(key, (key, { next }) => {
* const unsubscribe = dataSource.subscribe(key, (err, data) => {
* next(err, data)
* })
* return unsubscribe
* })
* ```
*/
declare const useSWRSubscription: SWRSubscriptionHook;
export { useSWRSubscription as default, subscription };
export type { SWRSubscription, SWRSubscriptionHook, SWRSubscriptionOptions, SWRSubscriptionResponse };

92
node_modules/swr/dist/subscription/index.js generated vendored Normal file
View File

@@ -0,0 +1,92 @@
Object.defineProperty(exports, '__esModule', { value: true });
var useSWR = require('../index/index.js');
var index_js = require('../_internal/index.js');
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
var useSWR__default = /*#__PURE__*/_interopDefault(useSWR);
const subscriptionStorage = new WeakMap();
const SUBSCRIPTION_PREFIX = '$sub$';
const subscription = (useSWRNext)=>(_key, subscribe, config)=>{
const [key, args] = index_js.serialize(_key);
// Prefix the key to avoid conflicts with other SWR resources.
const subscriptionKey = key ? SUBSCRIPTION_PREFIX + key : undefined;
const swr = useSWRNext(subscriptionKey, null, config);
const { cache } = config;
// Ensure that the subscription state is scoped by the cache boundary, so
// you can have multiple SWR zones with subscriptions having the same key.
if (!subscriptionStorage.has(cache)) {
subscriptionStorage.set(cache, [
new Map(),
new Map()
]);
}
const [subscriptions, disposers] = subscriptionStorage.get(cache);
index_js.useIsomorphicLayoutEffect(()=>{
if (!subscriptionKey) return;
const [, set] = index_js.createCacheHelper(cache, subscriptionKey);
const refCount = subscriptions.get(subscriptionKey) || 0;
const next = (error, data)=>{
if (error !== null && typeof error !== 'undefined') {
set({
error
});
} else {
set({
error: undefined
});
swr.mutate(data, false);
}
};
// Increment the ref count.
subscriptions.set(subscriptionKey, refCount + 1);
if (!refCount) {
const dispose = subscribe(args, {
next
});
if (typeof dispose !== 'function') {
throw new Error('The `subscribe` function must return a function to unsubscribe.');
}
disposers.set(subscriptionKey, dispose);
}
return ()=>{
const count = subscriptions.get(subscriptionKey) - 1;
subscriptions.set(subscriptionKey, count);
// Dispose if it's the last one.
if (!count) {
const dispose = disposers.get(subscriptionKey);
dispose == null ? void 0 : dispose();
}
};
}, [
subscriptionKey
]);
return {
get data () {
return swr.data;
},
get error () {
return swr.error;
}
};
};
/**
* A hook to subscribe a SWR resource to an external data source for continuous updates.
* @experimental This API is experimental and might change in the future.
* @example
* ```jsx
* import useSWRSubscription from 'swr/subscription'
*
* const { data, error } = useSWRSubscription(key, (key, { next }) => {
* const unsubscribe = dataSource.subscribe(key, (err, data) => {
* next(err, data)
* })
* return unsubscribe
* })
* ```
*/ const useSWRSubscription = index_js.withMiddleware(useSWR__default.default, subscription);
exports.default = useSWRSubscription;
exports.subscription = subscription;

85
node_modules/swr/dist/subscription/index.mjs generated vendored Normal file
View File

@@ -0,0 +1,85 @@
import useSWR from '../index/index.mjs';
import { withMiddleware, serialize, useIsomorphicLayoutEffect, createCacheHelper } from '../_internal/index.mjs';
const subscriptionStorage = new WeakMap();
const SUBSCRIPTION_PREFIX = '$sub$';
const subscription = (useSWRNext)=>(_key, subscribe, config)=>{
const [key, args] = serialize(_key);
// Prefix the key to avoid conflicts with other SWR resources.
const subscriptionKey = key ? SUBSCRIPTION_PREFIX + key : undefined;
const swr = useSWRNext(subscriptionKey, null, config);
const { cache } = config;
// Ensure that the subscription state is scoped by the cache boundary, so
// you can have multiple SWR zones with subscriptions having the same key.
if (!subscriptionStorage.has(cache)) {
subscriptionStorage.set(cache, [
new Map(),
new Map()
]);
}
const [subscriptions, disposers] = subscriptionStorage.get(cache);
useIsomorphicLayoutEffect(()=>{
if (!subscriptionKey) return;
const [, set] = createCacheHelper(cache, subscriptionKey);
const refCount = subscriptions.get(subscriptionKey) || 0;
const next = (error, data)=>{
if (error !== null && typeof error !== 'undefined') {
set({
error
});
} else {
set({
error: undefined
});
swr.mutate(data, false);
}
};
// Increment the ref count.
subscriptions.set(subscriptionKey, refCount + 1);
if (!refCount) {
const dispose = subscribe(args, {
next
});
if (typeof dispose !== 'function') {
throw new Error('The `subscribe` function must return a function to unsubscribe.');
}
disposers.set(subscriptionKey, dispose);
}
return ()=>{
const count = subscriptions.get(subscriptionKey) - 1;
subscriptions.set(subscriptionKey, count);
// Dispose if it's the last one.
if (!count) {
const dispose = disposers.get(subscriptionKey);
dispose == null ? void 0 : dispose();
}
};
}, [
subscriptionKey
]);
return {
get data () {
return swr.data;
},
get error () {
return swr.error;
}
};
};
/**
* A hook to subscribe a SWR resource to an external data source for continuous updates.
* @experimental This API is experimental and might change in the future.
* @example
* ```jsx
* import useSWRSubscription from 'swr/subscription'
*
* const { data, error } = useSWRSubscription(key, (key, { next }) => {
* const unsubscribe = dataSource.subscribe(key, (err, data) => {
* next(err, data)
* })
* return unsubscribe
* })
* ```
*/ const useSWRSubscription = withMiddleware(useSWR, subscription);
export { useSWRSubscription as default, subscription };