UNPKG

@clerk/chrome-extension

Version:

Clerk SDK for Chrome extensions

1,534 lines (1,520 loc) • 184 kB
'use strict'; var React8 = require('react'); var index_js = require('use-sync-external-store/shim/index.js'); var reactDom = require('react-dom'); var noRhc = require('@clerk/clerk-js/no-rhc'); var browser2 = require('webextension-polyfill'); var jsxRuntime = require('react/jsx-runtime'); function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; } var React8__default = /*#__PURE__*/_interopDefault(React8); var browser2__default = /*#__PURE__*/_interopDefault(browser2); var __defProp = Object.defineProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; // ../shared/dist/chunk-DL452J2I.mjs function isClerkAPIResponseError(err) { return "clerkError" in err; } function isClerkRuntimeError(err) { return "clerkRuntimeError" in err; } var ClerkRuntimeError = class _ClerkRuntimeError extends Error { constructor(message, { code }) { const prefix = "\u{1F512} Clerk:"; const regex = new RegExp(prefix.replace(" ", "\\s*"), "i"); const sanitized = message.replace(regex, ""); const _message = `${prefix} ${sanitized.trim()} (code="${code}") `; super(_message); this.toString = () => { return `[${this.name}] Message:${this.message}`; }; Object.setPrototypeOf(this, _ClerkRuntimeError.prototype); this.code = code; this.message = _message; this.clerkRuntimeError = true; this.name = "ClerkRuntimeError"; } }; var DefaultMessages = Object.freeze({ InvalidProxyUrlErrorMessage: `The proxyUrl passed to Clerk is invalid. The expected value for proxyUrl is an absolute URL or a relative path with a leading '/'. (key={{url}})`, InvalidPublishableKeyErrorMessage: `The publishableKey passed to Clerk is invalid. You can get your Publishable key at https://dashboard.clerk.com/last-active?path=api-keys. (key={{key}})`, MissingPublishableKeyErrorMessage: `Missing publishableKey. You can get your key at https://dashboard.clerk.com/last-active?path=api-keys.`, MissingSecretKeyErrorMessage: `Missing secretKey. You can get your key at https://dashboard.clerk.com/last-active?path=api-keys.`, MissingClerkProvider: `{{source}} can only be used within the <ClerkProvider /> component. Learn more: https://clerk.com/docs/components/clerk-provider` }); function buildErrorThrower({ packageName, customMessages }) { let pkg = packageName; const messages = { ...DefaultMessages, ...customMessages }; function buildMessage(rawMessage, replacements) { if (!replacements) { return `${pkg}: ${rawMessage}`; } let msg = rawMessage; const matches = rawMessage.matchAll(/{{([a-zA-Z0-9-_]+)}}/g); for (const match of matches) { const replacement = (replacements[match[1]] || "").toString(); msg = msg.replace(`{{${match[1]}}}`, replacement); } return `${pkg}: ${msg}`; } return { setPackageName({ packageName: packageName2 }) { if (typeof packageName2 === "string") { pkg = packageName2; } return this; }, setMessages({ customMessages: customMessages2 }) { Object.assign(messages, customMessages2 || {}); return this; }, throwInvalidPublishableKeyError(params) { throw new Error(buildMessage(messages.InvalidPublishableKeyErrorMessage, params)); }, throwInvalidProxyUrl(params) { throw new Error(buildMessage(messages.InvalidProxyUrlErrorMessage, params)); }, throwMissingPublishableKeyError() { throw new Error(buildMessage(messages.MissingPublishableKeyErrorMessage)); }, throwMissingSecretKeyError() { throw new Error(buildMessage(messages.MissingSecretKeyErrorMessage)); }, throwMissingClerkProviderError(params) { throw new Error(buildMessage(messages.MissingClerkProvider, params)); }, throw(message) { throw new Error(buildMessage(message)); } }; } // ../shared/dist/chunk-7ELT755Q.mjs var __defProp2 = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export2 = (target, all) => { for (var name in all) __defProp2(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget); // ../shared/dist/chunk-X3VKQCBG.mjs var TYPES_TO_OBJECTS = { strict_mfa: { afterMinutes: 10, level: "multi_factor" }, strict: { afterMinutes: 10, level: "second_factor" }, moderate: { afterMinutes: 60, level: "second_factor" }, lax: { afterMinutes: 1440, level: "second_factor" } }; var ALLOWED_LEVELS = /* @__PURE__ */ new Set(["first_factor", "second_factor", "multi_factor"]); var ALLOWED_TYPES = /* @__PURE__ */ new Set(["strict_mfa", "strict", "moderate", "lax"]); var isValidMaxAge = (maxAge) => typeof maxAge === "number" && maxAge > 0; var isValidLevel = (level) => ALLOWED_LEVELS.has(level); var isValidVerificationType = (type) => ALLOWED_TYPES.has(type); var checkOrgAuthorization = (params, options) => { const { orgId, orgRole, orgPermissions } = options; if (!params.role && !params.permission) { return null; } if (!orgId || !orgRole || !orgPermissions) { return null; } if (params.permission) { return orgPermissions.includes(params.permission); } if (params.role) { return orgRole === params.role; } return null; }; var validateReverificationConfig = (config) => { if (!config) { return false; } const convertConfigToObject = (config2) => { if (typeof config2 === "string") { return TYPES_TO_OBJECTS[config2]; } return config2; }; const isValidStringValue = typeof config === "string" && isValidVerificationType(config); const isValidObjectValue = typeof config === "object" && isValidLevel(config.level) && isValidMaxAge(config.afterMinutes); if (isValidStringValue || isValidObjectValue) { return convertConfigToObject.bind(null, config); } return false; }; var checkStepUpAuthorization = (params, { factorVerificationAge }) => { if (!params.reverification || !factorVerificationAge) { return null; } const isValidReverification = validateReverificationConfig(params.reverification); if (!isValidReverification) { return null; } const { level, afterMinutes } = isValidReverification(); const [factor1Age, factor2Age] = factorVerificationAge; const isValidFactor1 = factor1Age !== -1 ? afterMinutes > factor1Age : null; const isValidFactor2 = factor2Age !== -1 ? afterMinutes > factor2Age : null; switch (level) { case "first_factor": return isValidFactor1; case "second_factor": return factor2Age !== -1 ? isValidFactor2 : isValidFactor1; case "multi_factor": return factor2Age === -1 ? isValidFactor1 : isValidFactor1 && isValidFactor2; } }; var createCheckAuthorization = (options) => { return (params) => { if (!options.userId) { return false; } const orgAuthorization = checkOrgAuthorization(params, options); const stepUpAuthorization = checkStepUpAuthorization(params, options); if ([orgAuthorization, stepUpAuthorization].some((a) => a === null)) { return [orgAuthorization, stepUpAuthorization].some((a) => a === true); } return [orgAuthorization, stepUpAuthorization].every((a) => a === true); }; }; // ../shared/dist/chunk-TUVJ3GI6.mjs var EVENT_METHOD_CALLED = "METHOD_CALLED"; function eventMethodCalled(method, payload) { return { event: EVENT_METHOD_CALLED, payload: { method, ...payload } }; } // ../shared/dist/chunk-7FNX7RWY.mjs var noop = (..._args) => { }; // ../shared/dist/chunk-BS4QFUKM.mjs var createDeferredPromise = () => { let resolve = noop; let reject = noop; const promise = new Promise((res, rej) => { resolve = res; reject = rej; }); return { promise, resolve, reject }; }; // ../shared/dist/chunk-5C3LHKBE.mjs var REVERIFICATION_REASON = "reverification-error"; var reverificationError = (missingConfig) => ({ clerk_error: { type: "forbidden", reason: REVERIFICATION_REASON, metadata: { reverification: missingConfig } } }); var isReverificationHint = (result) => { var _a, _b; return result && typeof result === "object" && "clerk_error" in result && ((_a = result.clerk_error) == null ? void 0 : _a.type) === "forbidden" && ((_b = result.clerk_error) == null ? void 0 : _b.reason) === REVERIFICATION_REASON; }; // ../../node_modules/.pnpm/swr@2.2.5_react@18.3.1/node_modules/swr/dist/core/index.mjs var core_exports = {}; __export(core_exports, { SWRConfig: () => SWRConfig2, default: () => useSWR, mutate: () => mutate, preload: () => preload, unstable_serialize: () => unstable_serialize, useSWRConfig: () => useSWRConfig }); var noop2 = () => { }; var UNDEFINED = ( /*#__NOINLINE__*/ noop2() ); var OBJECT = Object; var isUndefined = (v) => v === UNDEFINED; var isFunction = (v) => typeof v == "function"; var mergeObjects = (a, b) => ({ ...a, ...b }); var isPromiseLike = (x) => isFunction(x.then); var table = /* @__PURE__ */ new WeakMap(); var counter = 0; var stableHash = (arg) => { const type = typeof arg; const constructor = arg && arg.constructor; const isDate = constructor == Date; let result; let index; if (OBJECT(arg) === arg && !isDate && constructor != RegExp) { result = table.get(arg); if (result) return result; result = ++counter + "~"; table.set(arg, result); if (constructor == Array) { result = "@"; for (index = 0; index < arg.length; index++) { result += stableHash(arg[index]) + ","; } table.set(arg, result); } if (constructor == OBJECT) { result = "#"; const keys = OBJECT.keys(arg).sort(); while (!isUndefined(index = keys.pop())) { if (!isUndefined(arg[index])) { result += index + ":" + stableHash(arg[index]) + ","; } } table.set(arg, result); } } else { result = isDate ? arg.toJSON() : type == "symbol" ? arg.toString() : type == "string" ? JSON.stringify(arg) : "" + arg; } return result; }; var SWRGlobalState = /* @__PURE__ */ new WeakMap(); var EMPTY_CACHE = {}; var INITIAL_CACHE = {}; var STR_UNDEFINED = "undefined"; var isWindowDefined = typeof window != STR_UNDEFINED; var isDocumentDefined = typeof document != STR_UNDEFINED; var hasRequestAnimationFrame = () => isWindowDefined && typeof window["requestAnimationFrame"] != STR_UNDEFINED; var createCacheHelper = (cache2, key) => { const state = SWRGlobalState.get(cache2); return [ // Getter () => !isUndefined(key) && cache2.get(key) || EMPTY_CACHE, // Setter (info) => { if (!isUndefined(key)) { const prev = cache2.get(key); if (!(key in INITIAL_CACHE)) { INITIAL_CACHE[key] = prev; } state[5](key, mergeObjects(prev, info), prev || EMPTY_CACHE); } }, // Subscriber state[6], // Get server cache snapshot () => { if (!isUndefined(key)) { if (key in INITIAL_CACHE) return INITIAL_CACHE[key]; } return !isUndefined(key) && cache2.get(key) || EMPTY_CACHE; } ]; }; var online = true; var isOnline = () => online; var [onWindowEvent, offWindowEvent] = isWindowDefined && window.addEventListener ? [ window.addEventListener.bind(window), window.removeEventListener.bind(window) ] : [ noop2, noop2 ]; var isVisible = () => { const visibilityState = isDocumentDefined && document.visibilityState; return isUndefined(visibilityState) || visibilityState !== "hidden"; }; var initFocus = (callback) => { if (isDocumentDefined) { document.addEventListener("visibilitychange", callback); } onWindowEvent("focus", callback); return () => { if (isDocumentDefined) { document.removeEventListener("visibilitychange", callback); } offWindowEvent("focus", callback); }; }; var initReconnect = (callback) => { const onOnline = () => { online = true; callback(); }; const onOffline = () => { online = false; }; onWindowEvent("online", onOnline); onWindowEvent("offline", onOffline); return () => { offWindowEvent("online", onOnline); offWindowEvent("offline", onOffline); }; }; var preset = { isOnline, isVisible }; var defaultConfigOptions = { initFocus, initReconnect }; var IS_REACT_LEGACY = !React8__default.default.useId; var IS_SERVER = !isWindowDefined || "Deno" in window; var rAF = (f) => hasRequestAnimationFrame() ? window["requestAnimationFrame"](f) : setTimeout(f, 1); var useIsomorphicLayoutEffect = IS_SERVER ? React8.useEffect : React8.useLayoutEffect; var navigatorConnection = typeof navigator !== "undefined" && navigator.connection; var slowConnection = !IS_SERVER && navigatorConnection && ([ "slow-2g", "2g" ].includes(navigatorConnection.effectiveType) || navigatorConnection.saveData); var serialize = (key) => { if (isFunction(key)) { try { key = key(); } catch (err) { key = ""; } } const args = key; key = typeof key == "string" ? key : (Array.isArray(key) ? key.length : key) ? stableHash(key) : ""; return [ key, args ]; }; var __timestamp = 0; var getTimestamp = () => ++__timestamp; var FOCUS_EVENT = 0; var RECONNECT_EVENT = 1; var MUTATE_EVENT = 2; var ERROR_REVALIDATE_EVENT = 3; var events = { __proto__: null, ERROR_REVALIDATE_EVENT, FOCUS_EVENT, MUTATE_EVENT, RECONNECT_EVENT }; async function internalMutate(...args) { const [cache2, _key, _data, _opts] = args; const options = mergeObjects({ populateCache: true, throwOnError: true }, typeof _opts === "boolean" ? { revalidate: _opts } : _opts || {}); let populateCache = options.populateCache; const rollbackOnErrorOption = options.rollbackOnError; let optimisticData = options.optimisticData; const rollbackOnError = (error) => { return typeof rollbackOnErrorOption === "function" ? rollbackOnErrorOption(error) : rollbackOnErrorOption !== false; }; const throwOnError = options.throwOnError; if (isFunction(_key)) { const keyFilter = _key; const matchedKeys = []; const it = cache2.keys(); for (const key of it) { if ( // Skip the special useSWRInfinite and useSWRSubscription keys. !/^\$(inf|sub)\$/.test(key) && keyFilter(cache2.get(key)._k) ) { matchedKeys.push(key); } } return Promise.all(matchedKeys.map(mutateByKey)); } return mutateByKey(_key); async function mutateByKey(_k) { const [key] = serialize(_k); if (!key) return; const [get, set] = createCacheHelper(cache2, key); const [EVENT_REVALIDATORS, MUTATION, FETCH, PRELOAD] = SWRGlobalState.get(cache2); const startRevalidate = () => { const revalidators = EVENT_REVALIDATORS[key]; const revalidate = isFunction(options.revalidate) ? options.revalidate(get().data, _k) : options.revalidate !== false; if (revalidate) { delete FETCH[key]; delete PRELOAD[key]; if (revalidators && revalidators[0]) { return revalidators[0](MUTATE_EVENT).then(() => get().data); } } return get().data; }; if (args.length < 3) { return startRevalidate(); } let data = _data; let error; const beforeMutationTs = getTimestamp(); MUTATION[key] = [ beforeMutationTs, 0 ]; const hasOptimisticData = !isUndefined(optimisticData); const state = get(); const displayedData = state.data; const currentData = state._c; const committedData = isUndefined(currentData) ? displayedData : currentData; if (hasOptimisticData) { optimisticData = isFunction(optimisticData) ? optimisticData(committedData, displayedData) : optimisticData; set({ data: optimisticData, _c: committedData }); } if (isFunction(data)) { try { data = data(committedData); } catch (err) { error = err; } } if (data && isPromiseLike(data)) { data = await data.catch((err) => { error = err; }); if (beforeMutationTs !== MUTATION[key][0]) { if (error) throw error; return data; } else if (error && hasOptimisticData && rollbackOnError(error)) { populateCache = true; set({ data: committedData, _c: UNDEFINED }); } } if (populateCache) { if (!error) { if (isFunction(populateCache)) { const populateCachedData = populateCache(data, committedData); set({ data: populateCachedData, error: UNDEFINED, _c: UNDEFINED }); } else { set({ data, error: UNDEFINED, _c: UNDEFINED }); } } } MUTATION[key][1] = getTimestamp(); Promise.resolve(startRevalidate()).then(() => { set({ _c: UNDEFINED }); }); if (error) { if (throwOnError) throw error; return; } return data; } } var revalidateAllKeys = (revalidators, type) => { for (const key in revalidators) { if (revalidators[key][0]) revalidators[key][0](type); } }; var initCache = (provider, options) => { if (!SWRGlobalState.has(provider)) { const opts = mergeObjects(defaultConfigOptions, options); const EVENT_REVALIDATORS = {}; const mutate2 = internalMutate.bind(UNDEFINED, provider); let unmount = noop2; const subscriptions = {}; const subscribe = (key, callback) => { const subs = subscriptions[key] || []; subscriptions[key] = subs; subs.push(callback); return () => subs.splice(subs.indexOf(callback), 1); }; const setter = (key, value, prev) => { provider.set(key, value); const subs = subscriptions[key]; if (subs) { for (const fn of subs) { fn(value, prev); } } }; const initProvider = () => { if (!SWRGlobalState.has(provider)) { SWRGlobalState.set(provider, [ EVENT_REVALIDATORS, {}, {}, {}, mutate2, setter, subscribe ]); if (!IS_SERVER) { const releaseFocus = opts.initFocus(setTimeout.bind(UNDEFINED, revalidateAllKeys.bind(UNDEFINED, EVENT_REVALIDATORS, FOCUS_EVENT))); const releaseReconnect = opts.initReconnect(setTimeout.bind(UNDEFINED, revalidateAllKeys.bind(UNDEFINED, EVENT_REVALIDATORS, RECONNECT_EVENT))); unmount = () => { releaseFocus && releaseFocus(); releaseReconnect && releaseReconnect(); SWRGlobalState.delete(provider); }; } } }; initProvider(); return [ provider, mutate2, initProvider, unmount ]; } return [ provider, SWRGlobalState.get(provider)[4] ]; }; var onErrorRetry = (_, __, config, revalidate, opts) => { const maxRetryCount = config.errorRetryCount; const currentRetryCount = opts.retryCount; const timeout = ~~((Math.random() + 0.5) * (1 << (currentRetryCount < 8 ? currentRetryCount : 8))) * config.errorRetryInterval; if (!isUndefined(maxRetryCount) && currentRetryCount > maxRetryCount) { return; } setTimeout(revalidate, timeout, opts); }; var compare = (currentData, newData) => stableHash(currentData) == stableHash(newData); var [cache, mutate] = initCache(/* @__PURE__ */ new Map()); var defaultConfig = mergeObjects( { // events onLoadingSlow: noop2, onSuccess: noop2, onError: noop2, onErrorRetry, onDiscarded: noop2, // switches revalidateOnFocus: true, revalidateOnReconnect: true, revalidateIfStale: true, shouldRetryOnError: true, // timeouts errorRetryInterval: slowConnection ? 1e4 : 5e3, focusThrottleInterval: 5 * 1e3, dedupingInterval: 2 * 1e3, loadingTimeout: slowConnection ? 5e3 : 3e3, // providers compare, isPaused: () => false, cache, mutate, fallback: {} }, // use web preset by default preset ); var mergeConfigs = (a, b) => { const v = mergeObjects(a, b); if (b) { const { use: u1, fallback: f1 } = a; const { use: u2, fallback: f2 } = b; if (u1 && u2) { v.use = u1.concat(u2); } if (f1 && f2) { v.fallback = mergeObjects(f1, f2); } } return v; }; var SWRConfigContext = React8.createContext({}); var SWRConfig = (props) => { const { value } = props; const parentConfig = React8.useContext(SWRConfigContext); const isFunctionalConfig = isFunction(value); const config = React8.useMemo(() => isFunctionalConfig ? value(parentConfig) : value, [ isFunctionalConfig, parentConfig, value ]); const extendedConfig = React8.useMemo(() => isFunctionalConfig ? config : mergeConfigs(parentConfig, config), [ isFunctionalConfig, parentConfig, config ]); const provider = config && config.provider; const cacheContextRef = React8.useRef(UNDEFINED); if (provider && !cacheContextRef.current) { cacheContextRef.current = initCache(provider(extendedConfig.cache || cache), config); } const cacheContext = cacheContextRef.current; if (cacheContext) { extendedConfig.cache = cacheContext[0]; extendedConfig.mutate = cacheContext[1]; } useIsomorphicLayoutEffect(() => { if (cacheContext) { cacheContext[2] && cacheContext[2](); return cacheContext[3]; } }, []); return React8.createElement(SWRConfigContext.Provider, mergeObjects(props, { value: extendedConfig })); }; var INFINITE_PREFIX = "$inf$"; var enableDevtools = isWindowDefined && window.__SWR_DEVTOOLS_USE__; var use = enableDevtools ? window.__SWR_DEVTOOLS_USE__ : []; var setupDevTools = () => { if (enableDevtools) { window.__SWR_DEVTOOLS_REACT__ = React8__default.default; } }; var normalize = (args) => { return isFunction(args[1]) ? [ args[0], args[1], args[2] || {} ] : [ args[0], null, (args[1] === null ? args[2] : args[1]) || {} ]; }; var useSWRConfig = () => { return mergeObjects(defaultConfig, React8.useContext(SWRConfigContext)); }; var preload = (key_, fetcher) => { const [key, fnArg] = serialize(key_); const [, , , PRELOAD] = SWRGlobalState.get(cache); if (PRELOAD[key]) return PRELOAD[key]; const req = fetcher(fnArg); PRELOAD[key] = req; return req; }; var middleware = (useSWRNext) => (key_, fetcher_, config) => { const fetcher = fetcher_ && ((...args) => { const [key] = serialize(key_); const [, , , PRELOAD] = SWRGlobalState.get(cache); if (key.startsWith(INFINITE_PREFIX)) { return fetcher_(...args); } const req = PRELOAD[key]; if (isUndefined(req)) return fetcher_(...args); delete PRELOAD[key]; return req; }); return useSWRNext(key_, fetcher, config); }; var BUILT_IN_MIDDLEWARE = use.concat(middleware); var withArgs = (hook) => { return function useSWRArgs(...args) { const fallbackConfig = useSWRConfig(); const [key, fn, _config2] = normalize(args); const config = mergeConfigs(fallbackConfig, _config2); let next = hook; const { use: use4 } = config; const middleware2 = (use4 || []).concat(BUILT_IN_MIDDLEWARE); for (let i = middleware2.length; i--; ) { next = middleware2[i](next); } return next(key, fn || config.fetcher || null, config); }; }; var subscribeCallback = (key, callbacks, callback) => { const keyedRevalidators = callbacks[key] || (callbacks[key] = []); keyedRevalidators.push(callback); return () => { const index = keyedRevalidators.indexOf(callback); if (index >= 0) { keyedRevalidators[index] = keyedRevalidators[keyedRevalidators.length - 1]; keyedRevalidators.pop(); } }; }; var withMiddleware = (useSWR3, middleware2) => { return (...args) => { const [key, fn, config] = normalize(args); const uses = (config.use || []).concat(middleware2); return useSWR3(key, fn, { ...config, use: uses }); }; }; setupDevTools(); // ../../node_modules/.pnpm/swr@2.2.5_react@18.3.1/node_modules/swr/dist/core/index.mjs var unstable_serialize = (key) => serialize(key)[0]; var use2 = React8__default.default.use || ((promise) => { if (promise.status === "pending") { throw promise; } else if (promise.status === "fulfilled") { return promise.value; } else if (promise.status === "rejected") { throw promise.reason; } else { promise.status = "pending"; promise.then((v) => { promise.status = "fulfilled"; promise.value = v; }, (e) => { promise.status = "rejected"; promise.reason = e; }); throw promise; } }); var WITH_DEDUPE = { dedupe: true }; var useSWRHandler = (_key, fetcher, config) => { const { cache: cache2, compare: compare2, suspense, fallbackData, revalidateOnMount, revalidateIfStale, refreshInterval, refreshWhenHidden, refreshWhenOffline, keepPreviousData } = config; const [EVENT_REVALIDATORS, MUTATION, FETCH, PRELOAD] = SWRGlobalState.get(cache2); const [key, fnArg] = serialize(_key); const initialMountedRef = React8.useRef(false); const unmountedRef = React8.useRef(false); const keyRef = React8.useRef(key); const fetcherRef = React8.useRef(fetcher); const configRef = React8.useRef(config); const getConfig = () => configRef.current; const isActive = () => getConfig().isVisible() && getConfig().isOnline(); const [getCache, setCache, subscribeCache, getInitialCache] = createCacheHelper(cache2, key); const stateDependencies = React8.useRef({}).current; const fallback = isUndefined(fallbackData) ? config.fallback[key] : fallbackData; const isEqual = (prev, current) => { for (const _ in stateDependencies) { const t = _; if (t === "data") { if (!compare2(prev[t], current[t])) { if (!isUndefined(prev[t])) { return false; } if (!compare2(returnedData, current[t])) { return false; } } } else { if (current[t] !== prev[t]) { return false; } } } return true; }; const getSnapshot = React8.useMemo(() => { const shouldStartRequest = (() => { if (!key) return false; if (!fetcher) return false; if (!isUndefined(revalidateOnMount)) return revalidateOnMount; if (getConfig().isPaused()) return false; if (suspense) return false; if (!isUndefined(revalidateIfStale)) return revalidateIfStale; return true; })(); const getSelectedCache = (state) => { const snapshot = mergeObjects(state); delete snapshot._k; if (!shouldStartRequest) { return snapshot; } return { isValidating: true, isLoading: true, ...snapshot }; }; const cachedData2 = getCache(); const initialData = getInitialCache(); const clientSnapshot = getSelectedCache(cachedData2); const serverSnapshot = cachedData2 === initialData ? clientSnapshot : getSelectedCache(initialData); let memorizedSnapshot = clientSnapshot; return [ () => { const newSnapshot = getSelectedCache(getCache()); const compareResult = isEqual(newSnapshot, memorizedSnapshot); if (compareResult) { memorizedSnapshot.data = newSnapshot.data; memorizedSnapshot.isLoading = newSnapshot.isLoading; memorizedSnapshot.isValidating = newSnapshot.isValidating; memorizedSnapshot.error = newSnapshot.error; return memorizedSnapshot; } else { memorizedSnapshot = newSnapshot; return newSnapshot; } }, () => serverSnapshot ]; }, [ cache2, key ]); const cached = index_js.useSyncExternalStore(React8.useCallback( (callback) => subscribeCache(key, (current, prev) => { if (!isEqual(prev, current)) callback(); }), // eslint-disable-next-line react-hooks/exhaustive-deps [ cache2, key ] ), getSnapshot[0], getSnapshot[1]); const isInitialMount = !initialMountedRef.current; const hasRevalidator = EVENT_REVALIDATORS[key] && EVENT_REVALIDATORS[key].length > 0; const cachedData = cached.data; const data = isUndefined(cachedData) ? fallback : cachedData; const error = cached.error; const laggyDataRef = React8.useRef(data); const returnedData = keepPreviousData ? isUndefined(cachedData) ? laggyDataRef.current : cachedData : data; const shouldDoInitialRevalidation = (() => { if (hasRevalidator && !isUndefined(error)) return false; if (isInitialMount && !isUndefined(revalidateOnMount)) return revalidateOnMount; if (getConfig().isPaused()) return false; if (suspense) return isUndefined(data) ? false : revalidateIfStale; return isUndefined(data) || revalidateIfStale; })(); const defaultValidatingState = !!(key && fetcher && isInitialMount && shouldDoInitialRevalidation); const isValidating = isUndefined(cached.isValidating) ? defaultValidatingState : cached.isValidating; const isLoading = isUndefined(cached.isLoading) ? defaultValidatingState : cached.isLoading; const revalidate = React8.useCallback( async (revalidateOpts) => { const currentFetcher = fetcherRef.current; if (!key || !currentFetcher || unmountedRef.current || getConfig().isPaused()) { return false; } let newData; let startAt; let loading = true; const opts = revalidateOpts || {}; const shouldStartNewRequest = !FETCH[key] || !opts.dedupe; const callbackSafeguard = () => { if (IS_REACT_LEGACY) { return !unmountedRef.current && key === keyRef.current && initialMountedRef.current; } return key === keyRef.current; }; const finalState = { isValidating: false, isLoading: false }; const finishRequestAndUpdateState = () => { setCache(finalState); }; const cleanupState = () => { const requestInfo = FETCH[key]; if (requestInfo && requestInfo[1] === startAt) { delete FETCH[key]; } }; const initialState = { isValidating: true }; if (isUndefined(getCache().data)) { initialState.isLoading = true; } try { if (shouldStartNewRequest) { setCache(initialState); if (config.loadingTimeout && isUndefined(getCache().data)) { setTimeout(() => { if (loading && callbackSafeguard()) { getConfig().onLoadingSlow(key, config); } }, config.loadingTimeout); } FETCH[key] = [ currentFetcher(fnArg), getTimestamp() ]; } [newData, startAt] = FETCH[key]; newData = await newData; if (shouldStartNewRequest) { setTimeout(cleanupState, config.dedupingInterval); } if (!FETCH[key] || FETCH[key][1] !== startAt) { if (shouldStartNewRequest) { if (callbackSafeguard()) { getConfig().onDiscarded(key); } } return false; } finalState.error = UNDEFINED; const mutationInfo = MUTATION[key]; if (!isUndefined(mutationInfo) && // case 1 (startAt <= mutationInfo[0] || // case 2 startAt <= mutationInfo[1] || // case 3 mutationInfo[1] === 0)) { finishRequestAndUpdateState(); if (shouldStartNewRequest) { if (callbackSafeguard()) { getConfig().onDiscarded(key); } } return false; } const cacheData = getCache().data; finalState.data = compare2(cacheData, newData) ? cacheData : newData; if (shouldStartNewRequest) { if (callbackSafeguard()) { getConfig().onSuccess(newData, key, config); } } } catch (err) { cleanupState(); const currentConfig = getConfig(); const { shouldRetryOnError } = currentConfig; if (!currentConfig.isPaused()) { finalState.error = err; if (shouldStartNewRequest && callbackSafeguard()) { currentConfig.onError(err, key, currentConfig); if (shouldRetryOnError === true || isFunction(shouldRetryOnError) && shouldRetryOnError(err)) { if (!getConfig().revalidateOnFocus || !getConfig().revalidateOnReconnect || isActive()) { currentConfig.onErrorRetry(err, key, currentConfig, (_opts) => { const revalidators = EVENT_REVALIDATORS[key]; if (revalidators && revalidators[0]) { revalidators[0](events.ERROR_REVALIDATE_EVENT, _opts); } }, { retryCount: (opts.retryCount || 0) + 1, dedupe: true }); } } } } } loading = false; finishRequestAndUpdateState(); return true; }, // `setState` is immutable, and `eventsCallback`, `fnArg`, and // `keyValidating` are depending on `key`, so we can exclude them from // the deps array. // // FIXME: // `fn` and `config` might be changed during the lifecycle, // but they might be changed every render like this. // `useSWR('key', () => fetch('/api/'), { suspense: true })` // So we omit the values from the deps array // even though it might cause unexpected behaviors. // eslint-disable-next-line react-hooks/exhaustive-deps [ key, cache2 ] ); const boundMutate = React8.useCallback( // Use callback to make sure `keyRef.current` returns latest result every time (...args) => { return internalMutate(cache2, keyRef.current, ...args); }, // eslint-disable-next-line react-hooks/exhaustive-deps [] ); useIsomorphicLayoutEffect(() => { fetcherRef.current = fetcher; configRef.current = config; if (!isUndefined(cachedData)) { laggyDataRef.current = cachedData; } }); useIsomorphicLayoutEffect(() => { if (!key) return; const softRevalidate = revalidate.bind(UNDEFINED, WITH_DEDUPE); let nextFocusRevalidatedAt = 0; const onRevalidate = (type, opts = {}) => { if (type == events.FOCUS_EVENT) { const now = Date.now(); if (getConfig().revalidateOnFocus && now > nextFocusRevalidatedAt && isActive()) { nextFocusRevalidatedAt = now + getConfig().focusThrottleInterval; softRevalidate(); } } else if (type == events.RECONNECT_EVENT) { if (getConfig().revalidateOnReconnect && isActive()) { softRevalidate(); } } else if (type == events.MUTATE_EVENT) { return revalidate(); } else if (type == events.ERROR_REVALIDATE_EVENT) { return revalidate(opts); } return; }; const unsubEvents = subscribeCallback(key, EVENT_REVALIDATORS, onRevalidate); unmountedRef.current = false; keyRef.current = key; initialMountedRef.current = true; setCache({ _k: fnArg }); if (shouldDoInitialRevalidation) { if (isUndefined(data) || IS_SERVER) { softRevalidate(); } else { rAF(softRevalidate); } } return () => { unmountedRef.current = true; unsubEvents(); }; }, [ key ]); useIsomorphicLayoutEffect(() => { let timer; function next() { const interval = isFunction(refreshInterval) ? refreshInterval(getCache().data) : refreshInterval; if (interval && timer !== -1) { timer = setTimeout(execute, interval); } } function execute() { if (!getCache().error && (refreshWhenHidden || getConfig().isVisible()) && (refreshWhenOffline || getConfig().isOnline())) { revalidate(WITH_DEDUPE).then(next); } else { next(); } } next(); return () => { if (timer) { clearTimeout(timer); timer = -1; } }; }, [ refreshInterval, refreshWhenHidden, refreshWhenOffline, key ]); React8.useDebugValue(returnedData); if (suspense && isUndefined(data) && key) { if (!IS_REACT_LEGACY && IS_SERVER) { throw new Error("Fallback data is required when using suspense in SSR."); } fetcherRef.current = fetcher; configRef.current = config; unmountedRef.current = false; const req = PRELOAD[key]; if (!isUndefined(req)) { const promise = boundMutate(req); use2(promise); } if (isUndefined(error)) { const promise = revalidate(WITH_DEDUPE); if (!isUndefined(returnedData)) { promise.status = "fulfilled"; promise.value = true; } use2(promise); } else { throw error; } } return { mutate: boundMutate, get data() { stateDependencies.data = true; return returnedData; }, get error() { stateDependencies.error = true; return error; }, get isValidating() { stateDependencies.isValidating = true; return isValidating; }, get isLoading() { stateDependencies.isLoading = true; return isLoading; } }; }; var SWRConfig2 = OBJECT.defineProperty(SWRConfig, "defaultValue", { value: defaultConfig }); var useSWR = withArgs(useSWRHandler); var use3 = React8__default.default.use || ((promise) => { if (promise.status === "pending") { throw promise; } else if (promise.status === "fulfilled") { return promise.value; } else if (promise.status === "rejected") { throw promise.reason; } else { promise.status = "pending"; promise.then((v) => { promise.status = "fulfilled"; promise.value = v; }, (e) => { promise.status = "rejected"; promise.reason = e; }); throw promise; } }); var WITH_DEDUPE2 = { dedupe: true }; var useSWRHandler2 = (_key, fetcher, config) => { const { cache: cache2, compare: compare2, suspense, fallbackData, revalidateOnMount, revalidateIfStale, refreshInterval, refreshWhenHidden, refreshWhenOffline, keepPreviousData } = config; const [EVENT_REVALIDATORS, MUTATION, FETCH, PRELOAD] = SWRGlobalState.get(cache2); const [key, fnArg] = serialize(_key); const initialMountedRef = React8.useRef(false); const unmountedRef = React8.useRef(false); const keyRef = React8.useRef(key); const fetcherRef = React8.useRef(fetcher); const configRef = React8.useRef(config); const getConfig = () => configRef.current; const isActive = () => getConfig().isVisible() && getConfig().isOnline(); const [getCache, setCache, subscribeCache, getInitialCache] = createCacheHelper(cache2, key); const stateDependencies = React8.useRef({}).current; const fallback = isUndefined(fallbackData) ? config.fallback[key] : fallbackData; const isEqual = (prev, current) => { for (const _ in stateDependencies) { const t = _; if (t === "data") { if (!compare2(prev[t], current[t])) { if (!isUndefined(prev[t])) { return false; } if (!compare2(returnedData, current[t])) { return false; } } } else { if (current[t] !== prev[t]) { return false; } } } return true; }; const getSnapshot = React8.useMemo(() => { const shouldStartRequest = (() => { if (!key) return false; if (!fetcher) return false; if (!isUndefined(revalidateOnMount)) return revalidateOnMount; if (getConfig().isPaused()) return false; if (suspense) return false; if (!isUndefined(revalidateIfStale)) return revalidateIfStale; return true; })(); const getSelectedCache = (state) => { const snapshot = mergeObjects(state); delete snapshot._k; if (!shouldStartRequest) { return snapshot; } return { isValidating: true, isLoading: true, ...snapshot }; }; const cachedData2 = getCache(); const initialData = getInitialCache(); const clientSnapshot = getSelectedCache(cachedData2); const serverSnapshot = cachedData2 === initialData ? clientSnapshot : getSelectedCache(initialData); let memorizedSnapshot = clientSnapshot; return [ () => { const newSnapshot = getSelectedCache(getCache()); const compareResult = isEqual(newSnapshot, memorizedSnapshot); if (compareResult) { memorizedSnapshot.data = newSnapshot.data; memorizedSnapshot.isLoading = newSnapshot.isLoading; memorizedSnapshot.isValidating = newSnapshot.isValidating; memorizedSnapshot.error = newSnapshot.error; return memorizedSnapshot; } else { memorizedSnapshot = newSnapshot; return newSnapshot; } }, () => serverSnapshot ]; }, [ cache2, key ]); const cached = index_js.useSyncExternalStore(React8.useCallback( (callback) => subscribeCache(key, (current, prev) => { if (!isEqual(prev, current)) callback(); }), // eslint-disable-next-line react-hooks/exhaustive-deps [ cache2, key ] ), getSnapshot[0], getSnapshot[1]); const isInitialMount = !initialMountedRef.current; const hasRevalidator = EVENT_REVALIDATORS[key] && EVENT_REVALIDATORS[key].length > 0; const cachedData = cached.data; const data = isUndefined(cachedData) ? fallback : cachedData; const error = cached.error; const laggyDataRef = React8.useRef(data); const returnedData = keepPreviousData ? isUndefined(cachedData) ? laggyDataRef.current : cachedData : data; const shouldDoInitialRevalidation = (() => { if (hasRevalidator && !isUndefined(error)) return false; if (isInitialMount && !isUndefined(revalidateOnMount)) return revalidateOnMount; if (getConfig().isPaused()) return false; if (suspense) return isUndefined(data) ? false : revalidateIfStale; return isUndefined(data) || revalidateIfStale; })(); const defaultValidatingState = !!(key && fetcher && isInitialMount && shouldDoInitialRevalidation); const isValidating = isUndefined(cached.isValidating) ? defaultValidatingState : cached.isValidating; const isLoading = isUndefined(cached.isLoading) ? defaultValidatingState : cached.isLoading; const revalidate = React8.useCallback( async (revalidateOpts) => { const currentFetcher = fetcherRef.current; if (!key || !currentFetcher || unmountedRef.current || getConfig().isPaused()) { return false; } let newData; let startAt; let loading = true; const opts = revalidateOpts || {}; const shouldStartNewRequest = !FETCH[key] || !opts.dedupe; const callbackSafeguard = () => { if (IS_REACT_LEGACY) { return !unmountedRef.current && key === keyRef.current && initialMountedRef.current; } return key === keyRef.current; }; const finalState = { isValidating: false, isLoading: false }; const finishRequestAndUpdateState = () => { setCache(finalState); }; const cleanupState = () => { const requestInfo = FETCH[key]; if (requestInfo && requestInfo[1] === startAt) { delete FETCH[key]; } }; const initialState = { isValidating: true }; if (isUndefined(getCache().data)) { initialState.isLoading = true; } try { if (shouldStartNewRequest) { setCache(initialState); if (config.loadingTimeout && isUndefined(getCache().data)) { setTimeout(() => { if (loading && callbackSafeguard()) { getConfig().onLoadingSlow(key, config); } }, config.loadingTimeout); } FETCH[key] = [ currentFetcher(fnArg), getTimestamp() ]; } [newData, startAt] = FETCH[key]; newData = await newData; if (shouldStartNewRequest) { setTimeout(cleanupState, config.dedupingInterval); } if (!FETCH[key] || FETCH[key][1] !== startAt) { if (shouldStartNewRequest) { if (callbackSafeguard()) { getConfig().onDiscarded(key); } } return false; } finalState.error = UNDEFINED; const mutationInfo = MUTATION[key]; if (!isUndefined(mutationInfo) && // case 1 (startAt <= mutationInfo[0] || // case 2 startAt <= mutationInfo[1] || // case 3 mutationInfo[1] === 0)) { finishRequestAndUpdateState(); if (shouldStartNewRequest) { if (callbackSafeguard()) { getConfig().onDiscarded(key); } } return false; } const cacheData = getCache().data; finalState.data = compare2(cacheData, newData) ? cacheData : newData; if (shouldStartNewRequest) { if (callbackSafeguard()) { getConfig().onSuccess(newData, key, config); } } } catch (err) { cleanupState(); const currentConfig = getConfig(); const { shouldRetryOnError } = currentConfig; if (!currentConfig.isPaused()) { finalState.error = err; if (shouldStartNewRequest && callbackSafeguard()) { currentConfig.onError(err, key, currentConfig); if (shouldRetryOnError === true || isFunction(shouldRetryOnError) && shouldRetryOnError(err)) { if (!getConfig().revalidateOnFocus || !getConfig().revalidateOnReconnect || isActive()) { currentConfig.onErrorRetry(err, key, currentConfig, (_opts) => { const revalidators = EVENT_REVALIDATORS[key]; if (revalidators && revalidators[0]) { revalidators[0](events.ERROR_REVALIDATE_EVENT, _opts); } }, { retryCount: (opts.retryCount || 0) + 1, dedupe: true }); } } } } } loading = false; finishRequestAndUpdateState(); return true; }, // `setState` is immutable, and `eventsCallback`, `fnArg`, and // `keyValidating` are depending on `key`, so we can exclude them from // the deps array. // // FIXME: // `fn` and `config` might be changed during the lifecycle, // but they might be changed every render like this. // `useSWR('key', () => fetch('/api/'), { suspense: true })` // So we omit the values from the deps array // even though it might cause unexpected behaviors. // eslint-disable-next-line react-hooks/exhaustive-deps [ key, cache2 ] ); const boundMutate = React8.useCallback( // Use callback to make sure `keyRef.current` returns latest result every time (...args) => { return internalMutate(cache2, keyRef.current, ...args); }, // eslint-disable-next-line react-hooks/exhaustive-deps [] ); useIsomorphicLayoutEffect(() => { fetcherRef.current = fetcher; configRef.current = config; if (!isUndefined(cachedData)) { laggyDataRef.current = cachedData; } }); useIsomorphicLayoutEffect(() => { if (!key) return; const softRevalidate = revalidate.bind(UNDEFINED, WITH_DEDUPE2); let nextFocusRevalidatedAt = 0; const onRevalidate = (type, opts = {}) => { if (type == events.FOCUS_EVENT) { const now = Date.now(); if (getConfig().revalidateOnFocus && now > nextFocusRevalidatedAt && isActive()) { nextFocusRevalidatedAt = now + getConfig().focusThrottleInterval; softRevalidate(); } } else if (type == events.RECONNECT_EVENT) { if (getConfig().revalidateOnReconnect && isActive()) { softRevalidate(); } } else if (type == events.MUTATE_EVENT) { return revalidate(); } else if (type == events.ERROR_REVALIDATE_EVENT) { return revalidate(opts); } return; }; const unsubEvents = subscribeCallback(key, EVENT_REVALIDATORS, onRevalidate); unmountedRef.current = false; keyRef.current = key; initialMountedRef.current = true; setCache({ _k: fnArg }); if (shouldDoInitialRevalidation) { if (isUndefined(data) || IS_SERVER) { softRevalidate(); } else { rAF(softRevalidate); } } return () => { unmountedRef.current = true; unsubEvents(); }; }, [ key ]); useIsomorphicLayoutEffect(() => { let timer; function next() { const interval = isFunction(refreshInterval) ? refreshInterval(getCache().data) : refreshInterval; if (interval && timer !== -1) { timer = setTimeout(execute, interval); } } function execute() { if (!getCache().error && (refreshWhenHidden || getConfig().isVisible()) && (refreshWhenOffline || getConfig().isOnline())) { revalidate(WITH_DEDUPE2).then(next); } else { next(); } } next(); return () => { if (timer) { clearTimeout(timer); timer = -1; } }; }, [ refreshInterval, refreshWhenHidden, refreshWhenOffline, key ]); React8.useDebugValue(returnedData); if (suspense &&