Comparing version 2.0.0-beta.4 to 2.0.0-beta.5
@@ -92,6 +92,4 @@ import * as revalidateEvents from './constants'; | ||
export interface ScopedMutator<Data = any> { | ||
/** This is used for bound mutator */ | ||
(key: Key, data?: Data | Promise<Data> | MutatorCallback<Data>, opts?: boolean | MutatorOptions<Data>): Promise<Data | undefined>; | ||
/** This is used for global mutator */ | ||
<T = any>(key: Key, data?: T | Promise<T> | MutatorCallback<T>, opts?: boolean | MutatorOptions<Data>): Promise<T | undefined>; | ||
<T = Data>(matcher: (key?: Arguments) => boolean, data?: T | Promise<T> | MutatorCallback<T>, opts?: boolean | MutatorOptions<Data>): Promise<Array<T | undefined>>; | ||
<T = Data>(key: Arguments, data?: T | Promise<T> | MutatorCallback<T>, opts?: boolean | MutatorOptions<Data>): Promise<T | undefined>; | ||
} | ||
@@ -121,2 +119,3 @@ export declare type KeyedMutator<Data> = (data?: Data | Promise<Data> | MutatorCallback<Data>, opts?: boolean | MutatorOptions<Data>) => Promise<Data | undefined>; | ||
export interface Cache<Data = any> { | ||
keys(): IterableIterator<string>; | ||
get(key: Key): State<Data> | undefined; | ||
@@ -123,0 +122,0 @@ set(key: Key, value: State<Data>): void; |
@@ -1,2 +0,2 @@ | ||
import { Key, Cache, State } from '../types'; | ||
import type { Key, Cache, State } from '../types'; | ||
export declare const noop: () => void; | ||
@@ -6,5 +6,4 @@ export declare const UNDEFINED: undefined; | ||
export declare const isUndefined: (v: any) => v is undefined; | ||
export declare const isFunction: (v: any) => v is Function; | ||
export declare const isEmptyCache: (v: any) => boolean; | ||
export declare const mergeObjects: (a: any, b: any) => any; | ||
export declare const isFunction: <T extends (...args: any[]) => any = (...args: any[]) => any>(v: unknown) => v is T; | ||
export declare const mergeObjects: (a: any, b?: any) => any; | ||
export declare const isWindowDefined: boolean; | ||
@@ -11,0 +10,0 @@ export declare const isDocumentDefined: boolean; |
@@ -1,2 +0,5 @@ | ||
import { Key, Cache, MutatorCallback, MutatorOptions } from '../types'; | ||
export declare const internalMutate: <Data>(args_0: Cache<any>, args_1: Key, args_2: Data | Promise<Data | undefined> | MutatorCallback<Data> | undefined, args_3: boolean | MutatorOptions<Data> | undefined) => Promise<Data | undefined>; | ||
import { Cache, MutatorCallback, MutatorOptions, Arguments } from '../types'; | ||
declare type KeyFilter = (key?: Arguments) => boolean; | ||
export declare function internalMutate<Data>(cache: Cache, _key: KeyFilter, _data?: Data | Promise<Data | undefined> | MutatorCallback<Data>, _opts?: boolean | MutatorOptions<Data>): Promise<Array<Data | undefined>>; | ||
export declare function internalMutate<Data>(cache: Cache, _key: Arguments, _data?: Data | Promise<Data | undefined> | MutatorCallback<Data>, _opts?: boolean | MutatorOptions<Data>): Promise<Data | undefined>; | ||
export {}; |
@@ -1,3 +0,3 @@ | ||
import { Middleware, Key, BareFetcher } from '../types'; | ||
export declare const preload: <Data = any>(key_: Key, fetcher: BareFetcher<Data>) => import("../types").FetcherResponse<Data>; | ||
import type { Middleware, Key, BareFetcher } from '../types'; | ||
export declare const preload: <Data = any>(key_: Key, fetcher: BareFetcher<Data>) => any; | ||
export declare const middleware: Middleware; |
import React, { useEffect, useLayoutEffect, createContext, useContext, useState, createElement, useRef, useCallback } from 'react'; | ||
/****************************************************************************** | ||
Copyright (c) Microsoft Corporation. | ||
Permission to use, copy, modify, and/or distribute this software for any | ||
purpose with or without fee is hereby granted. | ||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH | ||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY | ||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, | ||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM | ||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR | ||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | ||
PERFORMANCE OF THIS SOFTWARE. | ||
***************************************************************************** */ | ||
var __assign = function() { | ||
__assign = Object.assign || function __assign(t) { | ||
for (var s, i = 1, n = arguments.length; i < n; i++) { | ||
s = arguments[i]; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; | ||
} | ||
return t; | ||
}; | ||
return __assign.apply(this, arguments); | ||
}; | ||
function __awaiter(thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
} | ||
function __generator(thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
} | ||
function __values(o) { | ||
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; | ||
if (m) return m.call(o); | ||
if (o && typeof o.length === "number") return { | ||
next: function () { | ||
if (o && i >= o.length) o = void 0; | ||
return { value: o && o[i++], done: !o }; | ||
} | ||
}; | ||
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); | ||
} | ||
function __read(o, n) { | ||
var m = typeof Symbol === "function" && o[Symbol.iterator]; | ||
if (!m) return o; | ||
var i = m.call(o), r, ar = [], e; | ||
try { | ||
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); | ||
} | ||
catch (error) { e = { error: error }; } | ||
finally { | ||
try { | ||
if (r && !r.done && (m = i["return"])) m.call(i); | ||
} | ||
finally { if (e) throw e.error; } | ||
} | ||
return ar; | ||
} | ||
function __spreadArray(to, from, pack) { | ||
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { | ||
if (ar || !(i in from)) { | ||
if (!ar) ar = Array.prototype.slice.call(from, 0, i); | ||
ar[i] = from[i]; | ||
} | ||
} | ||
return to.concat(ar || Array.prototype.slice.call(from)); | ||
} | ||
// Global state used to deduplicate requests and store listeners | ||
@@ -16,3 +119,2 @@ var SWRGlobalState = new WeakMap(); | ||
var isFunction = function (v) { return typeof v == 'function'; }; | ||
var isEmptyCache = function (v) { return v === EMPTY_CACHE; }; | ||
var mergeObjects = function (a, b) { return OBJECT.assign({}, a, b); }; | ||
@@ -115,3 +217,3 @@ var STR_UNDEFINED = 'undefined'; | ||
// For node and React Native, `add/removeEventListener` doesn't exist on window. | ||
var _a$1 = isWindowDefined && window.addEventListener | ||
var _a$1 = __read(isWindowDefined && window.addEventListener | ||
? [ | ||
@@ -121,3 +223,3 @@ window.addEventListener.bind(window), | ||
] | ||
: [noop, noop], onWindowEvent = _a$1[0], offWindowEvent = _a$1[1]; | ||
: [noop, noop], 2), onWindowEvent = _a$1[0], offWindowEvent = _a$1[1]; | ||
var isVisible = function () { | ||
@@ -187,66 +289,2 @@ var visibilityState = isDocumentDefined && document.visibilityState; | ||
/****************************************************************************** | ||
Copyright (c) Microsoft Corporation. | ||
Permission to use, copy, modify, and/or distribute this software for any | ||
purpose with or without fee is hereby granted. | ||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH | ||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY | ||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, | ||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM | ||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR | ||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | ||
PERFORMANCE OF THIS SOFTWARE. | ||
***************************************************************************** */ | ||
var __assign = function() { | ||
__assign = Object.assign || function __assign(t) { | ||
for (var s, i = 1, n = arguments.length; i < n; i++) { | ||
s = arguments[i]; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; | ||
} | ||
return t; | ||
}; | ||
return __assign.apply(this, arguments); | ||
}; | ||
function __awaiter(thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
} | ||
function __generator(thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
} | ||
var serialize = function (key) { | ||
@@ -290,3 +328,3 @@ if (isFunction(key)) { | ||
var internalMutate = function () { | ||
function internalMutate() { | ||
var args = []; | ||
@@ -296,124 +334,158 @@ for (var _i = 0; _i < arguments.length; _i++) { | ||
} | ||
return __awaiter(void 0, void 0, void 0, function () { | ||
var cache, _key, _data, _opts, options, populateCache, optimisticData, revalidate, rollbackOnError, key, _a, get, set, _b, EVENT_REVALIDATORS, MUTATION, FETCH, revalidators, startRevalidate, data, error, beforeMutationTs, hasOptimisticData, state, displayedData, committedData, res; | ||
return __generator(this, function (_d) { | ||
switch (_d.label) { | ||
case 0: | ||
cache = args[0], _key = args[1], _data = args[2], _opts = args[3]; | ||
options = typeof _opts === 'boolean' ? { revalidate: _opts } : _opts || {}; | ||
populateCache = isUndefined(options.populateCache) | ||
? true | ||
: options.populateCache; | ||
optimisticData = options.optimisticData; | ||
revalidate = options.revalidate !== false; | ||
rollbackOnError = options.rollbackOnError !== false; | ||
key = serialize(_key)[0]; | ||
if (!key) | ||
return [2 /*return*/]; | ||
_a = createCacheHelper(cache, key), get = _a[0], set = _a[1]; | ||
_b = SWRGlobalState.get(cache), EVENT_REVALIDATORS = _b[0], MUTATION = _b[1], FETCH = _b[2]; | ||
revalidators = EVENT_REVALIDATORS[key]; | ||
startRevalidate = function () { | ||
if (revalidate) { | ||
// Invalidate the key by deleting the concurrent request markers so new | ||
// requests will not be deduped. | ||
delete FETCH[key]; | ||
if (revalidators && revalidators[0]) { | ||
return revalidators[0](MUTATE_EVENT).then(function () { return get().data; }); | ||
return __awaiter(this, void 0, void 0, function () { | ||
function mutateByKey(_k) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var _a, key, _b, get, set, _d, EVENT_REVALIDATORS, MUTATION, FETCH, revalidators, startRevalidate, data, error, beforeMutationTs, hasOptimisticData, state, displayedData, committedData, res; | ||
return __generator(this, function (_e) { | ||
switch (_e.label) { | ||
case 0: | ||
_a = __read(serialize(_k), 1), key = _a[0]; | ||
if (!key) | ||
return [2 /*return*/]; | ||
_b = __read(createCacheHelper(cache, key), 2), get = _b[0], set = _b[1]; | ||
_d = __read(SWRGlobalState.get(cache), 3), EVENT_REVALIDATORS = _d[0], MUTATION = _d[1], FETCH = _d[2]; | ||
revalidators = EVENT_REVALIDATORS[key]; | ||
startRevalidate = function () { | ||
if (revalidate) { | ||
// Invalidate the key by deleting the concurrent request markers so new | ||
// requests will not be deduped. | ||
delete FETCH[key]; | ||
if (revalidators && revalidators[0]) { | ||
return revalidators[0](MUTATE_EVENT).then(function () { return 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 [2 /*return*/, startRevalidate()]; | ||
} | ||
} | ||
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 [2 /*return*/, startRevalidate()]; | ||
data = _data; | ||
beforeMutationTs = getTimestamp(); | ||
MUTATION[key] = [beforeMutationTs, 0]; | ||
hasOptimisticData = !isUndefined(optimisticData); | ||
state = get(); | ||
displayedData = state.data; | ||
committedData = isUndefined(state._c) ? displayedData : state._c; | ||
// Do optimistic data update. | ||
if (hasOptimisticData) { | ||
optimisticData = isFunction(optimisticData) | ||
? optimisticData(committedData) | ||
: 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; | ||
} | ||
} | ||
if (!(data && isFunction(data.then))) return [3 /*break*/, 2]; | ||
return [4 /*yield*/, data.catch(function (err) { | ||
error = err; | ||
}) | ||
// 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. | ||
]; | ||
case 1: | ||
// This means that the mutation is async, we need to check timestamps to | ||
// avoid race conditions. | ||
data = _e.sent(); | ||
// 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 (error) | ||
throw error; | ||
return [2 /*return*/, data]; | ||
} | ||
else if (error && hasOptimisticData && rollbackOnError) { | ||
// Rollback. Always populate the cache in this case but without | ||
// transforming the data. | ||
populateCache = true; | ||
data = committedData; | ||
// Reset data to be the latest committed data, and clear the `_c` value. | ||
set({ data: data, _c: UNDEFINED }); | ||
} | ||
_e.label = 2; | ||
case 2: | ||
// If we should write back the cache after request. | ||
if (populateCache) { | ||
if (!error) { | ||
// Transform the result into data. | ||
if (isFunction(populateCache)) { | ||
data = populateCache(data, committedData); | ||
} | ||
// Only update cached data if there's no error. Data can be `undefined` here. | ||
set({ data: data, _c: UNDEFINED }); | ||
} | ||
// Always update error and original data here. | ||
set({ error: error }); | ||
} | ||
// Reset the timestamp to mark the mutation has ended. | ||
MUTATION[key][1] = getTimestamp(); | ||
return [4 /*yield*/, startRevalidate() | ||
// The mutation and revalidation are ended, we can clear it since the data is | ||
// not an optimistic value anymore. | ||
]; | ||
case 3: | ||
res = _e.sent(); | ||
// 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 (error) | ||
throw error; | ||
return [2 /*return*/, populateCache ? res : data]; | ||
} | ||
data = _data; | ||
beforeMutationTs = getTimestamp(); | ||
MUTATION[key] = [beforeMutationTs, 0]; | ||
hasOptimisticData = !isUndefined(optimisticData); | ||
state = get(); | ||
displayedData = state.data; | ||
committedData = isUndefined(state._c) ? displayedData : state._c; | ||
// Do optimistic data update. | ||
if (hasOptimisticData) { | ||
optimisticData = isFunction(optimisticData) | ||
? optimisticData(committedData) | ||
: 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); | ||
}); | ||
}); | ||
} | ||
var _a, cache, _key, _data, _opts, options, populateCache, optimisticData, revalidate, rollbackOnError, keyFilter, matchedKeys, _b, _d, key; | ||
var e_1, _e; | ||
return __generator(this, function (_f) { | ||
_a = __read(args, 4), cache = _a[0], _key = _a[1], _data = _a[2], _opts = _a[3]; | ||
options = typeof _opts === 'boolean' ? { revalidate: _opts } : _opts || {}; | ||
populateCache = isUndefined(options.populateCache) | ||
? true | ||
: options.populateCache; | ||
optimisticData = options.optimisticData; | ||
revalidate = options.revalidate !== false; | ||
rollbackOnError = options.rollbackOnError !== false; | ||
// If the second argument is a key filter, return the mutation results for all | ||
// filtered keys. | ||
if (isFunction(_key)) { | ||
keyFilter = _key; | ||
matchedKeys = []; | ||
try { | ||
for (_b = __values(cache.keys()), _d = _b.next(); !_d.done; _d = _b.next()) { | ||
key = _d.value; | ||
if ( | ||
// Skip the speical useSWRInfinite keys. | ||
!key.startsWith('$inf$') && | ||
keyFilter(cache.get(key)._k)) { | ||
matchedKeys.push(key); | ||
} | ||
catch (err) { | ||
// If it throws an error synchronously, we shouldn't update the cache. | ||
error = err; | ||
} | ||
} | ||
if (!(data && isFunction(data.then))) return [3 /*break*/, 2]; | ||
return [4 /*yield*/, data.catch(function (err) { | ||
error = err; | ||
}) | ||
// 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. | ||
]; | ||
case 1: | ||
// This means that the mutation is async, we need to check timestamps to | ||
// avoid race conditions. | ||
data = _d.sent(); | ||
// 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 (error) | ||
throw error; | ||
return [2 /*return*/, data]; | ||
} | ||
catch (e_1_1) { e_1 = { error: e_1_1 }; } | ||
finally { | ||
try { | ||
if (_d && !_d.done && (_e = _b.return)) _e.call(_b); | ||
} | ||
else if (error && hasOptimisticData && rollbackOnError) { | ||
// Rollback. Always populate the cache in this case but without | ||
// transforming the data. | ||
populateCache = true; | ||
data = committedData; | ||
// Reset data to be the latest committed data, and clear the `_c` value. | ||
set({ data: data, _c: UNDEFINED }); | ||
} | ||
_d.label = 2; | ||
case 2: | ||
// If we should write back the cache after request. | ||
if (populateCache) { | ||
if (!error) { | ||
// Transform the result into data. | ||
if (isFunction(populateCache)) { | ||
data = populateCache(data, committedData); | ||
} | ||
// Only update cached data if there's no error. Data can be `undefined` here. | ||
set({ data: data, _c: UNDEFINED }); | ||
} | ||
// Always update error and original data here. | ||
set({ error: error }); | ||
} | ||
// Reset the timestamp to mark the mutation has ended. | ||
MUTATION[key][1] = getTimestamp(); | ||
return [4 /*yield*/, startRevalidate() | ||
// The mutation and revalidation are ended, we can clear it since the data is | ||
// not an optimistic value anymore. | ||
]; | ||
case 3: | ||
res = _d.sent(); | ||
// 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 (error) | ||
throw error; | ||
return [2 /*return*/, populateCache ? res : data]; | ||
finally { if (e_1) throw e_1.error; } | ||
} | ||
return [2 /*return*/, Promise.all(matchedKeys.map(mutateByKey))]; | ||
} | ||
return [2 /*return*/, mutateByKey(_key)]; | ||
}); | ||
}); | ||
}; | ||
} | ||
@@ -444,5 +516,3 @@ var revalidateAllKeys = function (revalidators, type) { | ||
subs.push(callback); | ||
return function () { | ||
subs.splice(subs.indexOf(callback), 1); | ||
}; | ||
return function () { return subs.splice(subs.indexOf(callback), 1); }; | ||
}; | ||
@@ -454,3 +524,3 @@ var setter_1 = function (key, value, prev) { | ||
for (var i = subs.length; i--;) { | ||
subs[i](value, prev); | ||
subs[i](prev, value); | ||
} | ||
@@ -518,3 +588,3 @@ } | ||
// Default cache provider | ||
var _a = initCache(new Map()), cache = _a[0], mutate = _a[1]; | ||
var _a = __read(initCache(new Map()), 2), cache = _a[0], mutate = _a[1]; | ||
// Default config | ||
@@ -578,7 +648,7 @@ var defaultConfig = mergeObjects({ | ||
// Use a lazy initialized state to create the cache on first access. | ||
var cacheContext = useState(function () { | ||
var _a = __read(useState(function () { | ||
return provider | ||
? initCache(provider(extendedConfig.cache || cache), config) | ||
: UNDEFINED; | ||
})[0]; | ||
}), 1), cacheContext = _a[0]; | ||
// Override the cache if a new provider is given. | ||
@@ -612,5 +682,8 @@ if (cacheContext) { | ||
var preload = function (key_, fetcher) { | ||
var key = serialize(key_)[0]; | ||
var _a = __read(SWRGlobalState.get(cache), 4), PRELOAD = _a[3]; | ||
// Prevent preload to be called multiple times before used. | ||
if (PRELOAD[key]) | ||
return PRELOAD[key]; | ||
var req = fetcher(key_); | ||
var key = serialize(key_)[0]; | ||
var _a = SWRGlobalState.get(cache), PRELOAD = _a[3]; | ||
PRELOAD[key] = req; | ||
@@ -628,3 +701,3 @@ return req; | ||
var key = serialize(key_)[0]; | ||
var _a = SWRGlobalState.get(cache), PRELOAD = _a[3]; | ||
var _a = __read(SWRGlobalState.get(cache), 4), PRELOAD = _a[3]; | ||
var req = PRELOAD[key]; | ||
@@ -635,3 +708,3 @@ if (req) { | ||
} | ||
return fetcher_.apply(void 0, args); | ||
return fetcher_.apply(void 0, __spreadArray([], __read(args), false)); | ||
}); | ||
@@ -654,3 +727,3 @@ return useSWRNext(key_, fetcher, config); | ||
// Normalize arguments. | ||
var _a = normalize(args), key = _a[0], fn = _a[1], _config = _a[2]; | ||
var _a = __read(normalize(args), 3), key = _a[0], fn = _a[1], _config = _a[2]; | ||
// Merge configurations. | ||
@@ -761,3 +834,3 @@ var config = mergeConfigs(fallbackConfig, _config); | ||
} | ||
var _a = normalize(args), key = _a[0], fn = _a[1], config = _a[2]; | ||
var _a = __read(normalize(args), 3), key = _a[0], fn = _a[1], config = _a[2]; | ||
var uses = (config.use || []).concat(middleware); | ||
@@ -768,2 +841,2 @@ return useSWR(key, fn, __assign(__assign({}, config), { use: uses })); | ||
export { IS_REACT_LEGACY, IS_SERVER, OBJECT, SWRConfig, SWRGlobalState, UNDEFINED, cache, compare, createCacheHelper, defaultConfig, defaultConfigOptions, getTimestamp, hasRequestAnimationFrame, initCache, internalMutate, isDocumentDefined, isEmptyCache, isFunction, isUndefined, isWindowDefined, mergeConfigs, mergeObjects, mutate, noop, normalize, preload, preset, rAF, constants as revalidateEvents, serialize, slowConnection, stableHash, subscribeCallback, useIsomorphicLayoutEffect, useSWRConfig, useStateWithDeps, withArgs, withMiddleware }; | ||
export { IS_REACT_LEGACY, IS_SERVER, OBJECT, SWRConfig, SWRGlobalState, UNDEFINED, cache, compare, createCacheHelper, defaultConfig, defaultConfigOptions, getTimestamp, hasRequestAnimationFrame, initCache, internalMutate, isDocumentDefined, isFunction, isUndefined, isWindowDefined, mergeConfigs, mergeObjects, mutate, noop, normalize, preload, preset, rAF, constants as revalidateEvents, serialize, slowConnection, stableHash, subscribeCallback, useIsomorphicLayoutEffect, useSWRConfig, useStateWithDeps, withArgs, withMiddleware }; |
@@ -9,2 +9,105 @@ Object.defineProperty(exports, '__esModule', { value: true }); | ||
/****************************************************************************** | ||
Copyright (c) Microsoft Corporation. | ||
Permission to use, copy, modify, and/or distribute this software for any | ||
purpose with or without fee is hereby granted. | ||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH | ||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY | ||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, | ||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM | ||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR | ||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | ||
PERFORMANCE OF THIS SOFTWARE. | ||
***************************************************************************** */ | ||
var __assign = function() { | ||
__assign = Object.assign || function __assign(t) { | ||
for (var s, i = 1, n = arguments.length; i < n; i++) { | ||
s = arguments[i]; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; | ||
} | ||
return t; | ||
}; | ||
return __assign.apply(this, arguments); | ||
}; | ||
function __awaiter(thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
} | ||
function __generator(thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
} | ||
function __values(o) { | ||
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; | ||
if (m) return m.call(o); | ||
if (o && typeof o.length === "number") return { | ||
next: function () { | ||
if (o && i >= o.length) o = void 0; | ||
return { value: o && o[i++], done: !o }; | ||
} | ||
}; | ||
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); | ||
} | ||
function __read(o, n) { | ||
var m = typeof Symbol === "function" && o[Symbol.iterator]; | ||
if (!m) return o; | ||
var i = m.call(o), r, ar = [], e; | ||
try { | ||
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); | ||
} | ||
catch (error) { e = { error: error }; } | ||
finally { | ||
try { | ||
if (r && !r.done && (m = i["return"])) m.call(i); | ||
} | ||
finally { if (e) throw e.error; } | ||
} | ||
return ar; | ||
} | ||
function __spreadArray(to, from, pack) { | ||
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { | ||
if (ar || !(i in from)) { | ||
if (!ar) ar = Array.prototype.slice.call(from, 0, i); | ||
ar[i] = from[i]; | ||
} | ||
} | ||
return to.concat(ar || Array.prototype.slice.call(from)); | ||
} | ||
// Global state used to deduplicate requests and store listeners | ||
@@ -23,3 +126,2 @@ var SWRGlobalState = new WeakMap(); | ||
var isFunction = function (v) { return typeof v == 'function'; }; | ||
var isEmptyCache = function (v) { return v === EMPTY_CACHE; }; | ||
var mergeObjects = function (a, b) { return OBJECT.assign({}, a, b); }; | ||
@@ -122,3 +224,3 @@ var STR_UNDEFINED = 'undefined'; | ||
// For node and React Native, `add/removeEventListener` doesn't exist on window. | ||
var _a$1 = isWindowDefined && window.addEventListener | ||
var _a$1 = __read(isWindowDefined && window.addEventListener | ||
? [ | ||
@@ -128,3 +230,3 @@ window.addEventListener.bind(window), | ||
] | ||
: [noop, noop], onWindowEvent = _a$1[0], offWindowEvent = _a$1[1]; | ||
: [noop, noop], 2), onWindowEvent = _a$1[0], offWindowEvent = _a$1[1]; | ||
var isVisible = function () { | ||
@@ -194,66 +296,2 @@ var visibilityState = isDocumentDefined && document.visibilityState; | ||
/****************************************************************************** | ||
Copyright (c) Microsoft Corporation. | ||
Permission to use, copy, modify, and/or distribute this software for any | ||
purpose with or without fee is hereby granted. | ||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH | ||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY | ||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, | ||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM | ||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR | ||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | ||
PERFORMANCE OF THIS SOFTWARE. | ||
***************************************************************************** */ | ||
var __assign = function() { | ||
__assign = Object.assign || function __assign(t) { | ||
for (var s, i = 1, n = arguments.length; i < n; i++) { | ||
s = arguments[i]; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; | ||
} | ||
return t; | ||
}; | ||
return __assign.apply(this, arguments); | ||
}; | ||
function __awaiter(thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
} | ||
function __generator(thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
} | ||
var serialize = function (key) { | ||
@@ -297,3 +335,3 @@ if (isFunction(key)) { | ||
var internalMutate = function () { | ||
function internalMutate() { | ||
var args = []; | ||
@@ -303,124 +341,158 @@ for (var _i = 0; _i < arguments.length; _i++) { | ||
} | ||
return __awaiter(void 0, void 0, void 0, function () { | ||
var cache, _key, _data, _opts, options, populateCache, optimisticData, revalidate, rollbackOnError, key, _a, get, set, _b, EVENT_REVALIDATORS, MUTATION, FETCH, revalidators, startRevalidate, data, error, beforeMutationTs, hasOptimisticData, state, displayedData, committedData, res; | ||
return __generator(this, function (_d) { | ||
switch (_d.label) { | ||
case 0: | ||
cache = args[0], _key = args[1], _data = args[2], _opts = args[3]; | ||
options = typeof _opts === 'boolean' ? { revalidate: _opts } : _opts || {}; | ||
populateCache = isUndefined(options.populateCache) | ||
? true | ||
: options.populateCache; | ||
optimisticData = options.optimisticData; | ||
revalidate = options.revalidate !== false; | ||
rollbackOnError = options.rollbackOnError !== false; | ||
key = serialize(_key)[0]; | ||
if (!key) | ||
return [2 /*return*/]; | ||
_a = createCacheHelper(cache, key), get = _a[0], set = _a[1]; | ||
_b = SWRGlobalState.get(cache), EVENT_REVALIDATORS = _b[0], MUTATION = _b[1], FETCH = _b[2]; | ||
revalidators = EVENT_REVALIDATORS[key]; | ||
startRevalidate = function () { | ||
if (revalidate) { | ||
// Invalidate the key by deleting the concurrent request markers so new | ||
// requests will not be deduped. | ||
delete FETCH[key]; | ||
if (revalidators && revalidators[0]) { | ||
return revalidators[0](MUTATE_EVENT).then(function () { return get().data; }); | ||
return __awaiter(this, void 0, void 0, function () { | ||
function mutateByKey(_k) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var _a, key, _b, get, set, _d, EVENT_REVALIDATORS, MUTATION, FETCH, revalidators, startRevalidate, data, error, beforeMutationTs, hasOptimisticData, state, displayedData, committedData, res; | ||
return __generator(this, function (_e) { | ||
switch (_e.label) { | ||
case 0: | ||
_a = __read(serialize(_k), 1), key = _a[0]; | ||
if (!key) | ||
return [2 /*return*/]; | ||
_b = __read(createCacheHelper(cache, key), 2), get = _b[0], set = _b[1]; | ||
_d = __read(SWRGlobalState.get(cache), 3), EVENT_REVALIDATORS = _d[0], MUTATION = _d[1], FETCH = _d[2]; | ||
revalidators = EVENT_REVALIDATORS[key]; | ||
startRevalidate = function () { | ||
if (revalidate) { | ||
// Invalidate the key by deleting the concurrent request markers so new | ||
// requests will not be deduped. | ||
delete FETCH[key]; | ||
if (revalidators && revalidators[0]) { | ||
return revalidators[0](MUTATE_EVENT).then(function () { return 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 [2 /*return*/, startRevalidate()]; | ||
} | ||
} | ||
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 [2 /*return*/, startRevalidate()]; | ||
data = _data; | ||
beforeMutationTs = getTimestamp(); | ||
MUTATION[key] = [beforeMutationTs, 0]; | ||
hasOptimisticData = !isUndefined(optimisticData); | ||
state = get(); | ||
displayedData = state.data; | ||
committedData = isUndefined(state._c) ? displayedData : state._c; | ||
// Do optimistic data update. | ||
if (hasOptimisticData) { | ||
optimisticData = isFunction(optimisticData) | ||
? optimisticData(committedData) | ||
: 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; | ||
} | ||
} | ||
if (!(data && isFunction(data.then))) return [3 /*break*/, 2]; | ||
return [4 /*yield*/, data.catch(function (err) { | ||
error = err; | ||
}) | ||
// 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. | ||
]; | ||
case 1: | ||
// This means that the mutation is async, we need to check timestamps to | ||
// avoid race conditions. | ||
data = _e.sent(); | ||
// 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 (error) | ||
throw error; | ||
return [2 /*return*/, data]; | ||
} | ||
else if (error && hasOptimisticData && rollbackOnError) { | ||
// Rollback. Always populate the cache in this case but without | ||
// transforming the data. | ||
populateCache = true; | ||
data = committedData; | ||
// Reset data to be the latest committed data, and clear the `_c` value. | ||
set({ data: data, _c: UNDEFINED }); | ||
} | ||
_e.label = 2; | ||
case 2: | ||
// If we should write back the cache after request. | ||
if (populateCache) { | ||
if (!error) { | ||
// Transform the result into data. | ||
if (isFunction(populateCache)) { | ||
data = populateCache(data, committedData); | ||
} | ||
// Only update cached data if there's no error. Data can be `undefined` here. | ||
set({ data: data, _c: UNDEFINED }); | ||
} | ||
// Always update error and original data here. | ||
set({ error: error }); | ||
} | ||
// Reset the timestamp to mark the mutation has ended. | ||
MUTATION[key][1] = getTimestamp(); | ||
return [4 /*yield*/, startRevalidate() | ||
// The mutation and revalidation are ended, we can clear it since the data is | ||
// not an optimistic value anymore. | ||
]; | ||
case 3: | ||
res = _e.sent(); | ||
// 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 (error) | ||
throw error; | ||
return [2 /*return*/, populateCache ? res : data]; | ||
} | ||
data = _data; | ||
beforeMutationTs = getTimestamp(); | ||
MUTATION[key] = [beforeMutationTs, 0]; | ||
hasOptimisticData = !isUndefined(optimisticData); | ||
state = get(); | ||
displayedData = state.data; | ||
committedData = isUndefined(state._c) ? displayedData : state._c; | ||
// Do optimistic data update. | ||
if (hasOptimisticData) { | ||
optimisticData = isFunction(optimisticData) | ||
? optimisticData(committedData) | ||
: 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); | ||
}); | ||
}); | ||
} | ||
var _a, cache, _key, _data, _opts, options, populateCache, optimisticData, revalidate, rollbackOnError, keyFilter, matchedKeys, _b, _d, key; | ||
var e_1, _e; | ||
return __generator(this, function (_f) { | ||
_a = __read(args, 4), cache = _a[0], _key = _a[1], _data = _a[2], _opts = _a[3]; | ||
options = typeof _opts === 'boolean' ? { revalidate: _opts } : _opts || {}; | ||
populateCache = isUndefined(options.populateCache) | ||
? true | ||
: options.populateCache; | ||
optimisticData = options.optimisticData; | ||
revalidate = options.revalidate !== false; | ||
rollbackOnError = options.rollbackOnError !== false; | ||
// If the second argument is a key filter, return the mutation results for all | ||
// filtered keys. | ||
if (isFunction(_key)) { | ||
keyFilter = _key; | ||
matchedKeys = []; | ||
try { | ||
for (_b = __values(cache.keys()), _d = _b.next(); !_d.done; _d = _b.next()) { | ||
key = _d.value; | ||
if ( | ||
// Skip the speical useSWRInfinite keys. | ||
!key.startsWith('$inf$') && | ||
keyFilter(cache.get(key)._k)) { | ||
matchedKeys.push(key); | ||
} | ||
catch (err) { | ||
// If it throws an error synchronously, we shouldn't update the cache. | ||
error = err; | ||
} | ||
} | ||
if (!(data && isFunction(data.then))) return [3 /*break*/, 2]; | ||
return [4 /*yield*/, data.catch(function (err) { | ||
error = err; | ||
}) | ||
// 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. | ||
]; | ||
case 1: | ||
// This means that the mutation is async, we need to check timestamps to | ||
// avoid race conditions. | ||
data = _d.sent(); | ||
// 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 (error) | ||
throw error; | ||
return [2 /*return*/, data]; | ||
} | ||
catch (e_1_1) { e_1 = { error: e_1_1 }; } | ||
finally { | ||
try { | ||
if (_d && !_d.done && (_e = _b.return)) _e.call(_b); | ||
} | ||
else if (error && hasOptimisticData && rollbackOnError) { | ||
// Rollback. Always populate the cache in this case but without | ||
// transforming the data. | ||
populateCache = true; | ||
data = committedData; | ||
// Reset data to be the latest committed data, and clear the `_c` value. | ||
set({ data: data, _c: UNDEFINED }); | ||
} | ||
_d.label = 2; | ||
case 2: | ||
// If we should write back the cache after request. | ||
if (populateCache) { | ||
if (!error) { | ||
// Transform the result into data. | ||
if (isFunction(populateCache)) { | ||
data = populateCache(data, committedData); | ||
} | ||
// Only update cached data if there's no error. Data can be `undefined` here. | ||
set({ data: data, _c: UNDEFINED }); | ||
} | ||
// Always update error and original data here. | ||
set({ error: error }); | ||
} | ||
// Reset the timestamp to mark the mutation has ended. | ||
MUTATION[key][1] = getTimestamp(); | ||
return [4 /*yield*/, startRevalidate() | ||
// The mutation and revalidation are ended, we can clear it since the data is | ||
// not an optimistic value anymore. | ||
]; | ||
case 3: | ||
res = _d.sent(); | ||
// 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 (error) | ||
throw error; | ||
return [2 /*return*/, populateCache ? res : data]; | ||
finally { if (e_1) throw e_1.error; } | ||
} | ||
return [2 /*return*/, Promise.all(matchedKeys.map(mutateByKey))]; | ||
} | ||
return [2 /*return*/, mutateByKey(_key)]; | ||
}); | ||
}); | ||
}; | ||
} | ||
@@ -451,5 +523,3 @@ var revalidateAllKeys = function (revalidators, type) { | ||
subs.push(callback); | ||
return function () { | ||
subs.splice(subs.indexOf(callback), 1); | ||
}; | ||
return function () { return subs.splice(subs.indexOf(callback), 1); }; | ||
}; | ||
@@ -461,3 +531,3 @@ var setter_1 = function (key, value, prev) { | ||
for (var i = subs.length; i--;) { | ||
subs[i](value, prev); | ||
subs[i](prev, value); | ||
} | ||
@@ -525,3 +595,3 @@ } | ||
// Default cache provider | ||
var _a = initCache(new Map()), cache = _a[0], mutate = _a[1]; | ||
var _a = __read(initCache(new Map()), 2), cache = _a[0], mutate = _a[1]; | ||
// Default config | ||
@@ -585,7 +655,7 @@ var defaultConfig = mergeObjects({ | ||
// Use a lazy initialized state to create the cache on first access. | ||
var cacheContext = React.useState(function () { | ||
var _a = __read(React.useState(function () { | ||
return provider | ||
? initCache(provider(extendedConfig.cache || cache), config) | ||
: UNDEFINED; | ||
})[0]; | ||
}), 1), cacheContext = _a[0]; | ||
// Override the cache if a new provider is given. | ||
@@ -619,5 +689,8 @@ if (cacheContext) { | ||
var preload = function (key_, fetcher) { | ||
var key = serialize(key_)[0]; | ||
var _a = __read(SWRGlobalState.get(cache), 4), PRELOAD = _a[3]; | ||
// Prevent preload to be called multiple times before used. | ||
if (PRELOAD[key]) | ||
return PRELOAD[key]; | ||
var req = fetcher(key_); | ||
var key = serialize(key_)[0]; | ||
var _a = SWRGlobalState.get(cache), PRELOAD = _a[3]; | ||
PRELOAD[key] = req; | ||
@@ -635,3 +708,3 @@ return req; | ||
var key = serialize(key_)[0]; | ||
var _a = SWRGlobalState.get(cache), PRELOAD = _a[3]; | ||
var _a = __read(SWRGlobalState.get(cache), 4), PRELOAD = _a[3]; | ||
var req = PRELOAD[key]; | ||
@@ -642,3 +715,3 @@ if (req) { | ||
} | ||
return fetcher_.apply(void 0, args); | ||
return fetcher_.apply(void 0, __spreadArray([], __read(args), false)); | ||
}); | ||
@@ -661,3 +734,3 @@ return useSWRNext(key_, fetcher, config); | ||
// Normalize arguments. | ||
var _a = normalize(args), key = _a[0], fn = _a[1], _config = _a[2]; | ||
var _a = __read(normalize(args), 3), key = _a[0], fn = _a[1], _config = _a[2]; | ||
// Merge configurations. | ||
@@ -768,3 +841,3 @@ var config = mergeConfigs(fallbackConfig, _config); | ||
} | ||
var _a = normalize(args), key = _a[0], fn = _a[1], config = _a[2]; | ||
var _a = __read(normalize(args), 3), key = _a[0], fn = _a[1], config = _a[2]; | ||
var uses = (config.use || []).concat(middleware); | ||
@@ -791,3 +864,2 @@ return useSWR(key, fn, __assign(__assign({}, config), { use: uses })); | ||
exports.isDocumentDefined = isDocumentDefined; | ||
exports.isEmptyCache = isEmptyCache; | ||
exports.isFunction = isFunction; | ||
@@ -794,0 +866,0 @@ exports.isUndefined = isUndefined; |
/// <reference types="react" /> | ||
import { defaultConfig, Fetcher, Key, SWRResponse, FullConfiguration, SWRConfiguration, SWRHook } from 'swr/_internal'; | ||
import { defaultConfig } from 'swr/_internal'; | ||
import type { Fetcher, Key, SWRResponse, FullConfiguration, SWRConfiguration, SWRHook } from 'swr/_internal'; | ||
export declare const useSWRHandler: <Data = any, Error_1 = any>(_key: Key, fetcher: ((args: string) => import("_internal/types").FetcherResponse<Data>) | ((args: [any, ...unknown[]]) => import("_internal/types").FetcherResponse<Data>) | ((args: readonly [any, ...unknown[]]) => import("_internal/types").FetcherResponse<Data>) | ((args: Record<any, any>) => import("_internal/types").FetcherResponse<Data>) | ((args: string | [any, ...unknown[]] | readonly [any, ...unknown[]] | Record<any, any>) => import("_internal/types").FetcherResponse<Data>) | null, config: import("_internal/types").InternalConfiguration<import("_internal/types").Cache<any>> & import("_internal/types").PublicConfiguration<any, any, import("_internal/types").BareFetcher<unknown>> & Partial<import("_internal/types").PublicConfiguration<Data, Error_1, import("_internal/types").BareFetcher<any>>>) => SWRResponse<Data, Error_1>; | ||
@@ -4,0 +5,0 @@ export declare const SWRConfig: import("react").FC<import("react").PropsWithChildren<{ |
@@ -1,4 +0,4 @@ | ||
import { useRef, useCallback, useDebugValue } from 'react'; | ||
import { useSyncExternalStoreWithSelector } from 'use-sync-external-store/shim/with-selector.js'; | ||
import { OBJECT, SWRConfig as SWRConfig$1, defaultConfig, withArgs, SWRGlobalState, serialize, createCacheHelper, isUndefined, internalMutate, UNDEFINED, useIsomorphicLayoutEffect, subscribeCallback, IS_SERVER, rAF, IS_REACT_LEGACY, isEmptyCache, revalidateEvents, isFunction, getTimestamp } from 'swr/_internal'; | ||
import { useRef, useMemo, useCallback, useDebugValue } from 'react'; | ||
import { useSyncExternalStore } from 'use-sync-external-store/shim/index.js'; | ||
import { OBJECT, SWRConfig as SWRConfig$1, defaultConfig, withArgs, SWRGlobalState, serialize, createCacheHelper, isUndefined, internalMutate, useIsomorphicLayoutEffect, UNDEFINED, subscribeCallback, IS_SERVER, rAF, IS_REACT_LEGACY, mergeObjects, revalidateEvents, isFunction, getTimestamp } from 'swr/_internal'; | ||
export { mutate, preload, useSWRConfig } from 'swr/_internal'; | ||
@@ -59,6 +59,33 @@ | ||
function __read(o, n) { | ||
var m = typeof Symbol === "function" && o[Symbol.iterator]; | ||
if (!m) return o; | ||
var i = m.call(o), r, ar = [], e; | ||
try { | ||
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); | ||
} | ||
catch (error) { e = { error: error }; } | ||
finally { | ||
try { | ||
if (r && !r.done && (m = i["return"])) m.call(i); | ||
} | ||
finally { if (e) throw e.error; } | ||
} | ||
return ar; | ||
} | ||
function __spreadArray(to, from, pack) { | ||
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { | ||
if (ar || !(i in from)) { | ||
if (!ar) ar = Array.prototype.slice.call(from, 0, i); | ||
ar[i] = from[i]; | ||
} | ||
} | ||
return to.concat(ar || Array.prototype.slice.call(from)); | ||
} | ||
var WITH_DEDUPE = { dedupe: true }; | ||
var useSWRHandler = function (_key, fetcher, config) { | ||
var cache = config.cache, compare = config.compare, suspense = config.suspense, fallbackData = config.fallbackData, revalidateOnMount = config.revalidateOnMount, refreshInterval = config.refreshInterval, refreshWhenHidden = config.refreshWhenHidden, refreshWhenOffline = config.refreshWhenOffline, keepPreviousData = config.keepPreviousData; | ||
var _a = SWRGlobalState.get(cache), EVENT_REVALIDATORS = _a[0], MUTATION = _a[1], FETCH = _a[2]; | ||
var _a = __read(SWRGlobalState.get(cache), 3), EVENT_REVALIDATORS = _a[0], MUTATION = _a[1], FETCH = _a[2]; | ||
// `key` is the identifier of the SWR `data` state, `keyInfo` holds extra | ||
@@ -69,3 +96,3 @@ // states such as `error` and `isValidating` inside, | ||
// to the fetcher. | ||
var _b = serialize(_key), key = _b[0], fnArg = _b[1]; | ||
var _b = __read(serialize(_key), 2), key = _b[0], fnArg = _b[1]; | ||
// If it's the initial render of this hook. | ||
@@ -82,10 +109,26 @@ var initialMountedRef = useRef(false); | ||
var isActive = function () { return getConfig().isVisible() && getConfig().isOnline(); }; | ||
var _c = createCacheHelper(cache, key), getCache = _c[0], setCache = _c[1], subscribeCache = _c[2]; | ||
var _c = __read(createCacheHelper(cache, key), 3), getCache = _c[0], setCache = _c[1], subscribeCache = _c[2]; | ||
var stateDependencies = useRef({}).current; | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
var getSnapshot = useCallback(getCache, [cache, key]); | ||
var fallback = isUndefined(fallbackData) | ||
? config.fallback[key] | ||
: fallbackData; | ||
var selector = function (snapshot) { | ||
var isEqual = function (prev, current) { | ||
var equal = true; | ||
for (var _ in stateDependencies) { | ||
var t = _; | ||
if (!compare(current[t], prev[t])) { | ||
if (t === 'data' && isUndefined(prev[t])) { | ||
if (!compare(current[t], fallback)) { | ||
equal = false; | ||
} | ||
} | ||
else { | ||
equal = false; | ||
} | ||
} | ||
} | ||
return equal; | ||
}; | ||
var getSnapshot = useMemo(function () { | ||
var shouldStartRequest = (function () { | ||
@@ -106,39 +149,33 @@ if (!key) | ||
})(); | ||
if (!shouldStartRequest) | ||
return snapshot; | ||
if (isEmptyCache(snapshot)) { | ||
return { | ||
var getSelectedCache = function () { | ||
var state = getCache(); | ||
// We only select the needed fields from the state. | ||
var snapshot = mergeObjects(state); | ||
delete snapshot._k; | ||
if (!shouldStartRequest) { | ||
return snapshot; | ||
} | ||
return Object.assign({ | ||
isValidating: true, | ||
isLoading: true | ||
}; | ||
} | ||
return snapshot; | ||
}; | ||
var isEqual = useCallback(function (prev, current) { | ||
var equal = true; | ||
for (var _ in stateDependencies) { | ||
var t = _; | ||
if (!compare(current[t], prev[t])) { | ||
if (t === 'data' && isUndefined(prev[t])) { | ||
if (!compare(current[t], fallback)) { | ||
equal = false; | ||
} | ||
} | ||
else { | ||
equal = false; | ||
} | ||
} | ||
} | ||
return equal; | ||
}, | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
[cache, key]); | ||
}, snapshot); | ||
}; | ||
var memorizedSnapshot = getSelectedCache(); | ||
return function () { | ||
var snapshot = getSelectedCache(); | ||
return isEqual(snapshot, memorizedSnapshot) | ||
? memorizedSnapshot | ||
: (memorizedSnapshot = snapshot); | ||
}; | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
}, [cache, key]); | ||
// Get the current state that SWR should return. | ||
var cached = useSyncExternalStoreWithSelector(useCallback(function (callback) { | ||
return subscribeCache(key, function () { | ||
callback(); | ||
var cached = useSyncExternalStore(useCallback(function (callback) { | ||
return subscribeCache(key, function (prev, current) { | ||
if (!isEqual(prev, current)) | ||
callback(); | ||
}); | ||
}, | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
[cache, key]), getSnapshot, getSnapshot, selector, isEqual); | ||
[cache, key]), getSnapshot, getSnapshot); | ||
var isInitialMount = !initialMountedRef.current; | ||
@@ -180,4 +217,8 @@ var cachedData = cached.data; | ||
shouldDoInitialRevalidation); | ||
var isValidating = cached.isValidating || defaultValidatingState; | ||
var isLoading = cached.isLoading || defaultValidatingState; | ||
var isValidating = isUndefined(cached.isValidating) | ||
? defaultValidatingState | ||
: cached.isValidating; | ||
var isLoading = isUndefined(cached.isLoading) | ||
? defaultValidatingState | ||
: cached.isLoading; | ||
// The revalidation function is a carefully crafted wrapper of the original | ||
@@ -250,3 +291,3 @@ // `fetcher`, to correctly handle the many edge cases. | ||
} | ||
_a = FETCH[key], newData = _a[0], startAt = _a[1]; | ||
_a = __read(FETCH[key], 2), newData = _a[0], startAt = _a[1]; | ||
return [4 /*yield*/, newData]; | ||
@@ -357,6 +398,10 @@ case 2: | ||
var boundMutate = useCallback( | ||
// By using `bind` we don't need to modify the size of the rest arguments. | ||
// Due to https://github.com/microsoft/TypeScript/issues/37181, we have to | ||
// cast it to any for now. | ||
internalMutate.bind(UNDEFINED, cache, function () { return keyRef.current; }), | ||
// Use callback to make sure `keyRef.current` returns latest result every time | ||
function () { | ||
var args = []; | ||
for (var _i = 0; _i < arguments.length; _i++) { | ||
args[_i] = arguments[_i]; | ||
} | ||
return internalMutate.apply(void 0, __spreadArray([cache, keyRef.current], __read(args), false)); | ||
}, | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
@@ -407,2 +452,4 @@ []); | ||
initialMountedRef.current = true; | ||
// Keep the original key in the cache. | ||
setCache({ _k: fnArg }); | ||
// Trigger a revalidation. | ||
@@ -409,0 +456,0 @@ if (shouldDoInitialRevalidation) { |
Object.defineProperty(exports, '__esModule', { value: true }); | ||
var react = require('react'); | ||
var withSelector_js = require('use-sync-external-store/shim/with-selector.js'); | ||
var index_js = require('use-sync-external-store/shim/index.js'); | ||
var _internal = require('swr/_internal'); | ||
@@ -60,6 +60,33 @@ | ||
function __read(o, n) { | ||
var m = typeof Symbol === "function" && o[Symbol.iterator]; | ||
if (!m) return o; | ||
var i = m.call(o), r, ar = [], e; | ||
try { | ||
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); | ||
} | ||
catch (error) { e = { error: error }; } | ||
finally { | ||
try { | ||
if (r && !r.done && (m = i["return"])) m.call(i); | ||
} | ||
finally { if (e) throw e.error; } | ||
} | ||
return ar; | ||
} | ||
function __spreadArray(to, from, pack) { | ||
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { | ||
if (ar || !(i in from)) { | ||
if (!ar) ar = Array.prototype.slice.call(from, 0, i); | ||
ar[i] = from[i]; | ||
} | ||
} | ||
return to.concat(ar || Array.prototype.slice.call(from)); | ||
} | ||
var WITH_DEDUPE = { dedupe: true }; | ||
var useSWRHandler = function (_key, fetcher, config) { | ||
var cache = config.cache, compare = config.compare, suspense = config.suspense, fallbackData = config.fallbackData, revalidateOnMount = config.revalidateOnMount, refreshInterval = config.refreshInterval, refreshWhenHidden = config.refreshWhenHidden, refreshWhenOffline = config.refreshWhenOffline, keepPreviousData = config.keepPreviousData; | ||
var _a = _internal.SWRGlobalState.get(cache), EVENT_REVALIDATORS = _a[0], MUTATION = _a[1], FETCH = _a[2]; | ||
var _a = __read(_internal.SWRGlobalState.get(cache), 3), EVENT_REVALIDATORS = _a[0], MUTATION = _a[1], FETCH = _a[2]; | ||
// `key` is the identifier of the SWR `data` state, `keyInfo` holds extra | ||
@@ -70,3 +97,3 @@ // states such as `error` and `isValidating` inside, | ||
// to the fetcher. | ||
var _b = _internal.serialize(_key), key = _b[0], fnArg = _b[1]; | ||
var _b = __read(_internal.serialize(_key), 2), key = _b[0], fnArg = _b[1]; | ||
// If it's the initial render of this hook. | ||
@@ -83,10 +110,26 @@ var initialMountedRef = react.useRef(false); | ||
var isActive = function () { return getConfig().isVisible() && getConfig().isOnline(); }; | ||
var _c = _internal.createCacheHelper(cache, key), getCache = _c[0], setCache = _c[1], subscribeCache = _c[2]; | ||
var _c = __read(_internal.createCacheHelper(cache, key), 3), getCache = _c[0], setCache = _c[1], subscribeCache = _c[2]; | ||
var stateDependencies = react.useRef({}).current; | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
var getSnapshot = react.useCallback(getCache, [cache, key]); | ||
var fallback = _internal.isUndefined(fallbackData) | ||
? config.fallback[key] | ||
: fallbackData; | ||
var selector = function (snapshot) { | ||
var isEqual = function (prev, current) { | ||
var equal = true; | ||
for (var _ in stateDependencies) { | ||
var t = _; | ||
if (!compare(current[t], prev[t])) { | ||
if (t === 'data' && _internal.isUndefined(prev[t])) { | ||
if (!compare(current[t], fallback)) { | ||
equal = false; | ||
} | ||
} | ||
else { | ||
equal = false; | ||
} | ||
} | ||
} | ||
return equal; | ||
}; | ||
var getSnapshot = react.useMemo(function () { | ||
var shouldStartRequest = (function () { | ||
@@ -107,39 +150,33 @@ if (!key) | ||
})(); | ||
if (!shouldStartRequest) | ||
return snapshot; | ||
if (_internal.isEmptyCache(snapshot)) { | ||
return { | ||
var getSelectedCache = function () { | ||
var state = getCache(); | ||
// We only select the needed fields from the state. | ||
var snapshot = _internal.mergeObjects(state); | ||
delete snapshot._k; | ||
if (!shouldStartRequest) { | ||
return snapshot; | ||
} | ||
return Object.assign({ | ||
isValidating: true, | ||
isLoading: true | ||
}; | ||
} | ||
return snapshot; | ||
}; | ||
var isEqual = react.useCallback(function (prev, current) { | ||
var equal = true; | ||
for (var _ in stateDependencies) { | ||
var t = _; | ||
if (!compare(current[t], prev[t])) { | ||
if (t === 'data' && _internal.isUndefined(prev[t])) { | ||
if (!compare(current[t], fallback)) { | ||
equal = false; | ||
} | ||
} | ||
else { | ||
equal = false; | ||
} | ||
} | ||
} | ||
return equal; | ||
}, | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
[cache, key]); | ||
}, snapshot); | ||
}; | ||
var memorizedSnapshot = getSelectedCache(); | ||
return function () { | ||
var snapshot = getSelectedCache(); | ||
return isEqual(snapshot, memorizedSnapshot) | ||
? memorizedSnapshot | ||
: (memorizedSnapshot = snapshot); | ||
}; | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
}, [cache, key]); | ||
// Get the current state that SWR should return. | ||
var cached = withSelector_js.useSyncExternalStoreWithSelector(react.useCallback(function (callback) { | ||
return subscribeCache(key, function () { | ||
callback(); | ||
var cached = index_js.useSyncExternalStore(react.useCallback(function (callback) { | ||
return subscribeCache(key, function (prev, current) { | ||
if (!isEqual(prev, current)) | ||
callback(); | ||
}); | ||
}, | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
[cache, key]), getSnapshot, getSnapshot, selector, isEqual); | ||
[cache, key]), getSnapshot, getSnapshot); | ||
var isInitialMount = !initialMountedRef.current; | ||
@@ -181,4 +218,8 @@ var cachedData = cached.data; | ||
shouldDoInitialRevalidation); | ||
var isValidating = cached.isValidating || defaultValidatingState; | ||
var isLoading = cached.isLoading || defaultValidatingState; | ||
var isValidating = _internal.isUndefined(cached.isValidating) | ||
? defaultValidatingState | ||
: cached.isValidating; | ||
var isLoading = _internal.isUndefined(cached.isLoading) | ||
? defaultValidatingState | ||
: cached.isLoading; | ||
// The revalidation function is a carefully crafted wrapper of the original | ||
@@ -251,3 +292,3 @@ // `fetcher`, to correctly handle the many edge cases. | ||
} | ||
_a = FETCH[key], newData = _a[0], startAt = _a[1]; | ||
_a = __read(FETCH[key], 2), newData = _a[0], startAt = _a[1]; | ||
return [4 /*yield*/, newData]; | ||
@@ -358,6 +399,10 @@ case 2: | ||
var boundMutate = react.useCallback( | ||
// By using `bind` we don't need to modify the size of the rest arguments. | ||
// Due to https://github.com/microsoft/TypeScript/issues/37181, we have to | ||
// cast it to any for now. | ||
_internal.internalMutate.bind(_internal.UNDEFINED, cache, function () { return keyRef.current; }), | ||
// Use callback to make sure `keyRef.current` returns latest result every time | ||
function () { | ||
var args = []; | ||
for (var _i = 0; _i < arguments.length; _i++) { | ||
args[_i] = arguments[_i]; | ||
} | ||
return _internal.internalMutate.apply(void 0, __spreadArray([cache, keyRef.current], __read(args), false)); | ||
}, | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
@@ -408,2 +453,4 @@ []); | ||
initialMountedRef.current = true; | ||
// Keep the original key in the cache. | ||
setCache({ _k: fnArg }); | ||
// Trigger a revalidation. | ||
@@ -410,0 +457,0 @@ if (shouldDoInitialRevalidation) { |
@@ -1,4 +0,4 @@ | ||
import { Middleware } from 'swr'; | ||
import type { Middleware } from 'swr'; | ||
export declare const immutable: Middleware; | ||
declare const _default: import("swr").SWRHook; | ||
export default _default; |
import { useRef, useCallback } from 'react'; | ||
import useSWR from 'swr'; | ||
import { withMiddleware, serialize, createCacheHelper, isUndefined, useIsomorphicLayoutEffect, isFunction, UNDEFINED, mergeObjects } from 'swr/_internal'; | ||
import { withMiddleware, serialize, createCacheHelper, isUndefined, useIsomorphicLayoutEffect, isFunction, UNDEFINED } from 'swr/_internal'; | ||
import { useSyncExternalStore } from 'use-sync-external-store/shim/index.js'; | ||
@@ -59,2 +59,19 @@ | ||
function __read(o, n) { | ||
var m = typeof Symbol === "function" && o[Symbol.iterator]; | ||
if (!m) return o; | ||
var i = m.call(o), r, ar = [], e; | ||
try { | ||
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); | ||
} | ||
catch (error) { e = { error: error }; } | ||
finally { | ||
try { | ||
if (r && !r.done && (m = i["return"])) m.call(i); | ||
} | ||
finally { if (e) throw e.error; } | ||
} | ||
return ar; | ||
} | ||
// We have to several type castings here because `useSWRInfinite` is a special | ||
@@ -85,5 +102,5 @@ var INFINITE_PREFIX = '$inf$'; | ||
} | ||
var _f = createCacheHelper(cache, infiniteKey), get = _f[0], set = _f[1], subscribeCache = _f[2]; | ||
var _f = __read(createCacheHelper(cache, infiniteKey), 3), get = _f[0], set = _f[1], subscribeCache = _f[2]; | ||
var getSnapshot = useCallback(function () { | ||
var size = isUndefined(get().$len) ? initialSize : get().$len; | ||
var size = isUndefined(get()._l) ? initialSize : get()._l; | ||
return size; | ||
@@ -102,3 +119,3 @@ // eslint-disable-next-line react-hooks/exhaustive-deps | ||
var resolvePageSize = useCallback(function () { | ||
var cachedPageSize = get().$len; | ||
var cachedPageSize = get()._l; | ||
return isUndefined(cachedPageSize) ? initialSize : cachedPageSize; | ||
@@ -118,3 +135,3 @@ // `cache` isn't allowed to change during the lifecycle | ||
// If the key has been changed, we keep the current page size if persistSize is enabled | ||
set({ $len: persistSize ? lastPageSizeRef.current : initialSize }); | ||
set({ _l: persistSize ? lastPageSizeRef.current : initialSize }); | ||
} | ||
@@ -132,3 +149,3 @@ // `initialSize` isn't allowed to change during the lifecycle | ||
case 0: | ||
_a = get().$ctx || [], forceRevalidateAll = _a[0], originalData = _a[1]; | ||
_a = __read(get()._i || [], 2), forceRevalidateAll = _a[0], originalData = _a[1]; | ||
data = []; | ||
@@ -141,3 +158,3 @@ pageSize = resolvePageSize(); | ||
if (!(i < pageSize)) return [3 /*break*/, 5]; | ||
_b = serialize(getKey(i, previousPageData)), pageKey = _b[0], pageArg = _b[1]; | ||
_b = __read(serialize(getKey(i, previousPageData)), 2), pageKey = _b[0], pageArg = _b[1]; | ||
if (!pageKey) { | ||
@@ -147,3 +164,3 @@ // `pageKey` is falsy, stop fetching new pages. | ||
} | ||
_c = createCacheHelper(cache, pageKey), getSWRCache = _c[0], setSWRCache = _c[1]; | ||
_c = __read(createCacheHelper(cache, pageKey), 2), getSWRCache = _c[0], setSWRCache = _c[1]; | ||
pageData = getSWRCache().data; | ||
@@ -162,3 +179,3 @@ shouldFetchPage = revalidateAll || | ||
pageData = _d.sent(); | ||
setSWRCache(mergeObjects(getSWRCache(), { data: pageData })); | ||
setSWRCache({ data: pageData, _k: pageArg }); | ||
_d.label = 3; | ||
@@ -174,3 +191,3 @@ case 3: | ||
// once we executed the data fetching based on the context, clear the context | ||
set({ $ctx: UNDEFINED }); | ||
set({ _i: UNDEFINED }); | ||
// return the data | ||
@@ -200,7 +217,7 @@ return [2 /*return*/, data]; | ||
var originalData = dataRef.current; | ||
set({ $ctx: [false, originalData] }); | ||
set({ _i: [false, originalData] }); | ||
} | ||
else { | ||
// Calling `mutate()`, we revalidate all pages | ||
set({ $ctx: [true] }); | ||
set({ _i: [true] }); | ||
} | ||
@@ -222,3 +239,3 @@ } | ||
for (var i = 0; i < pageSize; ++i) { | ||
var pageKey = serialize(getKey(i, previousPageData))[0]; | ||
var _b = __read(serialize(getKey(i, previousPageData)), 1), pageKey = _b[0]; | ||
// Get the cached page data. | ||
@@ -249,3 +266,3 @@ var pageData = pageKey ? (_a = cache.get(pageKey)) === null || _a === void 0 ? void 0 : _a.data : UNDEFINED; | ||
return EMPTY_PROMISE; | ||
set({ $len: size }); | ||
set({ _l: size }); | ||
lastPageSizeRef.current = size; | ||
@@ -252,0 +269,0 @@ return mutate(resolvePagesFromCache(size)); |
@@ -65,2 +65,19 @@ Object.defineProperty(exports, '__esModule', { value: true }); | ||
function __read(o, n) { | ||
var m = typeof Symbol === "function" && o[Symbol.iterator]; | ||
if (!m) return o; | ||
var i = m.call(o), r, ar = [], e; | ||
try { | ||
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); | ||
} | ||
catch (error) { e = { error: error }; } | ||
finally { | ||
try { | ||
if (r && !r.done && (m = i["return"])) m.call(i); | ||
} | ||
finally { if (e) throw e.error; } | ||
} | ||
return ar; | ||
} | ||
// We have to several type castings here because `useSWRInfinite` is a special | ||
@@ -91,5 +108,5 @@ var INFINITE_PREFIX = '$inf$'; | ||
} | ||
var _f = _internal.createCacheHelper(cache, infiniteKey), get = _f[0], set = _f[1], subscribeCache = _f[2]; | ||
var _f = __read(_internal.createCacheHelper(cache, infiniteKey), 3), get = _f[0], set = _f[1], subscribeCache = _f[2]; | ||
var getSnapshot = react.useCallback(function () { | ||
var size = _internal.isUndefined(get().$len) ? initialSize : get().$len; | ||
var size = _internal.isUndefined(get()._l) ? initialSize : get()._l; | ||
return size; | ||
@@ -108,3 +125,3 @@ // eslint-disable-next-line react-hooks/exhaustive-deps | ||
var resolvePageSize = react.useCallback(function () { | ||
var cachedPageSize = get().$len; | ||
var cachedPageSize = get()._l; | ||
return _internal.isUndefined(cachedPageSize) ? initialSize : cachedPageSize; | ||
@@ -124,3 +141,3 @@ // `cache` isn't allowed to change during the lifecycle | ||
// If the key has been changed, we keep the current page size if persistSize is enabled | ||
set({ $len: persistSize ? lastPageSizeRef.current : initialSize }); | ||
set({ _l: persistSize ? lastPageSizeRef.current : initialSize }); | ||
} | ||
@@ -138,3 +155,3 @@ // `initialSize` isn't allowed to change during the lifecycle | ||
case 0: | ||
_a = get().$ctx || [], forceRevalidateAll = _a[0], originalData = _a[1]; | ||
_a = __read(get()._i || [], 2), forceRevalidateAll = _a[0], originalData = _a[1]; | ||
data = []; | ||
@@ -147,3 +164,3 @@ pageSize = resolvePageSize(); | ||
if (!(i < pageSize)) return [3 /*break*/, 5]; | ||
_b = _internal.serialize(getKey(i, previousPageData)), pageKey = _b[0], pageArg = _b[1]; | ||
_b = __read(_internal.serialize(getKey(i, previousPageData)), 2), pageKey = _b[0], pageArg = _b[1]; | ||
if (!pageKey) { | ||
@@ -153,3 +170,3 @@ // `pageKey` is falsy, stop fetching new pages. | ||
} | ||
_c = _internal.createCacheHelper(cache, pageKey), getSWRCache = _c[0], setSWRCache = _c[1]; | ||
_c = __read(_internal.createCacheHelper(cache, pageKey), 2), getSWRCache = _c[0], setSWRCache = _c[1]; | ||
pageData = getSWRCache().data; | ||
@@ -168,3 +185,3 @@ shouldFetchPage = revalidateAll || | ||
pageData = _d.sent(); | ||
setSWRCache(_internal.mergeObjects(getSWRCache(), { data: pageData })); | ||
setSWRCache({ data: pageData, _k: pageArg }); | ||
_d.label = 3; | ||
@@ -180,3 +197,3 @@ case 3: | ||
// once we executed the data fetching based on the context, clear the context | ||
set({ $ctx: _internal.UNDEFINED }); | ||
set({ _i: _internal.UNDEFINED }); | ||
// return the data | ||
@@ -206,7 +223,7 @@ return [2 /*return*/, data]; | ||
var originalData = dataRef.current; | ||
set({ $ctx: [false, originalData] }); | ||
set({ _i: [false, originalData] }); | ||
} | ||
else { | ||
// Calling `mutate()`, we revalidate all pages | ||
set({ $ctx: [true] }); | ||
set({ _i: [true] }); | ||
} | ||
@@ -228,3 +245,3 @@ } | ||
for (var i = 0; i < pageSize; ++i) { | ||
var pageKey = _internal.serialize(getKey(i, previousPageData))[0]; | ||
var _b = __read(_internal.serialize(getKey(i, previousPageData)), 1), pageKey = _b[0]; | ||
// Get the cached page data. | ||
@@ -255,3 +272,3 @@ var pageData = pageKey ? (_a = cache.get(pageKey)) === null || _a === void 0 ? void 0 : _a.data : _internal.UNDEFINED; | ||
return EMPTY_PROMISE; | ||
set({ $len: size }); | ||
set({ _l: size }); | ||
lastPageSizeRef.current = size; | ||
@@ -258,0 +275,0 @@ return mutate(resolvePagesFromCache(size)); |
@@ -1,2 +0,2 @@ | ||
import { Middleware } from 'swr/_internal'; | ||
import type { Middleware } from 'swr/_internal'; | ||
import type { SWRInfiniteConfiguration, SWRInfiniteResponse, SWRInfiniteHook, SWRInfiniteKeyLoader, SWRInfiniteFetcher } from './types'; | ||
@@ -3,0 +3,0 @@ export declare const unstable_serialize: (getKey: SWRInfiniteKeyLoader) => string; |
@@ -27,5 +27,6 @@ import { SWRConfiguration, SWRResponse, Arguments, BareFetcher, State } from 'swr/_internal'; | ||
export interface SWRInfiniteCacheValue<Data = any, Error = any> extends State<Data, Error> { | ||
$ctx?: [boolean] | [boolean, Data[] | undefined]; | ||
$len?: number; | ||
_i?: [boolean] | [boolean, Data[] | undefined]; | ||
_l?: number; | ||
_k?: Arguments; | ||
} | ||
export {}; |
@@ -58,2 +58,19 @@ import { useRef, useCallback } from 'react'; | ||
function __read(o, n) { | ||
var m = typeof Symbol === "function" && o[Symbol.iterator]; | ||
if (!m) return o; | ||
var i = m.call(o), r, ar = [], e; | ||
try { | ||
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); | ||
} | ||
catch (error) { e = { error: error }; } | ||
finally { | ||
try { | ||
if (r && !r.done && (m = i["return"])) m.call(i); | ||
} | ||
finally { if (e) throw e.error; } | ||
} | ||
return ar; | ||
} | ||
var mutation = (function () { | ||
@@ -66,7 +83,7 @@ return function (key, fetcher, config) { | ||
var ditchMutationsUntilRef = useRef(0); | ||
var _a = useStateWithDeps({ | ||
var _a = __read(useStateWithDeps({ | ||
data: UNDEFINED, | ||
error: UNDEFINED, | ||
isMutating: false | ||
}), stateRef = _a[0], stateDependencies = _a[1], setState = _a[2]; | ||
}), 3), stateRef = _a[0], stateDependencies = _a[1], setState = _a[2]; | ||
var currentState = stateRef.current; | ||
@@ -79,3 +96,3 @@ var trigger = useCallback(function (arg, opts) { return __awaiter(void 0, void 0, void 0, function () { | ||
case 0: | ||
_a = serialize(keyRef.current), serializedKey = _a[0], resolvedKey = _a[1]; | ||
_a = __read(serialize(keyRef.current), 2), serializedKey = _a[0], resolvedKey = _a[1]; | ||
if (!fetcher) { | ||
@@ -82,0 +99,0 @@ throw new Error('Can’t trigger the mutation: missing fetcher.'); |
@@ -64,2 +64,19 @@ Object.defineProperty(exports, '__esModule', { value: true }); | ||
function __read(o, n) { | ||
var m = typeof Symbol === "function" && o[Symbol.iterator]; | ||
if (!m) return o; | ||
var i = m.call(o), r, ar = [], e; | ||
try { | ||
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); | ||
} | ||
catch (error) { e = { error: error }; } | ||
finally { | ||
try { | ||
if (r && !r.done && (m = i["return"])) m.call(i); | ||
} | ||
finally { if (e) throw e.error; } | ||
} | ||
return ar; | ||
} | ||
var mutation = (function () { | ||
@@ -72,7 +89,7 @@ return function (key, fetcher, config) { | ||
var ditchMutationsUntilRef = react.useRef(0); | ||
var _a = _internal.useStateWithDeps({ | ||
var _a = __read(_internal.useStateWithDeps({ | ||
data: _internal.UNDEFINED, | ||
error: _internal.UNDEFINED, | ||
isMutating: false | ||
}), stateRef = _a[0], stateDependencies = _a[1], setState = _a[2]; | ||
}), 3), stateRef = _a[0], stateDependencies = _a[1], setState = _a[2]; | ||
var currentState = stateRef.current; | ||
@@ -85,3 +102,3 @@ var trigger = react.useCallback(function (arg, opts) { return __awaiter(void 0, void 0, void 0, function () { | ||
case 0: | ||
_a = _internal.serialize(keyRef.current), serializedKey = _a[0], resolvedKey = _a[1]; | ||
_a = __read(_internal.serialize(keyRef.current), 2), serializedKey = _a[0], resolvedKey = _a[1]; | ||
if (!fetcher) { | ||
@@ -88,0 +105,0 @@ throw new Error('Can’t trigger the mutation: missing fetcher.'); |
@@ -1,4 +0,4 @@ | ||
import { SWRMutationConfiguration, SWRMutationResponse, SWRMutationHook } from './types'; | ||
import type { SWRMutationConfiguration, SWRMutationResponse, SWRMutationHook } from './types'; | ||
declare const _default: SWRMutationHook; | ||
export default _default; | ||
export { SWRMutationConfiguration, SWRMutationResponse, SWRMutationHook }; |
{ | ||
"name": "swr", | ||
"version": "2.0.0-beta.4", | ||
"version": "2.0.0-beta.5", | ||
"description": "React Hooks library for remote data fetching", | ||
@@ -89,3 +89,4 @@ "keywords": [ | ||
"coverage": "jest --coverage", | ||
"test": "tsc --noEmit -p test && jest" | ||
"test-typing": "tsc --noEmit -p test/type/tsconfig.json && tsc --noEmit -p test/tsconfig.json", | ||
"test": "jest" | ||
}, | ||
@@ -92,0 +93,0 @@ "husky": { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
460432
5746