index.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395
  1. Object.defineProperty(exports, '__esModule', { value: true });
  2. var react = require('react');
  3. var useSWR = require('swr');
  4. function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
  5. var useSWR__default = /*#__PURE__*/_interopDefaultLegacy(useSWR);
  6. /*! *****************************************************************************
  7. Copyright (c) Microsoft Corporation.
  8. Permission to use, copy, modify, and/or distribute this software for any
  9. purpose with or without fee is hereby granted.
  10. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
  11. REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  12. AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
  13. INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  14. LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  15. OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  16. PERFORMANCE OF THIS SOFTWARE.
  17. ***************************************************************************** */
  18. var __assign = function() {
  19. __assign = Object.assign || function __assign(t) {
  20. for (var s, i = 1, n = arguments.length; i < n; i++) {
  21. s = arguments[i];
  22. for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
  23. }
  24. return t;
  25. };
  26. return __assign.apply(this, arguments);
  27. };
  28. function __awaiter(thisArg, _arguments, P, generator) {
  29. function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
  30. return new (P || (P = Promise))(function (resolve, reject) {
  31. function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
  32. function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
  33. function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
  34. step((generator = generator.apply(thisArg, _arguments || [])).next());
  35. });
  36. }
  37. function __generator(thisArg, body) {
  38. var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
  39. return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
  40. function verb(n) { return function (v) { return step([n, v]); }; }
  41. function step(op) {
  42. if (f) throw new TypeError("Generator is already executing.");
  43. while (_) try {
  44. 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;
  45. if (y = 0, t) op = [op[0] & 2, t.value];
  46. switch (op[0]) {
  47. case 0: case 1: t = op; break;
  48. case 4: _.label++; return { value: op[1], done: false };
  49. case 5: _.label++; y = op[1]; op = [0]; continue;
  50. case 7: op = _.ops.pop(); _.trys.pop(); continue;
  51. default:
  52. if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
  53. if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
  54. if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
  55. if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
  56. if (t[2]) _.ops.pop();
  57. _.trys.pop(); continue;
  58. }
  59. op = body.call(thisArg, _);
  60. } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
  61. if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
  62. }
  63. }
  64. var noop = function () { };
  65. // Using noop() as the undefined value as undefined can possibly be replaced
  66. // by something else. Prettier ignore and extra parentheses are necessary here
  67. // to ensure that tsc doesn't remove the __NOINLINE__ comment.
  68. // prettier-ignore
  69. var UNDEFINED = ( /*#__NOINLINE__*/noop());
  70. var OBJECT = Object;
  71. var isUndefined = function (v) { return v === UNDEFINED; };
  72. var isFunction = function (v) { return typeof v == 'function'; };
  73. var STR_UNDEFINED = 'undefined';
  74. // NOTE: Use function to guarantee it's re-evaluated between jsdom and node runtime for tests.
  75. var hasWindow = function () { return typeof window != STR_UNDEFINED; };
  76. var IS_SERVER = !hasWindow() || 'Deno' in window;
  77. // React currently throws a warning when using useLayoutEffect on the server.
  78. // To get around it, we can conditionally useEffect on the server (no-op) and
  79. // useLayoutEffect in the browser.
  80. var useIsomorphicLayoutEffect = IS_SERVER ? react.useEffect : react.useLayoutEffect;
  81. // use WeakMap to store the object->key mapping
  82. // so the objects can be garbage collected.
  83. // WeakMap uses a hashtable under the hood, so the lookup
  84. // complexity is almost O(1).
  85. var table = new WeakMap();
  86. // counter of the key
  87. var counter = 0;
  88. // A stable hash implementation that supports:
  89. // - Fast and ensures unique hash properties
  90. // - Handles unserializable values
  91. // - Handles object key ordering
  92. // - Generates short results
  93. //
  94. // This is not a serialization function, and the result is not guaranteed to be
  95. // parsible.
  96. var stableHash = function (arg) {
  97. var type = typeof arg;
  98. var constructor = arg && arg.constructor;
  99. var isDate = constructor == Date;
  100. var result;
  101. var index;
  102. if (OBJECT(arg) === arg && !isDate && constructor != RegExp) {
  103. // Object/function, not null/date/regexp. Use WeakMap to store the id first.
  104. // If it's already hashed, directly return the result.
  105. result = table.get(arg);
  106. if (result)
  107. return result;
  108. // Store the hash first for circular reference detection before entering the
  109. // recursive `stableHash` calls.
  110. // For other objects like set and map, we use this id directly as the hash.
  111. result = ++counter + '~';
  112. table.set(arg, result);
  113. if (constructor == Array) {
  114. // Array.
  115. result = '@';
  116. for (index = 0; index < arg.length; index++) {
  117. result += stableHash(arg[index]) + ',';
  118. }
  119. table.set(arg, result);
  120. }
  121. if (constructor == OBJECT) {
  122. // Object, sort keys.
  123. result = '#';
  124. var keys = OBJECT.keys(arg).sort();
  125. while (!isUndefined((index = keys.pop()))) {
  126. if (!isUndefined(arg[index])) {
  127. result += index + ':' + stableHash(arg[index]) + ',';
  128. }
  129. }
  130. table.set(arg, result);
  131. }
  132. }
  133. else {
  134. result = isDate
  135. ? arg.toJSON()
  136. : type == 'symbol'
  137. ? arg.toString()
  138. : type == 'string'
  139. ? JSON.stringify(arg)
  140. : '' + arg;
  141. }
  142. return result;
  143. };
  144. var serialize = function (key) {
  145. if (isFunction(key)) {
  146. try {
  147. key = key();
  148. }
  149. catch (err) {
  150. // dependencies not ready
  151. key = '';
  152. }
  153. }
  154. var args = [].concat(key);
  155. // If key is not falsy, or not an empty array, hash it.
  156. key =
  157. typeof key == 'string'
  158. ? key
  159. : (Array.isArray(key) ? key.length : key)
  160. ? stableHash(key)
  161. : '';
  162. var infoKey = key ? '$swr$' + key : '';
  163. return [key, args, infoKey];
  164. };
  165. var normalize = function (args) {
  166. return isFunction(args[1])
  167. ? [args[0], args[1], args[2] || {}]
  168. : [args[0], null, (args[1] === null ? args[2] : args[1]) || {}];
  169. };
  170. // Create a custom hook with a middleware
  171. var withMiddleware = function (useSWR, middleware) {
  172. return function () {
  173. var args = [];
  174. for (var _i = 0; _i < arguments.length; _i++) {
  175. args[_i] = arguments[_i];
  176. }
  177. var _a = normalize(args), key = _a[0], fn = _a[1], config = _a[2];
  178. var uses = (config.use || []).concat(middleware);
  179. return useSWR(key, fn, __assign(__assign({}, config), { use: uses }));
  180. };
  181. };
  182. // We have to several type castings here because `useSWRInfinite` is a special
  183. var INFINITE_PREFIX = '$inf$';
  184. var getFirstPageKey = function (getKey) {
  185. return serialize(getKey ? getKey(0, null) : null)[0];
  186. };
  187. var unstable_serialize = function (getKey) {
  188. return INFINITE_PREFIX + getFirstPageKey(getKey);
  189. };
  190. var infinite = (function (useSWRNext) {
  191. return function (getKey, fn, config) {
  192. var rerender = react.useState({})[1];
  193. var didMountRef = react.useRef(false);
  194. var dataRef = react.useRef();
  195. var cache = config.cache, _a = config.initialSize, initialSize = _a === void 0 ? 1 : _a, _b = config.revalidateAll, revalidateAll = _b === void 0 ? false : _b, _c = config.persistSize, persistSize = _c === void 0 ? false : _c, _d = config.revalidateFirstPage, revalidateFirstPage = _d === void 0 ? true : _d, _e = config.revalidateOnMount, revalidateOnMount = _e === void 0 ? false : _e;
  196. // The serialized key of the first page.
  197. var firstPageKey = null;
  198. try {
  199. firstPageKey = getFirstPageKey(getKey);
  200. }
  201. catch (err) {
  202. // not ready
  203. }
  204. // We use cache to pass extra info (context) to fetcher so it can be globally
  205. // shared. The key of the context data is based on the first page key.
  206. var contextCacheKey = null;
  207. // Page size is also cached to share the page data between hooks with the
  208. // same key.
  209. var pageSizeCacheKey = null;
  210. if (firstPageKey) {
  211. contextCacheKey = '$ctx$' + firstPageKey;
  212. pageSizeCacheKey = '$len$' + firstPageKey;
  213. }
  214. var resolvePageSize = react.useCallback(function () {
  215. var cachedPageSize = cache.get(pageSizeCacheKey);
  216. return isUndefined(cachedPageSize) ? initialSize : cachedPageSize;
  217. // `cache` isn't allowed to change during the lifecycle
  218. // eslint-disable-next-line react-hooks/exhaustive-deps
  219. }, [pageSizeCacheKey, initialSize]);
  220. // keep the last page size to restore it with the persistSize option
  221. var lastPageSizeRef = react.useRef(resolvePageSize());
  222. // When the page key changes, we reset the page size if it's not persisted
  223. useIsomorphicLayoutEffect(function () {
  224. if (!didMountRef.current) {
  225. didMountRef.current = true;
  226. return;
  227. }
  228. if (firstPageKey) {
  229. // If the key has been changed, we keep the current page size if persistSize is enabled
  230. cache.set(pageSizeCacheKey, persistSize ? lastPageSizeRef.current : initialSize);
  231. }
  232. // `initialSize` isn't allowed to change during the lifecycle
  233. // eslint-disable-next-line react-hooks/exhaustive-deps
  234. }, [firstPageKey]);
  235. // Needs to check didMountRef during mounting, not in the fetcher
  236. var shouldRevalidateOnMount = revalidateOnMount && !didMountRef.current;
  237. // Actual SWR hook to load all pages in one fetcher.
  238. var swr = useSWRNext(firstPageKey ? INFINITE_PREFIX + firstPageKey : null, function () { return __awaiter(void 0, void 0, void 0, function () {
  239. var _a, forceRevalidateAll, originalData, data, pageSize, previousPageData, i, _b, pageKey, pageArgs, pageData, shouldFetchPage;
  240. return __generator(this, function (_c) {
  241. switch (_c.label) {
  242. case 0:
  243. _a = cache.get(contextCacheKey) || [], forceRevalidateAll = _a[0], originalData = _a[1];
  244. data = [];
  245. pageSize = resolvePageSize();
  246. previousPageData = null;
  247. i = 0;
  248. _c.label = 1;
  249. case 1:
  250. if (!(i < pageSize)) return [3 /*break*/, 5];
  251. _b = serialize(getKey(i, previousPageData)), pageKey = _b[0], pageArgs = _b[1];
  252. if (!pageKey) {
  253. // `pageKey` is falsy, stop fetching new pages.
  254. return [3 /*break*/, 5];
  255. }
  256. pageData = cache.get(pageKey);
  257. shouldFetchPage = revalidateAll ||
  258. forceRevalidateAll ||
  259. isUndefined(pageData) ||
  260. (revalidateFirstPage && !i && !isUndefined(dataRef.current)) ||
  261. shouldRevalidateOnMount ||
  262. (originalData &&
  263. !isUndefined(originalData[i]) &&
  264. !config.compare(originalData[i], pageData));
  265. if (!(fn && shouldFetchPage)) return [3 /*break*/, 3];
  266. return [4 /*yield*/, fn.apply(void 0, pageArgs)];
  267. case 2:
  268. pageData = _c.sent();
  269. cache.set(pageKey, pageData);
  270. _c.label = 3;
  271. case 3:
  272. data.push(pageData);
  273. previousPageData = pageData;
  274. _c.label = 4;
  275. case 4:
  276. ++i;
  277. return [3 /*break*/, 1];
  278. case 5:
  279. // once we executed the data fetching based on the context, clear the context
  280. cache.delete(contextCacheKey);
  281. // return the data
  282. return [2 /*return*/, data];
  283. }
  284. });
  285. }); }, config);
  286. // update dataRef
  287. useIsomorphicLayoutEffect(function () {
  288. dataRef.current = swr.data;
  289. }, [swr.data]);
  290. var mutate = react.useCallback(function () {
  291. var args = [];
  292. for (var _i = 0; _i < arguments.length; _i++) {
  293. args[_i] = arguments[_i];
  294. }
  295. var data = args[0];
  296. // Default to true.
  297. var shouldRevalidate = args[1] !== false;
  298. // It is possible that the key is still falsy.
  299. if (!contextCacheKey)
  300. return;
  301. if (shouldRevalidate) {
  302. if (!isUndefined(data)) {
  303. // We only revalidate the pages that are changed
  304. var originalData = dataRef.current;
  305. cache.set(contextCacheKey, [false, originalData]);
  306. }
  307. else {
  308. // Calling `mutate()`, we revalidate all pages
  309. cache.set(contextCacheKey, [true]);
  310. }
  311. }
  312. return args.length ? swr.mutate(data, shouldRevalidate) : swr.mutate();
  313. },
  314. // swr.mutate is always the same reference
  315. // eslint-disable-next-line react-hooks/exhaustive-deps
  316. [contextCacheKey]);
  317. // Function to load pages data from the cache based on the page size.
  318. var resolvePagesFromCache = function (pageSize) {
  319. // return an array of page data
  320. var data = [];
  321. var previousPageData = null;
  322. for (var i = 0; i < pageSize; ++i) {
  323. var pageKey = serialize(getKey(i, previousPageData))[0];
  324. // Get the cached page data.
  325. var pageData = pageKey ? cache.get(pageKey) : UNDEFINED;
  326. // Return the current data if we can't get it from the cache.
  327. if (isUndefined(pageData))
  328. return dataRef.current;
  329. data.push(pageData);
  330. previousPageData = pageData;
  331. }
  332. // Return the data
  333. return data;
  334. };
  335. // Extend the SWR API
  336. var setSize = react.useCallback(function (arg) {
  337. // It is possible that the key is still falsy.
  338. if (!pageSizeCacheKey)
  339. return;
  340. var size;
  341. if (isFunction(arg)) {
  342. size = arg(resolvePageSize());
  343. }
  344. else if (typeof arg == 'number') {
  345. size = arg;
  346. }
  347. if (typeof size != 'number')
  348. return;
  349. cache.set(pageSizeCacheKey, size);
  350. lastPageSizeRef.current = size;
  351. rerender({});
  352. return mutate(resolvePagesFromCache(size));
  353. },
  354. // `cache` and `rerender` isn't allowed to change during the lifecycle
  355. // eslint-disable-next-line react-hooks/exhaustive-deps
  356. [pageSizeCacheKey, resolvePageSize, mutate]);
  357. // Use getter functions to avoid unnecessary re-renders caused by triggering
  358. // all the getters of the returned swr object.
  359. return {
  360. size: resolvePageSize(),
  361. setSize: setSize,
  362. mutate: mutate,
  363. get error() {
  364. return swr.error;
  365. },
  366. get data() {
  367. return swr.data;
  368. },
  369. get isValidating() {
  370. return swr.isValidating;
  371. }
  372. };
  373. };
  374. });
  375. var index = withMiddleware(useSWR__default['default'], infinite);
  376. exports['default'] = index;
  377. exports.infinite = infinite;
  378. exports.unstable_serialize = unstable_serialize;