| "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| var __typeError = (msg) => { |
| throw TypeError(msg); |
| }; |
| var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg); |
| var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj)); |
| var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value); |
|
|
| |
| var Action = ((Action2) => { |
| Action2["Pop"] = "POP"; |
| Action2["Push"] = "PUSH"; |
| Action2["Replace"] = "REPLACE"; |
| return Action2; |
| })(Action || {}); |
| var PopStateEventType = "popstate"; |
| function isLocation(obj) { |
| return typeof obj === "object" && obj != null && "pathname" in obj && "search" in obj && "hash" in obj && "state" in obj && "key" in obj; |
| } |
| function createMemoryHistory(options = {}) { |
| let { initialEntries = ["/"], initialIndex, v5Compat = false } = options; |
| let entries; |
| entries = initialEntries.map( |
| (entry, index2) => createMemoryLocation( |
| entry, |
| typeof entry === "string" ? null : entry.state, |
| index2 === 0 ? "default" : void 0, |
| typeof entry === "string" ? void 0 : entry.unstable_mask |
| ) |
| ); |
| let index = clampIndex( |
| initialIndex == null ? entries.length - 1 : initialIndex |
| ); |
| let action = "POP" ; |
| let listener = null; |
| function clampIndex(n) { |
| return Math.min(Math.max(n, 0), entries.length - 1); |
| } |
| function getCurrentLocation() { |
| return entries[index]; |
| } |
| function createMemoryLocation(to, state = null, key, unstable_mask) { |
| let location = createLocation( |
| entries ? getCurrentLocation().pathname : "/", |
| to, |
| state, |
| key, |
| unstable_mask |
| ); |
| warning( |
| location.pathname.charAt(0) === "/", |
| `relative pathnames are not supported in memory history: ${JSON.stringify( |
| to |
| )}` |
| ); |
| return location; |
| } |
| function createHref(to) { |
| return typeof to === "string" ? to : createPath(to); |
| } |
| let history = { |
| get index() { |
| return index; |
| }, |
| get action() { |
| return action; |
| }, |
| get location() { |
| return getCurrentLocation(); |
| }, |
| createHref, |
| createURL(to) { |
| return new URL(createHref(to), "http://localhost"); |
| }, |
| encodeLocation(to) { |
| let path = typeof to === "string" ? parsePath(to) : to; |
| return { |
| pathname: path.pathname || "", |
| search: path.search || "", |
| hash: path.hash || "" |
| }; |
| }, |
| push(to, state) { |
| action = "PUSH" ; |
| let nextLocation = isLocation(to) ? to : createMemoryLocation(to, state); |
| index += 1; |
| entries.splice(index, entries.length, nextLocation); |
| if (v5Compat && listener) { |
| listener({ action, location: nextLocation, delta: 1 }); |
| } |
| }, |
| replace(to, state) { |
| action = "REPLACE" ; |
| let nextLocation = isLocation(to) ? to : createMemoryLocation(to, state); |
| entries[index] = nextLocation; |
| if (v5Compat && listener) { |
| listener({ action, location: nextLocation, delta: 0 }); |
| } |
| }, |
| go(delta) { |
| action = "POP" ; |
| let nextIndex = clampIndex(index + delta); |
| let nextLocation = entries[nextIndex]; |
| index = nextIndex; |
| if (listener) { |
| listener({ action, location: nextLocation, delta }); |
| } |
| }, |
| listen(fn) { |
| listener = fn; |
| return () => { |
| listener = null; |
| }; |
| } |
| }; |
| return history; |
| } |
| function createBrowserHistory(options = {}) { |
| function createBrowserLocation(window2, globalHistory) { |
| let maskedLocation = _optionalChain([globalHistory, 'access', _2 => _2.state, 'optionalAccess', _3 => _3.masked]); |
| let { pathname, search, hash } = maskedLocation || window2.location; |
| return createLocation( |
| "", |
| { pathname, search, hash }, |
| |
| globalHistory.state && globalHistory.state.usr || null, |
| globalHistory.state && globalHistory.state.key || "default", |
| maskedLocation ? { |
| pathname: window2.location.pathname, |
| search: window2.location.search, |
| hash: window2.location.hash |
| } : void 0 |
| ); |
| } |
| function createBrowserHref(window2, to) { |
| return typeof to === "string" ? to : createPath(to); |
| } |
| return getUrlBasedHistory( |
| createBrowserLocation, |
| createBrowserHref, |
| null, |
| options |
| ); |
| } |
| function createHashHistory(options = {}) { |
| function createHashLocation(window2, globalHistory) { |
| let { |
| pathname = "/", |
| search = "", |
| hash = "" |
| } = parsePath(window2.location.hash.substring(1)); |
| if (!pathname.startsWith("/") && !pathname.startsWith(".")) { |
| pathname = "/" + pathname; |
| } |
| return createLocation( |
| "", |
| { pathname, search, hash }, |
| |
| globalHistory.state && globalHistory.state.usr || null, |
| globalHistory.state && globalHistory.state.key || "default" |
| ); |
| } |
| function createHashHref(window2, to) { |
| let base = window2.document.querySelector("base"); |
| let href = ""; |
| if (base && base.getAttribute("href")) { |
| let url = window2.location.href; |
| let hashIndex = url.indexOf("#"); |
| href = hashIndex === -1 ? url : url.slice(0, hashIndex); |
| } |
| return href + "#" + (typeof to === "string" ? to : createPath(to)); |
| } |
| function validateHashLocation(location, to) { |
| warning( |
| location.pathname.charAt(0) === "/", |
| `relative pathnames are not supported in hash history.push(${JSON.stringify( |
| to |
| )})` |
| ); |
| } |
| return getUrlBasedHistory( |
| createHashLocation, |
| createHashHref, |
| validateHashLocation, |
| options |
| ); |
| } |
| function invariant(value, message) { |
| if (value === false || value === null || typeof value === "undefined") { |
| throw new Error(message); |
| } |
| } |
| function warning(cond, message) { |
| if (!cond) { |
| if (typeof console !== "undefined") console.warn(message); |
| try { |
| throw new Error(message); |
| } catch (e) { |
| } |
| } |
| } |
| function createKey() { |
| return Math.random().toString(36).substring(2, 10); |
| } |
| function getHistoryState(location, index) { |
| return { |
| usr: location.state, |
| key: location.key, |
| idx: index, |
| masked: location.unstable_mask ? { |
| pathname: location.pathname, |
| search: location.search, |
| hash: location.hash |
| } : void 0 |
| }; |
| } |
| function createLocation(current, to, state = null, key, unstable_mask) { |
| let location = { |
| pathname: typeof current === "string" ? current : current.pathname, |
| search: "", |
| hash: "", |
| ...typeof to === "string" ? parsePath(to) : to, |
| state, |
| |
| |
| |
| |
| key: to && to.key || key || createKey(), |
| unstable_mask |
| }; |
| return location; |
| } |
| function createPath({ |
| pathname = "/", |
| search = "", |
| hash = "" |
| }) { |
| if (search && search !== "?") |
| pathname += search.charAt(0) === "?" ? search : "?" + search; |
| if (hash && hash !== "#") |
| pathname += hash.charAt(0) === "#" ? hash : "#" + hash; |
| return pathname; |
| } |
| function parsePath(path) { |
| let parsedPath = {}; |
| if (path) { |
| let hashIndex = path.indexOf("#"); |
| if (hashIndex >= 0) { |
| parsedPath.hash = path.substring(hashIndex); |
| path = path.substring(0, hashIndex); |
| } |
| let searchIndex = path.indexOf("?"); |
| if (searchIndex >= 0) { |
| parsedPath.search = path.substring(searchIndex); |
| path = path.substring(0, searchIndex); |
| } |
| if (path) { |
| parsedPath.pathname = path; |
| } |
| } |
| return parsedPath; |
| } |
| function getUrlBasedHistory(getLocation, createHref, validateLocation, options = {}) { |
| let { window: window2 = document.defaultView, v5Compat = false } = options; |
| let globalHistory = window2.history; |
| let action = "POP" ; |
| let listener = null; |
| let index = getIndex(); |
| if (index == null) { |
| index = 0; |
| globalHistory.replaceState({ ...globalHistory.state, idx: index }, ""); |
| } |
| function getIndex() { |
| let state = globalHistory.state || { idx: null }; |
| return state.idx; |
| } |
| function handlePop() { |
| action = "POP" ; |
| let nextIndex = getIndex(); |
| let delta = nextIndex == null ? null : nextIndex - index; |
| index = nextIndex; |
| if (listener) { |
| listener({ action, location: history.location, delta }); |
| } |
| } |
| function push(to, state) { |
| action = "PUSH" ; |
| let location = isLocation(to) ? to : createLocation(history.location, to, state); |
| if (validateLocation) validateLocation(location, to); |
| index = getIndex() + 1; |
| let historyState = getHistoryState(location, index); |
| let url = history.createHref(location.unstable_mask || location); |
| try { |
| globalHistory.pushState(historyState, "", url); |
| } catch (error) { |
| if (error instanceof DOMException && error.name === "DataCloneError") { |
| throw error; |
| } |
| window2.location.assign(url); |
| } |
| if (v5Compat && listener) { |
| listener({ action, location: history.location, delta: 1 }); |
| } |
| } |
| function replace2(to, state) { |
| action = "REPLACE" ; |
| let location = isLocation(to) ? to : createLocation(history.location, to, state); |
| if (validateLocation) validateLocation(location, to); |
| index = getIndex(); |
| let historyState = getHistoryState(location, index); |
| let url = history.createHref(location.unstable_mask || location); |
| globalHistory.replaceState(historyState, "", url); |
| if (v5Compat && listener) { |
| listener({ action, location: history.location, delta: 0 }); |
| } |
| } |
| function createURL(to) { |
| return createBrowserURLImpl(to); |
| } |
| let history = { |
| get action() { |
| return action; |
| }, |
| get location() { |
| return getLocation(window2, globalHistory); |
| }, |
| listen(fn) { |
| if (listener) { |
| throw new Error("A history only accepts one active listener"); |
| } |
| window2.addEventListener(PopStateEventType, handlePop); |
| listener = fn; |
| return () => { |
| window2.removeEventListener(PopStateEventType, handlePop); |
| listener = null; |
| }; |
| }, |
| createHref(to) { |
| return createHref(window2, to); |
| }, |
| createURL, |
| encodeLocation(to) { |
| let url = createURL(to); |
| return { |
| pathname: url.pathname, |
| search: url.search, |
| hash: url.hash |
| }; |
| }, |
| push, |
| replace: replace2, |
| go(n) { |
| return globalHistory.go(n); |
| } |
| }; |
| return history; |
| } |
| function createBrowserURLImpl(to, isAbsolute = false) { |
| let base = "http://localhost"; |
| if (typeof window !== "undefined") { |
| base = window.location.origin !== "null" ? window.location.origin : window.location.href; |
| } |
| invariant(base, "No window.location.(origin|href) available to create URL"); |
| let href = typeof to === "string" ? to : createPath(to); |
| href = href.replace(/ $/, "%20"); |
| if (!isAbsolute && href.startsWith("//")) { |
| href = base + href; |
| } |
| return new URL(href, base); |
| } |
|
|
| |
| function createContext(defaultValue) { |
| return { defaultValue }; |
| } |
| var _map; |
| var RouterContextProvider = class { |
| |
| |
| |
| |
| constructor(init) { |
| __privateAdd(this, _map, new Map()); |
| if (init) { |
| for (let [context, value] of init) { |
| this.set(context, value); |
| } |
| } |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| get(context) { |
| if (__privateGet(this, _map).has(context)) { |
| return __privateGet(this, _map).get(context); |
| } |
| if (context.defaultValue !== void 0) { |
| return context.defaultValue; |
| } |
| throw new Error("No value found for context"); |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| set(context, value) { |
| __privateGet(this, _map).set(context, value); |
| } |
| }; |
| _map = new WeakMap(); |
| var unsupportedLazyRouteObjectKeys = new Set([ |
| "lazy", |
| "caseSensitive", |
| "path", |
| "id", |
| "index", |
| "children" |
| ]); |
| function isUnsupportedLazyRouteObjectKey(key) { |
| return unsupportedLazyRouteObjectKeys.has( |
| key |
| ); |
| } |
| var unsupportedLazyRouteFunctionKeys = new Set([ |
| "lazy", |
| "caseSensitive", |
| "path", |
| "id", |
| "index", |
| "middleware", |
| "children" |
| ]); |
| function isUnsupportedLazyRouteFunctionKey(key) { |
| return unsupportedLazyRouteFunctionKeys.has( |
| key |
| ); |
| } |
| function isIndexRoute(route) { |
| return route.index === true; |
| } |
| function convertRoutesToDataRoutes(routes, mapRouteProperties2, parentPath = [], manifest = {}, allowInPlaceMutations = false) { |
| return routes.map((route, index) => { |
| let treePath = [...parentPath, String(index)]; |
| let id = typeof route.id === "string" ? route.id : treePath.join("-"); |
| invariant( |
| route.index !== true || !route.children, |
| `Cannot specify children on an index route` |
| ); |
| invariant( |
| allowInPlaceMutations || !manifest[id], |
| `Found a route id collision on id "${id}". Route id's must be globally unique within Data Router usages` |
| ); |
| if (isIndexRoute(route)) { |
| let indexRoute = { |
| ...route, |
| id |
| }; |
| manifest[id] = mergeRouteUpdates( |
| indexRoute, |
| mapRouteProperties2(indexRoute) |
| ); |
| return indexRoute; |
| } else { |
| let pathOrLayoutRoute = { |
| ...route, |
| id, |
| children: void 0 |
| }; |
| manifest[id] = mergeRouteUpdates( |
| pathOrLayoutRoute, |
| mapRouteProperties2(pathOrLayoutRoute) |
| ); |
| if (route.children) { |
| pathOrLayoutRoute.children = convertRoutesToDataRoutes( |
| route.children, |
| mapRouteProperties2, |
| treePath, |
| manifest, |
| allowInPlaceMutations |
| ); |
| } |
| return pathOrLayoutRoute; |
| } |
| }); |
| } |
| function mergeRouteUpdates(route, updates) { |
| return Object.assign(route, { |
| ...updates, |
| ...typeof updates.lazy === "object" && updates.lazy != null ? { |
| lazy: { |
| ...route.lazy, |
| ...updates.lazy |
| } |
| } : {} |
| }); |
| } |
| function matchRoutes(routes, locationArg, basename = "/") { |
| return matchRoutesImpl(routes, locationArg, basename, false); |
| } |
| function matchRoutesImpl(routes, locationArg, basename, allowPartial) { |
| let location = typeof locationArg === "string" ? parsePath(locationArg) : locationArg; |
| let pathname = stripBasename(location.pathname || "/", basename); |
| if (pathname == null) { |
| return null; |
| } |
| let branches = flattenRoutes(routes); |
| rankRouteBranches(branches); |
| let matches = null; |
| for (let i = 0; matches == null && i < branches.length; ++i) { |
| let decoded = decodePath(pathname); |
| matches = matchRouteBranch( |
| branches[i], |
| decoded, |
| allowPartial |
| ); |
| } |
| return matches; |
| } |
| function convertRouteMatchToUiMatch(match, loaderData) { |
| let { route, pathname, params } = match; |
| return { |
| id: route.id, |
| pathname, |
| params, |
| data: loaderData[route.id], |
| loaderData: loaderData[route.id], |
| handle: route.handle |
| }; |
| } |
| function flattenRoutes(routes, branches = [], parentsMeta = [], parentPath = "", _hasParentOptionalSegments = false) { |
| let flattenRoute = (route, index, hasParentOptionalSegments = _hasParentOptionalSegments, relativePath) => { |
| let meta = { |
| relativePath: relativePath === void 0 ? route.path || "" : relativePath, |
| caseSensitive: route.caseSensitive === true, |
| childrenIndex: index, |
| route |
| }; |
| if (meta.relativePath.startsWith("/")) { |
| if (!meta.relativePath.startsWith(parentPath) && hasParentOptionalSegments) { |
| return; |
| } |
| invariant( |
| meta.relativePath.startsWith(parentPath), |
| `Absolute route path "${meta.relativePath}" nested under path "${parentPath}" is not valid. An absolute child route path must start with the combined path of all its parent routes.` |
| ); |
| meta.relativePath = meta.relativePath.slice(parentPath.length); |
| } |
| let path = joinPaths([parentPath, meta.relativePath]); |
| let routesMeta = parentsMeta.concat(meta); |
| if (route.children && route.children.length > 0) { |
| invariant( |
| |
| |
| route.index !== true, |
| `Index routes must not have child routes. Please remove all child routes from route path "${path}".` |
| ); |
| flattenRoutes( |
| route.children, |
| branches, |
| routesMeta, |
| path, |
| hasParentOptionalSegments |
| ); |
| } |
| if (route.path == null && !route.index) { |
| return; |
| } |
| branches.push({ |
| path, |
| score: computeScore(path, route.index), |
| routesMeta |
| }); |
| }; |
| routes.forEach((route, index) => { |
| if (route.path === "" || !_optionalChain([route, 'access', _4 => _4.path, 'optionalAccess', _5 => _5.includes, 'call', _6 => _6("?")])) { |
| flattenRoute(route, index); |
| } else { |
| for (let exploded of explodeOptionalSegments(route.path)) { |
| flattenRoute(route, index, true, exploded); |
| } |
| } |
| }); |
| return branches; |
| } |
| function explodeOptionalSegments(path) { |
| let segments = path.split("/"); |
| if (segments.length === 0) return []; |
| let [first, ...rest] = segments; |
| let isOptional = first.endsWith("?"); |
| let required = first.replace(/\?$/, ""); |
| if (rest.length === 0) { |
| return isOptional ? [required, ""] : [required]; |
| } |
| let restExploded = explodeOptionalSegments(rest.join("/")); |
| let result = []; |
| result.push( |
| ...restExploded.map( |
| (subpath) => subpath === "" ? required : [required, subpath].join("/") |
| ) |
| ); |
| if (isOptional) { |
| result.push(...restExploded); |
| } |
| return result.map( |
| (exploded) => path.startsWith("/") && exploded === "" ? "/" : exploded |
| ); |
| } |
| function rankRouteBranches(branches) { |
| branches.sort( |
| (a, b) => a.score !== b.score ? b.score - a.score : compareIndexes( |
| a.routesMeta.map((meta) => meta.childrenIndex), |
| b.routesMeta.map((meta) => meta.childrenIndex) |
| ) |
| ); |
| } |
| var paramRe = /^:[\w-]+$/; |
| var dynamicSegmentValue = 3; |
| var indexRouteValue = 2; |
| var emptySegmentValue = 1; |
| var staticSegmentValue = 10; |
| var splatPenalty = -2; |
| var isSplat = (s) => s === "*"; |
| function computeScore(path, index) { |
| let segments = path.split("/"); |
| let initialScore = segments.length; |
| if (segments.some(isSplat)) { |
| initialScore += splatPenalty; |
| } |
| if (index) { |
| initialScore += indexRouteValue; |
| } |
| return segments.filter((s) => !isSplat(s)).reduce( |
| (score, segment) => score + (paramRe.test(segment) ? dynamicSegmentValue : segment === "" ? emptySegmentValue : staticSegmentValue), |
| initialScore |
| ); |
| } |
| function compareIndexes(a, b) { |
| let siblings = a.length === b.length && a.slice(0, -1).every((n, i) => n === b[i]); |
| return siblings ? ( |
| |
| |
| |
| |
| a[a.length - 1] - b[b.length - 1] |
| ) : ( |
| |
| |
| 0 |
| ); |
| } |
| function matchRouteBranch(branch, pathname, allowPartial = false) { |
| let { routesMeta } = branch; |
| let matchedParams = {}; |
| let matchedPathname = "/"; |
| let matches = []; |
| for (let i = 0; i < routesMeta.length; ++i) { |
| let meta = routesMeta[i]; |
| let end = i === routesMeta.length - 1; |
| let remainingPathname = matchedPathname === "/" ? pathname : pathname.slice(matchedPathname.length) || "/"; |
| let match = matchPath( |
| { path: meta.relativePath, caseSensitive: meta.caseSensitive, end }, |
| remainingPathname |
| ); |
| let route = meta.route; |
| if (!match && end && allowPartial && !routesMeta[routesMeta.length - 1].route.index) { |
| match = matchPath( |
| { |
| path: meta.relativePath, |
| caseSensitive: meta.caseSensitive, |
| end: false |
| }, |
| remainingPathname |
| ); |
| } |
| if (!match) { |
| return null; |
| } |
| Object.assign(matchedParams, match.params); |
| matches.push({ |
| |
| params: matchedParams, |
| pathname: joinPaths([matchedPathname, match.pathname]), |
| pathnameBase: normalizePathname( |
| joinPaths([matchedPathname, match.pathnameBase]) |
| ), |
| route |
| }); |
| if (match.pathnameBase !== "/") { |
| matchedPathname = joinPaths([matchedPathname, match.pathnameBase]); |
| } |
| } |
| return matches; |
| } |
| function generatePath(originalPath, params = {}) { |
| let path = originalPath; |
| if (path.endsWith("*") && path !== "*" && !path.endsWith("/*")) { |
| warning( |
| false, |
| `Route path "${path}" will be treated as if it were "${path.replace(/\*$/, "/*")}" because the \`*\` character must always follow a \`/\` in the pattern. To get rid of this warning, please change the route path to "${path.replace(/\*$/, "/*")}".` |
| ); |
| path = path.replace(/\*$/, "/*"); |
| } |
| const prefix = path.startsWith("/") ? "/" : ""; |
| const stringify2 = (p) => p == null ? "" : typeof p === "string" ? p : String(p); |
| const segments = path.split(/\/+/).map((segment, index, array) => { |
| const isLastSegment = index === array.length - 1; |
| if (isLastSegment && segment === "*") { |
| return stringify2(params["*"]); |
| } |
| const keyMatch = segment.match(/^:([\w-]+)(\??)(.*)/); |
| if (keyMatch) { |
| const [, key, optional, suffix] = keyMatch; |
| let param = params[key]; |
| invariant(optional === "?" || param != null, `Missing ":${key}" param`); |
| return encodeURIComponent(stringify2(param)) + suffix; |
| } |
| return segment.replace(/\?$/g, ""); |
| }).filter((segment) => !!segment); |
| return prefix + segments.join("/"); |
| } |
| function matchPath(pattern, pathname) { |
| if (typeof pattern === "string") { |
| pattern = { path: pattern, caseSensitive: false, end: true }; |
| } |
| let [matcher, compiledParams] = compilePath( |
| pattern.path, |
| pattern.caseSensitive, |
| pattern.end |
| ); |
| let match = pathname.match(matcher); |
| if (!match) return null; |
| let matchedPathname = match[0]; |
| let pathnameBase = matchedPathname.replace(/(.)\/+$/, "$1"); |
| let captureGroups = match.slice(1); |
| let params = compiledParams.reduce( |
| (memo2, { paramName, isOptional }, index) => { |
| if (paramName === "*") { |
| let splatValue = captureGroups[index] || ""; |
| pathnameBase = matchedPathname.slice(0, matchedPathname.length - splatValue.length).replace(/(.)\/+$/, "$1"); |
| } |
| const value = captureGroups[index]; |
| if (isOptional && !value) { |
| memo2[paramName] = void 0; |
| } else { |
| memo2[paramName] = (value || "").replace(/%2F/g, "/"); |
| } |
| return memo2; |
| }, |
| {} |
| ); |
| return { |
| params, |
| pathname: matchedPathname, |
| pathnameBase, |
| pattern |
| }; |
| } |
| function compilePath(path, caseSensitive = false, end = true) { |
| warning( |
| path === "*" || !path.endsWith("*") || path.endsWith("/*"), |
| `Route path "${path}" will be treated as if it were "${path.replace(/\*$/, "/*")}" because the \`*\` character must always follow a \`/\` in the pattern. To get rid of this warning, please change the route path to "${path.replace(/\*$/, "/*")}".` |
| ); |
| let params = []; |
| let regexpSource = "^" + path.replace(/\/*\*?$/, "").replace(/^\/*/, "/").replace(/[\\.*+^${}|()[\]]/g, "\\$&").replace( |
| /\/:([\w-]+)(\?)?/g, |
| (match, paramName, isOptional, index, str) => { |
| params.push({ paramName, isOptional: isOptional != null }); |
| if (isOptional) { |
| let nextChar = str.charAt(index + match.length); |
| if (nextChar && nextChar !== "/") { |
| return "/([^\\/]*)"; |
| } |
| return "(?:/([^\\/]*))?"; |
| } |
| return "/([^\\/]+)"; |
| } |
| ).replace(/\/([\w-]+)\?(\/|$)/g, "(/$1)?$2"); |
| if (path.endsWith("*")) { |
| params.push({ paramName: "*" }); |
| regexpSource += path === "*" || path === "/*" ? "(.*)$" : "(?:\\/(.+)|\\/*)$"; |
| } else if (end) { |
| regexpSource += "\\/*$"; |
| } else if (path !== "" && path !== "/") { |
| regexpSource += "(?:(?=\\/|$))"; |
| } else { |
| } |
| let matcher = new RegExp(regexpSource, caseSensitive ? void 0 : "i"); |
| return [matcher, params]; |
| } |
| function decodePath(value) { |
| try { |
| return value.split("/").map((v) => decodeURIComponent(v).replace(/\//g, "%2F")).join("/"); |
| } catch (error) { |
| warning( |
| false, |
| `The URL path "${value}" could not be decoded because it is a malformed URL segment. This is probably due to a bad percent encoding (${error}).` |
| ); |
| return value; |
| } |
| } |
| function stripBasename(pathname, basename) { |
| if (basename === "/") return pathname; |
| if (!pathname.toLowerCase().startsWith(basename.toLowerCase())) { |
| return null; |
| } |
| let startIndex = basename.endsWith("/") ? basename.length - 1 : basename.length; |
| let nextChar = pathname.charAt(startIndex); |
| if (nextChar && nextChar !== "/") { |
| return null; |
| } |
| return pathname.slice(startIndex) || "/"; |
| } |
| function prependBasename({ |
| basename, |
| pathname |
| }) { |
| return pathname === "/" ? basename : joinPaths([basename, pathname]); |
| } |
| var ABSOLUTE_URL_REGEX = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i; |
| var isAbsoluteUrl = (url) => ABSOLUTE_URL_REGEX.test(url); |
| function resolvePath(to, fromPathname = "/") { |
| let { |
| pathname: toPathname, |
| search = "", |
| hash = "" |
| } = typeof to === "string" ? parsePath(to) : to; |
| let pathname; |
| if (toPathname) { |
| toPathname = removeDoubleSlashes(toPathname); |
| if (toPathname.startsWith("/")) { |
| pathname = resolvePathname(toPathname.substring(1), "/"); |
| } else { |
| pathname = resolvePathname(toPathname, fromPathname); |
| } |
| } else { |
| pathname = fromPathname; |
| } |
| return { |
| pathname, |
| search: normalizeSearch(search), |
| hash: normalizeHash(hash) |
| }; |
| } |
| function resolvePathname(relativePath, fromPathname) { |
| let segments = removeTrailingSlash(fromPathname).split("/"); |
| let relativeSegments = relativePath.split("/"); |
| relativeSegments.forEach((segment) => { |
| if (segment === "..") { |
| if (segments.length > 1) segments.pop(); |
| } else if (segment !== ".") { |
| segments.push(segment); |
| } |
| }); |
| return segments.length > 1 ? segments.join("/") : "/"; |
| } |
| function getInvalidPathError(char, field, dest, path) { |
| return `Cannot include a '${char}' character in a manually specified \`to.${field}\` field [${JSON.stringify( |
| path |
| )}]. Please separate it out to the \`to.${dest}\` field. Alternatively you may provide the full path as a string in <Link to="..."> and the router will parse it for you.`; |
| } |
| function getPathContributingMatches(matches) { |
| return matches.filter( |
| (match, index) => index === 0 || match.route.path && match.route.path.length > 0 |
| ); |
| } |
| function getResolveToMatches(matches) { |
| let pathMatches = getPathContributingMatches(matches); |
| return pathMatches.map( |
| (match, idx) => idx === pathMatches.length - 1 ? match.pathname : match.pathnameBase |
| ); |
| } |
| function resolveTo(toArg, routePathnames, locationPathname, isPathRelative = false) { |
| let to; |
| if (typeof toArg === "string") { |
| to = parsePath(toArg); |
| } else { |
| to = { ...toArg }; |
| invariant( |
| !to.pathname || !to.pathname.includes("?"), |
| getInvalidPathError("?", "pathname", "search", to) |
| ); |
| invariant( |
| !to.pathname || !to.pathname.includes("#"), |
| getInvalidPathError("#", "pathname", "hash", to) |
| ); |
| invariant( |
| !to.search || !to.search.includes("#"), |
| getInvalidPathError("#", "search", "hash", to) |
| ); |
| } |
| let isEmptyPath = toArg === "" || to.pathname === ""; |
| let toPathname = isEmptyPath ? "/" : to.pathname; |
| let from; |
| if (toPathname == null) { |
| from = locationPathname; |
| } else { |
| let routePathnameIndex = routePathnames.length - 1; |
| if (!isPathRelative && toPathname.startsWith("..")) { |
| let toSegments = toPathname.split("/"); |
| while (toSegments[0] === "..") { |
| toSegments.shift(); |
| routePathnameIndex -= 1; |
| } |
| to.pathname = toSegments.join("/"); |
| } |
| from = routePathnameIndex >= 0 ? routePathnames[routePathnameIndex] : "/"; |
| } |
| let path = resolvePath(to, from); |
| let hasExplicitTrailingSlash = toPathname && toPathname !== "/" && toPathname.endsWith("/"); |
| let hasCurrentTrailingSlash = (isEmptyPath || toPathname === ".") && locationPathname.endsWith("/"); |
| if (!path.pathname.endsWith("/") && (hasExplicitTrailingSlash || hasCurrentTrailingSlash)) { |
| path.pathname += "/"; |
| } |
| return path; |
| } |
| var removeDoubleSlashes = (path) => path.replace(/\/\/+/g, "/"); |
| var joinPaths = (paths) => removeDoubleSlashes(paths.join("/")); |
| var removeTrailingSlash = (path) => path.replace(/\/+$/, ""); |
| var normalizePathname = (pathname) => removeTrailingSlash(pathname).replace(/^\/*/, "/"); |
| var normalizeSearch = (search) => !search || search === "?" ? "" : search.startsWith("?") ? search : "?" + search; |
| var normalizeHash = (hash) => !hash || hash === "#" ? "" : hash.startsWith("#") ? hash : "#" + hash; |
| var DataWithResponseInit = class { |
| constructor(data2, init) { |
| this.type = "DataWithResponseInit"; |
| this.data = data2; |
| this.init = init || null; |
| } |
| }; |
| function data(data2, init) { |
| return new DataWithResponseInit( |
| data2, |
| typeof init === "number" ? { status: init } : init |
| ); |
| } |
| var redirect = (url, init = 302) => { |
| let responseInit = init; |
| if (typeof responseInit === "number") { |
| responseInit = { status: responseInit }; |
| } else if (typeof responseInit.status === "undefined") { |
| responseInit.status = 302; |
| } |
| let headers = new Headers(responseInit.headers); |
| headers.set("Location", url); |
| return new Response(null, { ...responseInit, headers }); |
| }; |
| var redirectDocument = (url, init) => { |
| let response = redirect(url, init); |
| response.headers.set("X-Remix-Reload-Document", "true"); |
| return response; |
| }; |
| var replace = (url, init) => { |
| let response = redirect(url, init); |
| response.headers.set("X-Remix-Replace", "true"); |
| return response; |
| }; |
| var ErrorResponseImpl = class { |
| constructor(status, statusText, data2, internal = false) { |
| this.status = status; |
| this.statusText = statusText || ""; |
| this.internal = internal; |
| if (data2 instanceof Error) { |
| this.data = data2.toString(); |
| this.error = data2; |
| } else { |
| this.data = data2; |
| } |
| } |
| }; |
| function isRouteErrorResponse(error) { |
| return error != null && typeof error.status === "number" && typeof error.statusText === "string" && typeof error.internal === "boolean" && "data" in error; |
| } |
| function getRoutePattern(matches) { |
| let parts = matches.map((m) => m.route.path).filter(Boolean); |
| return joinPaths(parts) || "/"; |
| } |
| var isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined"; |
| function parseToInfo(_to, basename) { |
| let to = _to; |
| if (typeof to !== "string" || !ABSOLUTE_URL_REGEX.test(to)) { |
| return { |
| absoluteURL: void 0, |
| isExternal: false, |
| to |
| }; |
| } |
| let absoluteURL = to; |
| let isExternal = false; |
| if (isBrowser) { |
| try { |
| let currentUrl = new URL(window.location.href); |
| let targetUrl = to.startsWith("//") ? new URL(currentUrl.protocol + to) : new URL(to); |
| let path = stripBasename(targetUrl.pathname, basename); |
| if (targetUrl.origin === currentUrl.origin && path != null) { |
| to = path + targetUrl.search + targetUrl.hash; |
| } else { |
| isExternal = true; |
| } |
| } catch (e) { |
| warning( |
| false, |
| `<Link to="${to}"> contains an invalid URL which will probably break when clicked - please update to a valid URL path.` |
| ); |
| } |
| } |
| return { |
| absoluteURL, |
| isExternal, |
| to |
| }; |
| } |
|
|
| |
| var UninstrumentedSymbol = Symbol("Uninstrumented"); |
| function getRouteInstrumentationUpdates(fns, route) { |
| let aggregated = { |
| lazy: [], |
| "lazy.loader": [], |
| "lazy.action": [], |
| "lazy.middleware": [], |
| middleware: [], |
| loader: [], |
| action: [] |
| }; |
| fns.forEach( |
| (fn) => fn({ |
| id: route.id, |
| index: route.index, |
| path: route.path, |
| instrument(i) { |
| let keys = Object.keys(aggregated); |
| for (let key of keys) { |
| if (i[key]) { |
| aggregated[key].push(i[key]); |
| } |
| } |
| } |
| }) |
| ); |
| let updates = {}; |
| if (typeof route.lazy === "function" && aggregated.lazy.length > 0) { |
| let instrumented = wrapImpl(aggregated.lazy, route.lazy, () => void 0); |
| if (instrumented) { |
| updates.lazy = instrumented; |
| } |
| } |
| if (typeof route.lazy === "object") { |
| let lazyObject = route.lazy; |
| ["middleware", "loader", "action"].forEach((key) => { |
| let lazyFn = lazyObject[key]; |
| let instrumentations = aggregated[`lazy.${key}`]; |
| if (typeof lazyFn === "function" && instrumentations.length > 0) { |
| let instrumented = wrapImpl(instrumentations, lazyFn, () => void 0); |
| if (instrumented) { |
| updates.lazy = Object.assign(updates.lazy || {}, { |
| [key]: instrumented |
| }); |
| } |
| } |
| }); |
| } |
| ["loader", "action"].forEach((key) => { |
| let handler = route[key]; |
| if (typeof handler === "function" && aggregated[key].length > 0) { |
| let original = _nullishCoalesce(handler[UninstrumentedSymbol], () => ( handler)); |
| let instrumented = wrapImpl( |
| aggregated[key], |
| original, |
| (...args) => getHandlerInfo(args[0]) |
| ); |
| if (instrumented) { |
| if (key === "loader" && original.hydrate === true) { |
| instrumented.hydrate = true; |
| } |
| instrumented[UninstrumentedSymbol] = original; |
| updates[key] = instrumented; |
| } |
| } |
| }); |
| if (route.middleware && route.middleware.length > 0 && aggregated.middleware.length > 0) { |
| updates.middleware = route.middleware.map((middleware) => { |
| let original = _nullishCoalesce(middleware[UninstrumentedSymbol], () => ( middleware)); |
| let instrumented = wrapImpl( |
| aggregated.middleware, |
| original, |
| (...args) => getHandlerInfo(args[0]) |
| ); |
| if (instrumented) { |
| instrumented[UninstrumentedSymbol] = original; |
| return instrumented; |
| } |
| return middleware; |
| }); |
| } |
| return updates; |
| } |
| function instrumentClientSideRouter(router, fns) { |
| let aggregated = { |
| navigate: [], |
| fetch: [] |
| }; |
| fns.forEach( |
| (fn) => fn({ |
| instrument(i) { |
| let keys = Object.keys(i); |
| for (let key of keys) { |
| if (i[key]) { |
| aggregated[key].push(i[key]); |
| } |
| } |
| } |
| }) |
| ); |
| if (aggregated.navigate.length > 0) { |
| let navigate = _nullishCoalesce(router.navigate[UninstrumentedSymbol], () => ( router.navigate)); |
| let instrumentedNavigate = wrapImpl( |
| aggregated.navigate, |
| navigate, |
| (...args) => { |
| let [to, opts] = args; |
| return { |
| to: typeof to === "number" || typeof to === "string" ? to : to ? createPath(to) : ".", |
| ...getRouterInfo(router, _nullishCoalesce(opts, () => ( {}))) |
| }; |
| } |
| ); |
| if (instrumentedNavigate) { |
| instrumentedNavigate[UninstrumentedSymbol] = navigate; |
| router.navigate = instrumentedNavigate; |
| } |
| } |
| if (aggregated.fetch.length > 0) { |
| let fetch2 = _nullishCoalesce(router.fetch[UninstrumentedSymbol], () => ( router.fetch)); |
| let instrumentedFetch = wrapImpl(aggregated.fetch, fetch2, (...args) => { |
| let [key, , href, opts] = args; |
| return { |
| href: _nullishCoalesce(href, () => ( ".")), |
| fetcherKey: key, |
| ...getRouterInfo(router, _nullishCoalesce(opts, () => ( {}))) |
| }; |
| }); |
| if (instrumentedFetch) { |
| instrumentedFetch[UninstrumentedSymbol] = fetch2; |
| router.fetch = instrumentedFetch; |
| } |
| } |
| return router; |
| } |
| function instrumentHandler(handler, fns) { |
| let aggregated = { |
| request: [] |
| }; |
| fns.forEach( |
| (fn) => fn({ |
| instrument(i) { |
| let keys = Object.keys(i); |
| for (let key of keys) { |
| if (i[key]) { |
| aggregated[key].push(i[key]); |
| } |
| } |
| } |
| }) |
| ); |
| let instrumentedHandler = handler; |
| if (aggregated.request.length > 0) { |
| instrumentedHandler = wrapImpl(aggregated.request, handler, (...args) => { |
| let [request, context] = args; |
| return { |
| request: getReadonlyRequest(request), |
| context: context != null ? getReadonlyContext(context) : context |
| }; |
| }); |
| } |
| return instrumentedHandler; |
| } |
| function wrapImpl(impls, handler, getInfo) { |
| if (impls.length === 0) { |
| return null; |
| } |
| return async (...args) => { |
| let result = await recurseRight( |
| impls, |
| getInfo(...args), |
| () => handler(...args), |
| impls.length - 1 |
| ); |
| if (result.type === "error") { |
| throw result.value; |
| } |
| return result.value; |
| }; |
| } |
| async function recurseRight(impls, info, handler, index) { |
| let impl = impls[index]; |
| let result; |
| if (!impl) { |
| try { |
| let value = await handler(); |
| result = { type: "success", value }; |
| } catch (e) { |
| result = { type: "error", value: e }; |
| } |
| } else { |
| let handlerPromise = void 0; |
| let callHandler = async () => { |
| if (handlerPromise) { |
| console.error("You cannot call instrumented handlers more than once"); |
| } else { |
| handlerPromise = recurseRight(impls, info, handler, index - 1); |
| } |
| result = await handlerPromise; |
| invariant(result, "Expected a result"); |
| if (result.type === "error" && result.value instanceof Error) { |
| return { status: "error", error: result.value }; |
| } |
| return { status: "success", error: void 0 }; |
| }; |
| try { |
| await impl(callHandler, info); |
| } catch (e) { |
| console.error("An instrumentation function threw an error:", e); |
| } |
| if (!handlerPromise) { |
| await callHandler(); |
| } |
| await handlerPromise; |
| } |
| if (result) { |
| return result; |
| } |
| return { |
| type: "error", |
| value: new Error("No result assigned in instrumentation chain.") |
| }; |
| } |
| function getHandlerInfo(args) { |
| let { request, context, params, unstable_pattern } = args; |
| return { |
| request: getReadonlyRequest(request), |
| params: { ...params }, |
| unstable_pattern, |
| context: getReadonlyContext(context) |
| }; |
| } |
| function getRouterInfo(router, opts) { |
| return { |
| currentUrl: createPath(router.state.location), |
| ..."formMethod" in opts ? { formMethod: opts.formMethod } : {}, |
| ..."formEncType" in opts ? { formEncType: opts.formEncType } : {}, |
| ..."formData" in opts ? { formData: opts.formData } : {}, |
| ..."body" in opts ? { body: opts.body } : {} |
| }; |
| } |
| function getReadonlyRequest(request) { |
| return { |
| method: request.method, |
| url: request.url, |
| headers: { |
| get: (...args) => request.headers.get(...args) |
| } |
| }; |
| } |
| function getReadonlyContext(context) { |
| if (isPlainObject(context)) { |
| let frozen = { ...context }; |
| Object.freeze(frozen); |
| return frozen; |
| } else { |
| return { |
| get: (ctx) => context.get(ctx) |
| }; |
| } |
| } |
| var objectProtoNames = Object.getOwnPropertyNames(Object.prototype).sort().join("\0"); |
| function isPlainObject(thing) { |
| if (thing === null || typeof thing !== "object") { |
| return false; |
| } |
| const proto = Object.getPrototypeOf(thing); |
| return proto === Object.prototype || proto === null || Object.getOwnPropertyNames(proto).sort().join("\0") === objectProtoNames; |
| } |
|
|
| |
| var validMutationMethodsArr = [ |
| "POST", |
| "PUT", |
| "PATCH", |
| "DELETE" |
| ]; |
| var validMutationMethods = new Set( |
| validMutationMethodsArr |
| ); |
| var validRequestMethodsArr = [ |
| "GET", |
| ...validMutationMethodsArr |
| ]; |
| var validRequestMethods = new Set(validRequestMethodsArr); |
| var redirectStatusCodes = new Set([301, 302, 303, 307, 308]); |
| var redirectPreserveMethodStatusCodes = new Set([307, 308]); |
| var IDLE_NAVIGATION = { |
| state: "idle", |
| location: void 0, |
| formMethod: void 0, |
| formAction: void 0, |
| formEncType: void 0, |
| formData: void 0, |
| json: void 0, |
| text: void 0 |
| }; |
| var IDLE_FETCHER = { |
| state: "idle", |
| data: void 0, |
| formMethod: void 0, |
| formAction: void 0, |
| formEncType: void 0, |
| formData: void 0, |
| json: void 0, |
| text: void 0 |
| }; |
| var IDLE_BLOCKER = { |
| state: "unblocked", |
| proceed: void 0, |
| reset: void 0, |
| location: void 0 |
| }; |
| var defaultMapRouteProperties = (route) => ({ |
| hasErrorBoundary: Boolean(route.hasErrorBoundary) |
| }); |
| var TRANSITIONS_STORAGE_KEY = "remix-router-transitions"; |
| var ResetLoaderDataSymbol = Symbol("ResetLoaderData"); |
| function createRouter(init) { |
| const routerWindow = init.window ? init.window : typeof window !== "undefined" ? window : void 0; |
| const isBrowser2 = typeof routerWindow !== "undefined" && typeof routerWindow.document !== "undefined" && typeof routerWindow.document.createElement !== "undefined"; |
| invariant( |
| init.routes.length > 0, |
| "You must provide a non-empty routes array to createRouter" |
| ); |
| let hydrationRouteProperties2 = init.hydrationRouteProperties || []; |
| let _mapRouteProperties = init.mapRouteProperties || defaultMapRouteProperties; |
| let mapRouteProperties2 = _mapRouteProperties; |
| if (init.unstable_instrumentations) { |
| let instrumentations = init.unstable_instrumentations; |
| mapRouteProperties2 = (route) => { |
| return { |
| ..._mapRouteProperties(route), |
| ...getRouteInstrumentationUpdates( |
| instrumentations.map((i) => i.route).filter(Boolean), |
| route |
| ) |
| }; |
| }; |
| } |
| let manifest = {}; |
| let dataRoutes = convertRoutesToDataRoutes( |
| init.routes, |
| mapRouteProperties2, |
| void 0, |
| manifest |
| ); |
| let inFlightDataRoutes; |
| let basename = init.basename || "/"; |
| if (!basename.startsWith("/")) { |
| basename = `/${basename}`; |
| } |
| let dataStrategyImpl = init.dataStrategy || defaultDataStrategyWithMiddleware; |
| let future = { |
| unstable_passThroughRequests: false, |
| ...init.future |
| }; |
| let unlistenHistory = null; |
| let subscribers = new Set(); |
| let savedScrollPositions = null; |
| let getScrollRestorationKey = null; |
| let getScrollPosition = null; |
| let initialScrollRestored = init.hydrationData != null; |
| let initialMatches = matchRoutes(dataRoutes, init.history.location, basename); |
| let initialMatchesIsFOW = false; |
| let initialErrors = null; |
| let initialized; |
| let renderFallback; |
| if (initialMatches == null && !init.patchRoutesOnNavigation) { |
| let error = getInternalRouterError(404, { |
| pathname: init.history.location.pathname |
| }); |
| let { matches, route } = getShortCircuitMatches(dataRoutes); |
| initialized = true; |
| renderFallback = !initialized; |
| initialMatches = matches; |
| initialErrors = { [route.id]: error }; |
| } else { |
| if (initialMatches && !init.hydrationData) { |
| let fogOfWar = checkFogOfWar( |
| initialMatches, |
| dataRoutes, |
| init.history.location.pathname |
| ); |
| if (fogOfWar.active) { |
| initialMatches = null; |
| } |
| } |
| if (!initialMatches) { |
| initialized = false; |
| renderFallback = !initialized; |
| initialMatches = []; |
| let fogOfWar = checkFogOfWar( |
| null, |
| dataRoutes, |
| init.history.location.pathname |
| ); |
| if (fogOfWar.active && fogOfWar.matches) { |
| initialMatchesIsFOW = true; |
| initialMatches = fogOfWar.matches; |
| } |
| } else if (initialMatches.some((m) => m.route.lazy)) { |
| initialized = false; |
| renderFallback = !initialized; |
| } else if (!initialMatches.some((m) => routeHasLoaderOrMiddleware(m.route))) { |
| initialized = true; |
| renderFallback = !initialized; |
| } else { |
| let loaderData = init.hydrationData ? init.hydrationData.loaderData : null; |
| let errors = init.hydrationData ? init.hydrationData.errors : null; |
| let relevantMatches = initialMatches; |
| if (errors) { |
| let idx = initialMatches.findIndex( |
| (m) => errors[m.route.id] !== void 0 |
| ); |
| relevantMatches = relevantMatches.slice(0, idx + 1); |
| } |
| renderFallback = false; |
| initialized = true; |
| relevantMatches.forEach((m) => { |
| let status = getRouteHydrationStatus(m.route, loaderData, errors); |
| renderFallback = renderFallback || status.renderFallback; |
| initialized = initialized && !status.shouldLoad; |
| }); |
| } |
| } |
| let router; |
| let state = { |
| historyAction: init.history.action, |
| location: init.history.location, |
| matches: initialMatches, |
| initialized, |
| renderFallback, |
| navigation: IDLE_NAVIGATION, |
| |
| restoreScrollPosition: init.hydrationData != null ? false : null, |
| preventScrollReset: false, |
| revalidation: "idle", |
| loaderData: init.hydrationData && init.hydrationData.loaderData || {}, |
| actionData: init.hydrationData && init.hydrationData.actionData || null, |
| errors: init.hydrationData && init.hydrationData.errors || initialErrors, |
| fetchers: new Map(), |
| blockers: new Map() |
| }; |
| let pendingAction = "POP" ; |
| let pendingPopstateNavigationDfd = null; |
| let pendingPreventScrollReset = false; |
| let pendingNavigationController; |
| let pendingViewTransitionEnabled = false; |
| let appliedViewTransitions = new Map(); |
| let removePageHideEventListener = null; |
| let isUninterruptedRevalidation = false; |
| let isRevalidationRequired = false; |
| let cancelledFetcherLoads = new Set(); |
| let fetchControllers = new Map(); |
| let incrementingLoadId = 0; |
| let pendingNavigationLoadId = -1; |
| let fetchReloadIds = new Map(); |
| let fetchRedirectIds = new Set(); |
| let fetchLoadMatches = new Map(); |
| let activeFetchers = new Map(); |
| let fetchersQueuedForDeletion = new Set(); |
| let blockerFunctions = new Map(); |
| let unblockBlockerHistoryUpdate = void 0; |
| let pendingRevalidationDfd = null; |
| function initialize() { |
| unlistenHistory = init.history.listen( |
| ({ action: historyAction, location, delta }) => { |
| if (unblockBlockerHistoryUpdate) { |
| unblockBlockerHistoryUpdate(); |
| unblockBlockerHistoryUpdate = void 0; |
| return; |
| } |
| warning( |
| blockerFunctions.size === 0 || delta != null, |
| "You are trying to use a blocker on a POP navigation to a location that was not created by @remix-run/router. This will fail silently in production. This can happen if you are navigating outside the router via `window.history.pushState`/`window.location.hash` instead of using router navigation APIs. This can also happen if you are using createHashRouter and the user manually changes the URL." |
| ); |
| let blockerKey = shouldBlockNavigation({ |
| currentLocation: state.location, |
| nextLocation: location, |
| historyAction |
| }); |
| if (blockerKey && delta != null) { |
| let nextHistoryUpdatePromise = new Promise((resolve) => { |
| unblockBlockerHistoryUpdate = resolve; |
| }); |
| init.history.go(delta * -1); |
| updateBlocker(blockerKey, { |
| state: "blocked", |
| location, |
| proceed() { |
| updateBlocker(blockerKey, { |
| state: "proceeding", |
| proceed: void 0, |
| reset: void 0, |
| location |
| }); |
| nextHistoryUpdatePromise.then(() => init.history.go(delta)); |
| }, |
| reset() { |
| let blockers = new Map(state.blockers); |
| blockers.set(blockerKey, IDLE_BLOCKER); |
| updateState({ blockers }); |
| } |
| }); |
| _optionalChain([pendingPopstateNavigationDfd, 'optionalAccess', _7 => _7.resolve, 'call', _8 => _8()]); |
| pendingPopstateNavigationDfd = null; |
| return; |
| } |
| return startNavigation(historyAction, location); |
| } |
| ); |
| if (isBrowser2) { |
| restoreAppliedTransitions(routerWindow, appliedViewTransitions); |
| let _saveAppliedTransitions = () => persistAppliedTransitions(routerWindow, appliedViewTransitions); |
| routerWindow.addEventListener("pagehide", _saveAppliedTransitions); |
| removePageHideEventListener = () => routerWindow.removeEventListener("pagehide", _saveAppliedTransitions); |
| } |
| if (!state.initialized) { |
| startNavigation("POP" , state.location, { |
| initialHydration: true |
| }); |
| } |
| return router; |
| } |
| function dispose() { |
| if (unlistenHistory) { |
| unlistenHistory(); |
| } |
| if (removePageHideEventListener) { |
| removePageHideEventListener(); |
| } |
| subscribers.clear(); |
| pendingNavigationController && pendingNavigationController.abort(); |
| state.fetchers.forEach((_, key) => deleteFetcher(key)); |
| state.blockers.forEach((_, key) => deleteBlocker(key)); |
| } |
| function subscribe(fn) { |
| subscribers.add(fn); |
| return () => subscribers.delete(fn); |
| } |
| function updateState(newState, opts = {}) { |
| if (newState.matches) { |
| newState.matches = newState.matches.map((m) => { |
| let route = manifest[m.route.id]; |
| let matchRoute = m.route; |
| if (matchRoute.element !== route.element || matchRoute.errorElement !== route.errorElement || matchRoute.hydrateFallbackElement !== route.hydrateFallbackElement) { |
| return { |
| ...m, |
| route |
| }; |
| } |
| return m; |
| }); |
| } |
| state = { |
| ...state, |
| ...newState |
| }; |
| let unmountedFetchers = []; |
| let mountedFetchers = []; |
| state.fetchers.forEach((fetcher, key) => { |
| if (fetcher.state === "idle") { |
| if (fetchersQueuedForDeletion.has(key)) { |
| unmountedFetchers.push(key); |
| } else { |
| mountedFetchers.push(key); |
| } |
| } |
| }); |
| fetchersQueuedForDeletion.forEach((key) => { |
| if (!state.fetchers.has(key) && !fetchControllers.has(key)) { |
| unmountedFetchers.push(key); |
| } |
| }); |
| [...subscribers].forEach( |
| (subscriber) => subscriber(state, { |
| deletedFetchers: unmountedFetchers, |
| newErrors: _nullishCoalesce(newState.errors, () => ( null)), |
| viewTransitionOpts: opts.viewTransitionOpts, |
| flushSync: opts.flushSync === true |
| }) |
| ); |
| unmountedFetchers.forEach((key) => deleteFetcher(key)); |
| mountedFetchers.forEach((key) => state.fetchers.delete(key)); |
| } |
| function completeNavigation(location, newState, { flushSync } = {}) { |
| let isActionReload = state.actionData != null && state.navigation.formMethod != null && isMutationMethod(state.navigation.formMethod) && state.navigation.state === "loading" && _optionalChain([location, 'access', _9 => _9.state, 'optionalAccess', _10 => _10._isRedirect]) !== true; |
| let actionData; |
| if (newState.actionData) { |
| if (Object.keys(newState.actionData).length > 0) { |
| actionData = newState.actionData; |
| } else { |
| actionData = null; |
| } |
| } else if (isActionReload) { |
| actionData = state.actionData; |
| } else { |
| actionData = null; |
| } |
| let loaderData = newState.loaderData ? mergeLoaderData( |
| state.loaderData, |
| newState.loaderData, |
| newState.matches || [], |
| newState.errors |
| ) : state.loaderData; |
| let blockers = state.blockers; |
| if (blockers.size > 0) { |
| blockers = new Map(blockers); |
| blockers.forEach((_, k) => blockers.set(k, IDLE_BLOCKER)); |
| } |
| let restoreScrollPosition = isUninterruptedRevalidation ? false : getSavedScrollPosition(location, newState.matches || state.matches); |
| let preventScrollReset = pendingPreventScrollReset === true || state.navigation.formMethod != null && isMutationMethod(state.navigation.formMethod) && _optionalChain([location, 'access', _11 => _11.state, 'optionalAccess', _12 => _12._isRedirect]) !== true; |
| if (inFlightDataRoutes) { |
| dataRoutes = inFlightDataRoutes; |
| inFlightDataRoutes = void 0; |
| } |
| if (isUninterruptedRevalidation) { |
| } else if (pendingAction === "POP" ) { |
| } else if (pendingAction === "PUSH" ) { |
| init.history.push(location, location.state); |
| } else if (pendingAction === "REPLACE" ) { |
| init.history.replace(location, location.state); |
| } |
| let viewTransitionOpts; |
| if (pendingAction === "POP" ) { |
| let priorPaths = appliedViewTransitions.get(state.location.pathname); |
| if (priorPaths && priorPaths.has(location.pathname)) { |
| viewTransitionOpts = { |
| currentLocation: state.location, |
| nextLocation: location |
| }; |
| } else if (appliedViewTransitions.has(location.pathname)) { |
| viewTransitionOpts = { |
| currentLocation: location, |
| nextLocation: state.location |
| }; |
| } |
| } else if (pendingViewTransitionEnabled) { |
| let toPaths = appliedViewTransitions.get(state.location.pathname); |
| if (toPaths) { |
| toPaths.add(location.pathname); |
| } else { |
| toPaths = new Set([location.pathname]); |
| appliedViewTransitions.set(state.location.pathname, toPaths); |
| } |
| viewTransitionOpts = { |
| currentLocation: state.location, |
| nextLocation: location |
| }; |
| } |
| updateState( |
| { |
| ...newState, |
| |
| actionData, |
| loaderData, |
| historyAction: pendingAction, |
| location, |
| initialized: true, |
| renderFallback: false, |
| navigation: IDLE_NAVIGATION, |
| revalidation: "idle", |
| restoreScrollPosition, |
| preventScrollReset, |
| blockers |
| }, |
| { |
| viewTransitionOpts, |
| flushSync: flushSync === true |
| } |
| ); |
| pendingAction = "POP" ; |
| pendingPreventScrollReset = false; |
| pendingViewTransitionEnabled = false; |
| isUninterruptedRevalidation = false; |
| isRevalidationRequired = false; |
| _optionalChain([pendingPopstateNavigationDfd, 'optionalAccess', _13 => _13.resolve, 'call', _14 => _14()]); |
| pendingPopstateNavigationDfd = null; |
| _optionalChain([pendingRevalidationDfd, 'optionalAccess', _15 => _15.resolve, 'call', _16 => _16()]); |
| pendingRevalidationDfd = null; |
| } |
| async function navigate(to, opts) { |
| _optionalChain([pendingPopstateNavigationDfd, 'optionalAccess', _17 => _17.resolve, 'call', _18 => _18()]); |
| pendingPopstateNavigationDfd = null; |
| if (typeof to === "number") { |
| if (!pendingPopstateNavigationDfd) { |
| pendingPopstateNavigationDfd = createDeferred(); |
| } |
| let promise = pendingPopstateNavigationDfd.promise; |
| init.history.go(to); |
| return promise; |
| } |
| let normalizedPath = normalizeTo( |
| state.location, |
| state.matches, |
| basename, |
| to, |
| _optionalChain([opts, 'optionalAccess', _19 => _19.fromRouteId]), |
| _optionalChain([opts, 'optionalAccess', _20 => _20.relative]) |
| ); |
| let { path, submission, error } = normalizeNavigateOptions( |
| false, |
| normalizedPath, |
| opts |
| ); |
| let maskPath; |
| if (_optionalChain([opts, 'optionalAccess', _21 => _21.unstable_mask])) { |
| let partialPath = typeof opts.unstable_mask === "string" ? parsePath(opts.unstable_mask) : { |
| ...state.location.unstable_mask, |
| ...opts.unstable_mask |
| }; |
| maskPath = { |
| pathname: "", |
| search: "", |
| hash: "", |
| ...partialPath |
| }; |
| } |
| let currentLocation = state.location; |
| let nextLocation = createLocation( |
| currentLocation, |
| path, |
| opts && opts.state, |
| void 0, |
| maskPath |
| ); |
| nextLocation = { |
| ...nextLocation, |
| ...init.history.encodeLocation(nextLocation) |
| }; |
| let userReplace = opts && opts.replace != null ? opts.replace : void 0; |
| let historyAction = "PUSH" ; |
| if (userReplace === true) { |
| historyAction = "REPLACE" ; |
| } else if (userReplace === false) { |
| } else if (submission != null && isMutationMethod(submission.formMethod) && submission.formAction === state.location.pathname + state.location.search) { |
| historyAction = "REPLACE" ; |
| } |
| let preventScrollReset = opts && "preventScrollReset" in opts ? opts.preventScrollReset === true : void 0; |
| let flushSync = (opts && opts.flushSync) === true; |
| let blockerKey = shouldBlockNavigation({ |
| currentLocation, |
| nextLocation, |
| historyAction |
| }); |
| if (blockerKey) { |
| updateBlocker(blockerKey, { |
| state: "blocked", |
| location: nextLocation, |
| proceed() { |
| updateBlocker(blockerKey, { |
| state: "proceeding", |
| proceed: void 0, |
| reset: void 0, |
| location: nextLocation |
| }); |
| navigate(to, opts); |
| }, |
| reset() { |
| let blockers = new Map(state.blockers); |
| blockers.set(blockerKey, IDLE_BLOCKER); |
| updateState({ blockers }); |
| } |
| }); |
| return; |
| } |
| await startNavigation(historyAction, nextLocation, { |
| submission, |
| |
| |
| pendingError: error, |
| preventScrollReset, |
| replace: opts && opts.replace, |
| enableViewTransition: opts && opts.viewTransition, |
| flushSync, |
| callSiteDefaultShouldRevalidate: opts && opts.unstable_defaultShouldRevalidate |
| }); |
| } |
| function revalidate() { |
| if (!pendingRevalidationDfd) { |
| pendingRevalidationDfd = createDeferred(); |
| } |
| interruptActiveLoads(); |
| updateState({ revalidation: "loading" }); |
| let promise = pendingRevalidationDfd.promise; |
| if (state.navigation.state === "submitting") { |
| return promise; |
| } |
| if (state.navigation.state === "idle") { |
| startNavigation(state.historyAction, state.location, { |
| startUninterruptedRevalidation: true |
| }); |
| return promise; |
| } |
| startNavigation( |
| pendingAction || state.historyAction, |
| state.navigation.location, |
| { |
| overrideNavigation: state.navigation, |
| |
| enableViewTransition: pendingViewTransitionEnabled === true |
| } |
| ); |
| return promise; |
| } |
| async function startNavigation(historyAction, location, opts) { |
| pendingNavigationController && pendingNavigationController.abort(); |
| pendingNavigationController = null; |
| pendingAction = historyAction; |
| isUninterruptedRevalidation = (opts && opts.startUninterruptedRevalidation) === true; |
| saveScrollPosition(state.location, state.matches); |
| pendingPreventScrollReset = (opts && opts.preventScrollReset) === true; |
| pendingViewTransitionEnabled = (opts && opts.enableViewTransition) === true; |
| let routesToUse = inFlightDataRoutes || dataRoutes; |
| let loadingNavigation = opts && opts.overrideNavigation; |
| let matches = _optionalChain([opts, 'optionalAccess', _22 => _22.initialHydration]) && state.matches && state.matches.length > 0 && !initialMatchesIsFOW ? ( |
| |
| state.matches |
| ) : matchRoutes(routesToUse, location, basename); |
| let flushSync = (opts && opts.flushSync) === true; |
| if (matches && state.initialized && !isRevalidationRequired && isHashChangeOnly(state.location, location) && !(opts && opts.submission && isMutationMethod(opts.submission.formMethod))) { |
| completeNavigation(location, { matches }, { flushSync }); |
| return; |
| } |
| let fogOfWar = checkFogOfWar(matches, routesToUse, location.pathname); |
| if (fogOfWar.active && fogOfWar.matches) { |
| matches = fogOfWar.matches; |
| } |
| if (!matches) { |
| let { error, notFoundMatches, route } = handleNavigational404( |
| location.pathname |
| ); |
| completeNavigation( |
| location, |
| { |
| matches: notFoundMatches, |
| loaderData: {}, |
| errors: { |
| [route.id]: error |
| } |
| }, |
| { flushSync } |
| ); |
| return; |
| } |
| pendingNavigationController = new AbortController(); |
| let request = createClientSideRequest( |
| init.history, |
| location, |
| pendingNavigationController.signal, |
| opts && opts.submission |
| ); |
| let scopedContext = init.getContext ? await init.getContext() : new RouterContextProvider(); |
| let pendingActionResult; |
| if (opts && opts.pendingError) { |
| pendingActionResult = [ |
| findNearestBoundary(matches).route.id, |
| { type: "error" , error: opts.pendingError } |
| ]; |
| } else if (opts && opts.submission && isMutationMethod(opts.submission.formMethod)) { |
| let actionResult = await handleAction( |
| request, |
| location, |
| opts.submission, |
| matches, |
| scopedContext, |
| fogOfWar.active, |
| opts && opts.initialHydration === true, |
| { replace: opts.replace, flushSync } |
| ); |
| if (actionResult.shortCircuited) { |
| return; |
| } |
| if (actionResult.pendingActionResult) { |
| let [routeId, result] = actionResult.pendingActionResult; |
| if (isErrorResult(result) && isRouteErrorResponse(result.error) && result.error.status === 404) { |
| pendingNavigationController = null; |
| completeNavigation(location, { |
| matches: actionResult.matches, |
| loaderData: {}, |
| errors: { |
| [routeId]: result.error |
| } |
| }); |
| return; |
| } |
| } |
| matches = actionResult.matches || matches; |
| pendingActionResult = actionResult.pendingActionResult; |
| loadingNavigation = getLoadingNavigation(location, opts.submission); |
| flushSync = false; |
| fogOfWar.active = false; |
| request = createClientSideRequest( |
| init.history, |
| request.url, |
| request.signal |
| ); |
| } |
| let { |
| shortCircuited, |
| matches: updatedMatches, |
| loaderData, |
| errors |
| } = await handleLoaders( |
| request, |
| location, |
| matches, |
| scopedContext, |
| fogOfWar.active, |
| loadingNavigation, |
| opts && opts.submission, |
| opts && opts.fetcherSubmission, |
| opts && opts.replace, |
| opts && opts.initialHydration === true, |
| flushSync, |
| pendingActionResult, |
| opts && opts.callSiteDefaultShouldRevalidate |
| ); |
| if (shortCircuited) { |
| return; |
| } |
| pendingNavigationController = null; |
| completeNavigation(location, { |
| matches: updatedMatches || matches, |
| ...getActionDataForCommit(pendingActionResult), |
| loaderData, |
| errors |
| }); |
| } |
| async function handleAction(request, location, submission, matches, scopedContext, isFogOfWar, initialHydration, opts = {}) { |
| interruptActiveLoads(); |
| let navigation = getSubmittingNavigation(location, submission); |
| updateState({ navigation }, { flushSync: opts.flushSync === true }); |
| if (isFogOfWar) { |
| let discoverResult = await discoverRoutes( |
| matches, |
| location.pathname, |
| request.signal |
| ); |
| if (discoverResult.type === "aborted") { |
| return { shortCircuited: true }; |
| } else if (discoverResult.type === "error") { |
| if (discoverResult.partialMatches.length === 0) { |
| let { matches: matches2, route } = getShortCircuitMatches(dataRoutes); |
| return { |
| matches: matches2, |
| pendingActionResult: [ |
| route.id, |
| { |
| type: "error" , |
| error: discoverResult.error |
| } |
| ] |
| }; |
| } |
| let boundaryId = findNearestBoundary(discoverResult.partialMatches).route.id; |
| return { |
| matches: discoverResult.partialMatches, |
| pendingActionResult: [ |
| boundaryId, |
| { |
| type: "error" , |
| error: discoverResult.error |
| } |
| ] |
| }; |
| } else if (!discoverResult.matches) { |
| let { notFoundMatches, error, route } = handleNavigational404( |
| location.pathname |
| ); |
| return { |
| matches: notFoundMatches, |
| pendingActionResult: [ |
| route.id, |
| { |
| type: "error" , |
| error |
| } |
| ] |
| }; |
| } else { |
| matches = discoverResult.matches; |
| } |
| } |
| let result; |
| let actionMatch = getTargetMatch(matches, location); |
| if (!actionMatch.route.action && !actionMatch.route.lazy) { |
| result = { |
| type: "error" , |
| error: getInternalRouterError(405, { |
| method: request.method, |
| pathname: location.pathname, |
| routeId: actionMatch.route.id |
| }) |
| }; |
| } else { |
| let dsMatches = getTargetedDataStrategyMatches( |
| mapRouteProperties2, |
| manifest, |
| request, |
| location, |
| matches, |
| actionMatch, |
| initialHydration ? [] : hydrationRouteProperties2, |
| scopedContext |
| ); |
| let results = await callDataStrategy( |
| request, |
| location, |
| dsMatches, |
| scopedContext, |
| null |
| ); |
| result = results[actionMatch.route.id]; |
| if (!result) { |
| for (let match of matches) { |
| if (results[match.route.id]) { |
| result = results[match.route.id]; |
| break; |
| } |
| } |
| } |
| if (request.signal.aborted) { |
| return { shortCircuited: true }; |
| } |
| } |
| if (isRedirectResult(result)) { |
| let replace2; |
| if (opts && opts.replace != null) { |
| replace2 = opts.replace; |
| } else { |
| let location2 = normalizeRedirectLocation( |
| result.response.headers.get("Location"), |
| new URL(request.url), |
| basename, |
| init.history |
| ); |
| replace2 = location2 === state.location.pathname + state.location.search; |
| } |
| await startRedirectNavigation(request, result, true, { |
| submission, |
| replace: replace2 |
| }); |
| return { shortCircuited: true }; |
| } |
| if (isErrorResult(result)) { |
| let boundaryMatch = findNearestBoundary(matches, actionMatch.route.id); |
| if ((opts && opts.replace) !== true) { |
| pendingAction = "PUSH" ; |
| } |
| return { |
| matches, |
| pendingActionResult: [ |
| boundaryMatch.route.id, |
| result, |
| actionMatch.route.id |
| ] |
| }; |
| } |
| return { |
| matches, |
| pendingActionResult: [actionMatch.route.id, result] |
| }; |
| } |
| async function handleLoaders(request, location, matches, scopedContext, isFogOfWar, overrideNavigation, submission, fetcherSubmission, replace2, initialHydration, flushSync, pendingActionResult, callSiteDefaultShouldRevalidate) { |
| let loadingNavigation = overrideNavigation || getLoadingNavigation(location, submission); |
| let activeSubmission = submission || fetcherSubmission || getSubmissionFromNavigation(loadingNavigation); |
| let shouldUpdateNavigationState = !isUninterruptedRevalidation && !initialHydration; |
| if (isFogOfWar) { |
| if (shouldUpdateNavigationState) { |
| let actionData = getUpdatedActionData(pendingActionResult); |
| updateState( |
| { |
| navigation: loadingNavigation, |
| ...actionData !== void 0 ? { actionData } : {} |
| }, |
| { |
| flushSync |
| } |
| ); |
| } |
| let discoverResult = await discoverRoutes( |
| matches, |
| location.pathname, |
| request.signal |
| ); |
| if (discoverResult.type === "aborted") { |
| return { shortCircuited: true }; |
| } else if (discoverResult.type === "error") { |
| if (discoverResult.partialMatches.length === 0) { |
| let { matches: matches2, route } = getShortCircuitMatches(dataRoutes); |
| return { |
| matches: matches2, |
| loaderData: {}, |
| errors: { |
| [route.id]: discoverResult.error |
| } |
| }; |
| } |
| let boundaryId = findNearestBoundary(discoverResult.partialMatches).route.id; |
| return { |
| matches: discoverResult.partialMatches, |
| loaderData: {}, |
| errors: { |
| [boundaryId]: discoverResult.error |
| } |
| }; |
| } else if (!discoverResult.matches) { |
| let { error, notFoundMatches, route } = handleNavigational404( |
| location.pathname |
| ); |
| return { |
| matches: notFoundMatches, |
| loaderData: {}, |
| errors: { |
| [route.id]: error |
| } |
| }; |
| } else { |
| matches = discoverResult.matches; |
| } |
| } |
| let routesToUse = inFlightDataRoutes || dataRoutes; |
| let { dsMatches, revalidatingFetchers } = getMatchesToLoad( |
| request, |
| scopedContext, |
| mapRouteProperties2, |
| manifest, |
| init.history, |
| state, |
| matches, |
| activeSubmission, |
| location, |
| initialHydration ? [] : hydrationRouteProperties2, |
| initialHydration === true, |
| isRevalidationRequired, |
| cancelledFetcherLoads, |
| fetchersQueuedForDeletion, |
| fetchLoadMatches, |
| fetchRedirectIds, |
| routesToUse, |
| basename, |
| init.patchRoutesOnNavigation != null, |
| pendingActionResult, |
| callSiteDefaultShouldRevalidate |
| ); |
| pendingNavigationLoadId = ++incrementingLoadId; |
| if (!init.dataStrategy && !dsMatches.some((m) => m.shouldLoad) && !dsMatches.some( |
| (m) => m.route.middleware && m.route.middleware.length > 0 |
| ) && revalidatingFetchers.length === 0) { |
| let updatedFetchers2 = markFetchRedirectsDone(); |
| completeNavigation( |
| location, |
| { |
| matches, |
| loaderData: {}, |
| |
| errors: pendingActionResult && isErrorResult(pendingActionResult[1]) ? { [pendingActionResult[0]]: pendingActionResult[1].error } : null, |
| ...getActionDataForCommit(pendingActionResult), |
| ...updatedFetchers2 ? { fetchers: new Map(state.fetchers) } : {} |
| }, |
| { flushSync } |
| ); |
| return { shortCircuited: true }; |
| } |
| if (shouldUpdateNavigationState) { |
| let updates = {}; |
| if (!isFogOfWar) { |
| updates.navigation = loadingNavigation; |
| let actionData = getUpdatedActionData(pendingActionResult); |
| if (actionData !== void 0) { |
| updates.actionData = actionData; |
| } |
| } |
| if (revalidatingFetchers.length > 0) { |
| updates.fetchers = getUpdatedRevalidatingFetchers(revalidatingFetchers); |
| } |
| updateState(updates, { flushSync }); |
| } |
| revalidatingFetchers.forEach((rf) => { |
| abortFetcher(rf.key); |
| if (rf.controller) { |
| fetchControllers.set(rf.key, rf.controller); |
| } |
| }); |
| let abortPendingFetchRevalidations = () => revalidatingFetchers.forEach((f) => abortFetcher(f.key)); |
| if (pendingNavigationController) { |
| pendingNavigationController.signal.addEventListener( |
| "abort", |
| abortPendingFetchRevalidations |
| ); |
| } |
| let { loaderResults, fetcherResults } = await callLoadersAndMaybeResolveData( |
| dsMatches, |
| revalidatingFetchers, |
| request, |
| location, |
| scopedContext |
| ); |
| if (request.signal.aborted) { |
| return { shortCircuited: true }; |
| } |
| if (pendingNavigationController) { |
| pendingNavigationController.signal.removeEventListener( |
| "abort", |
| abortPendingFetchRevalidations |
| ); |
| } |
| revalidatingFetchers.forEach((rf) => fetchControllers.delete(rf.key)); |
| let redirect2 = findRedirect(loaderResults); |
| if (redirect2) { |
| await startRedirectNavigation(request, redirect2.result, true, { |
| replace: replace2 |
| }); |
| return { shortCircuited: true }; |
| } |
| redirect2 = findRedirect(fetcherResults); |
| if (redirect2) { |
| fetchRedirectIds.add(redirect2.key); |
| await startRedirectNavigation(request, redirect2.result, true, { |
| replace: replace2 |
| }); |
| return { shortCircuited: true }; |
| } |
| let { loaderData, errors } = processLoaderData( |
| state, |
| matches, |
| loaderResults, |
| pendingActionResult, |
| revalidatingFetchers, |
| fetcherResults |
| ); |
| if (initialHydration && state.errors) { |
| errors = { ...state.errors, ...errors }; |
| } |
| let updatedFetchers = markFetchRedirectsDone(); |
| let didAbortFetchLoads = abortStaleFetchLoads(pendingNavigationLoadId); |
| let shouldUpdateFetchers = updatedFetchers || didAbortFetchLoads || revalidatingFetchers.length > 0; |
| return { |
| matches, |
| loaderData, |
| errors, |
| ...shouldUpdateFetchers ? { fetchers: new Map(state.fetchers) } : {} |
| }; |
| } |
| function getUpdatedActionData(pendingActionResult) { |
| if (pendingActionResult && !isErrorResult(pendingActionResult[1])) { |
| return { |
| [pendingActionResult[0]]: pendingActionResult[1].data |
| }; |
| } else if (state.actionData) { |
| if (Object.keys(state.actionData).length === 0) { |
| return null; |
| } else { |
| return state.actionData; |
| } |
| } |
| } |
| function getUpdatedRevalidatingFetchers(revalidatingFetchers) { |
| revalidatingFetchers.forEach((rf) => { |
| let fetcher = state.fetchers.get(rf.key); |
| let revalidatingFetcher = getLoadingFetcher( |
| void 0, |
| fetcher ? fetcher.data : void 0 |
| ); |
| state.fetchers.set(rf.key, revalidatingFetcher); |
| }); |
| return new Map(state.fetchers); |
| } |
| async function fetch2(key, routeId, href, opts) { |
| abortFetcher(key); |
| let flushSync = (opts && opts.flushSync) === true; |
| let routesToUse = inFlightDataRoutes || dataRoutes; |
| let normalizedPath = normalizeTo( |
| state.location, |
| state.matches, |
| basename, |
| href, |
| routeId, |
| _optionalChain([opts, 'optionalAccess', _23 => _23.relative]) |
| ); |
| let matches = matchRoutes(routesToUse, normalizedPath, basename); |
| let fogOfWar = checkFogOfWar(matches, routesToUse, normalizedPath); |
| if (fogOfWar.active && fogOfWar.matches) { |
| matches = fogOfWar.matches; |
| } |
| if (!matches) { |
| setFetcherError( |
| key, |
| routeId, |
| getInternalRouterError(404, { pathname: normalizedPath }), |
| { flushSync } |
| ); |
| return; |
| } |
| let { path, submission, error } = normalizeNavigateOptions( |
| true, |
| normalizedPath, |
| opts |
| ); |
| if (error) { |
| setFetcherError(key, routeId, error, { flushSync }); |
| return; |
| } |
| let scopedContext = init.getContext ? await init.getContext() : new RouterContextProvider(); |
| let preventScrollReset = (opts && opts.preventScrollReset) === true; |
| if (submission && isMutationMethod(submission.formMethod)) { |
| await handleFetcherAction( |
| key, |
| routeId, |
| path, |
| matches, |
| scopedContext, |
| fogOfWar.active, |
| flushSync, |
| preventScrollReset, |
| submission, |
| opts && opts.unstable_defaultShouldRevalidate |
| ); |
| return; |
| } |
| fetchLoadMatches.set(key, { routeId, path }); |
| await handleFetcherLoader( |
| key, |
| routeId, |
| path, |
| matches, |
| scopedContext, |
| fogOfWar.active, |
| flushSync, |
| preventScrollReset, |
| submission |
| ); |
| } |
| async function handleFetcherAction(key, routeId, path, requestMatches, scopedContext, isFogOfWar, flushSync, preventScrollReset, submission, callSiteDefaultShouldRevalidate) { |
| interruptActiveLoads(); |
| fetchLoadMatches.delete(key); |
| let existingFetcher = state.fetchers.get(key); |
| updateFetcherState(key, getSubmittingFetcher(submission, existingFetcher), { |
| flushSync |
| }); |
| let abortController = new AbortController(); |
| let fetchRequest = createClientSideRequest( |
| init.history, |
| path, |
| abortController.signal, |
| submission |
| ); |
| if (isFogOfWar) { |
| let discoverResult = await discoverRoutes( |
| requestMatches, |
| new URL(fetchRequest.url).pathname, |
| fetchRequest.signal, |
| key |
| ); |
| if (discoverResult.type === "aborted") { |
| return; |
| } else if (discoverResult.type === "error") { |
| setFetcherError(key, routeId, discoverResult.error, { flushSync }); |
| return; |
| } else if (!discoverResult.matches) { |
| setFetcherError( |
| key, |
| routeId, |
| getInternalRouterError(404, { pathname: path }), |
| { flushSync } |
| ); |
| return; |
| } else { |
| requestMatches = discoverResult.matches; |
| } |
| } |
| let match = getTargetMatch(requestMatches, path); |
| if (!match.route.action && !match.route.lazy) { |
| let error = getInternalRouterError(405, { |
| method: submission.formMethod, |
| pathname: path, |
| routeId |
| }); |
| setFetcherError(key, routeId, error, { flushSync }); |
| return; |
| } |
| fetchControllers.set(key, abortController); |
| let originatingLoadId = incrementingLoadId; |
| let fetchMatches = getTargetedDataStrategyMatches( |
| mapRouteProperties2, |
| manifest, |
| fetchRequest, |
| path, |
| requestMatches, |
| match, |
| hydrationRouteProperties2, |
| scopedContext |
| ); |
| let actionResults = await callDataStrategy( |
| fetchRequest, |
| path, |
| fetchMatches, |
| scopedContext, |
| key |
| ); |
| let actionResult = actionResults[match.route.id]; |
| if (!actionResult) { |
| for (let match2 of fetchMatches) { |
| if (actionResults[match2.route.id]) { |
| actionResult = actionResults[match2.route.id]; |
| break; |
| } |
| } |
| } |
| if (fetchRequest.signal.aborted) { |
| if (fetchControllers.get(key) === abortController) { |
| fetchControllers.delete(key); |
| } |
| return; |
| } |
| if (fetchersQueuedForDeletion.has(key)) { |
| if (isRedirectResult(actionResult) || isErrorResult(actionResult)) { |
| updateFetcherState(key, getDoneFetcher(void 0)); |
| return; |
| } |
| } else { |
| if (isRedirectResult(actionResult)) { |
| fetchControllers.delete(key); |
| if (pendingNavigationLoadId > originatingLoadId) { |
| updateFetcherState(key, getDoneFetcher(void 0)); |
| return; |
| } else { |
| fetchRedirectIds.add(key); |
| updateFetcherState(key, getLoadingFetcher(submission)); |
| return startRedirectNavigation(fetchRequest, actionResult, false, { |
| fetcherSubmission: submission, |
| preventScrollReset |
| }); |
| } |
| } |
| if (isErrorResult(actionResult)) { |
| setFetcherError(key, routeId, actionResult.error); |
| return; |
| } |
| } |
| let nextLocation = state.navigation.location || state.location; |
| let revalidationRequest = createClientSideRequest( |
| init.history, |
| nextLocation, |
| abortController.signal |
| ); |
| let routesToUse = inFlightDataRoutes || dataRoutes; |
| let matches = state.navigation.state !== "idle" ? matchRoutes(routesToUse, state.navigation.location, basename) : state.matches; |
| invariant(matches, "Didn't find any matches after fetcher action"); |
| let loadId = ++incrementingLoadId; |
| fetchReloadIds.set(key, loadId); |
| let loadFetcher = getLoadingFetcher(submission, actionResult.data); |
| state.fetchers.set(key, loadFetcher); |
| let { dsMatches, revalidatingFetchers } = getMatchesToLoad( |
| revalidationRequest, |
| scopedContext, |
| mapRouteProperties2, |
| manifest, |
| init.history, |
| state, |
| matches, |
| submission, |
| nextLocation, |
| hydrationRouteProperties2, |
| false, |
| isRevalidationRequired, |
| cancelledFetcherLoads, |
| fetchersQueuedForDeletion, |
| fetchLoadMatches, |
| fetchRedirectIds, |
| routesToUse, |
| basename, |
| init.patchRoutesOnNavigation != null, |
| [match.route.id, actionResult], |
| callSiteDefaultShouldRevalidate |
| ); |
| revalidatingFetchers.filter((rf) => rf.key !== key).forEach((rf) => { |
| let staleKey = rf.key; |
| let existingFetcher2 = state.fetchers.get(staleKey); |
| let revalidatingFetcher = getLoadingFetcher( |
| void 0, |
| existingFetcher2 ? existingFetcher2.data : void 0 |
| ); |
| state.fetchers.set(staleKey, revalidatingFetcher); |
| abortFetcher(staleKey); |
| if (rf.controller) { |
| fetchControllers.set(staleKey, rf.controller); |
| } |
| }); |
| updateState({ fetchers: new Map(state.fetchers) }); |
| let abortPendingFetchRevalidations = () => revalidatingFetchers.forEach((rf) => abortFetcher(rf.key)); |
| abortController.signal.addEventListener( |
| "abort", |
| abortPendingFetchRevalidations |
| ); |
| let { loaderResults, fetcherResults } = await callLoadersAndMaybeResolveData( |
| dsMatches, |
| revalidatingFetchers, |
| revalidationRequest, |
| nextLocation, |
| scopedContext |
| ); |
| if (abortController.signal.aborted) { |
| return; |
| } |
| abortController.signal.removeEventListener( |
| "abort", |
| abortPendingFetchRevalidations |
| ); |
| fetchReloadIds.delete(key); |
| fetchControllers.delete(key); |
| revalidatingFetchers.forEach((r) => fetchControllers.delete(r.key)); |
| if (state.fetchers.has(key)) { |
| let doneFetcher = getDoneFetcher(actionResult.data); |
| state.fetchers.set(key, doneFetcher); |
| } |
| let redirect2 = findRedirect(loaderResults); |
| if (redirect2) { |
| return startRedirectNavigation( |
| revalidationRequest, |
| redirect2.result, |
| false, |
| { preventScrollReset } |
| ); |
| } |
| redirect2 = findRedirect(fetcherResults); |
| if (redirect2) { |
| fetchRedirectIds.add(redirect2.key); |
| return startRedirectNavigation( |
| revalidationRequest, |
| redirect2.result, |
| false, |
| { preventScrollReset } |
| ); |
| } |
| let { loaderData, errors } = processLoaderData( |
| state, |
| matches, |
| loaderResults, |
| void 0, |
| revalidatingFetchers, |
| fetcherResults |
| ); |
| abortStaleFetchLoads(loadId); |
| if (state.navigation.state === "loading" && loadId > pendingNavigationLoadId) { |
| invariant(pendingAction, "Expected pending action"); |
| pendingNavigationController && pendingNavigationController.abort(); |
| completeNavigation(state.navigation.location, { |
| matches, |
| loaderData, |
| errors, |
| fetchers: new Map(state.fetchers) |
| }); |
| } else { |
| updateState({ |
| errors, |
| loaderData: mergeLoaderData( |
| state.loaderData, |
| loaderData, |
| matches, |
| errors |
| ), |
| fetchers: new Map(state.fetchers) |
| }); |
| isRevalidationRequired = false; |
| } |
| } |
| async function handleFetcherLoader(key, routeId, path, matches, scopedContext, isFogOfWar, flushSync, preventScrollReset, submission) { |
| let existingFetcher = state.fetchers.get(key); |
| updateFetcherState( |
| key, |
| getLoadingFetcher( |
| submission, |
| existingFetcher ? existingFetcher.data : void 0 |
| ), |
| { flushSync } |
| ); |
| let abortController = new AbortController(); |
| let fetchRequest = createClientSideRequest( |
| init.history, |
| path, |
| abortController.signal |
| ); |
| if (isFogOfWar) { |
| let discoverResult = await discoverRoutes( |
| matches, |
| new URL(fetchRequest.url).pathname, |
| fetchRequest.signal, |
| key |
| ); |
| if (discoverResult.type === "aborted") { |
| return; |
| } else if (discoverResult.type === "error") { |
| setFetcherError(key, routeId, discoverResult.error, { flushSync }); |
| return; |
| } else if (!discoverResult.matches) { |
| setFetcherError( |
| key, |
| routeId, |
| getInternalRouterError(404, { pathname: path }), |
| { flushSync } |
| ); |
| return; |
| } else { |
| matches = discoverResult.matches; |
| } |
| } |
| let match = getTargetMatch(matches, path); |
| fetchControllers.set(key, abortController); |
| let originatingLoadId = incrementingLoadId; |
| let dsMatches = getTargetedDataStrategyMatches( |
| mapRouteProperties2, |
| manifest, |
| fetchRequest, |
| path, |
| matches, |
| match, |
| hydrationRouteProperties2, |
| scopedContext |
| ); |
| let results = await callDataStrategy( |
| fetchRequest, |
| path, |
| dsMatches, |
| scopedContext, |
| key |
| ); |
| let result = results[match.route.id]; |
| if (!result) { |
| for (let match2 of matches) { |
| if (results[match2.route.id]) { |
| result = results[match2.route.id]; |
| break; |
| } |
| } |
| } |
| if (fetchControllers.get(key) === abortController) { |
| fetchControllers.delete(key); |
| } |
| if (fetchRequest.signal.aborted) { |
| return; |
| } |
| if (fetchersQueuedForDeletion.has(key)) { |
| updateFetcherState(key, getDoneFetcher(void 0)); |
| return; |
| } |
| if (isRedirectResult(result)) { |
| if (pendingNavigationLoadId > originatingLoadId) { |
| updateFetcherState(key, getDoneFetcher(void 0)); |
| return; |
| } else { |
| fetchRedirectIds.add(key); |
| await startRedirectNavigation(fetchRequest, result, false, { |
| preventScrollReset |
| }); |
| return; |
| } |
| } |
| if (isErrorResult(result)) { |
| setFetcherError(key, routeId, result.error); |
| return; |
| } |
| updateFetcherState(key, getDoneFetcher(result.data)); |
| } |
| async function startRedirectNavigation(request, redirect2, isNavigation, { |
| submission, |
| fetcherSubmission, |
| preventScrollReset, |
| replace: replace2 |
| } = {}) { |
| if (!isNavigation) { |
| _optionalChain([pendingPopstateNavigationDfd, 'optionalAccess', _24 => _24.resolve, 'call', _25 => _25()]); |
| pendingPopstateNavigationDfd = null; |
| } |
| if (redirect2.response.headers.has("X-Remix-Revalidate")) { |
| isRevalidationRequired = true; |
| } |
| let location = redirect2.response.headers.get("Location"); |
| invariant(location, "Expected a Location header on the redirect Response"); |
| location = normalizeRedirectLocation( |
| location, |
| new URL(request.url), |
| basename, |
| init.history |
| ); |
| let redirectLocation = createLocation(state.location, location, { |
| _isRedirect: true |
| }); |
| if (isBrowser2) { |
| let isDocumentReload = false; |
| if (redirect2.response.headers.has("X-Remix-Reload-Document")) { |
| isDocumentReload = true; |
| } else if (isAbsoluteUrl(location)) { |
| const url = createBrowserURLImpl(location, true); |
| isDocumentReload = |
| url.origin !== routerWindow.location.origin || |
| stripBasename(url.pathname, basename) == null; |
| } |
| if (isDocumentReload) { |
| if (replace2) { |
| routerWindow.location.replace(location); |
| } else { |
| routerWindow.location.assign(location); |
| } |
| return; |
| } |
| } |
| pendingNavigationController = null; |
| let redirectNavigationType = replace2 === true || redirect2.response.headers.has("X-Remix-Replace") ? "REPLACE" : "PUSH" ; |
| let { formMethod, formAction, formEncType } = state.navigation; |
| if (!submission && !fetcherSubmission && formMethod && formAction && formEncType) { |
| submission = getSubmissionFromNavigation(state.navigation); |
| } |
| let activeSubmission = submission || fetcherSubmission; |
| if (redirectPreserveMethodStatusCodes.has(redirect2.response.status) && activeSubmission && isMutationMethod(activeSubmission.formMethod)) { |
| await startNavigation(redirectNavigationType, redirectLocation, { |
| submission: { |
| ...activeSubmission, |
| formAction: location |
| }, |
| |
| preventScrollReset: preventScrollReset || pendingPreventScrollReset, |
| enableViewTransition: isNavigation ? pendingViewTransitionEnabled : void 0 |
| }); |
| } else { |
| let overrideNavigation = getLoadingNavigation( |
| redirectLocation, |
| submission |
| ); |
| await startNavigation(redirectNavigationType, redirectLocation, { |
| overrideNavigation, |
| |
| fetcherSubmission, |
| |
| preventScrollReset: preventScrollReset || pendingPreventScrollReset, |
| enableViewTransition: isNavigation ? pendingViewTransitionEnabled : void 0 |
| }); |
| } |
| } |
| async function callDataStrategy(request, path, matches, scopedContext, fetcherKey) { |
| let results; |
| let dataResults = {}; |
| try { |
| results = await callDataStrategyImpl( |
| dataStrategyImpl, |
| request, |
| path, |
| matches, |
| fetcherKey, |
| scopedContext, |
| false |
| ); |
| } catch (e) { |
| matches.filter((m) => m.shouldLoad).forEach((m) => { |
| dataResults[m.route.id] = { |
| type: "error" , |
| error: e |
| }; |
| }); |
| return dataResults; |
| } |
| if (request.signal.aborted) { |
| return dataResults; |
| } |
| if (!isMutationMethod(request.method)) { |
| for (let match of matches) { |
| if (_optionalChain([results, 'access', _26 => _26[match.route.id], 'optionalAccess', _27 => _27.type]) === "error" ) { |
| break; |
| } |
| if (!results.hasOwnProperty(match.route.id) && !state.loaderData.hasOwnProperty(match.route.id) && (!state.errors || !state.errors.hasOwnProperty(match.route.id)) && match.shouldCallHandler()) { |
| results[match.route.id] = { |
| type: "error" , |
| result: new Error( |
| `No result returned from dataStrategy for route ${match.route.id}` |
| ) |
| }; |
| } |
| } |
| } |
| for (let [routeId, result] of Object.entries(results)) { |
| if (isRedirectDataStrategyResult(result)) { |
| let response = result.result; |
| dataResults[routeId] = { |
| type: "redirect" , |
| response: normalizeRelativeRoutingRedirectResponse( |
| response, |
| request, |
| routeId, |
| matches, |
| basename |
| ) |
| }; |
| } else { |
| dataResults[routeId] = await convertDataStrategyResultToDataResult(result); |
| } |
| } |
| return dataResults; |
| } |
| async function callLoadersAndMaybeResolveData(matches, fetchersToLoad, request, location, scopedContext) { |
| let loaderResultsPromise = callDataStrategy( |
| request, |
| location, |
| matches, |
| scopedContext, |
| null |
| ); |
| let fetcherResultsPromise = Promise.all( |
| fetchersToLoad.map(async (f) => { |
| if (f.matches && f.match && f.request && f.controller) { |
| let results = await callDataStrategy( |
| f.request, |
| f.path, |
| f.matches, |
| scopedContext, |
| f.key |
| ); |
| let result = results[f.match.route.id]; |
| return { [f.key]: result }; |
| } else { |
| return Promise.resolve({ |
| [f.key]: { |
| type: "error" , |
| error: getInternalRouterError(404, { |
| pathname: f.path |
| }) |
| } |
| }); |
| } |
| }) |
| ); |
| let loaderResults = await loaderResultsPromise; |
| let fetcherResults = (await fetcherResultsPromise).reduce( |
| (acc, r) => Object.assign(acc, r), |
| {} |
| ); |
| return { |
| loaderResults, |
| fetcherResults |
| }; |
| } |
| function interruptActiveLoads() { |
| isRevalidationRequired = true; |
| fetchLoadMatches.forEach((_, key) => { |
| if (fetchControllers.has(key)) { |
| cancelledFetcherLoads.add(key); |
| } |
| abortFetcher(key); |
| }); |
| } |
| function updateFetcherState(key, fetcher, opts = {}) { |
| state.fetchers.set(key, fetcher); |
| updateState( |
| { fetchers: new Map(state.fetchers) }, |
| { flushSync: (opts && opts.flushSync) === true } |
| ); |
| } |
| function setFetcherError(key, routeId, error, opts = {}) { |
| let boundaryMatch = findNearestBoundary(state.matches, routeId); |
| deleteFetcher(key); |
| updateState( |
| { |
| errors: { |
| [boundaryMatch.route.id]: error |
| }, |
| fetchers: new Map(state.fetchers) |
| }, |
| { flushSync: (opts && opts.flushSync) === true } |
| ); |
| } |
| function getFetcher(key) { |
| activeFetchers.set(key, (activeFetchers.get(key) || 0) + 1); |
| if (fetchersQueuedForDeletion.has(key)) { |
| fetchersQueuedForDeletion.delete(key); |
| } |
| return state.fetchers.get(key) || IDLE_FETCHER; |
| } |
| function resetFetcher(key, opts) { |
| abortFetcher(key, _optionalChain([opts, 'optionalAccess', _28 => _28.reason])); |
| updateFetcherState(key, getDoneFetcher(null)); |
| } |
| function deleteFetcher(key) { |
| let fetcher = state.fetchers.get(key); |
| if (fetchControllers.has(key) && !(fetcher && fetcher.state === "loading" && fetchReloadIds.has(key))) { |
| abortFetcher(key); |
| } |
| fetchLoadMatches.delete(key); |
| fetchReloadIds.delete(key); |
| fetchRedirectIds.delete(key); |
| fetchersQueuedForDeletion.delete(key); |
| cancelledFetcherLoads.delete(key); |
| state.fetchers.delete(key); |
| } |
| function queueFetcherForDeletion(key) { |
| let count = (activeFetchers.get(key) || 0) - 1; |
| if (count <= 0) { |
| activeFetchers.delete(key); |
| fetchersQueuedForDeletion.add(key); |
| } else { |
| activeFetchers.set(key, count); |
| } |
| updateState({ fetchers: new Map(state.fetchers) }); |
| } |
| function abortFetcher(key, reason) { |
| let controller = fetchControllers.get(key); |
| if (controller) { |
| controller.abort(reason); |
| fetchControllers.delete(key); |
| } |
| } |
| function markFetchersDone(keys) { |
| for (let key of keys) { |
| let fetcher = getFetcher(key); |
| let doneFetcher = getDoneFetcher(fetcher.data); |
| state.fetchers.set(key, doneFetcher); |
| } |
| } |
| function markFetchRedirectsDone() { |
| let doneKeys = []; |
| let updatedFetchers = false; |
| for (let key of fetchRedirectIds) { |
| let fetcher = state.fetchers.get(key); |
| invariant(fetcher, `Expected fetcher: ${key}`); |
| if (fetcher.state === "loading") { |
| fetchRedirectIds.delete(key); |
| doneKeys.push(key); |
| updatedFetchers = true; |
| } |
| } |
| markFetchersDone(doneKeys); |
| return updatedFetchers; |
| } |
| function abortStaleFetchLoads(landedId) { |
| let yeetedKeys = []; |
| for (let [key, id] of fetchReloadIds) { |
| if (id < landedId) { |
| let fetcher = state.fetchers.get(key); |
| invariant(fetcher, `Expected fetcher: ${key}`); |
| if (fetcher.state === "loading") { |
| abortFetcher(key); |
| fetchReloadIds.delete(key); |
| yeetedKeys.push(key); |
| } |
| } |
| } |
| markFetchersDone(yeetedKeys); |
| return yeetedKeys.length > 0; |
| } |
| function getBlocker(key, fn) { |
| let blocker = state.blockers.get(key) || IDLE_BLOCKER; |
| if (blockerFunctions.get(key) !== fn) { |
| blockerFunctions.set(key, fn); |
| } |
| return blocker; |
| } |
| function deleteBlocker(key) { |
| state.blockers.delete(key); |
| blockerFunctions.delete(key); |
| } |
| function updateBlocker(key, newBlocker) { |
| let blocker = state.blockers.get(key) || IDLE_BLOCKER; |
| invariant( |
| blocker.state === "unblocked" && newBlocker.state === "blocked" || blocker.state === "blocked" && newBlocker.state === "blocked" || blocker.state === "blocked" && newBlocker.state === "proceeding" || blocker.state === "blocked" && newBlocker.state === "unblocked" || blocker.state === "proceeding" && newBlocker.state === "unblocked", |
| `Invalid blocker state transition: ${blocker.state} -> ${newBlocker.state}` |
| ); |
| let blockers = new Map(state.blockers); |
| blockers.set(key, newBlocker); |
| updateState({ blockers }); |
| } |
| function shouldBlockNavigation({ |
| currentLocation, |
| nextLocation, |
| historyAction |
| }) { |
| if (blockerFunctions.size === 0) { |
| return; |
| } |
| if (blockerFunctions.size > 1) { |
| warning(false, "A router only supports one blocker at a time"); |
| } |
| let entries = Array.from(blockerFunctions.entries()); |
| let [blockerKey, blockerFunction] = entries[entries.length - 1]; |
| let blocker = state.blockers.get(blockerKey); |
| if (blocker && blocker.state === "proceeding") { |
| return; |
| } |
| if (blockerFunction({ currentLocation, nextLocation, historyAction })) { |
| return blockerKey; |
| } |
| } |
| function handleNavigational404(pathname) { |
| let error = getInternalRouterError(404, { pathname }); |
| let routesToUse = inFlightDataRoutes || dataRoutes; |
| let { matches, route } = getShortCircuitMatches(routesToUse); |
| return { notFoundMatches: matches, route, error }; |
| } |
| function enableScrollRestoration(positions, getPosition, getKey) { |
| savedScrollPositions = positions; |
| getScrollPosition = getPosition; |
| getScrollRestorationKey = getKey || null; |
| if (!initialScrollRestored && state.navigation === IDLE_NAVIGATION) { |
| initialScrollRestored = true; |
| let y = getSavedScrollPosition(state.location, state.matches); |
| if (y != null) { |
| updateState({ restoreScrollPosition: y }); |
| } |
| } |
| return () => { |
| savedScrollPositions = null; |
| getScrollPosition = null; |
| getScrollRestorationKey = null; |
| }; |
| } |
| function getScrollKey(location, matches) { |
| if (getScrollRestorationKey) { |
| let key = getScrollRestorationKey( |
| location, |
| matches.map((m) => convertRouteMatchToUiMatch(m, state.loaderData)) |
| ); |
| return key || location.key; |
| } |
| return location.key; |
| } |
| function saveScrollPosition(location, matches) { |
| if (savedScrollPositions && getScrollPosition) { |
| let key = getScrollKey(location, matches); |
| savedScrollPositions[key] = getScrollPosition(); |
| } |
| } |
| function getSavedScrollPosition(location, matches) { |
| if (savedScrollPositions) { |
| let key = getScrollKey(location, matches); |
| let y = savedScrollPositions[key]; |
| if (typeof y === "number") { |
| return y; |
| } |
| } |
| return null; |
| } |
| function checkFogOfWar(matches, routesToUse, pathname) { |
| if (init.patchRoutesOnNavigation) { |
| if (!matches) { |
| let fogMatches = matchRoutesImpl( |
| routesToUse, |
| pathname, |
| basename, |
| true |
| ); |
| return { active: true, matches: fogMatches || [] }; |
| } else { |
| if (Object.keys(matches[0].params).length > 0) { |
| let partialMatches = matchRoutesImpl( |
| routesToUse, |
| pathname, |
| basename, |
| true |
| ); |
| return { active: true, matches: partialMatches }; |
| } |
| } |
| } |
| return { active: false, matches: null }; |
| } |
| async function discoverRoutes(matches, pathname, signal, fetcherKey) { |
| if (!init.patchRoutesOnNavigation) { |
| return { type: "success", matches }; |
| } |
| let partialMatches = matches; |
| while (true) { |
| let isNonHMR = inFlightDataRoutes == null; |
| let routesToUse = inFlightDataRoutes || dataRoutes; |
| let localManifest = manifest; |
| try { |
| await init.patchRoutesOnNavigation({ |
| signal, |
| path: pathname, |
| matches: partialMatches, |
| fetcherKey, |
| patch: (routeId, children) => { |
| if (signal.aborted) return; |
| patchRoutesImpl( |
| routeId, |
| children, |
| routesToUse, |
| localManifest, |
| mapRouteProperties2, |
| false |
| ); |
| } |
| }); |
| } catch (e) { |
| return { type: "error", error: e, partialMatches }; |
| } finally { |
| if (isNonHMR && !signal.aborted) { |
| dataRoutes = [...dataRoutes]; |
| } |
| } |
| if (signal.aborted) { |
| return { type: "aborted" }; |
| } |
| let newMatches = matchRoutes(routesToUse, pathname, basename); |
| let newPartialMatches = null; |
| if (newMatches) { |
| if (Object.keys(newMatches[0].params).length === 0) { |
| return { type: "success", matches: newMatches }; |
| } else { |
| newPartialMatches = matchRoutesImpl( |
| routesToUse, |
| pathname, |
| basename, |
| true |
| ); |
| let matchedDeeper = newPartialMatches && partialMatches.length < newPartialMatches.length && compareMatches( |
| partialMatches, |
| newPartialMatches.slice(0, partialMatches.length) |
| ); |
| if (!matchedDeeper) { |
| return { type: "success", matches: newMatches }; |
| } |
| } |
| } |
| if (!newPartialMatches) { |
| newPartialMatches = matchRoutesImpl( |
| routesToUse, |
| pathname, |
| basename, |
| true |
| ); |
| } |
| if (!newPartialMatches || compareMatches(partialMatches, newPartialMatches)) { |
| return { type: "success", matches: null }; |
| } |
| partialMatches = newPartialMatches; |
| } |
| } |
| function compareMatches(a, b) { |
| return a.length === b.length && a.every((m, i) => m.route.id === b[i].route.id); |
| } |
| function _internalSetRoutes(newRoutes) { |
| manifest = {}; |
| inFlightDataRoutes = convertRoutesToDataRoutes( |
| newRoutes, |
| mapRouteProperties2, |
| void 0, |
| manifest |
| ); |
| } |
| function patchRoutes(routeId, children, unstable_allowElementMutations = false) { |
| let isNonHMR = inFlightDataRoutes == null; |
| let routesToUse = inFlightDataRoutes || dataRoutes; |
| patchRoutesImpl( |
| routeId, |
| children, |
| routesToUse, |
| manifest, |
| mapRouteProperties2, |
| unstable_allowElementMutations |
| ); |
| if (isNonHMR) { |
| dataRoutes = [...dataRoutes]; |
| updateState({}); |
| } |
| } |
| router = { |
| get basename() { |
| return basename; |
| }, |
| get future() { |
| return future; |
| }, |
| get state() { |
| return state; |
| }, |
| get routes() { |
| return dataRoutes; |
| }, |
| get window() { |
| return routerWindow; |
| }, |
| initialize, |
| subscribe, |
| enableScrollRestoration, |
| navigate, |
| fetch: fetch2, |
| revalidate, |
| |
| |
| createHref: (to) => init.history.createHref(to), |
| encodeLocation: (to) => init.history.encodeLocation(to), |
| getFetcher, |
| resetFetcher, |
| deleteFetcher: queueFetcherForDeletion, |
| dispose, |
| getBlocker, |
| deleteBlocker, |
| patchRoutes, |
| _internalFetchControllers: fetchControllers, |
| |
| |
| _internalSetRoutes, |
| _internalSetStateDoNotUseOrYouWillBreakYourApp(newState) { |
| updateState(newState); |
| } |
| }; |
| if (init.unstable_instrumentations) { |
| router = instrumentClientSideRouter( |
| router, |
| init.unstable_instrumentations.map((i) => i.router).filter(Boolean) |
| ); |
| } |
| return router; |
| } |
| function createStaticHandler(routes, opts) { |
| invariant( |
| routes.length > 0, |
| "You must provide a non-empty routes array to createStaticHandler" |
| ); |
| let manifest = {}; |
| let basename = (opts ? opts.basename : null) || "/"; |
| let _mapRouteProperties = _optionalChain([opts, 'optionalAccess', _29 => _29.mapRouteProperties]) || defaultMapRouteProperties; |
| let mapRouteProperties2 = _mapRouteProperties; |
| let future = { |
| unstable_passThroughRequests: false, |
| |
| ..._optionalChain([opts, 'optionalAccess', _30 => _30.future]) |
| }; |
| if (_optionalChain([opts, 'optionalAccess', _31 => _31.unstable_instrumentations])) { |
| let instrumentations = opts.unstable_instrumentations; |
| mapRouteProperties2 = (route) => { |
| return { |
| ..._mapRouteProperties(route), |
| ...getRouteInstrumentationUpdates( |
| instrumentations.map((i) => i.route).filter(Boolean), |
| route |
| ) |
| }; |
| }; |
| } |
| let dataRoutes = convertRoutesToDataRoutes( |
| routes, |
| mapRouteProperties2, |
| void 0, |
| manifest |
| ); |
| async function query(request, { |
| requestContext, |
| filterMatchesToLoad, |
| skipLoaderErrorBubbling, |
| skipRevalidation, |
| dataStrategy, |
| generateMiddlewareResponse, |
| unstable_normalizePath |
| } = {}) { |
| let normalizePath = unstable_normalizePath || defaultNormalizePath; |
| let method = request.method; |
| let location = createLocation("", normalizePath(request), null, "default"); |
| let matches = matchRoutes(dataRoutes, location, basename); |
| requestContext = requestContext != null ? requestContext : new RouterContextProvider(); |
| if (!isValidMethod(method) && method !== "HEAD") { |
| let error = getInternalRouterError(405, { method }); |
| let { matches: methodNotAllowedMatches, route } = getShortCircuitMatches(dataRoutes); |
| let staticContext = { |
| basename, |
| location, |
| matches: methodNotAllowedMatches, |
| loaderData: {}, |
| actionData: null, |
| errors: { |
| [route.id]: error |
| }, |
| statusCode: error.status, |
| loaderHeaders: {}, |
| actionHeaders: {} |
| }; |
| return generateMiddlewareResponse ? generateMiddlewareResponse(() => Promise.resolve(staticContext)) : staticContext; |
| } else if (!matches) { |
| let error = getInternalRouterError(404, { pathname: location.pathname }); |
| let { matches: notFoundMatches, route } = getShortCircuitMatches(dataRoutes); |
| let staticContext = { |
| basename, |
| location, |
| matches: notFoundMatches, |
| loaderData: {}, |
| actionData: null, |
| errors: { |
| [route.id]: error |
| }, |
| statusCode: error.status, |
| loaderHeaders: {}, |
| actionHeaders: {} |
| }; |
| return generateMiddlewareResponse ? generateMiddlewareResponse(() => Promise.resolve(staticContext)) : staticContext; |
| } |
| if (generateMiddlewareResponse) { |
| invariant( |
| requestContext instanceof RouterContextProvider, |
| "When using middleware in `staticHandler.query()`, any provided `requestContext` must be an instance of `RouterContextProvider`" |
| ); |
| try { |
| await loadLazyMiddlewareForMatches( |
| matches, |
| manifest, |
| mapRouteProperties2 |
| ); |
| let renderedStaticContext; |
| let response = await runServerMiddlewarePipeline( |
| { |
| request, |
| unstable_url: createDataFunctionUrl(request, location), |
| unstable_pattern: getRoutePattern(matches), |
| matches, |
| params: matches[0].params, |
| |
| |
| context: requestContext |
| }, |
| async () => { |
| let res = await generateMiddlewareResponse( |
| async (revalidationRequest, opts2 = {}) => { |
| let result2 = await queryImpl( |
| revalidationRequest, |
| location, |
| matches, |
| requestContext, |
| dataStrategy || null, |
| skipLoaderErrorBubbling === true, |
| null, |
| "filterMatchesToLoad" in opts2 ? _nullishCoalesce(opts2.filterMatchesToLoad, () => ( null)) : _nullishCoalesce(filterMatchesToLoad, () => ( null)), |
| skipRevalidation === true |
| ); |
| if (isResponse(result2)) { |
| return result2; |
| } |
| renderedStaticContext = { location, basename, ...result2 }; |
| return renderedStaticContext; |
| } |
| ); |
| return res; |
| }, |
| async (error, routeId) => { |
| if (isRedirectResponse(error)) { |
| return error; |
| } |
| if (isResponse(error)) { |
| try { |
| error = new ErrorResponseImpl( |
| error.status, |
| error.statusText, |
| await parseResponseBody(error) |
| ); |
| } catch (e) { |
| error = e; |
| } |
| } |
| if (isDataWithResponseInit(error)) { |
| error = dataWithResponseInitToErrorResponse(error); |
| } |
| if (renderedStaticContext) { |
| if (routeId in renderedStaticContext.loaderData) { |
| renderedStaticContext.loaderData[routeId] = void 0; |
| } |
| let staticContext = getStaticContextFromError( |
| dataRoutes, |
| renderedStaticContext, |
| error, |
| skipLoaderErrorBubbling ? routeId : findNearestBoundary(matches, routeId).route.id |
| ); |
| return generateMiddlewareResponse( |
| () => Promise.resolve(staticContext) |
| ); |
| } else { |
| let boundaryRouteId = skipLoaderErrorBubbling ? routeId : findNearestBoundary( |
| matches, |
| _optionalChain([matches, 'access', _32 => _32.find, 'call', _33 => _33( |
| (m) => m.route.id === routeId || m.route.loader |
| ), 'optionalAccess', _34 => _34.route, 'access', _35 => _35.id]) || routeId |
| ).route.id; |
| let staticContext = { |
| matches, |
| location, |
| basename, |
| loaderData: {}, |
| actionData: null, |
| errors: { |
| [boundaryRouteId]: error |
| }, |
| statusCode: isRouteErrorResponse(error) ? error.status : 500, |
| actionHeaders: {}, |
| loaderHeaders: {} |
| }; |
| return generateMiddlewareResponse( |
| () => Promise.resolve(staticContext) |
| ); |
| } |
| } |
| ); |
| invariant(isResponse(response), "Expected a response in query()"); |
| return response; |
| } catch (e) { |
| if (isResponse(e)) { |
| return e; |
| } |
| throw e; |
| } |
| } |
| let result = await queryImpl( |
| request, |
| location, |
| matches, |
| requestContext, |
| dataStrategy || null, |
| skipLoaderErrorBubbling === true, |
| null, |
| filterMatchesToLoad || null, |
| skipRevalidation === true |
| ); |
| if (isResponse(result)) { |
| return result; |
| } |
| return { location, basename, ...result }; |
| } |
| async function queryRoute(request, { |
| routeId, |
| requestContext, |
| dataStrategy, |
| generateMiddlewareResponse, |
| unstable_normalizePath |
| } = {}) { |
| let normalizePath = unstable_normalizePath || defaultNormalizePath; |
| let method = request.method; |
| let location = createLocation("", normalizePath(request), null, "default"); |
| let matches = matchRoutes(dataRoutes, location, basename); |
| requestContext = requestContext != null ? requestContext : new RouterContextProvider(); |
| if (!isValidMethod(method) && method !== "HEAD" && method !== "OPTIONS") { |
| throw getInternalRouterError(405, { method }); |
| } else if (!matches) { |
| throw getInternalRouterError(404, { pathname: location.pathname }); |
| } |
| let match = routeId ? matches.find((m) => m.route.id === routeId) : getTargetMatch(matches, location); |
| if (routeId && !match) { |
| throw getInternalRouterError(403, { |
| pathname: location.pathname, |
| routeId |
| }); |
| } else if (!match) { |
| throw getInternalRouterError(404, { pathname: location.pathname }); |
| } |
| if (generateMiddlewareResponse) { |
| invariant( |
| requestContext instanceof RouterContextProvider, |
| "When using middleware in `staticHandler.queryRoute()`, any provided `requestContext` must be an instance of `RouterContextProvider`" |
| ); |
| await loadLazyMiddlewareForMatches(matches, manifest, mapRouteProperties2); |
| let response = await runServerMiddlewarePipeline( |
| { |
| request, |
| unstable_url: createDataFunctionUrl(request, location), |
| unstable_pattern: getRoutePattern(matches), |
| matches, |
| params: matches[0].params, |
| |
| |
| context: requestContext |
| }, |
| async () => { |
| let res = await generateMiddlewareResponse( |
| async (innerRequest) => { |
| let result2 = await queryImpl( |
| innerRequest, |
| location, |
| matches, |
| requestContext, |
| dataStrategy || null, |
| false, |
| match, |
| null, |
| false |
| ); |
| let processed = handleQueryResult(result2); |
| return isResponse(processed) ? processed : typeof processed === "string" ? new Response(processed) : Response.json(processed); |
| } |
| ); |
| return res; |
| }, |
| (error) => { |
| if (isDataWithResponseInit(error)) { |
| return Promise.resolve(dataWithResponseInitToResponse(error)); |
| } |
| if (isResponse(error)) { |
| return Promise.resolve(error); |
| } |
| throw error; |
| } |
| ); |
| return response; |
| } |
| let result = await queryImpl( |
| request, |
| location, |
| matches, |
| requestContext, |
| dataStrategy || null, |
| false, |
| match, |
| null, |
| false |
| ); |
| return handleQueryResult(result); |
| function handleQueryResult(result2) { |
| if (isResponse(result2)) { |
| return result2; |
| } |
| let error = result2.errors ? Object.values(result2.errors)[0] : void 0; |
| if (error !== void 0) { |
| throw error; |
| } |
| if (result2.actionData) { |
| return Object.values(result2.actionData)[0]; |
| } |
| if (result2.loaderData) { |
| return Object.values(result2.loaderData)[0]; |
| } |
| return void 0; |
| } |
| } |
| async function queryImpl(request, location, matches, requestContext, dataStrategy, skipLoaderErrorBubbling, routeMatch, filterMatchesToLoad, skipRevalidation) { |
| invariant( |
| request.signal, |
| "query()/queryRoute() requests must contain an AbortController signal" |
| ); |
| try { |
| if (isMutationMethod(request.method)) { |
| let result2 = await submit( |
| request, |
| location, |
| matches, |
| routeMatch || getTargetMatch(matches, location), |
| requestContext, |
| dataStrategy, |
| skipLoaderErrorBubbling, |
| routeMatch != null, |
| filterMatchesToLoad, |
| skipRevalidation |
| ); |
| return result2; |
| } |
| let result = await loadRouteData( |
| request, |
| location, |
| matches, |
| requestContext, |
| dataStrategy, |
| skipLoaderErrorBubbling, |
| routeMatch, |
| filterMatchesToLoad |
| ); |
| return isResponse(result) ? result : { |
| ...result, |
| actionData: null, |
| actionHeaders: {} |
| }; |
| } catch (e) { |
| if (isDataStrategyResult(e) && isResponse(e.result)) { |
| if (e.type === "error" ) { |
| throw e.result; |
| } |
| return e.result; |
| } |
| if (isRedirectResponse(e)) { |
| return e; |
| } |
| throw e; |
| } |
| } |
| async function submit(request, location, matches, actionMatch, requestContext, dataStrategy, skipLoaderErrorBubbling, isRouteRequest, filterMatchesToLoad, skipRevalidation) { |
| let result; |
| if (!actionMatch.route.action && !actionMatch.route.lazy) { |
| let error = getInternalRouterError(405, { |
| method: request.method, |
| pathname: new URL(request.url).pathname, |
| routeId: actionMatch.route.id |
| }); |
| if (isRouteRequest) { |
| throw error; |
| } |
| result = { |
| type: "error" , |
| error |
| }; |
| } else { |
| let dsMatches = getTargetedDataStrategyMatches( |
| mapRouteProperties2, |
| manifest, |
| request, |
| location, |
| matches, |
| actionMatch, |
| [], |
| requestContext |
| ); |
| let results = await callDataStrategy( |
| request, |
| location, |
| dsMatches, |
| isRouteRequest, |
| requestContext, |
| dataStrategy |
| ); |
| result = results[actionMatch.route.id]; |
| if (request.signal.aborted) { |
| throwStaticHandlerAbortedError(request, isRouteRequest); |
| } |
| } |
| if (isRedirectResult(result)) { |
| throw new Response(null, { |
| status: result.response.status, |
| headers: { |
| Location: result.response.headers.get("Location") |
| } |
| }); |
| } |
| if (isRouteRequest) { |
| if (isErrorResult(result)) { |
| throw result.error; |
| } |
| return { |
| matches: [actionMatch], |
| loaderData: {}, |
| actionData: { [actionMatch.route.id]: result.data }, |
| errors: null, |
| |
| |
| statusCode: 200, |
| loaderHeaders: {}, |
| actionHeaders: {} |
| }; |
| } |
| if (skipRevalidation) { |
| if (isErrorResult(result)) { |
| let boundaryMatch = skipLoaderErrorBubbling ? actionMatch : findNearestBoundary(matches, actionMatch.route.id); |
| return { |
| statusCode: isRouteErrorResponse(result.error) ? result.error.status : result.statusCode != null ? result.statusCode : 500, |
| actionData: null, |
| actionHeaders: { |
| ...result.headers ? { [actionMatch.route.id]: result.headers } : {} |
| }, |
| matches, |
| loaderData: {}, |
| errors: { |
| [boundaryMatch.route.id]: result.error |
| }, |
| loaderHeaders: {} |
| }; |
| } else { |
| return { |
| actionData: { |
| [actionMatch.route.id]: result.data |
| }, |
| actionHeaders: result.headers ? { [actionMatch.route.id]: result.headers } : {}, |
| matches, |
| loaderData: {}, |
| errors: null, |
| statusCode: result.statusCode || 200, |
| loaderHeaders: {} |
| }; |
| } |
| } |
| let loaderRequest = new Request(request.url, { |
| headers: request.headers, |
| redirect: request.redirect, |
| signal: request.signal |
| }); |
| if (isErrorResult(result)) { |
| let boundaryMatch = skipLoaderErrorBubbling ? actionMatch : findNearestBoundary(matches, actionMatch.route.id); |
| let handlerContext2 = await loadRouteData( |
| loaderRequest, |
| location, |
| matches, |
| requestContext, |
| dataStrategy, |
| skipLoaderErrorBubbling, |
| null, |
| filterMatchesToLoad, |
| [boundaryMatch.route.id, result] |
| ); |
| return { |
| ...handlerContext2, |
| statusCode: isRouteErrorResponse(result.error) ? result.error.status : result.statusCode != null ? result.statusCode : 500, |
| actionData: null, |
| actionHeaders: { |
| ...result.headers ? { [actionMatch.route.id]: result.headers } : {} |
| } |
| }; |
| } |
| let handlerContext = await loadRouteData( |
| loaderRequest, |
| location, |
| matches, |
| requestContext, |
| dataStrategy, |
| skipLoaderErrorBubbling, |
| null, |
| filterMatchesToLoad |
| ); |
| return { |
| ...handlerContext, |
| actionData: { |
| [actionMatch.route.id]: result.data |
| }, |
| |
| ...result.statusCode ? { statusCode: result.statusCode } : {}, |
| actionHeaders: result.headers ? { [actionMatch.route.id]: result.headers } : {} |
| }; |
| } |
| async function loadRouteData(request, location, matches, requestContext, dataStrategy, skipLoaderErrorBubbling, routeMatch, filterMatchesToLoad, pendingActionResult) { |
| let isRouteRequest = routeMatch != null; |
| if (isRouteRequest && !_optionalChain([routeMatch, 'optionalAccess', _36 => _36.route, 'access', _37 => _37.loader]) && !_optionalChain([routeMatch, 'optionalAccess', _38 => _38.route, 'access', _39 => _39.lazy])) { |
| throw getInternalRouterError(400, { |
| method: request.method, |
| pathname: new URL(request.url).pathname, |
| routeId: _optionalChain([routeMatch, 'optionalAccess', _40 => _40.route, 'access', _41 => _41.id]) |
| }); |
| } |
| let dsMatches; |
| if (routeMatch) { |
| dsMatches = getTargetedDataStrategyMatches( |
| mapRouteProperties2, |
| manifest, |
| request, |
| location, |
| matches, |
| routeMatch, |
| [], |
| requestContext |
| ); |
| } else { |
| let maxIdx = pendingActionResult && isErrorResult(pendingActionResult[1]) ? ( |
| |
| matches.findIndex((m) => m.route.id === pendingActionResult[0]) - 1 |
| ) : void 0; |
| let pattern = getRoutePattern(matches); |
| dsMatches = matches.map((match, index) => { |
| if (maxIdx != null && index > maxIdx) { |
| return getDataStrategyMatch( |
| mapRouteProperties2, |
| manifest, |
| request, |
| location, |
| pattern, |
| match, |
| [], |
| requestContext, |
| false |
| ); |
| } |
| return getDataStrategyMatch( |
| mapRouteProperties2, |
| manifest, |
| request, |
| location, |
| pattern, |
| match, |
| [], |
| requestContext, |
| (match.route.loader || match.route.lazy) != null && (!filterMatchesToLoad || filterMatchesToLoad(match)) |
| ); |
| }); |
| } |
| if (!dataStrategy && !dsMatches.some((m) => m.shouldLoad)) { |
| return { |
| matches, |
| loaderData: {}, |
| errors: pendingActionResult && isErrorResult(pendingActionResult[1]) ? { |
| [pendingActionResult[0]]: pendingActionResult[1].error |
| } : null, |
| statusCode: 200, |
| loaderHeaders: {} |
| }; |
| } |
| let results = await callDataStrategy( |
| request, |
| location, |
| dsMatches, |
| isRouteRequest, |
| requestContext, |
| dataStrategy |
| ); |
| if (request.signal.aborted) { |
| throwStaticHandlerAbortedError(request, isRouteRequest); |
| } |
| let handlerContext = processRouteLoaderData( |
| matches, |
| results, |
| pendingActionResult, |
| true, |
| skipLoaderErrorBubbling |
| ); |
| return { |
| ...handlerContext, |
| matches |
| }; |
| } |
| async function callDataStrategy(request, location, matches, isRouteRequest, requestContext, dataStrategy) { |
| let results = await callDataStrategyImpl( |
| dataStrategy || defaultDataStrategy, |
| request, |
| location, |
| matches, |
| null, |
| requestContext, |
| true |
| ); |
| let dataResults = {}; |
| await Promise.all( |
| matches.map(async (match) => { |
| if (!(match.route.id in results)) { |
| return; |
| } |
| let result = results[match.route.id]; |
| if (isRedirectDataStrategyResult(result)) { |
| let response = result.result; |
| throw normalizeRelativeRoutingRedirectResponse( |
| response, |
| request, |
| match.route.id, |
| matches, |
| basename |
| ); |
| } |
| if (isRouteRequest) { |
| if (isResponse(result.result)) { |
| throw result; |
| } else if (isDataWithResponseInit(result.result)) { |
| throw dataWithResponseInitToResponse(result.result); |
| } |
| } |
| dataResults[match.route.id] = await convertDataStrategyResultToDataResult(result); |
| }) |
| ); |
| return dataResults; |
| } |
| return { |
| dataRoutes, |
| query, |
| queryRoute |
| }; |
| } |
| function getStaticContextFromError(routes, handlerContext, error, boundaryId) { |
| let errorBoundaryId = boundaryId || handlerContext._deepestRenderedBoundaryId || routes[0].id; |
| return { |
| ...handlerContext, |
| statusCode: isRouteErrorResponse(error) ? error.status : 500, |
| errors: { |
| [errorBoundaryId]: error |
| } |
| }; |
| } |
| function throwStaticHandlerAbortedError(request, isRouteRequest) { |
| if (request.signal.reason !== void 0) { |
| throw request.signal.reason; |
| } |
| let method = isRouteRequest ? "queryRoute" : "query"; |
| throw new Error( |
| `${method}() call aborted without an \`AbortSignal.reason\`: ${request.method} ${request.url}` |
| ); |
| } |
| function isSubmissionNavigation(opts) { |
| return opts != null && ("formData" in opts && opts.formData != null || "body" in opts && opts.body !== void 0); |
| } |
| function defaultNormalizePath(request) { |
| let url = new URL(request.url); |
| return { |
| pathname: url.pathname, |
| search: url.search, |
| hash: url.hash |
| }; |
| } |
| function normalizeTo(location, matches, basename, to, fromRouteId, relative) { |
| let contextualMatches; |
| let activeRouteMatch; |
| if (fromRouteId) { |
| contextualMatches = []; |
| for (let match of matches) { |
| contextualMatches.push(match); |
| if (match.route.id === fromRouteId) { |
| activeRouteMatch = match; |
| break; |
| } |
| } |
| } else { |
| contextualMatches = matches; |
| activeRouteMatch = matches[matches.length - 1]; |
| } |
| let path = resolveTo( |
| to ? to : ".", |
| getResolveToMatches(contextualMatches), |
| stripBasename(location.pathname, basename) || location.pathname, |
| relative === "path" |
| ); |
| if (to == null) { |
| path.search = location.search; |
| path.hash = location.hash; |
| } |
| if ((to == null || to === "" || to === ".") && activeRouteMatch) { |
| let nakedIndex = hasNakedIndexQuery(path.search); |
| if (activeRouteMatch.route.index && !nakedIndex) { |
| path.search = path.search ? path.search.replace(/^\?/, "?index&") : "?index"; |
| } else if (!activeRouteMatch.route.index && nakedIndex) { |
| let params = new URLSearchParams(path.search); |
| let indexValues = params.getAll("index"); |
| params.delete("index"); |
| indexValues.filter((v) => v).forEach((v) => params.append("index", v)); |
| let qs = params.toString(); |
| path.search = qs ? `?${qs}` : ""; |
| } |
| } |
| if (basename !== "/") { |
| path.pathname = prependBasename({ basename, pathname: path.pathname }); |
| } |
| return createPath(path); |
| } |
| function normalizeNavigateOptions(isFetcher, path, opts) { |
| if (!opts || !isSubmissionNavigation(opts)) { |
| return { path }; |
| } |
| if (opts.formMethod && !isValidMethod(opts.formMethod)) { |
| return { |
| path, |
| error: getInternalRouterError(405, { method: opts.formMethod }) |
| }; |
| } |
| let getInvalidBodyError = () => ({ |
| path, |
| error: getInternalRouterError(400, { type: "invalid-body" }) |
| }); |
| let rawFormMethod = opts.formMethod || "get"; |
| let formMethod = rawFormMethod.toUpperCase(); |
| let formAction = stripHashFromPath(path); |
| if (opts.body !== void 0) { |
| if (opts.formEncType === "text/plain") { |
| if (!isMutationMethod(formMethod)) { |
| return getInvalidBodyError(); |
| } |
| let text = typeof opts.body === "string" ? opts.body : opts.body instanceof FormData || opts.body instanceof URLSearchParams ? ( |
| |
| Array.from(opts.body.entries()).reduce( |
| (acc, [name, value]) => `${acc}${name}=${value} |
| `, |
| "" |
| ) |
| ) : String(opts.body); |
| return { |
| path, |
| submission: { |
| formMethod, |
| formAction, |
| formEncType: opts.formEncType, |
| formData: void 0, |
| json: void 0, |
| text |
| } |
| }; |
| } else if (opts.formEncType === "application/json") { |
| if (!isMutationMethod(formMethod)) { |
| return getInvalidBodyError(); |
| } |
| try { |
| let json = typeof opts.body === "string" ? JSON.parse(opts.body) : opts.body; |
| return { |
| path, |
| submission: { |
| formMethod, |
| formAction, |
| formEncType: opts.formEncType, |
| formData: void 0, |
| json, |
| text: void 0 |
| } |
| }; |
| } catch (e) { |
| return getInvalidBodyError(); |
| } |
| } |
| } |
| invariant( |
| typeof FormData === "function", |
| "FormData is not available in this environment" |
| ); |
| let searchParams; |
| let formData; |
| if (opts.formData) { |
| searchParams = convertFormDataToSearchParams(opts.formData); |
| formData = opts.formData; |
| } else if (opts.body instanceof FormData) { |
| searchParams = convertFormDataToSearchParams(opts.body); |
| formData = opts.body; |
| } else if (opts.body instanceof URLSearchParams) { |
| searchParams = opts.body; |
| formData = convertSearchParamsToFormData(searchParams); |
| } else if (opts.body == null) { |
| searchParams = new URLSearchParams(); |
| formData = new FormData(); |
| } else { |
| try { |
| searchParams = new URLSearchParams(opts.body); |
| formData = convertSearchParamsToFormData(searchParams); |
| } catch (e) { |
| return getInvalidBodyError(); |
| } |
| } |
| let submission = { |
| formMethod, |
| formAction, |
| formEncType: opts && opts.formEncType || "application/x-www-form-urlencoded", |
| formData, |
| json: void 0, |
| text: void 0 |
| }; |
| if (isMutationMethod(submission.formMethod)) { |
| return { path, submission }; |
| } |
| let parsedPath = parsePath(path); |
| if (isFetcher && parsedPath.search && hasNakedIndexQuery(parsedPath.search)) { |
| searchParams.append("index", ""); |
| } |
| parsedPath.search = `?${searchParams}`; |
| return { path: createPath(parsedPath), submission }; |
| } |
| function getMatchesToLoad(request, scopedContext, mapRouteProperties2, manifest, history, state, matches, submission, location, lazyRoutePropertiesToSkip, initialHydration, isRevalidationRequired, cancelledFetcherLoads, fetchersQueuedForDeletion, fetchLoadMatches, fetchRedirectIds, routesToUse, basename, hasPatchRoutesOnNavigation, pendingActionResult, callSiteDefaultShouldRevalidate) { |
| let actionResult = pendingActionResult ? isErrorResult(pendingActionResult[1]) ? pendingActionResult[1].error : pendingActionResult[1].data : void 0; |
| let currentUrl = history.createURL(state.location); |
| let nextUrl = history.createURL(location); |
| let maxIdx; |
| if (initialHydration && state.errors) { |
| let boundaryId = Object.keys(state.errors)[0]; |
| maxIdx = matches.findIndex((m) => m.route.id === boundaryId); |
| } else if (pendingActionResult && isErrorResult(pendingActionResult[1])) { |
| let boundaryId = pendingActionResult[0]; |
| maxIdx = matches.findIndex((m) => m.route.id === boundaryId) - 1; |
| } |
| let actionStatus = pendingActionResult ? pendingActionResult[1].statusCode : void 0; |
| let shouldSkipRevalidation = actionStatus && actionStatus >= 400; |
| let baseShouldRevalidateArgs = { |
| currentUrl, |
| currentParams: _optionalChain([state, 'access', _42 => _42.matches, 'access', _43 => _43[0], 'optionalAccess', _44 => _44.params]) || {}, |
| nextUrl, |
| nextParams: matches[0].params, |
| ...submission, |
| actionResult, |
| actionStatus |
| }; |
| let pattern = getRoutePattern(matches); |
| let dsMatches = matches.map((match, index) => { |
| let { route } = match; |
| let forceShouldLoad = null; |
| if (maxIdx != null && index > maxIdx) { |
| forceShouldLoad = false; |
| } else if (route.lazy) { |
| forceShouldLoad = true; |
| } else if (!routeHasLoaderOrMiddleware(route)) { |
| forceShouldLoad = false; |
| } else if (initialHydration) { |
| let { shouldLoad: shouldLoad2 } = getRouteHydrationStatus( |
| route, |
| state.loaderData, |
| state.errors |
| ); |
| forceShouldLoad = shouldLoad2; |
| } else if (isNewLoader(state.loaderData, state.matches[index], match)) { |
| forceShouldLoad = true; |
| } |
| if (forceShouldLoad !== null) { |
| return getDataStrategyMatch( |
| mapRouteProperties2, |
| manifest, |
| request, |
| location, |
| pattern, |
| match, |
| lazyRoutePropertiesToSkip, |
| scopedContext, |
| forceShouldLoad |
| ); |
| } |
| let defaultShouldRevalidate = false; |
| if (typeof callSiteDefaultShouldRevalidate === "boolean") { |
| defaultShouldRevalidate = callSiteDefaultShouldRevalidate; |
| } else if (shouldSkipRevalidation) { |
| defaultShouldRevalidate = false; |
| } else if (isRevalidationRequired) { |
| defaultShouldRevalidate = true; |
| } else if (currentUrl.pathname + currentUrl.search === nextUrl.pathname + nextUrl.search) { |
| defaultShouldRevalidate = true; |
| } else if (currentUrl.search !== nextUrl.search) { |
| defaultShouldRevalidate = true; |
| } else if (isNewRouteInstance(state.matches[index], match)) { |
| defaultShouldRevalidate = true; |
| } |
| let shouldRevalidateArgs = { |
| ...baseShouldRevalidateArgs, |
| defaultShouldRevalidate |
| }; |
| let shouldLoad = shouldRevalidateLoader(match, shouldRevalidateArgs); |
| return getDataStrategyMatch( |
| mapRouteProperties2, |
| manifest, |
| request, |
| location, |
| pattern, |
| match, |
| lazyRoutePropertiesToSkip, |
| scopedContext, |
| shouldLoad, |
| shouldRevalidateArgs, |
| callSiteDefaultShouldRevalidate |
| ); |
| }); |
| let revalidatingFetchers = []; |
| fetchLoadMatches.forEach((f, key) => { |
| if (initialHydration || !matches.some((m) => m.route.id === f.routeId) || fetchersQueuedForDeletion.has(key)) { |
| return; |
| } |
| let fetcher = state.fetchers.get(key); |
| let isMidInitialLoad = fetcher && fetcher.state !== "idle" && fetcher.data === void 0; |
| let fetcherMatches = matchRoutes(routesToUse, f.path, basename); |
| if (!fetcherMatches) { |
| if (hasPatchRoutesOnNavigation && isMidInitialLoad) { |
| return; |
| } |
| revalidatingFetchers.push({ |
| key, |
| routeId: f.routeId, |
| path: f.path, |
| matches: null, |
| match: null, |
| request: null, |
| controller: null |
| }); |
| return; |
| } |
| if (fetchRedirectIds.has(key)) { |
| return; |
| } |
| let fetcherMatch = getTargetMatch(fetcherMatches, f.path); |
| let fetchController = new AbortController(); |
| let fetchRequest = createClientSideRequest( |
| history, |
| f.path, |
| fetchController.signal |
| ); |
| let fetcherDsMatches = null; |
| if (cancelledFetcherLoads.has(key)) { |
| cancelledFetcherLoads.delete(key); |
| fetcherDsMatches = getTargetedDataStrategyMatches( |
| mapRouteProperties2, |
| manifest, |
| fetchRequest, |
| f.path, |
| fetcherMatches, |
| fetcherMatch, |
| lazyRoutePropertiesToSkip, |
| scopedContext |
| ); |
| } else if (isMidInitialLoad) { |
| if (isRevalidationRequired) { |
| fetcherDsMatches = getTargetedDataStrategyMatches( |
| mapRouteProperties2, |
| manifest, |
| fetchRequest, |
| f.path, |
| fetcherMatches, |
| fetcherMatch, |
| lazyRoutePropertiesToSkip, |
| scopedContext |
| ); |
| } |
| } else { |
| let defaultShouldRevalidate; |
| if (typeof callSiteDefaultShouldRevalidate === "boolean") { |
| defaultShouldRevalidate = callSiteDefaultShouldRevalidate; |
| } else if (shouldSkipRevalidation) { |
| defaultShouldRevalidate = false; |
| } else { |
| defaultShouldRevalidate = isRevalidationRequired; |
| } |
| let shouldRevalidateArgs = { |
| ...baseShouldRevalidateArgs, |
| defaultShouldRevalidate |
| }; |
| if (shouldRevalidateLoader(fetcherMatch, shouldRevalidateArgs)) { |
| fetcherDsMatches = getTargetedDataStrategyMatches( |
| mapRouteProperties2, |
| manifest, |
| fetchRequest, |
| f.path, |
| fetcherMatches, |
| fetcherMatch, |
| lazyRoutePropertiesToSkip, |
| scopedContext, |
| shouldRevalidateArgs |
| ); |
| } |
| } |
| if (fetcherDsMatches) { |
| revalidatingFetchers.push({ |
| key, |
| routeId: f.routeId, |
| path: f.path, |
| matches: fetcherDsMatches, |
| match: fetcherMatch, |
| request: fetchRequest, |
| controller: fetchController |
| }); |
| } |
| }); |
| return { dsMatches, revalidatingFetchers }; |
| } |
| function routeHasLoaderOrMiddleware(route) { |
| return route.loader != null || route.middleware != null && route.middleware.length > 0; |
| } |
| function getRouteHydrationStatus(route, loaderData, errors) { |
| if (route.lazy) { |
| return { shouldLoad: true, renderFallback: true }; |
| } |
| if (!routeHasLoaderOrMiddleware(route)) { |
| return { shouldLoad: false, renderFallback: false }; |
| } |
| let hasData = loaderData != null && route.id in loaderData; |
| let hasError = errors != null && errors[route.id] !== void 0; |
| if (!hasData && hasError) { |
| return { shouldLoad: false, renderFallback: false }; |
| } |
| if (typeof route.loader === "function" && route.loader.hydrate === true) { |
| return { shouldLoad: true, renderFallback: !hasData }; |
| } |
| let shouldLoad = !hasData && !hasError; |
| return { shouldLoad, renderFallback: shouldLoad }; |
| } |
| function isNewLoader(currentLoaderData, currentMatch, match) { |
| let isNew = ( |
| |
| !currentMatch || |
| match.route.id !== currentMatch.route.id |
| ); |
| let isMissingData = !currentLoaderData.hasOwnProperty(match.route.id); |
| return isNew || isMissingData; |
| } |
| function isNewRouteInstance(currentMatch, match) { |
| let currentPath = currentMatch.route.path; |
| return ( |
| |
| currentMatch.pathname !== match.pathname || |
| |
| currentPath != null && currentPath.endsWith("*") && currentMatch.params["*"] !== match.params["*"] |
| ); |
| } |
| function shouldRevalidateLoader(loaderMatch, arg) { |
| if (loaderMatch.route.shouldRevalidate) { |
| let routeChoice = loaderMatch.route.shouldRevalidate(arg); |
| if (typeof routeChoice === "boolean") { |
| return routeChoice; |
| } |
| } |
| return arg.defaultShouldRevalidate; |
| } |
| function patchRoutesImpl(routeId, children, routesToUse, manifest, mapRouteProperties2, allowElementMutations) { |
| let childrenToPatch; |
| if (routeId) { |
| let route = manifest[routeId]; |
| invariant( |
| route, |
| `No route found to patch children into: routeId = ${routeId}` |
| ); |
| if (!route.children) { |
| route.children = []; |
| } |
| childrenToPatch = route.children; |
| } else { |
| childrenToPatch = routesToUse; |
| } |
| let uniqueChildren = []; |
| let existingChildren = []; |
| children.forEach((newRoute) => { |
| let existingRoute = childrenToPatch.find( |
| (existingRoute2) => isSameRoute(newRoute, existingRoute2) |
| ); |
| if (existingRoute) { |
| existingChildren.push({ existingRoute, newRoute }); |
| } else { |
| uniqueChildren.push(newRoute); |
| } |
| }); |
| if (uniqueChildren.length > 0) { |
| let newRoutes = convertRoutesToDataRoutes( |
| uniqueChildren, |
| mapRouteProperties2, |
| [routeId || "_", "patch", String(_optionalChain([childrenToPatch, 'optionalAccess', _45 => _45.length]) || "0")], |
| manifest |
| ); |
| childrenToPatch.push(...newRoutes); |
| } |
| if (allowElementMutations && existingChildren.length > 0) { |
| for (let i = 0; i < existingChildren.length; i++) { |
| let { existingRoute, newRoute } = existingChildren[i]; |
| let existingRouteTyped = existingRoute; |
| let [newRouteTyped] = convertRoutesToDataRoutes( |
| [newRoute], |
| mapRouteProperties2, |
| [], |
| |
| {}, |
| |
| true |
| ); |
| Object.assign(existingRouteTyped, { |
| element: newRouteTyped.element ? newRouteTyped.element : existingRouteTyped.element, |
| errorElement: newRouteTyped.errorElement ? newRouteTyped.errorElement : existingRouteTyped.errorElement, |
| hydrateFallbackElement: newRouteTyped.hydrateFallbackElement ? newRouteTyped.hydrateFallbackElement : existingRouteTyped.hydrateFallbackElement |
| }); |
| } |
| } |
| } |
| function isSameRoute(newRoute, existingRoute) { |
| if ("id" in newRoute && "id" in existingRoute && newRoute.id === existingRoute.id) { |
| return true; |
| } |
| if (!(newRoute.index === existingRoute.index && newRoute.path === existingRoute.path && newRoute.caseSensitive === existingRoute.caseSensitive)) { |
| return false; |
| } |
| if ((!newRoute.children || newRoute.children.length === 0) && (!existingRoute.children || existingRoute.children.length === 0)) { |
| return true; |
| } |
| return _nullishCoalesce(_optionalChain([newRoute, 'access', _46 => _46.children, 'optionalAccess', _47 => _47.every, 'call', _48 => _48( |
| (aChild, i) => _optionalChain([existingRoute, 'access', _49 => _49.children, 'optionalAccess', _50 => _50.some, 'call', _51 => _51((bChild) => isSameRoute(aChild, bChild))]) |
| )]), () => ( false)); |
| } |
| var lazyRoutePropertyCache = new WeakMap(); |
| var loadLazyRouteProperty = ({ |
| key, |
| route, |
| manifest, |
| mapRouteProperties: mapRouteProperties2 |
| }) => { |
| let routeToUpdate = manifest[route.id]; |
| invariant(routeToUpdate, "No route found in manifest"); |
| if (!routeToUpdate.lazy || typeof routeToUpdate.lazy !== "object") { |
| return; |
| } |
| let lazyFn = routeToUpdate.lazy[key]; |
| if (!lazyFn) { |
| return; |
| } |
| let cache = lazyRoutePropertyCache.get(routeToUpdate); |
| if (!cache) { |
| cache = {}; |
| lazyRoutePropertyCache.set(routeToUpdate, cache); |
| } |
| let cachedPromise = cache[key]; |
| if (cachedPromise) { |
| return cachedPromise; |
| } |
| let propertyPromise = (async () => { |
| let isUnsupported = isUnsupportedLazyRouteObjectKey(key); |
| let staticRouteValue = routeToUpdate[key]; |
| let isStaticallyDefined = staticRouteValue !== void 0 && key !== "hasErrorBoundary"; |
| if (isUnsupported) { |
| warning( |
| !isUnsupported, |
| "Route property " + key + " is not a supported lazy route property. This property will be ignored." |
| ); |
| cache[key] = Promise.resolve(); |
| } else if (isStaticallyDefined) { |
| warning( |
| false, |
| `Route "${routeToUpdate.id}" has a static property "${key}" defined. The lazy property will be ignored.` |
| ); |
| } else { |
| let value = await lazyFn(); |
| if (value != null) { |
| Object.assign(routeToUpdate, { [key]: value }); |
| Object.assign(routeToUpdate, mapRouteProperties2(routeToUpdate)); |
| } |
| } |
| if (typeof routeToUpdate.lazy === "object") { |
| routeToUpdate.lazy[key] = void 0; |
| if (Object.values(routeToUpdate.lazy).every((value) => value === void 0)) { |
| routeToUpdate.lazy = void 0; |
| } |
| } |
| })(); |
| cache[key] = propertyPromise; |
| return propertyPromise; |
| }; |
| var lazyRouteFunctionCache = new WeakMap(); |
| function loadLazyRoute(route, type, manifest, mapRouteProperties2, lazyRoutePropertiesToSkip) { |
| let routeToUpdate = manifest[route.id]; |
| invariant(routeToUpdate, "No route found in manifest"); |
| if (!route.lazy) { |
| return { |
| lazyRoutePromise: void 0, |
| lazyHandlerPromise: void 0 |
| }; |
| } |
| if (typeof route.lazy === "function") { |
| let cachedPromise = lazyRouteFunctionCache.get(routeToUpdate); |
| if (cachedPromise) { |
| return { |
| lazyRoutePromise: cachedPromise, |
| lazyHandlerPromise: cachedPromise |
| }; |
| } |
| let lazyRoutePromise2 = (async () => { |
| invariant( |
| typeof route.lazy === "function", |
| "No lazy route function found" |
| ); |
| let lazyRoute = await route.lazy(); |
| let routeUpdates = {}; |
| for (let lazyRouteProperty in lazyRoute) { |
| let lazyValue = lazyRoute[lazyRouteProperty]; |
| if (lazyValue === void 0) { |
| continue; |
| } |
| let isUnsupported = isUnsupportedLazyRouteFunctionKey(lazyRouteProperty); |
| let staticRouteValue = routeToUpdate[lazyRouteProperty]; |
| let isStaticallyDefined = staticRouteValue !== void 0 && |
| |
| lazyRouteProperty !== "hasErrorBoundary"; |
| if (isUnsupported) { |
| warning( |
| !isUnsupported, |
| "Route property " + lazyRouteProperty + " is not a supported property to be returned from a lazy route function. This property will be ignored." |
| ); |
| } else if (isStaticallyDefined) { |
| warning( |
| !isStaticallyDefined, |
| `Route "${routeToUpdate.id}" has a static property "${lazyRouteProperty}" defined but its lazy function is also returning a value for this property. The lazy route property "${lazyRouteProperty}" will be ignored.` |
| ); |
| } else { |
| routeUpdates[lazyRouteProperty] = lazyValue; |
| } |
| } |
| Object.assign(routeToUpdate, routeUpdates); |
| Object.assign(routeToUpdate, { |
| |
| |
| |
| ...mapRouteProperties2(routeToUpdate), |
| lazy: void 0 |
| }); |
| })(); |
| lazyRouteFunctionCache.set(routeToUpdate, lazyRoutePromise2); |
| lazyRoutePromise2.catch(() => { |
| }); |
| return { |
| lazyRoutePromise: lazyRoutePromise2, |
| lazyHandlerPromise: lazyRoutePromise2 |
| }; |
| } |
| let lazyKeys = Object.keys(route.lazy); |
| let lazyPropertyPromises = []; |
| let lazyHandlerPromise = void 0; |
| for (let key of lazyKeys) { |
| if (lazyRoutePropertiesToSkip && lazyRoutePropertiesToSkip.includes(key)) { |
| continue; |
| } |
| let promise = loadLazyRouteProperty({ |
| key, |
| route, |
| manifest, |
| mapRouteProperties: mapRouteProperties2 |
| }); |
| if (promise) { |
| lazyPropertyPromises.push(promise); |
| if (key === type) { |
| lazyHandlerPromise = promise; |
| } |
| } |
| } |
| let lazyRoutePromise = lazyPropertyPromises.length > 0 ? Promise.all(lazyPropertyPromises).then(() => { |
| }) : void 0; |
| _optionalChain([lazyRoutePromise, 'optionalAccess', _52 => _52.catch, 'call', _53 => _53(() => { |
| })]); |
| _optionalChain([lazyHandlerPromise, 'optionalAccess', _54 => _54.catch, 'call', _55 => _55(() => { |
| })]); |
| return { |
| lazyRoutePromise, |
| lazyHandlerPromise |
| }; |
| } |
| function isNonNullable(value) { |
| return value !== void 0; |
| } |
| function loadLazyMiddlewareForMatches(matches, manifest, mapRouteProperties2) { |
| let promises = matches.map(({ route }) => { |
| if (typeof route.lazy !== "object" || !route.lazy.middleware) { |
| return void 0; |
| } |
| return loadLazyRouteProperty({ |
| key: "middleware", |
| route, |
| manifest, |
| mapRouteProperties: mapRouteProperties2 |
| }); |
| }).filter(isNonNullable); |
| return promises.length > 0 ? Promise.all(promises) : void 0; |
| } |
| async function defaultDataStrategy(args) { |
| let matchesToLoad = args.matches.filter((m) => m.shouldLoad); |
| let keyedResults = {}; |
| let results = await Promise.all(matchesToLoad.map((m) => m.resolve())); |
| results.forEach((result, i) => { |
| keyedResults[matchesToLoad[i].route.id] = result; |
| }); |
| return keyedResults; |
| } |
| async function defaultDataStrategyWithMiddleware(args) { |
| if (!args.matches.some((m) => m.route.middleware)) { |
| return defaultDataStrategy(args); |
| } |
| return runClientMiddlewarePipeline(args, () => defaultDataStrategy(args)); |
| } |
| function runServerMiddlewarePipeline(args, handler, errorHandler) { |
| return runMiddlewarePipeline( |
| args, |
| handler, |
| processResult, |
| isResponse, |
| errorHandler |
| ); |
| function processResult(result) { |
| return isDataWithResponseInit(result) ? dataWithResponseInitToResponse(result) : result; |
| } |
| } |
| function runClientMiddlewarePipeline(args, handler) { |
| return runMiddlewarePipeline( |
| args, |
| handler, |
| (r) => { |
| if (isRedirectResponse(r)) { |
| throw r; |
| } |
| return r; |
| }, |
| isDataStrategyResults, |
| errorHandler |
| ); |
| function errorHandler(error, routeId, nextResult) { |
| if (nextResult) { |
| return Promise.resolve( |
| Object.assign(nextResult.value, { |
| [routeId]: { type: "error", result: error } |
| }) |
| ); |
| } else { |
| let { matches } = args; |
| let maxBoundaryIdx = Math.min( |
| |
| Math.max( |
| matches.findIndex((m) => m.route.id === routeId), |
| 0 |
| ), |
| |
| Math.max( |
| matches.findIndex((m) => m.shouldCallHandler()), |
| 0 |
| ) |
| ); |
| let boundaryRouteId = findNearestBoundary( |
| matches, |
| matches[maxBoundaryIdx].route.id |
| ).route.id; |
| return Promise.resolve({ |
| [boundaryRouteId]: { type: "error", result: error } |
| }); |
| } |
| } |
| } |
| async function runMiddlewarePipeline(args, handler, processResult, isResult, errorHandler) { |
| let { matches, ...dataFnArgs } = args; |
| let tuples = matches.flatMap( |
| (m) => m.route.middleware ? m.route.middleware.map((fn) => [m.route.id, fn]) : [] |
| ); |
| let result = await callRouteMiddleware( |
| dataFnArgs, |
| tuples, |
| handler, |
| processResult, |
| isResult, |
| errorHandler |
| ); |
| return result; |
| } |
| async function callRouteMiddleware(args, middlewares, handler, processResult, isResult, errorHandler, idx = 0) { |
| let { request } = args; |
| if (request.signal.aborted) { |
| throw _nullishCoalesce(request.signal.reason, () => ( new Error(`Request aborted: ${request.method} ${request.url}`))); |
| } |
| let tuple = middlewares[idx]; |
| if (!tuple) { |
| let result = await handler(); |
| return result; |
| } |
| let [routeId, middleware] = tuple; |
| let nextResult; |
| let next = async () => { |
| if (nextResult) { |
| throw new Error("You may only call `next()` once per middleware"); |
| } |
| try { |
| let result = await callRouteMiddleware( |
| args, |
| middlewares, |
| handler, |
| processResult, |
| isResult, |
| errorHandler, |
| idx + 1 |
| ); |
| nextResult = { value: result }; |
| return nextResult.value; |
| } catch (error) { |
| nextResult = { value: await errorHandler(error, routeId, nextResult) }; |
| return nextResult.value; |
| } |
| }; |
| try { |
| let value = await middleware(args, next); |
| let result = value != null ? processResult(value) : void 0; |
| if (isResult(result)) { |
| return result; |
| } else if (nextResult) { |
| return _nullishCoalesce(result, () => ( nextResult.value)); |
| } else { |
| nextResult = { value: await next() }; |
| return nextResult.value; |
| } |
| } catch (error) { |
| let response = await errorHandler(error, routeId, nextResult); |
| return response; |
| } |
| } |
| function getDataStrategyMatchLazyPromises(mapRouteProperties2, manifest, request, match, lazyRoutePropertiesToSkip) { |
| let lazyMiddlewarePromise = loadLazyRouteProperty({ |
| key: "middleware", |
| route: match.route, |
| manifest, |
| mapRouteProperties: mapRouteProperties2 |
| }); |
| let lazyRoutePromises = loadLazyRoute( |
| match.route, |
| isMutationMethod(request.method) ? "action" : "loader", |
| manifest, |
| mapRouteProperties2, |
| lazyRoutePropertiesToSkip |
| ); |
| return { |
| middleware: lazyMiddlewarePromise, |
| route: lazyRoutePromises.lazyRoutePromise, |
| handler: lazyRoutePromises.lazyHandlerPromise |
| }; |
| } |
| function getDataStrategyMatch(mapRouteProperties2, manifest, request, path, unstable_pattern, match, lazyRoutePropertiesToSkip, scopedContext, shouldLoad, shouldRevalidateArgs = null, callSiteDefaultShouldRevalidate) { |
| let isUsingNewApi = false; |
| let _lazyPromises = getDataStrategyMatchLazyPromises( |
| mapRouteProperties2, |
| manifest, |
| request, |
| match, |
| lazyRoutePropertiesToSkip |
| ); |
| return { |
| ...match, |
| _lazyPromises, |
| shouldLoad, |
| shouldRevalidateArgs, |
| shouldCallHandler(defaultShouldRevalidate) { |
| isUsingNewApi = true; |
| if (!shouldRevalidateArgs) { |
| return shouldLoad; |
| } |
| if (typeof callSiteDefaultShouldRevalidate === "boolean") { |
| return shouldRevalidateLoader(match, { |
| ...shouldRevalidateArgs, |
| defaultShouldRevalidate: callSiteDefaultShouldRevalidate |
| }); |
| } |
| if (typeof defaultShouldRevalidate === "boolean") { |
| return shouldRevalidateLoader(match, { |
| ...shouldRevalidateArgs, |
| defaultShouldRevalidate |
| }); |
| } |
| return shouldRevalidateLoader(match, shouldRevalidateArgs); |
| }, |
| resolve(handlerOverride) { |
| let { lazy, loader, middleware } = match.route; |
| let callHandler = isUsingNewApi || shouldLoad || handlerOverride && !isMutationMethod(request.method) && (lazy || loader); |
| let isMiddlewareOnlyRoute = middleware && middleware.length > 0 && !loader && !lazy; |
| if (callHandler && (isMutationMethod(request.method) || !isMiddlewareOnlyRoute)) { |
| return callLoaderOrAction({ |
| request, |
| path, |
| unstable_pattern, |
| match, |
| lazyHandlerPromise: _optionalChain([_lazyPromises, 'optionalAccess', _56 => _56.handler]), |
| lazyRoutePromise: _optionalChain([_lazyPromises, 'optionalAccess', _57 => _57.route]), |
| handlerOverride, |
| scopedContext |
| }); |
| } |
| return Promise.resolve({ type: "data" , result: void 0 }); |
| } |
| }; |
| } |
| function getTargetedDataStrategyMatches(mapRouteProperties2, manifest, request, path, matches, targetMatch, lazyRoutePropertiesToSkip, scopedContext, shouldRevalidateArgs = null) { |
| return matches.map((match) => { |
| if (match.route.id !== targetMatch.route.id) { |
| return { |
| ...match, |
| shouldLoad: false, |
| shouldRevalidateArgs, |
| shouldCallHandler: () => false, |
| _lazyPromises: getDataStrategyMatchLazyPromises( |
| mapRouteProperties2, |
| manifest, |
| request, |
| match, |
| lazyRoutePropertiesToSkip |
| ), |
| resolve: () => Promise.resolve({ type: "data", result: void 0 }) |
| }; |
| } |
| return getDataStrategyMatch( |
| mapRouteProperties2, |
| manifest, |
| request, |
| path, |
| getRoutePattern(matches), |
| match, |
| lazyRoutePropertiesToSkip, |
| scopedContext, |
| true, |
| shouldRevalidateArgs |
| ); |
| }); |
| } |
| async function callDataStrategyImpl(dataStrategyImpl, request, path, matches, fetcherKey, scopedContext, isStaticHandler) { |
| if (matches.some((m) => _optionalChain([m, 'access', _58 => _58._lazyPromises, 'optionalAccess', _59 => _59.middleware]))) { |
| await Promise.all(matches.map((m) => _optionalChain([m, 'access', _60 => _60._lazyPromises, 'optionalAccess', _61 => _61.middleware]))); |
| } |
| let dataStrategyArgs = { |
| request, |
| unstable_url: createDataFunctionUrl(request, path), |
| unstable_pattern: getRoutePattern(matches), |
| params: matches[0].params, |
| context: scopedContext, |
| matches |
| }; |
| let runClientMiddleware = isStaticHandler ? () => { |
| throw new Error( |
| "You cannot call `runClientMiddleware()` from a static handler `dataStrategy`. Middleware is run outside of `dataStrategy` during SSR in order to bubble up the Response. You can enable middleware via the `respond` API in `query`/`queryRoute`" |
| ); |
| } : (cb) => { |
| let typedDataStrategyArgs = dataStrategyArgs; |
| return runClientMiddlewarePipeline(typedDataStrategyArgs, () => { |
| return cb({ |
| ...typedDataStrategyArgs, |
| fetcherKey, |
| runClientMiddleware: () => { |
| throw new Error( |
| "Cannot call `runClientMiddleware()` from within an `runClientMiddleware` handler" |
| ); |
| } |
| }); |
| }); |
| }; |
| let results = await dataStrategyImpl({ |
| ...dataStrategyArgs, |
| fetcherKey, |
| runClientMiddleware |
| }); |
| try { |
| await Promise.all( |
| matches.flatMap((m) => [ |
| _optionalChain([m, 'access', _62 => _62._lazyPromises, 'optionalAccess', _63 => _63.handler]), |
| _optionalChain([m, 'access', _64 => _64._lazyPromises, 'optionalAccess', _65 => _65.route]) |
| ]) |
| ); |
| } catch (e) { |
| } |
| return results; |
| } |
| async function callLoaderOrAction({ |
| request, |
| path, |
| unstable_pattern, |
| match, |
| lazyHandlerPromise, |
| lazyRoutePromise, |
| handlerOverride, |
| scopedContext |
| }) { |
| let result; |
| let onReject; |
| let isAction = isMutationMethod(request.method); |
| let type = isAction ? "action" : "loader"; |
| let runHandler = (handler) => { |
| let reject; |
| let abortPromise = new Promise((_, r) => reject = r); |
| onReject = () => reject(); |
| request.signal.addEventListener("abort", onReject); |
| let actualHandler = (ctx) => { |
| if (typeof handler !== "function") { |
| return Promise.reject( |
| new Error( |
| `You cannot call the handler for a route which defines a boolean "${type}" [routeId: ${match.route.id}]` |
| ) |
| ); |
| } |
| return handler( |
| { |
| request, |
| unstable_url: createDataFunctionUrl(request, path), |
| unstable_pattern, |
| params: match.params, |
| context: scopedContext |
| }, |
| ...ctx !== void 0 ? [ctx] : [] |
| ); |
| }; |
| let handlerPromise = (async () => { |
| try { |
| let val = await (handlerOverride ? handlerOverride((ctx) => actualHandler(ctx)) : actualHandler()); |
| return { type: "data", result: val }; |
| } catch (e) { |
| return { type: "error", result: e }; |
| } |
| })(); |
| return Promise.race([handlerPromise, abortPromise]); |
| }; |
| try { |
| let handler = isAction ? match.route.action : match.route.loader; |
| if (lazyHandlerPromise || lazyRoutePromise) { |
| if (handler) { |
| let handlerError; |
| let [value] = await Promise.all([ |
| |
| |
| |
| runHandler(handler).catch((e) => { |
| handlerError = e; |
| }), |
| |
| lazyHandlerPromise, |
| lazyRoutePromise |
| ]); |
| if (handlerError !== void 0) { |
| throw handlerError; |
| } |
| result = value; |
| } else { |
| await lazyHandlerPromise; |
| let handler2 = isAction ? match.route.action : match.route.loader; |
| if (handler2) { |
| [result] = await Promise.all([runHandler(handler2), lazyRoutePromise]); |
| } else if (type === "action") { |
| let url = new URL(request.url); |
| let pathname = url.pathname + url.search; |
| throw getInternalRouterError(405, { |
| method: request.method, |
| pathname, |
| routeId: match.route.id |
| }); |
| } else { |
| return { type: "data" , result: void 0 }; |
| } |
| } |
| } else if (!handler) { |
| let url = new URL(request.url); |
| let pathname = url.pathname + url.search; |
| throw getInternalRouterError(404, { |
| pathname |
| }); |
| } else { |
| result = await runHandler(handler); |
| } |
| } catch (e) { |
| return { type: "error" , result: e }; |
| } finally { |
| if (onReject) { |
| request.signal.removeEventListener("abort", onReject); |
| } |
| } |
| return result; |
| } |
| async function parseResponseBody(response) { |
| let contentType = response.headers.get("Content-Type"); |
| if (contentType && /\bapplication\/json\b/.test(contentType)) { |
| return response.body == null ? null : response.json(); |
| } |
| return response.text(); |
| } |
| async function convertDataStrategyResultToDataResult(dataStrategyResult) { |
| let { result, type } = dataStrategyResult; |
| if (isResponse(result)) { |
| let data2; |
| try { |
| data2 = await parseResponseBody(result); |
| } catch (e) { |
| return { type: "error" , error: e }; |
| } |
| if (type === "error" ) { |
| return { |
| type: "error" , |
| error: new ErrorResponseImpl(result.status, result.statusText, data2), |
| statusCode: result.status, |
| headers: result.headers |
| }; |
| } |
| return { |
| type: "data" , |
| data: data2, |
| statusCode: result.status, |
| headers: result.headers |
| }; |
| } |
| if (type === "error" ) { |
| if (isDataWithResponseInit(result)) { |
| if (result.data instanceof Error) { |
| return { |
| type: "error" , |
| error: result.data, |
| statusCode: _optionalChain([result, 'access', _66 => _66.init, 'optionalAccess', _67 => _67.status]), |
| headers: _optionalChain([result, 'access', _68 => _68.init, 'optionalAccess', _69 => _69.headers]) ? new Headers(result.init.headers) : void 0 |
| }; |
| } |
| return { |
| type: "error" , |
| error: dataWithResponseInitToErrorResponse(result), |
| statusCode: isRouteErrorResponse(result) ? result.status : void 0, |
| headers: _optionalChain([result, 'access', _70 => _70.init, 'optionalAccess', _71 => _71.headers]) ? new Headers(result.init.headers) : void 0 |
| }; |
| } |
| return { |
| type: "error" , |
| error: result, |
| statusCode: isRouteErrorResponse(result) ? result.status : void 0 |
| }; |
| } |
| if (isDataWithResponseInit(result)) { |
| return { |
| type: "data" , |
| data: result.data, |
| statusCode: _optionalChain([result, 'access', _72 => _72.init, 'optionalAccess', _73 => _73.status]), |
| headers: _optionalChain([result, 'access', _74 => _74.init, 'optionalAccess', _75 => _75.headers]) ? new Headers(result.init.headers) : void 0 |
| }; |
| } |
| return { type: "data" , data: result }; |
| } |
| function normalizeRelativeRoutingRedirectResponse(response, request, routeId, matches, basename) { |
| let location = response.headers.get("Location"); |
| invariant( |
| location, |
| "Redirects returned/thrown from loaders/actions must have a Location header" |
| ); |
| if (!isAbsoluteUrl(location)) { |
| let trimmedMatches = matches.slice( |
| 0, |
| matches.findIndex((m) => m.route.id === routeId) + 1 |
| ); |
| location = normalizeTo( |
| new URL(request.url), |
| trimmedMatches, |
| basename, |
| location |
| ); |
| response.headers.set("Location", location); |
| } |
| return response; |
| } |
| var invalidProtocols = [ |
| "about:", |
| "blob:", |
| "chrome:", |
| "chrome-untrusted:", |
| "content:", |
| "data:", |
| "devtools:", |
| "file:", |
| "filesystem:", |
| |
| "javascript:" |
| ]; |
| function normalizeRedirectLocation(location, currentUrl, basename, historyInstance) { |
| if (isAbsoluteUrl(location)) { |
| let normalizedLocation = location; |
| let url = normalizedLocation.startsWith("//") ? new URL(currentUrl.protocol + normalizedLocation) : new URL(normalizedLocation); |
| if (invalidProtocols.includes(url.protocol)) { |
| throw new Error("Invalid redirect location"); |
| } |
| let isSameBasename = stripBasename(url.pathname, basename) != null; |
| if (url.origin === currentUrl.origin && isSameBasename) { |
| return removeDoubleSlashes(url.pathname) + url.search + url.hash; |
| } |
| } |
| try { |
| let url = historyInstance.createURL(location); |
| if (invalidProtocols.includes(url.protocol)) { |
| throw new Error("Invalid redirect location"); |
| } |
| } catch (e) { |
| } |
| return location; |
| } |
| function createClientSideRequest(history, location, signal, submission) { |
| let url = history.createURL(stripHashFromPath(location)).toString(); |
| let init = { signal }; |
| if (submission && isMutationMethod(submission.formMethod)) { |
| let { formMethod, formEncType } = submission; |
| init.method = formMethod.toUpperCase(); |
| if (formEncType === "application/json") { |
| init.headers = new Headers({ "Content-Type": formEncType }); |
| init.body = JSON.stringify(submission.json); |
| } else if (formEncType === "text/plain") { |
| init.body = submission.text; |
| } else if (formEncType === "application/x-www-form-urlencoded" && submission.formData) { |
| init.body = convertFormDataToSearchParams(submission.formData); |
| } else { |
| init.body = submission.formData; |
| } |
| } |
| return new Request(url, init); |
| } |
| function createDataFunctionUrl(request, path) { |
| let url = new URL(request.url); |
| let parsed = typeof path === "string" ? parsePath(path) : path; |
| url.pathname = parsed.pathname || "/"; |
| if (parsed.search) { |
| let searchParams = new URLSearchParams(parsed.search); |
| let indexValues = searchParams.getAll("index"); |
| searchParams.delete("index"); |
| for (let value of indexValues.filter(Boolean)) { |
| searchParams.append("index", value); |
| } |
| url.search = searchParams.size ? `?${searchParams.toString()}` : ""; |
| } else { |
| url.search = ""; |
| } |
| url.hash = parsed.hash || ""; |
| return url; |
| } |
| function convertFormDataToSearchParams(formData) { |
| let searchParams = new URLSearchParams(); |
| for (let [key, value] of formData.entries()) { |
| searchParams.append(key, typeof value === "string" ? value : value.name); |
| } |
| return searchParams; |
| } |
| function convertSearchParamsToFormData(searchParams) { |
| let formData = new FormData(); |
| for (let [key, value] of searchParams.entries()) { |
| formData.append(key, value); |
| } |
| return formData; |
| } |
| function processRouteLoaderData(matches, results, pendingActionResult, isStaticHandler = false, skipLoaderErrorBubbling = false) { |
| let loaderData = {}; |
| let errors = null; |
| let statusCode; |
| let foundError = false; |
| let loaderHeaders = {}; |
| let pendingError = pendingActionResult && isErrorResult(pendingActionResult[1]) ? pendingActionResult[1].error : void 0; |
| matches.forEach((match) => { |
| if (!(match.route.id in results)) { |
| return; |
| } |
| let id = match.route.id; |
| let result = results[id]; |
| invariant( |
| !isRedirectResult(result), |
| "Cannot handle redirect results in processLoaderData" |
| ); |
| if (isErrorResult(result)) { |
| let error = result.error; |
| if (pendingError !== void 0) { |
| error = pendingError; |
| pendingError = void 0; |
| } |
| errors = errors || {}; |
| if (skipLoaderErrorBubbling) { |
| errors[id] = error; |
| } else { |
| let boundaryMatch = findNearestBoundary(matches, id); |
| if (errors[boundaryMatch.route.id] == null) { |
| errors[boundaryMatch.route.id] = error; |
| } |
| } |
| if (!isStaticHandler) { |
| loaderData[id] = ResetLoaderDataSymbol; |
| } |
| if (!foundError) { |
| foundError = true; |
| statusCode = isRouteErrorResponse(result.error) ? result.error.status : 500; |
| } |
| if (result.headers) { |
| loaderHeaders[id] = result.headers; |
| } |
| } else { |
| loaderData[id] = result.data; |
| if (result.statusCode && result.statusCode !== 200 && !foundError) { |
| statusCode = result.statusCode; |
| } |
| if (result.headers) { |
| loaderHeaders[id] = result.headers; |
| } |
| } |
| }); |
| if (pendingError !== void 0 && pendingActionResult) { |
| errors = { [pendingActionResult[0]]: pendingError }; |
| if (pendingActionResult[2]) { |
| loaderData[pendingActionResult[2]] = void 0; |
| } |
| } |
| return { |
| loaderData, |
| errors, |
| statusCode: statusCode || 200, |
| loaderHeaders |
| }; |
| } |
| function processLoaderData(state, matches, results, pendingActionResult, revalidatingFetchers, fetcherResults) { |
| let { loaderData, errors } = processRouteLoaderData( |
| matches, |
| results, |
| pendingActionResult |
| ); |
| revalidatingFetchers.filter((f) => !f.matches || f.matches.some((m) => m.shouldLoad)).forEach((rf) => { |
| let { key, match, controller } = rf; |
| if (controller && controller.signal.aborted) { |
| return; |
| } |
| let result = fetcherResults[key]; |
| invariant(result, "Did not find corresponding fetcher result"); |
| if (isErrorResult(result)) { |
| let boundaryMatch = findNearestBoundary(state.matches, _optionalChain([match, 'optionalAccess', _76 => _76.route, 'access', _77 => _77.id])); |
| if (!(errors && errors[boundaryMatch.route.id])) { |
| errors = { |
| ...errors, |
| [boundaryMatch.route.id]: result.error |
| }; |
| } |
| state.fetchers.delete(key); |
| } else if (isRedirectResult(result)) { |
| invariant(false, "Unhandled fetcher revalidation redirect"); |
| } else { |
| let doneFetcher = getDoneFetcher(result.data); |
| state.fetchers.set(key, doneFetcher); |
| } |
| }); |
| return { loaderData, errors }; |
| } |
| function mergeLoaderData(loaderData, newLoaderData, matches, errors) { |
| let mergedLoaderData = Object.entries(newLoaderData).filter(([, v]) => v !== ResetLoaderDataSymbol).reduce((merged, [k, v]) => { |
| merged[k] = v; |
| return merged; |
| }, {}); |
| for (let match of matches) { |
| let id = match.route.id; |
| if (!newLoaderData.hasOwnProperty(id) && loaderData.hasOwnProperty(id) && match.route.loader) { |
| mergedLoaderData[id] = loaderData[id]; |
| } |
| if (errors && errors.hasOwnProperty(id)) { |
| break; |
| } |
| } |
| return mergedLoaderData; |
| } |
| function getActionDataForCommit(pendingActionResult) { |
| if (!pendingActionResult) { |
| return {}; |
| } |
| return isErrorResult(pendingActionResult[1]) ? { |
| |
| actionData: {} |
| } : { |
| actionData: { |
| [pendingActionResult[0]]: pendingActionResult[1].data |
| } |
| }; |
| } |
| function findNearestBoundary(matches, routeId) { |
| let eligibleMatches = routeId ? matches.slice(0, matches.findIndex((m) => m.route.id === routeId) + 1) : [...matches]; |
| return eligibleMatches.reverse().find((m) => m.route.hasErrorBoundary === true) || matches[0]; |
| } |
| function getShortCircuitMatches(routes) { |
| let route = routes.length === 1 ? routes[0] : routes.find((r) => r.index || !r.path || r.path === "/") || { |
| id: `__shim-error-route__` |
| }; |
| return { |
| matches: [ |
| { |
| params: {}, |
| pathname: "", |
| pathnameBase: "", |
| route |
| } |
| ], |
| route |
| }; |
| } |
| function getInternalRouterError(status, { |
| pathname, |
| routeId, |
| method, |
| type, |
| message |
| } = {}) { |
| let statusText = "Unknown Server Error"; |
| let errorMessage = "Unknown @remix-run/router error"; |
| if (status === 400) { |
| statusText = "Bad Request"; |
| if (method && pathname && routeId) { |
| errorMessage = `You made a ${method} request to "${pathname}" but did not provide a \`loader\` for route "${routeId}", so there is no way to handle the request.`; |
| } else if (type === "invalid-body") { |
| errorMessage = "Unable to encode submission body"; |
| } |
| } else if (status === 403) { |
| statusText = "Forbidden"; |
| errorMessage = `Route "${routeId}" does not match URL "${pathname}"`; |
| } else if (status === 404) { |
| statusText = "Not Found"; |
| errorMessage = `No route matches URL "${pathname}"`; |
| } else if (status === 405) { |
| statusText = "Method Not Allowed"; |
| if (method && pathname && routeId) { |
| errorMessage = `You made a ${method.toUpperCase()} request to "${pathname}" but did not provide an \`action\` for route "${routeId}", so there is no way to handle the request.`; |
| } else if (method) { |
| errorMessage = `Invalid request method "${method.toUpperCase()}"`; |
| } |
| } |
| return new ErrorResponseImpl( |
| status || 500, |
| statusText, |
| new Error(errorMessage), |
| true |
| ); |
| } |
| function findRedirect(results) { |
| let entries = Object.entries(results); |
| for (let i = entries.length - 1; i >= 0; i--) { |
| let [key, result] = entries[i]; |
| if (isRedirectResult(result)) { |
| return { key, result }; |
| } |
| } |
| } |
| function stripHashFromPath(path) { |
| let parsedPath = typeof path === "string" ? parsePath(path) : path; |
| return createPath({ ...parsedPath, hash: "" }); |
| } |
| function isHashChangeOnly(a, b) { |
| if (a.pathname !== b.pathname || a.search !== b.search) { |
| return false; |
| } |
| if (a.hash === "") { |
| return b.hash !== ""; |
| } else if (a.hash === b.hash) { |
| return true; |
| } else if (b.hash !== "") { |
| return true; |
| } |
| return false; |
| } |
| function dataWithResponseInitToResponse(data2) { |
| return Response.json(data2.data, _nullishCoalesce(data2.init, () => ( void 0))); |
| } |
| function dataWithResponseInitToErrorResponse(data2) { |
| return new ErrorResponseImpl( |
| _nullishCoalesce(_optionalChain([data2, 'access', _78 => _78.init, 'optionalAccess', _79 => _79.status]), () => ( 500)), |
| _nullishCoalesce(_optionalChain([data2, 'access', _80 => _80.init, 'optionalAccess', _81 => _81.statusText]), () => ( "Internal Server Error")), |
| data2.data |
| ); |
| } |
| function isDataStrategyResults(result) { |
| return result != null && typeof result === "object" && Object.entries(result).every( |
| ([key, value]) => typeof key === "string" && isDataStrategyResult(value) |
| ); |
| } |
| function isDataStrategyResult(result) { |
| return result != null && typeof result === "object" && "type" in result && "result" in result && (result.type === "data" || result.type === "error" ); |
| } |
| function isRedirectDataStrategyResult(result) { |
| return isResponse(result.result) && redirectStatusCodes.has(result.result.status); |
| } |
| function isErrorResult(result) { |
| return result.type === "error" ; |
| } |
| function isRedirectResult(result) { |
| return (result && result.type) === "redirect" ; |
| } |
| function isDataWithResponseInit(value) { |
| return typeof value === "object" && value != null && "type" in value && "data" in value && "init" in value && value.type === "DataWithResponseInit"; |
| } |
| function isResponse(value) { |
| return value != null && typeof value.status === "number" && typeof value.statusText === "string" && typeof value.headers === "object" && typeof value.body !== "undefined"; |
| } |
| function isRedirectStatusCode(statusCode) { |
| return redirectStatusCodes.has(statusCode); |
| } |
| function isRedirectResponse(result) { |
| return isResponse(result) && isRedirectStatusCode(result.status) && result.headers.has("Location"); |
| } |
| function isValidMethod(method) { |
| return validRequestMethods.has(method.toUpperCase()); |
| } |
| function isMutationMethod(method) { |
| return validMutationMethods.has(method.toUpperCase()); |
| } |
| function hasNakedIndexQuery(search) { |
| return new URLSearchParams(search).getAll("index").some((v) => v === ""); |
| } |
| function getTargetMatch(matches, location) { |
| let search = typeof location === "string" ? parsePath(location).search : location.search; |
| if (matches[matches.length - 1].route.index && hasNakedIndexQuery(search || "")) { |
| return matches[matches.length - 1]; |
| } |
| let pathMatches = getPathContributingMatches(matches); |
| return pathMatches[pathMatches.length - 1]; |
| } |
| function getSubmissionFromNavigation(navigation) { |
| let { formMethod, formAction, formEncType, text, formData, json } = navigation; |
| if (!formMethod || !formAction || !formEncType) { |
| return; |
| } |
| if (text != null) { |
| return { |
| formMethod, |
| formAction, |
| formEncType, |
| formData: void 0, |
| json: void 0, |
| text |
| }; |
| } else if (formData != null) { |
| return { |
| formMethod, |
| formAction, |
| formEncType, |
| formData, |
| json: void 0, |
| text: void 0 |
| }; |
| } else if (json !== void 0) { |
| return { |
| formMethod, |
| formAction, |
| formEncType, |
| formData: void 0, |
| json, |
| text: void 0 |
| }; |
| } |
| } |
| function getLoadingNavigation(location, submission) { |
| if (submission) { |
| let navigation = { |
| state: "loading", |
| location, |
| formMethod: submission.formMethod, |
| formAction: submission.formAction, |
| formEncType: submission.formEncType, |
| formData: submission.formData, |
| json: submission.json, |
| text: submission.text |
| }; |
| return navigation; |
| } else { |
| let navigation = { |
| state: "loading", |
| location, |
| formMethod: void 0, |
| formAction: void 0, |
| formEncType: void 0, |
| formData: void 0, |
| json: void 0, |
| text: void 0 |
| }; |
| return navigation; |
| } |
| } |
| function getSubmittingNavigation(location, submission) { |
| let navigation = { |
| state: "submitting", |
| location, |
| formMethod: submission.formMethod, |
| formAction: submission.formAction, |
| formEncType: submission.formEncType, |
| formData: submission.formData, |
| json: submission.json, |
| text: submission.text |
| }; |
| return navigation; |
| } |
| function getLoadingFetcher(submission, data2) { |
| if (submission) { |
| let fetcher = { |
| state: "loading", |
| formMethod: submission.formMethod, |
| formAction: submission.formAction, |
| formEncType: submission.formEncType, |
| formData: submission.formData, |
| json: submission.json, |
| text: submission.text, |
| data: data2 |
| }; |
| return fetcher; |
| } else { |
| let fetcher = { |
| state: "loading", |
| formMethod: void 0, |
| formAction: void 0, |
| formEncType: void 0, |
| formData: void 0, |
| json: void 0, |
| text: void 0, |
| data: data2 |
| }; |
| return fetcher; |
| } |
| } |
| function getSubmittingFetcher(submission, existingFetcher) { |
| let fetcher = { |
| state: "submitting", |
| formMethod: submission.formMethod, |
| formAction: submission.formAction, |
| formEncType: submission.formEncType, |
| formData: submission.formData, |
| json: submission.json, |
| text: submission.text, |
| data: existingFetcher ? existingFetcher.data : void 0 |
| }; |
| return fetcher; |
| } |
| function getDoneFetcher(data2) { |
| let fetcher = { |
| state: "idle", |
| formMethod: void 0, |
| formAction: void 0, |
| formEncType: void 0, |
| formData: void 0, |
| json: void 0, |
| text: void 0, |
| data: data2 |
| }; |
| return fetcher; |
| } |
| function restoreAppliedTransitions(_window, transitions) { |
| try { |
| let sessionPositions = _window.sessionStorage.getItem( |
| TRANSITIONS_STORAGE_KEY |
| ); |
| if (sessionPositions) { |
| let json = JSON.parse(sessionPositions); |
| for (let [k, v] of Object.entries(json || {})) { |
| if (v && Array.isArray(v)) { |
| transitions.set(k, new Set(v || [])); |
| } |
| } |
| } |
| } catch (e) { |
| } |
| } |
| function persistAppliedTransitions(_window, transitions) { |
| if (transitions.size > 0) { |
| let json = {}; |
| for (let [k, v] of transitions) { |
| json[k] = [...v]; |
| } |
| try { |
| _window.sessionStorage.setItem( |
| TRANSITIONS_STORAGE_KEY, |
| JSON.stringify(json) |
| ); |
| } catch (error) { |
| warning( |
| false, |
| `Failed to save applied view transitions in sessionStorage (${error}).` |
| ); |
| } |
| } |
| } |
| function createDeferred() { |
| let resolve; |
| let reject; |
| let promise = new Promise((res, rej) => { |
| resolve = async (val) => { |
| res(val); |
| try { |
| await promise; |
| } catch (e) { |
| } |
| }; |
| reject = async (error) => { |
| rej(error); |
| try { |
| await promise; |
| } catch (e) { |
| } |
| }; |
| }); |
| return { |
| promise, |
| |
| resolve, |
| |
| reject |
| }; |
| } |
|
|
| |
| var _react = require('react'); var React = _interopRequireWildcard(_react); var React2 = _interopRequireWildcard(_react); var React3 = _interopRequireWildcard(_react); var React8 = _interopRequireWildcard(_react); var React7 = _interopRequireWildcard(_react); var React6 = _interopRequireWildcard(_react); var React5 = _interopRequireWildcard(_react); var React4 = _interopRequireWildcard(_react); var React9 = _interopRequireWildcard(_react); |
|
|
| |
| var HOLE = -1; |
| var NAN = -2; |
| var NEGATIVE_INFINITY = -3; |
| var NEGATIVE_ZERO = -4; |
| var NULL = -5; |
| var POSITIVE_INFINITY = -6; |
| var UNDEFINED = -7; |
| var TYPE_BIGINT = "B"; |
| var TYPE_DATE = "D"; |
| var TYPE_ERROR = "E"; |
| var TYPE_MAP = "M"; |
| var TYPE_NULL_OBJECT = "N"; |
| var TYPE_PROMISE = "P"; |
| var TYPE_REGEXP = "R"; |
| var TYPE_SET = "S"; |
| var TYPE_SYMBOL = "Y"; |
| var TYPE_URL = "U"; |
| var TYPE_PREVIOUS_RESOLVED = "Z"; |
| var SUPPORTED_ERROR_TYPES = [ |
| "EvalError", |
| "RangeError", |
| "ReferenceError", |
| "SyntaxError", |
| "TypeError", |
| "URIError" |
| ]; |
| var Deferred = class { |
| constructor() { |
| this.promise = new Promise((resolve, reject) => { |
| this.resolve = resolve; |
| this.reject = reject; |
| }); |
| } |
| }; |
| function createLineSplittingTransform() { |
| const decoder = new TextDecoder(); |
| let leftover = ""; |
| return new TransformStream({ |
| transform(chunk, controller) { |
| const str = decoder.decode(chunk, { stream: true }); |
| const parts = (leftover + str).split("\n"); |
| leftover = parts.pop() || ""; |
| for (const part of parts) { |
| controller.enqueue(part); |
| } |
| }, |
| flush(controller) { |
| if (leftover) { |
| controller.enqueue(leftover); |
| } |
| } |
| }); |
| } |
|
|
| |
| var TIME_LIMIT_MS = 1; |
| var getNow = () => Date.now(); |
| var yieldToMain = () => new Promise((resolve) => setTimeout(resolve, 0)); |
| async function flatten(input) { |
| const { indices } = this; |
| const existing = indices.get(input); |
| if (existing) return [existing]; |
| if (input === void 0) return UNDEFINED; |
| if (input === null) return NULL; |
| if (Number.isNaN(input)) return NAN; |
| if (input === Number.POSITIVE_INFINITY) return POSITIVE_INFINITY; |
| if (input === Number.NEGATIVE_INFINITY) return NEGATIVE_INFINITY; |
| if (input === 0 && 1 / input < 0) return NEGATIVE_ZERO; |
| const index = this.index++; |
| indices.set(input, index); |
| const stack = [[input, index]]; |
| await stringify.call(this, stack); |
| return index; |
| } |
| async function stringify(stack) { |
| const { deferred, indices, plugins, postPlugins } = this; |
| const str = this.stringified; |
| let lastYieldTime = getNow(); |
| const flattenValue = (value) => { |
| const existing = indices.get(value); |
| if (existing) return [existing]; |
| if (value === void 0) return UNDEFINED; |
| if (value === null) return NULL; |
| if (Number.isNaN(value)) return NAN; |
| if (value === Number.POSITIVE_INFINITY) return POSITIVE_INFINITY; |
| if (value === Number.NEGATIVE_INFINITY) return NEGATIVE_INFINITY; |
| if (value === 0 && 1 / value < 0) return NEGATIVE_ZERO; |
| const index = this.index++; |
| indices.set(value, index); |
| stack.push([value, index]); |
| return index; |
| }; |
| let i = 0; |
| while (stack.length > 0) { |
| const now = getNow(); |
| if (++i % 6e3 === 0 && now - lastYieldTime >= TIME_LIMIT_MS) { |
| await yieldToMain(); |
| lastYieldTime = getNow(); |
| } |
| const [input, index] = stack.pop(); |
| const partsForObj = (obj) => Object.keys(obj).map((k) => `"_${flattenValue(k)}":${flattenValue(obj[k])}`).join(","); |
| let error = null; |
| switch (typeof input) { |
| case "boolean": |
| case "number": |
| case "string": |
| str[index] = JSON.stringify(input); |
| break; |
| case "bigint": |
| str[index] = `["${TYPE_BIGINT}","${input}"]`; |
| break; |
| case "symbol": { |
| const keyFor = Symbol.keyFor(input); |
| if (!keyFor) { |
| error = new Error( |
| "Cannot encode symbol unless created with Symbol.for()" |
| ); |
| } else { |
| str[index] = `["${TYPE_SYMBOL}",${JSON.stringify(keyFor)}]`; |
| } |
| break; |
| } |
| case "object": { |
| if (!input) { |
| str[index] = `${NULL}`; |
| break; |
| } |
| const isArray = Array.isArray(input); |
| let pluginHandled = false; |
| if (!isArray && plugins) { |
| for (const plugin of plugins) { |
| const pluginResult = plugin(input); |
| if (Array.isArray(pluginResult)) { |
| pluginHandled = true; |
| const [pluginIdentifier, ...rest] = pluginResult; |
| str[index] = `[${JSON.stringify(pluginIdentifier)}`; |
| if (rest.length > 0) { |
| str[index] += `,${rest.map((v) => flattenValue(v)).join(",")}`; |
| } |
| str[index] += "]"; |
| break; |
| } |
| } |
| } |
| if (!pluginHandled) { |
| let result = isArray ? "[" : "{"; |
| if (isArray) { |
| for (let i2 = 0; i2 < input.length; i2++) |
| result += (i2 ? "," : "") + (i2 in input ? flattenValue(input[i2]) : HOLE); |
| str[index] = `${result}]`; |
| } else if (input instanceof Date) { |
| const dateTime = input.getTime(); |
| str[index] = `["${TYPE_DATE}",${Number.isNaN(dateTime) ? JSON.stringify("invalid") : dateTime}]`; |
| } else if (input instanceof URL) { |
| str[index] = `["${TYPE_URL}",${JSON.stringify(input.href)}]`; |
| } else if (input instanceof RegExp) { |
| str[index] = `["${TYPE_REGEXP}",${JSON.stringify( |
| input.source |
| )},${JSON.stringify(input.flags)}]`; |
| } else if (input instanceof Set) { |
| if (input.size > 0) { |
| str[index] = `["${TYPE_SET}",${[...input].map((val) => flattenValue(val)).join(",")}]`; |
| } else { |
| str[index] = `["${TYPE_SET}"]`; |
| } |
| } else if (input instanceof Map) { |
| if (input.size > 0) { |
| str[index] = `["${TYPE_MAP}",${[...input].flatMap(([k, v]) => [flattenValue(k), flattenValue(v)]).join(",")}]`; |
| } else { |
| str[index] = `["${TYPE_MAP}"]`; |
| } |
| } else if (input instanceof Promise) { |
| str[index] = `["${TYPE_PROMISE}",${index}]`; |
| deferred[index] = input; |
| } else if (input instanceof Error) { |
| str[index] = `["${TYPE_ERROR}",${JSON.stringify(input.message)}`; |
| if (input.name !== "Error") { |
| str[index] += `,${JSON.stringify(input.name)}`; |
| } |
| str[index] += "]"; |
| } else if (Object.getPrototypeOf(input) === null) { |
| str[index] = `["${TYPE_NULL_OBJECT}",{${partsForObj(input)}}]`; |
| } else if (isPlainObject2(input)) { |
| str[index] = `{${partsForObj(input)}}`; |
| } else { |
| error = new Error("Cannot encode object with prototype"); |
| } |
| } |
| break; |
| } |
| default: { |
| const isArray = Array.isArray(input); |
| let pluginHandled = false; |
| if (!isArray && plugins) { |
| for (const plugin of plugins) { |
| const pluginResult = plugin(input); |
| if (Array.isArray(pluginResult)) { |
| pluginHandled = true; |
| const [pluginIdentifier, ...rest] = pluginResult; |
| str[index] = `[${JSON.stringify(pluginIdentifier)}`; |
| if (rest.length > 0) { |
| str[index] += `,${rest.map((v) => flattenValue(v)).join(",")}`; |
| } |
| str[index] += "]"; |
| break; |
| } |
| } |
| } |
| if (!pluginHandled) { |
| error = new Error("Cannot encode function or unexpected type"); |
| } |
| } |
| } |
| if (error) { |
| let pluginHandled = false; |
| if (postPlugins) { |
| for (const plugin of postPlugins) { |
| const pluginResult = plugin(input); |
| if (Array.isArray(pluginResult)) { |
| pluginHandled = true; |
| const [pluginIdentifier, ...rest] = pluginResult; |
| str[index] = `[${JSON.stringify(pluginIdentifier)}`; |
| if (rest.length > 0) { |
| str[index] += `,${rest.map((v) => flattenValue(v)).join(",")}`; |
| } |
| str[index] += "]"; |
| break; |
| } |
| } |
| } |
| if (!pluginHandled) { |
| throw error; |
| } |
| } |
| } |
| } |
| var objectProtoNames2 = Object.getOwnPropertyNames(Object.prototype).sort().join("\0"); |
| function isPlainObject2(thing) { |
| const proto = Object.getPrototypeOf(thing); |
| return proto === Object.prototype || proto === null || Object.getOwnPropertyNames(proto).sort().join("\0") === objectProtoNames2; |
| } |
|
|
| |
| var globalObj = typeof window !== "undefined" ? window : typeof globalThis !== "undefined" ? globalThis : void 0; |
| function unflatten(parsed) { |
| const { hydrated, values } = this; |
| if (typeof parsed === "number") return hydrate.call(this, parsed); |
| if (!Array.isArray(parsed) || !parsed.length) throw new SyntaxError(); |
| const startIndex = values.length; |
| for (const value of parsed) { |
| values.push(value); |
| } |
| hydrated.length = values.length; |
| return hydrate.call(this, startIndex); |
| } |
| function hydrate(index) { |
| const { hydrated, values, deferred, plugins } = this; |
| let result; |
| const stack = [ |
| [ |
| index, |
| (v) => { |
| result = v; |
| } |
| ] |
| ]; |
| let postRun = []; |
| while (stack.length > 0) { |
| const [index2, set] = stack.pop(); |
| switch (index2) { |
| case UNDEFINED: |
| set(void 0); |
| continue; |
| case NULL: |
| set(null); |
| continue; |
| case NAN: |
| set(NaN); |
| continue; |
| case POSITIVE_INFINITY: |
| set(Infinity); |
| continue; |
| case NEGATIVE_INFINITY: |
| set(-Infinity); |
| continue; |
| case NEGATIVE_ZERO: |
| set(-0); |
| continue; |
| } |
| if (hydrated[index2]) { |
| set(hydrated[index2]); |
| continue; |
| } |
| const value = values[index2]; |
| if (!value || typeof value !== "object") { |
| hydrated[index2] = value; |
| set(value); |
| continue; |
| } |
| if (Array.isArray(value)) { |
| if (typeof value[0] === "string") { |
| const [type, b, c] = value; |
| switch (type) { |
| case TYPE_DATE: |
| set(hydrated[index2] = new Date(b)); |
| continue; |
| case TYPE_URL: |
| set(hydrated[index2] = new URL(b)); |
| continue; |
| case TYPE_BIGINT: |
| set(hydrated[index2] = BigInt(b)); |
| continue; |
| case TYPE_REGEXP: |
| set(hydrated[index2] = new RegExp(b, c)); |
| continue; |
| case TYPE_SYMBOL: |
| set(hydrated[index2] = Symbol.for(b)); |
| continue; |
| case TYPE_SET: |
| const newSet = new Set(); |
| hydrated[index2] = newSet; |
| for (let i = value.length - 1; i > 0; i--) |
| stack.push([ |
| value[i], |
| (v) => { |
| newSet.add(v); |
| } |
| ]); |
| set(newSet); |
| continue; |
| case TYPE_MAP: |
| const map = new Map(); |
| hydrated[index2] = map; |
| for (let i = value.length - 2; i > 0; i -= 2) { |
| const r = []; |
| stack.push([ |
| value[i + 1], |
| (v) => { |
| r[1] = v; |
| } |
| ]); |
| stack.push([ |
| value[i], |
| (k) => { |
| r[0] = k; |
| } |
| ]); |
| postRun.push(() => { |
| map.set(r[0], r[1]); |
| }); |
| } |
| set(map); |
| continue; |
| case TYPE_NULL_OBJECT: |
| const obj = Object.create(null); |
| hydrated[index2] = obj; |
| for (const key of Object.keys(b).reverse()) { |
| const r = []; |
| stack.push([ |
| b[key], |
| (v) => { |
| r[1] = v; |
| } |
| ]); |
| stack.push([ |
| Number(key.slice(1)), |
| (k) => { |
| r[0] = k; |
| } |
| ]); |
| postRun.push(() => { |
| obj[r[0]] = r[1]; |
| }); |
| } |
| set(obj); |
| continue; |
| case TYPE_PROMISE: |
| if (hydrated[b]) { |
| set(hydrated[index2] = hydrated[b]); |
| } else { |
| const d = new Deferred(); |
| deferred[b] = d; |
| set(hydrated[index2] = d.promise); |
| } |
| continue; |
| case TYPE_ERROR: |
| const [, message, errorType] = value; |
| let error = errorType && globalObj && SUPPORTED_ERROR_TYPES.includes(errorType) && errorType in globalObj && typeof globalObj[errorType] === "function" ? new globalObj[errorType](message) : new Error(message); |
| hydrated[index2] = error; |
| set(error); |
| continue; |
| case TYPE_PREVIOUS_RESOLVED: |
| set(hydrated[index2] = hydrated[b]); |
| continue; |
| default: |
| if (Array.isArray(plugins)) { |
| const r = []; |
| const vals = value.slice(1); |
| for (let i = 0; i < vals.length; i++) { |
| const v = vals[i]; |
| stack.push([ |
| v, |
| (v2) => { |
| r[i] = v2; |
| } |
| ]); |
| } |
| postRun.push(() => { |
| for (const plugin of plugins) { |
| const result2 = plugin(value[0], ...r); |
| if (result2) { |
| set(hydrated[index2] = result2.value); |
| return; |
| } |
| } |
| throw new SyntaxError(); |
| }); |
| continue; |
| } |
| throw new SyntaxError(); |
| } |
| } else { |
| const array = []; |
| hydrated[index2] = array; |
| for (let i = 0; i < value.length; i++) { |
| const n = value[i]; |
| if (n !== HOLE) { |
| stack.push([ |
| n, |
| (v) => { |
| array[i] = v; |
| } |
| ]); |
| } |
| } |
| set(array); |
| continue; |
| } |
| } else { |
| const object = {}; |
| hydrated[index2] = object; |
| for (const key of Object.keys(value).reverse()) { |
| const r = []; |
| stack.push([ |
| value[key], |
| (v) => { |
| r[1] = v; |
| } |
| ]); |
| stack.push([ |
| Number(key.slice(1)), |
| (k) => { |
| r[0] = k; |
| } |
| ]); |
| postRun.push(() => { |
| object[r[0]] = r[1]; |
| }); |
| } |
| set(object); |
| continue; |
| } |
| } |
| while (postRun.length > 0) { |
| postRun.pop()(); |
| } |
| return result; |
| } |
|
|
| |
| async function decode(readable, options) { |
| const { plugins } = _nullishCoalesce(options, () => ( {})); |
| const done = new Deferred(); |
| const reader = readable.pipeThrough(createLineSplittingTransform()).getReader(); |
| const decoder = { |
| values: [], |
| hydrated: [], |
| deferred: {}, |
| plugins |
| }; |
| const decoded = await decodeInitial.call(decoder, reader); |
| let donePromise = done.promise; |
| if (decoded.done) { |
| done.resolve(); |
| } else { |
| donePromise = decodeDeferred.call(decoder, reader).then(done.resolve).catch((reason) => { |
| for (const deferred of Object.values(decoder.deferred)) { |
| deferred.reject(reason); |
| } |
| done.reject(reason); |
| }); |
| } |
| return { |
| done: donePromise.then(() => reader.closed), |
| value: decoded.value |
| }; |
| } |
| async function decodeInitial(reader) { |
| const read = await reader.read(); |
| if (!read.value) { |
| throw new SyntaxError(); |
| } |
| let line; |
| try { |
| line = JSON.parse(read.value); |
| } catch (reason) { |
| throw new SyntaxError(); |
| } |
| return { |
| done: read.done, |
| value: unflatten.call(this, line) |
| }; |
| } |
| async function decodeDeferred(reader) { |
| let read = await reader.read(); |
| while (!read.done) { |
| if (!read.value) continue; |
| const line = read.value; |
| switch (line[0]) { |
| case TYPE_PROMISE: { |
| const colonIndex = line.indexOf(":"); |
| const deferredId = Number(line.slice(1, colonIndex)); |
| const deferred = this.deferred[deferredId]; |
| if (!deferred) { |
| throw new Error(`Deferred ID ${deferredId} not found in stream`); |
| } |
| const lineData = line.slice(colonIndex + 1); |
| let jsonLine; |
| try { |
| jsonLine = JSON.parse(lineData); |
| } catch (reason) { |
| throw new SyntaxError(); |
| } |
| const value = unflatten.call(this, jsonLine); |
| deferred.resolve(value); |
| break; |
| } |
| case TYPE_ERROR: { |
| const colonIndex = line.indexOf(":"); |
| const deferredId = Number(line.slice(1, colonIndex)); |
| const deferred = this.deferred[deferredId]; |
| if (!deferred) { |
| throw new Error(`Deferred ID ${deferredId} not found in stream`); |
| } |
| const lineData = line.slice(colonIndex + 1); |
| let jsonLine; |
| try { |
| jsonLine = JSON.parse(lineData); |
| } catch (reason) { |
| throw new SyntaxError(); |
| } |
| const value = unflatten.call(this, jsonLine); |
| deferred.reject(value); |
| break; |
| } |
| default: |
| throw new SyntaxError(); |
| } |
| read = await reader.read(); |
| } |
| } |
| function encode(input, options) { |
| const { onComplete, plugins, postPlugins, signal } = _nullishCoalesce(options, () => ( {})); |
| const encoder = { |
| deferred: {}, |
| index: 0, |
| indices: new Map(), |
| stringified: [], |
| plugins, |
| postPlugins, |
| signal |
| }; |
| const textEncoder = new TextEncoder(); |
| let lastSentIndex = 0; |
| const readable = new ReadableStream({ |
| async start(controller) { |
| const id = await flatten.call(encoder, input); |
| if (Array.isArray(id)) { |
| throw new Error("This should never happen"); |
| } |
| if (id < 0) { |
| controller.enqueue(textEncoder.encode(`${id} |
| `)); |
| } else { |
| controller.enqueue( |
| textEncoder.encode(`[${encoder.stringified.join(",")}] |
| `) |
| ); |
| lastSentIndex = encoder.stringified.length - 1; |
| } |
| const seenPromises = new WeakSet(); |
| let processingChain = Promise.resolve(); |
| if (Object.keys(encoder.deferred).length) { |
| let raceDone; |
| const racePromise = new Promise((resolve, reject) => { |
| raceDone = resolve; |
| if (signal) { |
| const rejectPromise = () => reject(signal.reason || new Error("Signal was aborted.")); |
| if (signal.aborted) { |
| rejectPromise(); |
| } else { |
| signal.addEventListener("abort", (event) => { |
| rejectPromise(); |
| }); |
| } |
| } |
| }); |
| while (Object.keys(encoder.deferred).length > 0) { |
| for (const [deferredId, deferred] of Object.entries( |
| encoder.deferred |
| )) { |
| if (seenPromises.has(deferred)) continue; |
| seenPromises.add( |
| |
| encoder.deferred[Number(deferredId)] = Promise.race([ |
| racePromise, |
| deferred |
| ]).then( |
| (resolved) => { |
| processingChain = processingChain.then(async () => { |
| const id2 = await flatten.call(encoder, resolved); |
| if (Array.isArray(id2)) { |
| controller.enqueue( |
| textEncoder.encode( |
| `${TYPE_PROMISE}${deferredId}:[["${TYPE_PREVIOUS_RESOLVED}",${id2[0]}]] |
| ` |
| ) |
| ); |
| encoder.index++; |
| lastSentIndex++; |
| } else if (id2 < 0) { |
| controller.enqueue( |
| textEncoder.encode( |
| `${TYPE_PROMISE}${deferredId}:${id2} |
| ` |
| ) |
| ); |
| } else { |
| const values = encoder.stringified.slice(lastSentIndex + 1).join(","); |
| controller.enqueue( |
| textEncoder.encode( |
| `${TYPE_PROMISE}${deferredId}:[${values}] |
| ` |
| ) |
| ); |
| lastSentIndex = encoder.stringified.length - 1; |
| } |
| }); |
| return processingChain; |
| }, |
| (reason) => { |
| processingChain = processingChain.then(async () => { |
| if (!reason || typeof reason !== "object" || !(reason instanceof Error)) { |
| reason = new Error("An unknown error occurred"); |
| } |
| const id2 = await flatten.call(encoder, reason); |
| if (Array.isArray(id2)) { |
| controller.enqueue( |
| textEncoder.encode( |
| `${TYPE_ERROR}${deferredId}:[["${TYPE_PREVIOUS_RESOLVED}",${id2[0]}]] |
| ` |
| ) |
| ); |
| encoder.index++; |
| lastSentIndex++; |
| } else if (id2 < 0) { |
| controller.enqueue( |
| textEncoder.encode( |
| `${TYPE_ERROR}${deferredId}:${id2} |
| ` |
| ) |
| ); |
| } else { |
| const values = encoder.stringified.slice(lastSentIndex + 1).join(","); |
| controller.enqueue( |
| textEncoder.encode( |
| `${TYPE_ERROR}${deferredId}:[${values}] |
| ` |
| ) |
| ); |
| lastSentIndex = encoder.stringified.length - 1; |
| } |
| }); |
| return processingChain; |
| } |
| ).finally(() => { |
| delete encoder.deferred[Number(deferredId)]; |
| }) |
| ); |
| } |
| await Promise.race(Object.values(encoder.deferred)); |
| } |
| raceDone(); |
| } |
| await Promise.all(Object.values(encoder.deferred)); |
| await processingChain; |
| controller.close(); |
| _optionalChain([onComplete, 'optionalCall', _82 => _82()]); |
| } |
| }); |
| return readable; |
| } |
|
|
| |
| async function createRequestInit(request) { |
| let init = { signal: request.signal }; |
| if (request.method !== "GET") { |
| init.method = request.method; |
| let contentType = request.headers.get("Content-Type"); |
| if (contentType && /\bapplication\/json\b/.test(contentType)) { |
| init.headers = { "Content-Type": contentType }; |
| init.body = JSON.stringify(await request.json()); |
| } else if (contentType && /\btext\/plain\b/.test(contentType)) { |
| init.headers = { "Content-Type": contentType }; |
| init.body = await request.text(); |
| } else if (contentType && /\bapplication\/x-www-form-urlencoded\b/.test(contentType)) { |
| init.body = new URLSearchParams(await request.text()); |
| } else { |
| init.body = await request.formData(); |
| } |
| } |
| return init; |
| } |
|
|
| |
| var ESCAPE_LOOKUP = { |
| "&": "\\u0026", |
| ">": "\\u003e", |
| "<": "\\u003c", |
| "\u2028": "\\u2028", |
| "\u2029": "\\u2029" |
| }; |
| var ESCAPE_REGEX = /[&><\u2028\u2029]/g; |
| function escapeHtml(html) { |
| return html.replace(ESCAPE_REGEX, (match) => ESCAPE_LOOKUP[match]); |
| } |
|
|
| |
| function invariant2(value, message) { |
| if (value === false || value === null || typeof value === "undefined") { |
| throw new Error(message); |
| } |
| } |
|
|
| |
| var SingleFetchRedirectSymbol = Symbol("SingleFetchRedirect"); |
| var SingleFetchNoResultError = class extends Error { |
| }; |
| var SINGLE_FETCH_REDIRECT_STATUS = 202; |
| var NO_BODY_STATUS_CODES = new Set([100, 101, 204, 205]); |
| function StreamTransfer({ |
| context, |
| identifier, |
| reader, |
| textDecoder, |
| nonce |
| }) { |
| if (!context.renderMeta || !context.renderMeta.didRenderScripts) { |
| return null; |
| } |
| if (!context.renderMeta.streamCache) { |
| context.renderMeta.streamCache = {}; |
| } |
| let { streamCache } = context.renderMeta; |
| let promise = streamCache[identifier]; |
| if (!promise) { |
| promise = streamCache[identifier] = reader.read().then((result) => { |
| streamCache[identifier].result = { |
| done: result.done, |
| value: textDecoder.decode(result.value, { stream: true }) |
| }; |
| }).catch((e) => { |
| streamCache[identifier].error = e; |
| }); |
| } |
| if (promise.error) { |
| throw promise.error; |
| } |
| if (promise.result === void 0) { |
| throw promise; |
| } |
| let { done, value } = promise.result; |
| let scriptTag = value ? React.createElement( |
| "script", |
| { |
| nonce, |
| dangerouslySetInnerHTML: { |
| __html: `window.__reactRouterContext.streamController.enqueue(${escapeHtml( |
| JSON.stringify(value) |
| )});` |
| } |
| } |
| ) : null; |
| if (done) { |
| return React.createElement(React.Fragment, null, scriptTag, React.createElement( |
| "script", |
| { |
| nonce, |
| dangerouslySetInnerHTML: { |
| __html: `window.__reactRouterContext.streamController.close();` |
| } |
| } |
| )); |
| } else { |
| return React.createElement(React.Fragment, null, scriptTag, React.createElement(React.Suspense, null, React.createElement( |
| StreamTransfer, |
| { |
| context, |
| identifier: identifier + 1, |
| reader, |
| textDecoder, |
| nonce |
| } |
| ))); |
| } |
| } |
| function getTurboStreamSingleFetchDataStrategy(getRouter, manifest, routeModules, ssr, basename, trailingSlashAware) { |
| let dataStrategy = getSingleFetchDataStrategyImpl( |
| getRouter, |
| (match) => { |
| let manifestRoute = manifest.routes[match.route.id]; |
| invariant2(manifestRoute, "Route not found in manifest"); |
| let routeModule = routeModules[match.route.id]; |
| return { |
| hasLoader: manifestRoute.hasLoader, |
| hasClientLoader: manifestRoute.hasClientLoader, |
| hasShouldRevalidate: Boolean(_optionalChain([routeModule, 'optionalAccess', _83 => _83.shouldRevalidate])) |
| }; |
| }, |
| fetchAndDecodeViaTurboStream, |
| ssr, |
| basename, |
| trailingSlashAware |
| ); |
| return async (args) => args.runClientMiddleware(dataStrategy); |
| } |
| function getSingleFetchDataStrategyImpl(getRouter, getRouteInfo, fetchAndDecode, ssr, basename, trailingSlashAware, shouldAllowOptOut = () => true) { |
| return async (args) => { |
| let { request, matches, fetcherKey } = args; |
| let router = getRouter(); |
| if (request.method !== "GET") { |
| return singleFetchActionStrategy( |
| args, |
| fetchAndDecode, |
| basename, |
| trailingSlashAware |
| ); |
| } |
| let foundRevalidatingServerLoader = matches.some((m) => { |
| let { hasLoader, hasClientLoader } = getRouteInfo(m); |
| return m.shouldCallHandler() && hasLoader && !hasClientLoader; |
| }); |
| if (!ssr && !foundRevalidatingServerLoader) { |
| return nonSsrStrategy( |
| args, |
| getRouteInfo, |
| fetchAndDecode, |
| basename, |
| trailingSlashAware |
| ); |
| } |
| if (fetcherKey) { |
| return singleFetchLoaderFetcherStrategy( |
| args, |
| fetchAndDecode, |
| basename, |
| trailingSlashAware |
| ); |
| } |
| return singleFetchLoaderNavigationStrategy( |
| args, |
| router, |
| getRouteInfo, |
| fetchAndDecode, |
| ssr, |
| basename, |
| trailingSlashAware, |
| shouldAllowOptOut |
| ); |
| }; |
| } |
| async function singleFetchActionStrategy(args, fetchAndDecode, basename, trailingSlashAware) { |
| let actionMatch = args.matches.find((m) => m.shouldCallHandler()); |
| invariant2(actionMatch, "No action match found"); |
| let actionStatus = void 0; |
| let result = await actionMatch.resolve(async (handler) => { |
| let result2 = await handler(async () => { |
| let { data: data2, status } = await fetchAndDecode( |
| args, |
| basename, |
| trailingSlashAware, |
| [actionMatch.route.id] |
| ); |
| actionStatus = status; |
| return unwrapSingleFetchResult(data2, actionMatch.route.id); |
| }); |
| return result2; |
| }); |
| if (isResponse(result.result) || isRouteErrorResponse(result.result) || isDataWithResponseInit(result.result)) { |
| return { [actionMatch.route.id]: result }; |
| } |
| return { |
| [actionMatch.route.id]: { |
| type: result.type, |
| result: data(result.result, actionStatus) |
| } |
| }; |
| } |
| async function nonSsrStrategy(args, getRouteInfo, fetchAndDecode, basename, trailingSlashAware) { |
| let matchesToLoad = args.matches.filter((m) => m.shouldCallHandler()); |
| let results = {}; |
| await Promise.all( |
| matchesToLoad.map( |
| (m) => m.resolve(async (handler) => { |
| try { |
| let { hasClientLoader } = getRouteInfo(m); |
| let routeId = m.route.id; |
| let result = hasClientLoader ? await handler(async () => { |
| let { data: data2 } = await fetchAndDecode( |
| args, |
| basename, |
| trailingSlashAware, |
| [routeId] |
| ); |
| return unwrapSingleFetchResult(data2, routeId); |
| }) : await handler(); |
| results[m.route.id] = { type: "data", result }; |
| } catch (e) { |
| results[m.route.id] = { type: "error", result: e }; |
| } |
| }) |
| ) |
| ); |
| return results; |
| } |
| async function singleFetchLoaderNavigationStrategy(args, router, getRouteInfo, fetchAndDecode, ssr, basename, trailingSlashAware, shouldAllowOptOut = () => true) { |
| let routesParams = new Set(); |
| let foundOptOutRoute = false; |
| let routeDfds = args.matches.map(() => createDeferred2()); |
| let singleFetchDfd = createDeferred2(); |
| let results = {}; |
| let resolvePromise = Promise.all( |
| args.matches.map( |
| async (m, i) => m.resolve(async (handler) => { |
| routeDfds[i].resolve(); |
| let routeId = m.route.id; |
| let { hasLoader, hasClientLoader, hasShouldRevalidate } = getRouteInfo(m); |
| let defaultShouldRevalidate = !m.shouldRevalidateArgs || m.shouldRevalidateArgs.actionStatus == null || m.shouldRevalidateArgs.actionStatus < 400; |
| let shouldCall = m.shouldCallHandler(defaultShouldRevalidate); |
| if (!shouldCall) { |
| foundOptOutRoute || (foundOptOutRoute = m.shouldRevalidateArgs != null && |
| hasLoader && |
| hasShouldRevalidate === true); |
| return; |
| } |
| if (shouldAllowOptOut(m) && hasClientLoader) { |
| if (hasLoader) { |
| foundOptOutRoute = true; |
| } |
| try { |
| let result = await handler(async () => { |
| let { data: data2 } = await fetchAndDecode( |
| args, |
| basename, |
| trailingSlashAware, |
| [routeId] |
| ); |
| return unwrapSingleFetchResult(data2, routeId); |
| }); |
| results[routeId] = { type: "data", result }; |
| } catch (e) { |
| results[routeId] = { type: "error", result: e }; |
| } |
| return; |
| } |
| if (hasLoader) { |
| routesParams.add(routeId); |
| } |
| try { |
| let result = await handler(async () => { |
| let data2 = await singleFetchDfd.promise; |
| return unwrapSingleFetchResult(data2, routeId); |
| }); |
| results[routeId] = { type: "data", result }; |
| } catch (e) { |
| results[routeId] = { type: "error", result: e }; |
| } |
| }) |
| ) |
| ); |
| await Promise.all(routeDfds.map((d) => d.promise)); |
| let isInitialLoad = !router.state.initialized && router.state.navigation.state === "idle"; |
| if ((isInitialLoad || routesParams.size === 0) && !window.__reactRouterHdrActive) { |
| singleFetchDfd.resolve({ routes: {} }); |
| } else { |
| let targetRoutes = ssr && foundOptOutRoute && routesParams.size > 0 ? [...routesParams.keys()] : void 0; |
| try { |
| let data2 = await fetchAndDecode( |
| args, |
| basename, |
| trailingSlashAware, |
| targetRoutes |
| ); |
| singleFetchDfd.resolve(data2.data); |
| } catch (e) { |
| singleFetchDfd.reject(e); |
| } |
| } |
| await resolvePromise; |
| await bubbleMiddlewareErrors( |
| singleFetchDfd.promise, |
| args.matches, |
| routesParams, |
| results |
| ); |
| return results; |
| } |
| async function bubbleMiddlewareErrors(singleFetchPromise, matches, routesParams, results) { |
| try { |
| let middlewareError; |
| let fetchedData = await singleFetchPromise; |
| if ("routes" in fetchedData) { |
| for (let match of matches) { |
| if (match.route.id in fetchedData.routes) { |
| let routeResult = fetchedData.routes[match.route.id]; |
| if ("error" in routeResult) { |
| middlewareError = routeResult.error; |
| if (_optionalChain([results, 'access', _84 => _84[match.route.id], 'optionalAccess', _85 => _85.result]) == null) { |
| results[match.route.id] = { |
| type: "error", |
| result: middlewareError |
| }; |
| } |
| break; |
| } |
| } |
| } |
| } |
| if (middlewareError !== void 0) { |
| Array.from(routesParams.values()).forEach((routeId) => { |
| if (results[routeId].result instanceof SingleFetchNoResultError) { |
| results[routeId].result = middlewareError; |
| } |
| }); |
| } |
| } catch (e) { |
| } |
| } |
| async function singleFetchLoaderFetcherStrategy(args, fetchAndDecode, basename, trailingSlashAware) { |
| let fetcherMatch = args.matches.find((m) => m.shouldCallHandler()); |
| invariant2(fetcherMatch, "No fetcher match found"); |
| let routeId = fetcherMatch.route.id; |
| let result = await fetcherMatch.resolve( |
| async (handler) => handler(async () => { |
| let { data: data2 } = await fetchAndDecode(args, basename, trailingSlashAware, [ |
| routeId |
| ]); |
| return unwrapSingleFetchResult(data2, routeId); |
| }) |
| ); |
| return { [fetcherMatch.route.id]: result }; |
| } |
| function stripIndexParam(url) { |
| let indexValues = url.searchParams.getAll("index"); |
| url.searchParams.delete("index"); |
| let indexValuesToKeep = []; |
| for (let indexValue of indexValues) { |
| if (indexValue) { |
| indexValuesToKeep.push(indexValue); |
| } |
| } |
| for (let toKeep of indexValuesToKeep) { |
| url.searchParams.append("index", toKeep); |
| } |
| return url; |
| } |
| function singleFetchUrl(reqUrl, basename, trailingSlashAware, extension) { |
| let url = typeof reqUrl === "string" ? new URL( |
| reqUrl, |
| |
| |
| typeof window === "undefined" ? "server://singlefetch/" : window.location.origin |
| ) : reqUrl; |
| if (trailingSlashAware) { |
| if (url.pathname.endsWith("/")) { |
| url.pathname = `${url.pathname}_.${extension}`; |
| } else { |
| url.pathname = `${url.pathname}.${extension}`; |
| } |
| } else { |
| if (url.pathname === "/") { |
| url.pathname = `_root.${extension}`; |
| } else if (basename && stripBasename(url.pathname, basename) === "/") { |
| url.pathname = `${removeTrailingSlash(basename)}/_root.${extension}`; |
| } else { |
| url.pathname = `${removeTrailingSlash(url.pathname)}.${extension}`; |
| } |
| } |
| return url; |
| } |
| async function fetchAndDecodeViaTurboStream(args, basename, trailingSlashAware, targetRoutes) { |
| let { request } = args; |
| let url = singleFetchUrl(request.url, basename, trailingSlashAware, "data"); |
| if (request.method === "GET") { |
| url = stripIndexParam(url); |
| if (targetRoutes) { |
| url.searchParams.set("_routes", targetRoutes.join(",")); |
| } |
| } |
| let res = await fetch(url, await createRequestInit(request)); |
| if (res.status >= 400 && !res.headers.has("X-Remix-Response")) { |
| throw new ErrorResponseImpl(res.status, res.statusText, await res.text()); |
| } |
| if (res.status === 204 && res.headers.has("X-Remix-Redirect")) { |
| return { |
| status: SINGLE_FETCH_REDIRECT_STATUS, |
| data: { |
| redirect: { |
| redirect: res.headers.get("X-Remix-Redirect"), |
| status: Number(res.headers.get("X-Remix-Status") || "302"), |
| revalidate: res.headers.get("X-Remix-Revalidate") === "true", |
| reload: res.headers.get("X-Remix-Reload-Document") === "true", |
| replace: res.headers.get("X-Remix-Replace") === "true" |
| } |
| } |
| }; |
| } |
| if (NO_BODY_STATUS_CODES.has(res.status)) { |
| let routes = {}; |
| if (targetRoutes && request.method !== "GET") { |
| routes[targetRoutes[0]] = { data: void 0 }; |
| } |
| return { |
| status: res.status, |
| data: { routes } |
| }; |
| } |
| invariant2(res.body, "No response body to decode"); |
| try { |
| let decoded = await decodeViaTurboStream(res.body, window); |
| let data2; |
| if (request.method === "GET") { |
| let typed = decoded.value; |
| if (SingleFetchRedirectSymbol in typed) { |
| data2 = { redirect: typed[SingleFetchRedirectSymbol] }; |
| } else { |
| data2 = { routes: typed }; |
| } |
| } else { |
| let typed = decoded.value; |
| let routeId = _optionalChain([targetRoutes, 'optionalAccess', _86 => _86[0]]); |
| invariant2(routeId, "No routeId found for single fetch call decoding"); |
| if ("redirect" in typed) { |
| data2 = { redirect: typed }; |
| } else { |
| data2 = { routes: { [routeId]: typed } }; |
| } |
| } |
| return { status: res.status, data: data2 }; |
| } catch (e) { |
| throw new Error("Unable to decode turbo-stream response"); |
| } |
| } |
| function decodeViaTurboStream(body, global) { |
| return decode(body, { |
| plugins: [ |
| (type, ...rest) => { |
| if (type === "SanitizedError") { |
| let [name, message, stack] = rest; |
| let Constructor = Error; |
| if (name && SUPPORTED_ERROR_TYPES.includes(name) && name in global && |
| typeof global[name] === "function") { |
| Constructor = global[name]; |
| } |
| let error = new Constructor(message); |
| error.stack = stack; |
| return { value: error }; |
| } |
| if (type === "ErrorResponse") { |
| let [data2, status, statusText] = rest; |
| return { |
| value: new ErrorResponseImpl(status, statusText, data2) |
| }; |
| } |
| if (type === "SingleFetchRedirect") { |
| return { value: { [SingleFetchRedirectSymbol]: rest[0] } }; |
| } |
| if (type === "SingleFetchClassInstance") { |
| return { value: rest[0] }; |
| } |
| if (type === "SingleFetchFallback") { |
| return { value: void 0 }; |
| } |
| } |
| ] |
| }); |
| } |
| function unwrapSingleFetchResult(result, routeId) { |
| if ("redirect" in result) { |
| let { |
| redirect: location, |
| revalidate, |
| reload, |
| replace: replace2, |
| status |
| } = result.redirect; |
| throw redirect(location, { |
| status, |
| headers: { |
| |
| ...revalidate ? { "X-Remix-Revalidate": "yes" } : null, |
| ...reload ? { "X-Remix-Reload-Document": "yes" } : null, |
| ...replace2 ? { "X-Remix-Replace": "yes" } : null |
| } |
| }); |
| } |
| let routeResult = result.routes[routeId]; |
| if (routeResult == null) { |
| throw new SingleFetchNoResultError( |
| `No result found for routeId "${routeId}"` |
| ); |
| } else if ("error" in routeResult) { |
| throw routeResult.error; |
| } else if ("data" in routeResult) { |
| return routeResult.data; |
| } else { |
| throw new Error(`Invalid response found for routeId "${routeId}"`); |
| } |
| } |
| function createDeferred2() { |
| let resolve; |
| let reject; |
| let promise = new Promise((res, rej) => { |
| resolve = async (val) => { |
| res(val); |
| try { |
| await promise; |
| } catch (e) { |
| } |
| }; |
| reject = async (error) => { |
| rej(error); |
| try { |
| await promise; |
| } catch (e) { |
| } |
| }; |
| }); |
| return { |
| promise, |
| |
| resolve, |
| |
| reject |
| }; |
| } |
|
|
| |
|
|
| var DataRouterContext = React2.createContext(null); |
| DataRouterContext.displayName = "DataRouter"; |
| var DataRouterStateContext = React2.createContext(null); |
| DataRouterStateContext.displayName = "DataRouterState"; |
| var RSCRouterContext = React2.createContext(false); |
| function useIsRSCRouterContext() { |
| return React2.useContext(RSCRouterContext); |
| } |
| var ViewTransitionContext = React2.createContext({ |
| isTransitioning: false |
| }); |
| ViewTransitionContext.displayName = "ViewTransition"; |
| var FetchersContext = React2.createContext( |
| new Map() |
| ); |
| FetchersContext.displayName = "Fetchers"; |
| var AwaitContext = React2.createContext(null); |
| AwaitContext.displayName = "Await"; |
| var AwaitContextProvider = (props) => React2.createElement(AwaitContext.Provider, props); |
| var NavigationContext = React2.createContext( |
| null |
| ); |
| NavigationContext.displayName = "Navigation"; |
| var LocationContext = React2.createContext( |
| null |
| ); |
| LocationContext.displayName = "Location"; |
| var RouteContext = React2.createContext({ |
| outlet: null, |
| matches: [], |
| isDataRoute: false |
| }); |
| RouteContext.displayName = "Route"; |
| var RouteErrorContext = React2.createContext(null); |
| RouteErrorContext.displayName = "RouteError"; |
| var ENABLE_DEV_WARNINGS = true; |
|
|
| |
|
|
|
|
| |
| var ERROR_DIGEST_BASE = "REACT_ROUTER_ERROR"; |
| var ERROR_DIGEST_REDIRECT = "REDIRECT"; |
| var ERROR_DIGEST_ROUTE_ERROR_RESPONSE = "ROUTE_ERROR_RESPONSE"; |
| function decodeRedirectErrorDigest(digest) { |
| if (digest.startsWith(`${ERROR_DIGEST_BASE}:${ERROR_DIGEST_REDIRECT}:{`)) { |
| try { |
| let parsed = JSON.parse(digest.slice(28)); |
| if (typeof parsed === "object" && parsed && typeof parsed.status === "number" && typeof parsed.statusText === "string" && typeof parsed.location === "string" && typeof parsed.reloadDocument === "boolean" && typeof parsed.replace === "boolean") { |
| return parsed; |
| } |
| } catch (e2) { |
| } |
| } |
| } |
| function decodeRouteErrorResponseDigest(digest) { |
| if (digest.startsWith( |
| `${ERROR_DIGEST_BASE}:${ERROR_DIGEST_ROUTE_ERROR_RESPONSE}:{` |
| )) { |
| try { |
| let parsed = JSON.parse(digest.slice(40)); |
| if (typeof parsed === "object" && parsed && typeof parsed.status === "number" && typeof parsed.statusText === "string") { |
| return new ErrorResponseImpl( |
| parsed.status, |
| parsed.statusText, |
| parsed.data |
| ); |
| } |
| } catch (e3) { |
| } |
| } |
| } |
|
|
| |
| function useHref(to, { relative } = {}) { |
| invariant( |
| useInRouterContext(), |
| |
| |
| `useHref() may be used only in the context of a <Router> component.` |
| ); |
| let { basename, navigator } = React3.useContext(NavigationContext); |
| let { hash, pathname, search } = useResolvedPath(to, { relative }); |
| let joinedPathname = pathname; |
| if (basename !== "/") { |
| joinedPathname = pathname === "/" ? basename : joinPaths([basename, pathname]); |
| } |
| return navigator.createHref({ pathname: joinedPathname, search, hash }); |
| } |
| function useInRouterContext() { |
| return React3.useContext(LocationContext) != null; |
| } |
| function useLocation() { |
| invariant( |
| useInRouterContext(), |
| |
| |
| `useLocation() may be used only in the context of a <Router> component.` |
| ); |
| return React3.useContext(LocationContext).location; |
| } |
| function useNavigationType() { |
| return React3.useContext(LocationContext).navigationType; |
| } |
| function useMatch(pattern) { |
| invariant( |
| useInRouterContext(), |
| |
| |
| `useMatch() may be used only in the context of a <Router> component.` |
| ); |
| let { pathname } = useLocation(); |
| return React3.useMemo( |
| () => matchPath(pattern, decodePath(pathname)), |
| [pathname, pattern] |
| ); |
| } |
| var navigateEffectWarning = `You should call navigate() in a React.useEffect(), not when your component is first rendered.`; |
| function useIsomorphicLayoutEffect(cb) { |
| let isStatic = React3.useContext(NavigationContext).static; |
| if (!isStatic) { |
| React3.useLayoutEffect(cb); |
| } |
| } |
| function useNavigate() { |
| let { isDataRoute } = React3.useContext(RouteContext); |
| return isDataRoute ? useNavigateStable() : useNavigateUnstable(); |
| } |
| function useNavigateUnstable() { |
| invariant( |
| useInRouterContext(), |
| |
| |
| `useNavigate() may be used only in the context of a <Router> component.` |
| ); |
| let dataRouterContext = React3.useContext(DataRouterContext); |
| let { basename, navigator } = React3.useContext(NavigationContext); |
| let { matches } = React3.useContext(RouteContext); |
| let { pathname: locationPathname } = useLocation(); |
| let routePathnamesJson = JSON.stringify(getResolveToMatches(matches)); |
| let activeRef = React3.useRef(false); |
| useIsomorphicLayoutEffect(() => { |
| activeRef.current = true; |
| }); |
| let navigate = React3.useCallback( |
| (to, options = {}) => { |
| warning(activeRef.current, navigateEffectWarning); |
| if (!activeRef.current) return; |
| if (typeof to === "number") { |
| navigator.go(to); |
| return; |
| } |
| let path = resolveTo( |
| to, |
| JSON.parse(routePathnamesJson), |
| locationPathname, |
| options.relative === "path" |
| ); |
| if (dataRouterContext == null && basename !== "/") { |
| path.pathname = path.pathname === "/" ? basename : joinPaths([basename, path.pathname]); |
| } |
| (!!options.replace ? navigator.replace : navigator.push)( |
| path, |
| options.state, |
| options |
| ); |
| }, |
| [ |
| basename, |
| navigator, |
| routePathnamesJson, |
| locationPathname, |
| dataRouterContext |
| ] |
| ); |
| return navigate; |
| } |
| var OutletContext = React3.createContext(null); |
| function useOutletContext() { |
| return React3.useContext(OutletContext); |
| } |
| function useOutlet(context) { |
| let outlet = React3.useContext(RouteContext).outlet; |
| return React3.useMemo( |
| () => outlet && React3.createElement(OutletContext.Provider, { value: context }, outlet), |
| [outlet, context] |
| ); |
| } |
| function useParams() { |
| let { matches } = React3.useContext(RouteContext); |
| let routeMatch = matches[matches.length - 1]; |
| return _nullishCoalesce(_optionalChain([routeMatch, 'optionalAccess', _87 => _87.params]), () => ( {})); |
| } |
| function useResolvedPath(to, { relative } = {}) { |
| let { matches } = React3.useContext(RouteContext); |
| let { pathname: locationPathname } = useLocation(); |
| let routePathnamesJson = JSON.stringify(getResolveToMatches(matches)); |
| return React3.useMemo( |
| () => resolveTo( |
| to, |
| JSON.parse(routePathnamesJson), |
| locationPathname, |
| relative === "path" |
| ), |
| [to, routePathnamesJson, locationPathname, relative] |
| ); |
| } |
| function useRoutes(routes, locationArg) { |
| return useRoutesImpl(routes, locationArg); |
| } |
| function useRoutesImpl(routes, locationArg, dataRouterOpts) { |
| invariant( |
| useInRouterContext(), |
| |
| |
| `useRoutes() may be used only in the context of a <Router> component.` |
| ); |
| let { navigator } = React3.useContext(NavigationContext); |
| let { matches: parentMatches } = React3.useContext(RouteContext); |
| let routeMatch = parentMatches[parentMatches.length - 1]; |
| let parentParams = routeMatch ? routeMatch.params : {}; |
| let parentPathname = routeMatch ? routeMatch.pathname : "/"; |
| let parentPathnameBase = routeMatch ? routeMatch.pathnameBase : "/"; |
| let parentRoute = routeMatch && routeMatch.route; |
| if (ENABLE_DEV_WARNINGS) { |
| let parentPath = parentRoute && parentRoute.path || ""; |
| warningOnce( |
| parentPathname, |
| !parentRoute || parentPath.endsWith("*") || parentPath.endsWith("*?"), |
| `You rendered descendant <Routes> (or called \`useRoutes()\`) at "${parentPathname}" (under <Route path="${parentPath}">) but the parent route path has no trailing "*". This means if you navigate deeper, the parent won't match anymore and therefore the child routes will never render. |
| |
| Please change the parent <Route path="${parentPath}"> to <Route path="${parentPath === "/" ? "*" : `${parentPath}/*`}">.` |
| ); |
| } |
| let locationFromContext = useLocation(); |
| let location; |
| if (locationArg) { |
| let parsedLocationArg = typeof locationArg === "string" ? parsePath(locationArg) : locationArg; |
| invariant( |
| parentPathnameBase === "/" || _optionalChain([parsedLocationArg, 'access', _88 => _88.pathname, 'optionalAccess', _89 => _89.startsWith, 'call', _90 => _90(parentPathnameBase)]), |
| `When overriding the location using \`<Routes location>\` or \`useRoutes(routes, location)\`, the location pathname must begin with the portion of the URL pathname that was matched by all parent routes. The current pathname base is "${parentPathnameBase}" but pathname "${parsedLocationArg.pathname}" was given in the \`location\` prop.` |
| ); |
| location = parsedLocationArg; |
| } else { |
| location = locationFromContext; |
| } |
| let pathname = location.pathname || "/"; |
| let remainingPathname = pathname; |
| if (parentPathnameBase !== "/") { |
| let parentSegments = parentPathnameBase.replace(/^\//, "").split("/"); |
| let segments = pathname.replace(/^\//, "").split("/"); |
| remainingPathname = "/" + segments.slice(parentSegments.length).join("/"); |
| } |
| let matches = matchRoutes(routes, { pathname: remainingPathname }); |
| if (ENABLE_DEV_WARNINGS) { |
| warning( |
| parentRoute || matches != null, |
| `No routes matched location "${location.pathname}${location.search}${location.hash}" ` |
| ); |
| warning( |
| matches == null || matches[matches.length - 1].route.element !== void 0 || matches[matches.length - 1].route.Component !== void 0 || matches[matches.length - 1].route.lazy !== void 0, |
| `Matched leaf route at location "${location.pathname}${location.search}${location.hash}" does not have an element or Component. This means it will render an <Outlet /> with a null value by default resulting in an "empty" page.` |
| ); |
| } |
| let renderedMatches = _renderMatches( |
| matches && matches.map( |
| (match) => Object.assign({}, match, { |
| params: Object.assign({}, parentParams, match.params), |
| pathname: joinPaths([ |
| parentPathnameBase, |
| |
| |
| |
| |
| navigator.encodeLocation ? navigator.encodeLocation( |
| match.pathname.replace(/%/g, "%25").replace(/\?/g, "%3F").replace(/#/g, "%23") |
| ).pathname : match.pathname |
| ]), |
| pathnameBase: match.pathnameBase === "/" ? parentPathnameBase : joinPaths([ |
| parentPathnameBase, |
| |
| |
| |
| |
| navigator.encodeLocation ? navigator.encodeLocation( |
| match.pathnameBase.replace(/%/g, "%25").replace(/\?/g, "%3F").replace(/#/g, "%23") |
| ).pathname : match.pathnameBase |
| ]) |
| }) |
| ), |
| parentMatches, |
| dataRouterOpts |
| ); |
| if (locationArg && renderedMatches) { |
| return React3.createElement( |
| LocationContext.Provider, |
| { |
| value: { |
| location: { |
| pathname: "/", |
| search: "", |
| hash: "", |
| state: null, |
| key: "default", |
| unstable_mask: void 0, |
| ...location |
| }, |
| navigationType: "POP" |
| } |
| }, |
| renderedMatches |
| ); |
| } |
| return renderedMatches; |
| } |
| function DefaultErrorComponent() { |
| let error = useRouteError(); |
| let message = isRouteErrorResponse(error) ? `${error.status} ${error.statusText}` : error instanceof Error ? error.message : JSON.stringify(error); |
| let stack = error instanceof Error ? error.stack : null; |
| let lightgrey = "rgba(200,200,200, 0.5)"; |
| let preStyles = { padding: "0.5rem", backgroundColor: lightgrey }; |
| let codeStyles = { padding: "2px 4px", backgroundColor: lightgrey }; |
| let devInfo = null; |
| if (ENABLE_DEV_WARNINGS) { |
| console.error( |
| "Error handled by React Router default ErrorBoundary:", |
| error |
| ); |
| devInfo = React3.createElement(React3.Fragment, null, React3.createElement("p", null, "\u{1F4BF} Hey developer \u{1F44B}"), React3.createElement("p", null, "You can provide a way better UX than this when your app throws errors by providing your own ", React3.createElement("code", { style: codeStyles }, "ErrorBoundary"), " or", " ", React3.createElement("code", { style: codeStyles }, "errorElement"), " prop on your route.")); |
| } |
| return React3.createElement(React3.Fragment, null, React3.createElement("h2", null, "Unexpected Application Error!"), React3.createElement("h3", { style: { fontStyle: "italic" } }, message), stack ? React3.createElement("pre", { style: preStyles }, stack) : null, devInfo); |
| } |
| var defaultErrorElement = React3.createElement(DefaultErrorComponent, null); |
| var RenderErrorBoundary = class extends React3.Component { |
| constructor(props) { |
| super(props); |
| this.state = { |
| location: props.location, |
| revalidation: props.revalidation, |
| error: props.error |
| }; |
| } |
| static getDerivedStateFromError(error) { |
| return { error }; |
| } |
| static getDerivedStateFromProps(props, state) { |
| if (state.location !== props.location || state.revalidation !== "idle" && props.revalidation === "idle") { |
| return { |
| error: props.error, |
| location: props.location, |
| revalidation: props.revalidation |
| }; |
| } |
| return { |
| error: props.error !== void 0 ? props.error : state.error, |
| location: state.location, |
| revalidation: props.revalidation || state.revalidation |
| }; |
| } |
| componentDidCatch(error, errorInfo) { |
| if (this.props.onError) { |
| this.props.onError(error, errorInfo); |
| } else { |
| console.error( |
| "React Router caught the following error during render", |
| error |
| ); |
| } |
| } |
| render() { |
| let error = this.state.error; |
| if (this.context && typeof error === "object" && error && "digest" in error && typeof error.digest === "string") { |
| const decoded = decodeRouteErrorResponseDigest(error.digest); |
| if (decoded) error = decoded; |
| } |
| let result = error !== void 0 ? React3.createElement(RouteContext.Provider, { value: this.props.routeContext }, React3.createElement( |
| RouteErrorContext.Provider, |
| { |
| value: error, |
| children: this.props.component |
| } |
| )) : this.props.children; |
| if (this.context) { |
| return React3.createElement(RSCErrorHandler, { error }, result); |
| } |
| return result; |
| } |
| }; |
| RenderErrorBoundary.contextType = RSCRouterContext; |
| var errorRedirectHandledMap = new WeakMap(); |
| function RSCErrorHandler({ |
| children, |
| error |
| }) { |
| let { basename } = React3.useContext(NavigationContext); |
| if (typeof error === "object" && error && "digest" in error && typeof error.digest === "string") { |
| let redirect2 = decodeRedirectErrorDigest(error.digest); |
| if (redirect2) { |
| let existingRedirect = errorRedirectHandledMap.get(error); |
| if (existingRedirect) throw existingRedirect; |
| let parsed = parseToInfo(redirect2.location, basename); |
| if (isBrowser && !errorRedirectHandledMap.get(error)) { |
| if (parsed.isExternal || redirect2.reloadDocument) { |
| window.location.href = parsed.absoluteURL || parsed.to; |
| } else { |
| const redirectPromise = Promise.resolve().then( |
| () => window.__reactRouterDataRouter.navigate(parsed.to, { |
| replace: redirect2.replace |
| }) |
| ); |
| errorRedirectHandledMap.set(error, redirectPromise); |
| throw redirectPromise; |
| } |
| } |
| return React3.createElement( |
| "meta", |
| { |
| httpEquiv: "refresh", |
| content: `0;url=${parsed.absoluteURL || parsed.to}` |
| } |
| ); |
| } |
| } |
| return children; |
| } |
| function RenderedRoute({ routeContext, match, children }) { |
| let dataRouterContext = React3.useContext(DataRouterContext); |
| if (dataRouterContext && dataRouterContext.static && dataRouterContext.staticContext && (match.route.errorElement || match.route.ErrorBoundary)) { |
| dataRouterContext.staticContext._deepestRenderedBoundaryId = match.route.id; |
| } |
| return React3.createElement(RouteContext.Provider, { value: routeContext }, children); |
| } |
| function _renderMatches(matches, parentMatches = [], dataRouterOpts) { |
| let dataRouterState = _optionalChain([dataRouterOpts, 'optionalAccess', _91 => _91.state]); |
| if (matches == null) { |
| if (!dataRouterState) { |
| return null; |
| } |
| if (dataRouterState.errors) { |
| matches = dataRouterState.matches; |
| } else if (parentMatches.length === 0 && !dataRouterState.initialized && dataRouterState.matches.length > 0) { |
| matches = dataRouterState.matches; |
| } else { |
| return null; |
| } |
| } |
| let renderedMatches = matches; |
| let errors = _optionalChain([dataRouterState, 'optionalAccess', _92 => _92.errors]); |
| if (errors != null) { |
| let errorIndex = renderedMatches.findIndex( |
| (m) => m.route.id && _optionalChain([errors, 'optionalAccess', _93 => _93[m.route.id]]) !== void 0 |
| ); |
| invariant( |
| errorIndex >= 0, |
| `Could not find a matching route for errors on route IDs: ${Object.keys( |
| errors |
| ).join(",")}` |
| ); |
| renderedMatches = renderedMatches.slice( |
| 0, |
| Math.min(renderedMatches.length, errorIndex + 1) |
| ); |
| } |
| let renderFallback = false; |
| let fallbackIndex = -1; |
| if (dataRouterOpts && dataRouterState) { |
| renderFallback = dataRouterState.renderFallback; |
| for (let i = 0; i < renderedMatches.length; i++) { |
| let match = renderedMatches[i]; |
| if (match.route.HydrateFallback || match.route.hydrateFallbackElement) { |
| fallbackIndex = i; |
| } |
| if (match.route.id) { |
| let { loaderData, errors: errors2 } = dataRouterState; |
| let needsToRunLoader = match.route.loader && !loaderData.hasOwnProperty(match.route.id) && (!errors2 || errors2[match.route.id] === void 0); |
| if (match.route.lazy || needsToRunLoader) { |
| if (dataRouterOpts.isStatic) { |
| renderFallback = true; |
| } |
| if (fallbackIndex >= 0) { |
| renderedMatches = renderedMatches.slice(0, fallbackIndex + 1); |
| } else { |
| renderedMatches = [renderedMatches[0]]; |
| } |
| break; |
| } |
| } |
| } |
| } |
| let onErrorHandler = _optionalChain([dataRouterOpts, 'optionalAccess', _94 => _94.onError]); |
| let onError = dataRouterState && onErrorHandler ? (error, errorInfo) => { |
| onErrorHandler(error, { |
| location: dataRouterState.location, |
| params: _nullishCoalesce(_optionalChain([dataRouterState, 'access', _95 => _95.matches, 'optionalAccess', _96 => _96[0], 'optionalAccess', _97 => _97.params]), () => ( {})), |
| unstable_pattern: getRoutePattern(dataRouterState.matches), |
| errorInfo |
| }); |
| } : void 0; |
| return renderedMatches.reduceRight( |
| (outlet, match, index) => { |
| let error; |
| let shouldRenderHydrateFallback = false; |
| let errorElement = null; |
| let hydrateFallbackElement = null; |
| if (dataRouterState) { |
| error = errors && match.route.id ? errors[match.route.id] : void 0; |
| errorElement = match.route.errorElement || defaultErrorElement; |
| if (renderFallback) { |
| if (fallbackIndex < 0 && index === 0) { |
| warningOnce( |
| "route-fallback", |
| false, |
| "No `HydrateFallback` element provided to render during initial hydration" |
| ); |
| shouldRenderHydrateFallback = true; |
| hydrateFallbackElement = null; |
| } else if (fallbackIndex === index) { |
| shouldRenderHydrateFallback = true; |
| hydrateFallbackElement = match.route.hydrateFallbackElement || null; |
| } |
| } |
| } |
| let matches2 = parentMatches.concat(renderedMatches.slice(0, index + 1)); |
| let getChildren = () => { |
| let children; |
| if (error) { |
| children = errorElement; |
| } else if (shouldRenderHydrateFallback) { |
| children = hydrateFallbackElement; |
| } else if (match.route.Component) { |
| children = React3.createElement(match.route.Component, null); |
| } else if (match.route.element) { |
| children = match.route.element; |
| } else { |
| children = outlet; |
| } |
| return React3.createElement( |
| RenderedRoute, |
| { |
| match, |
| routeContext: { |
| outlet, |
| matches: matches2, |
| isDataRoute: dataRouterState != null |
| }, |
| children |
| } |
| ); |
| }; |
| return dataRouterState && (match.route.ErrorBoundary || match.route.errorElement || index === 0) ? React3.createElement( |
| RenderErrorBoundary, |
| { |
| location: dataRouterState.location, |
| revalidation: dataRouterState.revalidation, |
| component: errorElement, |
| error, |
| children: getChildren(), |
| routeContext: { outlet: null, matches: matches2, isDataRoute: true }, |
| onError |
| } |
| ) : getChildren(); |
| }, |
| null |
| ); |
| } |
| function getDataRouterConsoleError(hookName) { |
| return `${hookName} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`; |
| } |
| function useDataRouterContext(hookName) { |
| let ctx = React3.useContext(DataRouterContext); |
| invariant(ctx, getDataRouterConsoleError(hookName)); |
| return ctx; |
| } |
| function useDataRouterState(hookName) { |
| let state = React3.useContext(DataRouterStateContext); |
| invariant(state, getDataRouterConsoleError(hookName)); |
| return state; |
| } |
| function useRouteContext(hookName) { |
| let route = React3.useContext(RouteContext); |
| invariant(route, getDataRouterConsoleError(hookName)); |
| return route; |
| } |
| function useCurrentRouteId(hookName) { |
| let route = useRouteContext(hookName); |
| let thisRoute = route.matches[route.matches.length - 1]; |
| invariant( |
| thisRoute.route.id, |
| `${hookName} can only be used on routes that contain a unique "id"` |
| ); |
| return thisRoute.route.id; |
| } |
| function useRouteId() { |
| return useCurrentRouteId("useRouteId" ); |
| } |
| function useNavigation() { |
| let state = useDataRouterState("useNavigation" ); |
| return state.navigation; |
| } |
| function useRevalidator() { |
| let dataRouterContext = useDataRouterContext("useRevalidator" ); |
| let state = useDataRouterState("useRevalidator" ); |
| let revalidate = React3.useCallback(async () => { |
| await dataRouterContext.router.revalidate(); |
| }, [dataRouterContext.router]); |
| return React3.useMemo( |
| () => ({ revalidate, state: state.revalidation }), |
| [revalidate, state.revalidation] |
| ); |
| } |
| function useMatches() { |
| let { matches, loaderData } = useDataRouterState( |
| "useMatches" |
| ); |
| return React3.useMemo( |
| () => matches.map((m) => convertRouteMatchToUiMatch(m, loaderData)), |
| [matches, loaderData] |
| ); |
| } |
| function useLoaderData() { |
| let state = useDataRouterState("useLoaderData" ); |
| let routeId = useCurrentRouteId("useLoaderData" ); |
| return state.loaderData[routeId]; |
| } |
| function useRouteLoaderData(routeId) { |
| let state = useDataRouterState("useRouteLoaderData" ); |
| return state.loaderData[routeId]; |
| } |
| function useActionData() { |
| let state = useDataRouterState("useActionData" ); |
| let routeId = useCurrentRouteId("useLoaderData" ); |
| return state.actionData ? state.actionData[routeId] : void 0; |
| } |
| function useRouteError() { |
| let error = React3.useContext(RouteErrorContext); |
| let state = useDataRouterState("useRouteError" ); |
| let routeId = useCurrentRouteId("useRouteError" ); |
| if (error !== void 0) { |
| return error; |
| } |
| return _optionalChain([state, 'access', _98 => _98.errors, 'optionalAccess', _99 => _99[routeId]]); |
| } |
| function useAsyncValue() { |
| let value = React3.useContext(AwaitContext); |
| return _optionalChain([value, 'optionalAccess', _100 => _100._data]); |
| } |
| function useAsyncError() { |
| let value = React3.useContext(AwaitContext); |
| return _optionalChain([value, 'optionalAccess', _101 => _101._error]); |
| } |
| var blockerId = 0; |
| function useBlocker(shouldBlock) { |
| let { router, basename } = useDataRouterContext("useBlocker" ); |
| let state = useDataRouterState("useBlocker" ); |
| let [blockerKey, setBlockerKey] = React3.useState(""); |
| let blockerFunction = React3.useCallback( |
| (arg) => { |
| if (typeof shouldBlock !== "function") { |
| return !!shouldBlock; |
| } |
| if (basename === "/") { |
| return shouldBlock(arg); |
| } |
| let { currentLocation, nextLocation, historyAction } = arg; |
| return shouldBlock({ |
| currentLocation: { |
| ...currentLocation, |
| pathname: stripBasename(currentLocation.pathname, basename) || currentLocation.pathname |
| }, |
| nextLocation: { |
| ...nextLocation, |
| pathname: stripBasename(nextLocation.pathname, basename) || nextLocation.pathname |
| }, |
| historyAction |
| }); |
| }, |
| [basename, shouldBlock] |
| ); |
| React3.useEffect(() => { |
| let key = String(++blockerId); |
| setBlockerKey(key); |
| return () => router.deleteBlocker(key); |
| }, [router]); |
| React3.useEffect(() => { |
| if (blockerKey !== "") { |
| router.getBlocker(blockerKey, blockerFunction); |
| } |
| }, [router, blockerKey, blockerFunction]); |
| return blockerKey && state.blockers.has(blockerKey) ? state.blockers.get(blockerKey) : IDLE_BLOCKER; |
| } |
| function useNavigateStable() { |
| let { router } = useDataRouterContext("useNavigate" ); |
| let id = useCurrentRouteId("useNavigate" ); |
| let activeRef = React3.useRef(false); |
| useIsomorphicLayoutEffect(() => { |
| activeRef.current = true; |
| }); |
| let navigate = React3.useCallback( |
| async (to, options = {}) => { |
| warning(activeRef.current, navigateEffectWarning); |
| if (!activeRef.current) return; |
| if (typeof to === "number") { |
| await router.navigate(to); |
| } else { |
| await router.navigate(to, { fromRouteId: id, ...options }); |
| } |
| }, |
| [router, id] |
| ); |
| return navigate; |
| } |
| var alreadyWarned = {}; |
| function warningOnce(key, cond, message) { |
| if (!cond && !alreadyWarned[key]) { |
| alreadyWarned[key] = true; |
| warning(false, message); |
| } |
| } |
| function useRoute(...args) { |
| const currentRouteId = useCurrentRouteId( |
| "useRoute" |
| ); |
| const id = _nullishCoalesce(args[0], () => ( currentRouteId)); |
| const state = useDataRouterState("useRoute" ); |
| const route = state.matches.find(({ route: route2 }) => route2.id === id); |
| if (route === void 0) return void 0; |
| return { |
| handle: route.route.handle, |
| loaderData: state.loaderData[id], |
| actionData: _optionalChain([state, 'access', _102 => _102.actionData, 'optionalAccess', _103 => _103[id]]) |
| }; |
| } |
|
|
| |
|
|
|
|
| |
|
|
|
|
| |
| async function loadRouteModule(route, routeModulesCache) { |
| if (route.id in routeModulesCache) { |
| return routeModulesCache[route.id]; |
| } |
| try { |
| let routeModule = await Promise.resolve().then(() => _interopRequireWildcard(require( |
| |
| |
| route.module |
| ))); |
| routeModulesCache[route.id] = routeModule; |
| return routeModule; |
| } catch (error) { |
| console.error( |
| `Error loading route module \`${route.module}\`, reloading page...` |
| ); |
| console.error(error); |
| if (window.__reactRouterContext && window.__reactRouterContext.isSpaMode && |
| void 0) { |
| throw error; |
| } |
| window.location.reload(); |
| return new Promise(() => { |
| }); |
| } |
| } |
|
|
| |
| function getKeyedLinksForMatches(matches, routeModules, manifest) { |
| let descriptors = matches.map((match) => { |
| let module = routeModules[match.route.id]; |
| let route = manifest.routes[match.route.id]; |
| return [ |
| route && route.css ? route.css.map((href) => ({ rel: "stylesheet", href })) : [], |
| _optionalChain([module, 'optionalAccess', _104 => _104.links, 'optionalCall', _105 => _105()]) || [] |
| ]; |
| }).flat(2); |
| let preloads = getModuleLinkHrefs(matches, manifest); |
| return dedupeLinkDescriptors(descriptors, preloads); |
| } |
| function getRouteCssDescriptors(route) { |
| if (!route.css) return []; |
| return route.css.map((href) => ({ rel: "stylesheet", href })); |
| } |
| async function prefetchRouteCss(route) { |
| if (!route.css) return; |
| let descriptors = getRouteCssDescriptors(route); |
| await Promise.all(descriptors.map(prefetchStyleLink)); |
| } |
| async function prefetchStyleLinks(route, routeModule) { |
| if (!route.css && !routeModule.links || !isPreloadSupported()) return; |
| let descriptors = []; |
| if (route.css) { |
| descriptors.push(...getRouteCssDescriptors(route)); |
| } |
| if (routeModule.links) { |
| descriptors.push(...routeModule.links()); |
| } |
| if (descriptors.length === 0) return; |
| let styleLinks = []; |
| for (let descriptor of descriptors) { |
| if (!isPageLinkDescriptor(descriptor) && descriptor.rel === "stylesheet") { |
| styleLinks.push({ |
| ...descriptor, |
| rel: "preload", |
| as: "style" |
| }); |
| } |
| } |
| await Promise.all(styleLinks.map(prefetchStyleLink)); |
| } |
| async function prefetchStyleLink(descriptor) { |
| return new Promise((resolve) => { |
| if (descriptor.media && !window.matchMedia(descriptor.media).matches || document.querySelector( |
| `link[rel="stylesheet"][href="${descriptor.href}"]` |
| )) { |
| return resolve(); |
| } |
| let link = document.createElement("link"); |
| Object.assign(link, descriptor); |
| function removeLink() { |
| if (document.head.contains(link)) { |
| document.head.removeChild(link); |
| } |
| } |
| link.onload = () => { |
| removeLink(); |
| resolve(); |
| }; |
| link.onerror = () => { |
| removeLink(); |
| resolve(); |
| }; |
| document.head.appendChild(link); |
| }); |
| } |
| function isPageLinkDescriptor(object) { |
| return object != null && typeof object.page === "string"; |
| } |
| function isHtmlLinkDescriptor(object) { |
| if (object == null) { |
| return false; |
| } |
| if (object.href == null) { |
| return object.rel === "preload" && typeof object.imageSrcSet === "string" && typeof object.imageSizes === "string"; |
| } |
| return typeof object.rel === "string" && typeof object.href === "string"; |
| } |
| async function getKeyedPrefetchLinks(matches, manifest, routeModules) { |
| let links = await Promise.all( |
| matches.map(async (match) => { |
| let route = manifest.routes[match.route.id]; |
| if (route) { |
| let mod = await loadRouteModule(route, routeModules); |
| return mod.links ? mod.links() : []; |
| } |
| return []; |
| }) |
| ); |
| return dedupeLinkDescriptors( |
| links.flat(1).filter(isHtmlLinkDescriptor).filter((link) => link.rel === "stylesheet" || link.rel === "preload").map( |
| (link) => link.rel === "stylesheet" ? { ...link, rel: "prefetch", as: "style" } : { ...link, rel: "prefetch" } |
| ) |
| ); |
| } |
| function getNewMatchesForLinks(page, nextMatches, currentMatches, manifest, location, mode) { |
| let isNew = (match, index) => { |
| if (!currentMatches[index]) return true; |
| return match.route.id !== currentMatches[index].route.id; |
| }; |
| let matchPathChanged = (match, index) => { |
| return ( |
| |
| currentMatches[index].pathname !== match.pathname || |
| |
| _optionalChain([currentMatches, 'access', _106 => _106[index], 'access', _107 => _107.route, 'access', _108 => _108.path, 'optionalAccess', _109 => _109.endsWith, 'call', _110 => _110("*")]) && currentMatches[index].params["*"] !== match.params["*"] |
| ); |
| }; |
| if (mode === "assets") { |
| return nextMatches.filter( |
| (match, index) => isNew(match, index) || matchPathChanged(match, index) |
| ); |
| } |
| if (mode === "data") { |
| return nextMatches.filter((match, index) => { |
| let manifestRoute = manifest.routes[match.route.id]; |
| if (!manifestRoute || !manifestRoute.hasLoader) { |
| return false; |
| } |
| if (isNew(match, index) || matchPathChanged(match, index)) { |
| return true; |
| } |
| if (match.route.shouldRevalidate) { |
| let routeChoice = match.route.shouldRevalidate({ |
| currentUrl: new URL( |
| location.pathname + location.search + location.hash, |
| window.origin |
| ), |
| currentParams: _optionalChain([currentMatches, 'access', _111 => _111[0], 'optionalAccess', _112 => _112.params]) || {}, |
| nextUrl: new URL(page, window.origin), |
| nextParams: match.params, |
| defaultShouldRevalidate: true |
| }); |
| if (typeof routeChoice === "boolean") { |
| return routeChoice; |
| } |
| } |
| return true; |
| }); |
| } |
| return []; |
| } |
| function getModuleLinkHrefs(matches, manifest, { includeHydrateFallback } = {}) { |
| return dedupeHrefs( |
| matches.map((match) => { |
| let route = manifest.routes[match.route.id]; |
| if (!route) return []; |
| let hrefs = [route.module]; |
| if (route.clientActionModule) { |
| hrefs = hrefs.concat(route.clientActionModule); |
| } |
| if (route.clientLoaderModule) { |
| hrefs = hrefs.concat(route.clientLoaderModule); |
| } |
| if (includeHydrateFallback && route.hydrateFallbackModule) { |
| hrefs = hrefs.concat(route.hydrateFallbackModule); |
| } |
| if (route.imports) { |
| hrefs = hrefs.concat(route.imports); |
| } |
| return hrefs; |
| }).flat(1) |
| ); |
| } |
| function dedupeHrefs(hrefs) { |
| return [...new Set(hrefs)]; |
| } |
| function sortKeys(obj) { |
| let sorted = {}; |
| let keys = Object.keys(obj).sort(); |
| for (let key of keys) { |
| sorted[key] = obj[key]; |
| } |
| return sorted; |
| } |
| function dedupeLinkDescriptors(descriptors, preloads) { |
| let set = new Set(); |
| let preloadsSet = new Set(preloads); |
| return descriptors.reduce((deduped, descriptor) => { |
| let alreadyModulePreload = preloads && !isPageLinkDescriptor(descriptor) && descriptor.as === "script" && descriptor.href && preloadsSet.has(descriptor.href); |
| if (alreadyModulePreload) { |
| return deduped; |
| } |
| let key = JSON.stringify(sortKeys(descriptor)); |
| if (!set.has(key)) { |
| set.add(key); |
| deduped.push({ key, link: descriptor }); |
| } |
| return deduped; |
| }, []); |
| } |
| var _isPreloadSupported; |
| function isPreloadSupported() { |
| if (_isPreloadSupported !== void 0) { |
| return _isPreloadSupported; |
| } |
| let el = document.createElement("link"); |
| _isPreloadSupported = el.relList.supports("preload"); |
| el = null; |
| return _isPreloadSupported; |
| } |
|
|
| |
| var alreadyWarned2 = {}; |
| function warnOnce(condition, message) { |
| if (!condition && !alreadyWarned2[message]) { |
| alreadyWarned2[message] = true; |
| console.warn(message); |
| } |
| } |
|
|
| |
|
|
|
|
| |
|
|
|
|
| |
|
|
| function RemixRootDefaultHydrateFallback() { |
| return React4.createElement(BoundaryShell, { title: "Loading...", renderScripts: true }, ENABLE_DEV_WARNINGS ? React4.createElement( |
| "script", |
| { |
| dangerouslySetInnerHTML: { |
| __html: ` |
| console.log( |
| "\u{1F4BF} Hey developer \u{1F44B}. You can provide a way better UX than this " + |
| "when your app is loading JS modules and/or running \`clientLoader\` " + |
| "functions. Check out https://reactrouter.com/start/framework/route-module#hydratefallback " + |
| "for more information." |
| ); |
| ` |
| } |
| } |
| ) : null); |
| } |
|
|
| |
| function groupRoutesByParentId(manifest) { |
| let routes = {}; |
| Object.values(manifest).forEach((route) => { |
| if (route) { |
| let parentId = route.parentId || ""; |
| if (!routes[parentId]) { |
| routes[parentId] = []; |
| } |
| routes[parentId].push(route); |
| } |
| }); |
| return routes; |
| } |
| function getRouteComponents(route, routeModule, isSpaMode) { |
| let Component4 = getRouteModuleComponent(routeModule); |
| let HydrateFallback = routeModule.HydrateFallback && (!isSpaMode || route.id === "root") ? routeModule.HydrateFallback : route.id === "root" ? RemixRootDefaultHydrateFallback : void 0; |
| let ErrorBoundary = routeModule.ErrorBoundary ? routeModule.ErrorBoundary : route.id === "root" ? () => React5.createElement(RemixRootDefaultErrorBoundary, { error: useRouteError() }) : void 0; |
| if (route.id === "root" && routeModule.Layout) { |
| return { |
| ...Component4 ? { |
| element: React5.createElement(routeModule.Layout, null, React5.createElement(Component4, null)) |
| } : { Component: Component4 }, |
| ...ErrorBoundary ? { |
| errorElement: React5.createElement(routeModule.Layout, null, React5.createElement(ErrorBoundary, null)) |
| } : { ErrorBoundary }, |
| ...HydrateFallback ? { |
| hydrateFallbackElement: React5.createElement(routeModule.Layout, null, React5.createElement(HydrateFallback, null)) |
| } : { HydrateFallback } |
| }; |
| } |
| return { Component: Component4, ErrorBoundary, HydrateFallback }; |
| } |
| function createServerRoutes(manifest, routeModules, future, isSpaMode, parentId = "", routesByParentId = groupRoutesByParentId(manifest), spaModeLazyPromise = Promise.resolve({ Component: () => null })) { |
| return (routesByParentId[parentId] || []).map((route) => { |
| let routeModule = routeModules[route.id]; |
| invariant2( |
| routeModule, |
| "No `routeModule` available to create server routes" |
| ); |
| let dataRoute = { |
| ...getRouteComponents(route, routeModule, isSpaMode), |
| caseSensitive: route.caseSensitive, |
| id: route.id, |
| index: route.index, |
| path: route.path, |
| handle: routeModule.handle, |
| |
| |
| |
| |
| lazy: isSpaMode ? () => spaModeLazyPromise : void 0, |
| |
| |
| |
| |
| loader: route.hasLoader || route.hasClientLoader ? () => null : void 0 |
| |
| |
| }; |
| let children = createServerRoutes( |
| manifest, |
| routeModules, |
| future, |
| isSpaMode, |
| route.id, |
| routesByParentId, |
| spaModeLazyPromise |
| ); |
| if (children.length > 0) dataRoute.children = children; |
| return dataRoute; |
| }); |
| } |
| function createClientRoutesWithHMRRevalidationOptOut(needsRevalidation, manifest, routeModulesCache, initialState, ssr, isSpaMode) { |
| return createClientRoutes( |
| manifest, |
| routeModulesCache, |
| initialState, |
| ssr, |
| isSpaMode, |
| "", |
| groupRoutesByParentId(manifest), |
| needsRevalidation |
| ); |
| } |
| function preventInvalidServerHandlerCall(type, route) { |
| if (type === "loader" && !route.hasLoader || type === "action" && !route.hasAction) { |
| let fn = type === "action" ? "serverAction()" : "serverLoader()"; |
| let msg = `You are trying to call ${fn} on a route that does not have a server ${type} (routeId: "${route.id}")`; |
| console.error(msg); |
| throw new ErrorResponseImpl(400, "Bad Request", new Error(msg), true); |
| } |
| } |
| function noActionDefinedError(type, routeId) { |
| let article = type === "clientAction" ? "a" : "an"; |
| let msg = `Route "${routeId}" does not have ${article} ${type}, but you are trying to submit to it. To fix this, please add ${article} \`${type}\` function to the route`; |
| console.error(msg); |
| throw new ErrorResponseImpl(405, "Method Not Allowed", new Error(msg), true); |
| } |
| function createClientRoutes(manifest, routeModulesCache, initialState, ssr, isSpaMode, parentId = "", routesByParentId = groupRoutesByParentId(manifest), needsRevalidation) { |
| return (routesByParentId[parentId] || []).map((route) => { |
| let routeModule = routeModulesCache[route.id]; |
| function fetchServerHandler(singleFetch) { |
| invariant2( |
| typeof singleFetch === "function", |
| "No single fetch function available for route handler" |
| ); |
| return singleFetch(); |
| } |
| function fetchServerLoader(singleFetch) { |
| if (!route.hasLoader) return Promise.resolve(null); |
| return fetchServerHandler(singleFetch); |
| } |
| function fetchServerAction(singleFetch) { |
| if (!route.hasAction) { |
| throw noActionDefinedError("action", route.id); |
| } |
| return fetchServerHandler(singleFetch); |
| } |
| function prefetchModule(modulePath) { |
| Promise.resolve().then(() => _interopRequireWildcard(require( |
| |
| |
| modulePath |
| ))); |
| } |
| function prefetchRouteModuleChunks(route2) { |
| if (route2.clientActionModule) { |
| prefetchModule(route2.clientActionModule); |
| } |
| if (route2.clientLoaderModule) { |
| prefetchModule(route2.clientLoaderModule); |
| } |
| } |
| async function prefetchStylesAndCallHandler(handler) { |
| let cachedModule = routeModulesCache[route.id]; |
| let linkPrefetchPromise = cachedModule ? prefetchStyleLinks(route, cachedModule) : Promise.resolve(); |
| try { |
| return handler(); |
| } finally { |
| await linkPrefetchPromise; |
| } |
| } |
| let dataRoute = { |
| id: route.id, |
| index: route.index, |
| path: route.path |
| }; |
| if (routeModule) { |
| Object.assign(dataRoute, { |
| ...dataRoute, |
| ...getRouteComponents(route, routeModule, isSpaMode), |
| middleware: routeModule.clientMiddleware, |
| handle: routeModule.handle, |
| shouldRevalidate: getShouldRevalidateFunction( |
| dataRoute.path, |
| routeModule, |
| route, |
| ssr, |
| needsRevalidation |
| ) |
| }); |
| let hasInitialData = initialState && initialState.loaderData && route.id in initialState.loaderData; |
| let initialData = hasInitialData ? _optionalChain([initialState, 'optionalAccess', _113 => _113.loaderData, 'optionalAccess', _114 => _114[route.id]]) : void 0; |
| let hasInitialError = initialState && initialState.errors && route.id in initialState.errors; |
| let initialError = hasInitialError ? _optionalChain([initialState, 'optionalAccess', _115 => _115.errors, 'optionalAccess', _116 => _116[route.id]]) : void 0; |
| let isHydrationRequest = needsRevalidation == null && (_optionalChain([routeModule, 'access', _117 => _117.clientLoader, 'optionalAccess', _118 => _118.hydrate]) === true || !route.hasLoader); |
| dataRoute.loader = async ({ |
| request, |
| params, |
| context, |
| unstable_pattern, |
| unstable_url |
| }, singleFetch) => { |
| try { |
| let result = await prefetchStylesAndCallHandler(async () => { |
| invariant2( |
| routeModule, |
| "No `routeModule` available for critical-route loader" |
| ); |
| if (!routeModule.clientLoader) { |
| return fetchServerLoader(singleFetch); |
| } |
| return routeModule.clientLoader({ |
| request, |
| params, |
| context, |
| unstable_pattern, |
| unstable_url, |
| async serverLoader() { |
| preventInvalidServerHandlerCall("loader", route); |
| if (isHydrationRequest) { |
| if (hasInitialData) { |
| return initialData; |
| } |
| if (hasInitialError) { |
| throw initialError; |
| } |
| } |
| return fetchServerLoader(singleFetch); |
| } |
| }); |
| }); |
| return result; |
| } finally { |
| isHydrationRequest = false; |
| } |
| }; |
| dataRoute.loader.hydrate = shouldHydrateRouteLoader( |
| route.id, |
| routeModule.clientLoader, |
| route.hasLoader, |
| isSpaMode |
| ); |
| dataRoute.action = ({ |
| request, |
| params, |
| context, |
| unstable_pattern, |
| unstable_url |
| }, singleFetch) => { |
| return prefetchStylesAndCallHandler(async () => { |
| invariant2( |
| routeModule, |
| "No `routeModule` available for critical-route action" |
| ); |
| if (!routeModule.clientAction) { |
| if (isSpaMode) { |
| throw noActionDefinedError("clientAction", route.id); |
| } |
| return fetchServerAction(singleFetch); |
| } |
| return routeModule.clientAction({ |
| request, |
| params, |
| context, |
| unstable_pattern, |
| unstable_url, |
| async serverAction() { |
| preventInvalidServerHandlerCall("action", route); |
| return fetchServerAction(singleFetch); |
| } |
| }); |
| }); |
| }; |
| } else { |
| if (!route.hasClientLoader) { |
| dataRoute.loader = (_, singleFetch) => prefetchStylesAndCallHandler(() => { |
| return fetchServerLoader(singleFetch); |
| }); |
| } |
| if (!route.hasClientAction) { |
| dataRoute.action = (_, singleFetch) => prefetchStylesAndCallHandler(() => { |
| if (isSpaMode) { |
| throw noActionDefinedError("clientAction", route.id); |
| } |
| return fetchServerAction(singleFetch); |
| }); |
| } |
| let lazyRoutePromise; |
| async function getLazyRoute() { |
| if (lazyRoutePromise) { |
| return await lazyRoutePromise; |
| } |
| lazyRoutePromise = (async () => { |
| if (route.clientLoaderModule || route.clientActionModule) { |
| await new Promise((resolve) => setTimeout(resolve, 0)); |
| } |
| let routeModulePromise = loadRouteModuleWithBlockingLinks( |
| route, |
| routeModulesCache |
| ); |
| prefetchRouteModuleChunks(route); |
| return await routeModulePromise; |
| })(); |
| return await lazyRoutePromise; |
| } |
| dataRoute.lazy = { |
| loader: route.hasClientLoader ? async () => { |
| let { clientLoader } = route.clientLoaderModule ? await Promise.resolve().then(() => _interopRequireWildcard(require( |
| |
| |
| route.clientLoaderModule |
| ))) : await getLazyRoute(); |
| invariant2(clientLoader, "No `clientLoader` export found"); |
| return (args, singleFetch) => clientLoader({ |
| ...args, |
| async serverLoader() { |
| preventInvalidServerHandlerCall("loader", route); |
| return fetchServerLoader(singleFetch); |
| } |
| }); |
| } : void 0, |
| action: route.hasClientAction ? async () => { |
| let clientActionPromise = route.clientActionModule ? Promise.resolve().then(() => _interopRequireWildcard(require( |
| |
| |
| route.clientActionModule |
| ))) : getLazyRoute(); |
| prefetchRouteModuleChunks(route); |
| let { clientAction } = await clientActionPromise; |
| invariant2(clientAction, "No `clientAction` export found"); |
| return (args, singleFetch) => clientAction({ |
| ...args, |
| async serverAction() { |
| preventInvalidServerHandlerCall("action", route); |
| return fetchServerAction(singleFetch); |
| } |
| }); |
| } : void 0, |
| middleware: route.hasClientMiddleware ? async () => { |
| let { clientMiddleware } = route.clientMiddlewareModule ? await Promise.resolve().then(() => _interopRequireWildcard(require( |
| |
| |
| route.clientMiddlewareModule |
| ))) : await getLazyRoute(); |
| invariant2(clientMiddleware, "No `clientMiddleware` export found"); |
| return clientMiddleware; |
| } : void 0, |
| shouldRevalidate: async () => { |
| let lazyRoute = await getLazyRoute(); |
| return getShouldRevalidateFunction( |
| dataRoute.path, |
| lazyRoute, |
| route, |
| ssr, |
| needsRevalidation |
| ); |
| }, |
| handle: async () => (await getLazyRoute()).handle, |
| |
| |
| Component: async () => (await getLazyRoute()).Component, |
| ErrorBoundary: route.hasErrorBoundary ? async () => (await getLazyRoute()).ErrorBoundary : void 0 |
| }; |
| } |
| let children = createClientRoutes( |
| manifest, |
| routeModulesCache, |
| initialState, |
| ssr, |
| isSpaMode, |
| route.id, |
| routesByParentId, |
| needsRevalidation |
| ); |
| if (children.length > 0) dataRoute.children = children; |
| return dataRoute; |
| }); |
| } |
| function getShouldRevalidateFunction(path, route, manifestRoute, ssr, needsRevalidation) { |
| if (needsRevalidation) { |
| return wrapShouldRevalidateForHdr( |
| manifestRoute.id, |
| route.shouldRevalidate, |
| needsRevalidation |
| ); |
| } |
| if (!ssr && manifestRoute.hasLoader && !manifestRoute.hasClientLoader) { |
| let myParams = path ? compilePath(path)[1].map((p) => p.paramName) : []; |
| const didParamsChange = (opts) => myParams.some((p) => opts.currentParams[p] !== opts.nextParams[p]); |
| if (route.shouldRevalidate) { |
| let fn = route.shouldRevalidate; |
| return (opts) => fn({ |
| ...opts, |
| defaultShouldRevalidate: didParamsChange(opts) |
| }); |
| } else { |
| return (opts) => didParamsChange(opts); |
| } |
| } |
| return route.shouldRevalidate; |
| } |
| function wrapShouldRevalidateForHdr(routeId, routeShouldRevalidate, needsRevalidation) { |
| let handledRevalidation = false; |
| return (arg) => { |
| if (!handledRevalidation) { |
| handledRevalidation = true; |
| return needsRevalidation.has(routeId); |
| } |
| return routeShouldRevalidate ? routeShouldRevalidate(arg) : arg.defaultShouldRevalidate; |
| }; |
| } |
| async function loadRouteModuleWithBlockingLinks(route, routeModules) { |
| let routeModulePromise = loadRouteModule(route, routeModules); |
| let prefetchRouteCssPromise = prefetchRouteCss(route); |
| let routeModule = await routeModulePromise; |
| await Promise.all([ |
| prefetchRouteCssPromise, |
| prefetchStyleLinks(route, routeModule) |
| ]); |
| return { |
| Component: getRouteModuleComponent(routeModule), |
| ErrorBoundary: routeModule.ErrorBoundary, |
| clientMiddleware: routeModule.clientMiddleware, |
| clientAction: routeModule.clientAction, |
| clientLoader: routeModule.clientLoader, |
| handle: routeModule.handle, |
| links: routeModule.links, |
| meta: routeModule.meta, |
| shouldRevalidate: routeModule.shouldRevalidate |
| }; |
| } |
| function getRouteModuleComponent(routeModule) { |
| if (routeModule.default == null) return void 0; |
| let isEmptyObject = typeof routeModule.default === "object" && Object.keys(routeModule.default).length === 0; |
| if (!isEmptyObject) { |
| return routeModule.default; |
| } |
| } |
| function shouldHydrateRouteLoader(routeId, clientLoader, hasLoader, isSpaMode) { |
| return isSpaMode && routeId !== "root" || clientLoader != null && (clientLoader.hydrate === true || hasLoader !== true); |
| } |
|
|
| |
| var nextPaths = new Set(); |
| var discoveredPathsMaxSize = 1e3; |
| var discoveredPaths = new Set(); |
| var URL_LIMIT = 7680; |
| function isFogOfWarEnabled(routeDiscovery, ssr) { |
| return routeDiscovery.mode === "lazy" && ssr === true; |
| } |
| function getPartialManifest({ sri, ...manifest }, router) { |
| let routeIds = new Set(router.state.matches.map((m) => m.route.id)); |
| let segments = router.state.location.pathname.split("/").filter(Boolean); |
| let paths = ["/"]; |
| segments.pop(); |
| while (segments.length > 0) { |
| paths.push(`/${segments.join("/")}`); |
| segments.pop(); |
| } |
| paths.forEach((path) => { |
| let matches = matchRoutes(router.routes, path, router.basename); |
| if (matches) { |
| matches.forEach((m) => routeIds.add(m.route.id)); |
| } |
| }); |
| let initialRoutes = [...routeIds].reduce( |
| (acc, id) => Object.assign(acc, { [id]: manifest.routes[id] }), |
| {} |
| ); |
| return { |
| ...manifest, |
| routes: initialRoutes, |
| sri: sri ? true : void 0 |
| }; |
| } |
| function getPatchRoutesOnNavigationFunction(getRouter, manifest, routeModules, ssr, routeDiscovery, isSpaMode, basename) { |
| if (!isFogOfWarEnabled(routeDiscovery, ssr)) { |
| return void 0; |
| } |
| return async ({ path, patch, signal, fetcherKey }) => { |
| if (discoveredPaths.has(path)) { |
| return; |
| } |
| let { state } = getRouter(); |
| await fetchAndApplyManifestPatches( |
| [path], |
| |
| |
| fetcherKey ? window.location.href : createPath(state.navigation.location || state.location), |
| manifest, |
| routeModules, |
| ssr, |
| isSpaMode, |
| basename, |
| routeDiscovery.manifestPath, |
| patch, |
| signal |
| ); |
| }; |
| } |
| function useFogOFWarDiscovery(router, manifest, routeModules, ssr, routeDiscovery, isSpaMode) { |
| React6.useEffect(() => { |
| if (!isFogOfWarEnabled(routeDiscovery, ssr) || |
| _optionalChain([window, 'access', _119 => _119.navigator, 'optionalAccess', _120 => _120.connection, 'optionalAccess', _121 => _121.saveData]) === true) { |
| return; |
| } |
| function registerElement(el) { |
| let path = el.tagName === "FORM" ? el.getAttribute("action") : el.getAttribute("href"); |
| if (!path) { |
| return; |
| } |
| let pathname = el.tagName === "A" ? el.pathname : new URL(path, window.location.origin).pathname; |
| if (!discoveredPaths.has(pathname)) { |
| nextPaths.add(pathname); |
| } |
| } |
| async function fetchPatches() { |
| document.querySelectorAll("a[data-discover], form[data-discover]").forEach(registerElement); |
| let lazyPaths = Array.from(nextPaths.keys()).filter((path) => { |
| if (discoveredPaths.has(path)) { |
| nextPaths.delete(path); |
| return false; |
| } |
| return true; |
| }); |
| if (lazyPaths.length === 0) { |
| return; |
| } |
| try { |
| await fetchAndApplyManifestPatches( |
| lazyPaths, |
| null, |
| manifest, |
| routeModules, |
| ssr, |
| isSpaMode, |
| router.basename, |
| routeDiscovery.manifestPath, |
| router.patchRoutes |
| ); |
| } catch (e) { |
| console.error("Failed to fetch manifest patches", e); |
| } |
| } |
| let debouncedFetchPatches = debounce(fetchPatches, 100); |
| fetchPatches(); |
| let observer = new MutationObserver(() => debouncedFetchPatches()); |
| observer.observe(document.documentElement, { |
| subtree: true, |
| childList: true, |
| attributes: true, |
| attributeFilter: ["data-discover", "href", "action"] |
| }); |
| return () => observer.disconnect(); |
| }, [ssr, isSpaMode, manifest, routeModules, router, routeDiscovery]); |
| } |
| function getManifestPath(_manifestPath, basename) { |
| let manifestPath = _manifestPath || "/__manifest"; |
| return basename == null ? manifestPath : joinPaths([basename, manifestPath]); |
| } |
| var MANIFEST_VERSION_STORAGE_KEY = "react-router-manifest-version"; |
| async function fetchAndApplyManifestPatches(paths, errorReloadPath, manifest, routeModules, ssr, isSpaMode, basename, manifestPath, patchRoutes, signal) { |
| const searchParams = new URLSearchParams(); |
| searchParams.set("paths", paths.sort().join(",")); |
| searchParams.set("version", manifest.version); |
| let url = new URL( |
| getManifestPath(manifestPath, basename), |
| window.location.origin |
| ); |
| url.search = searchParams.toString(); |
| if (url.toString().length > URL_LIMIT) { |
| nextPaths.clear(); |
| return; |
| } |
| let serverPatches; |
| try { |
| let res = await fetch(url, { signal }); |
| if (!res.ok) { |
| throw new Error(`${res.status} ${res.statusText}`); |
| } else if (res.status === 204 && res.headers.has("X-Remix-Reload-Document")) { |
| if (!errorReloadPath) { |
| console.warn( |
| "Detected a manifest version mismatch during eager route discovery. The next navigation/fetch to an undiscovered route will result in a new document navigation to sync up with the latest manifest." |
| ); |
| return; |
| } |
| try { |
| if (sessionStorage.getItem(MANIFEST_VERSION_STORAGE_KEY) === manifest.version) { |
| console.error( |
| "Unable to discover routes due to manifest version mismatch." |
| ); |
| return; |
| } |
| sessionStorage.setItem(MANIFEST_VERSION_STORAGE_KEY, manifest.version); |
| } catch (e4) { |
| } |
| window.location.href = errorReloadPath; |
| console.warn("Detected manifest version mismatch, reloading..."); |
| await new Promise(() => { |
| }); |
| } else if (res.status >= 400) { |
| throw new Error(await res.text()); |
| } |
| try { |
| sessionStorage.removeItem(MANIFEST_VERSION_STORAGE_KEY); |
| } catch (e5) { |
| } |
| serverPatches = await res.json(); |
| } catch (e) { |
| if (_optionalChain([signal, 'optionalAccess', _122 => _122.aborted])) return; |
| throw e; |
| } |
| let knownRoutes = new Set(Object.keys(manifest.routes)); |
| let patches = Object.values(serverPatches).reduce((acc, route) => { |
| if (route && !knownRoutes.has(route.id)) { |
| acc[route.id] = route; |
| } |
| return acc; |
| }, {}); |
| Object.assign(manifest.routes, patches); |
| paths.forEach((p) => addToFifoQueue(p, discoveredPaths)); |
| let parentIds = new Set(); |
| Object.values(patches).forEach((patch) => { |
| if (patch && (!patch.parentId || !patches[patch.parentId])) { |
| parentIds.add(patch.parentId); |
| } |
| }); |
| parentIds.forEach( |
| (parentId) => patchRoutes( |
| parentId || null, |
| createClientRoutes(patches, routeModules, null, ssr, isSpaMode, parentId) |
| ) |
| ); |
| } |
| function addToFifoQueue(path, queue) { |
| if (queue.size >= discoveredPathsMaxSize) { |
| let first = queue.values().next().value; |
| queue.delete(first); |
| } |
| queue.add(path); |
| } |
| function debounce(callback, wait) { |
| let timeoutId; |
| return (...args) => { |
| window.clearTimeout(timeoutId); |
| timeoutId = window.setTimeout(() => callback(...args), wait); |
| }; |
| } |
|
|
| |
| function useDataRouterContext2() { |
| let context = React7.useContext(DataRouterContext); |
| invariant2( |
| context, |
| "You must render this element inside a <DataRouterContext.Provider> element" |
| ); |
| return context; |
| } |
| function useDataRouterStateContext() { |
| let context = React7.useContext(DataRouterStateContext); |
| invariant2( |
| context, |
| "You must render this element inside a <DataRouterStateContext.Provider> element" |
| ); |
| return context; |
| } |
| var FrameworkContext = React7.createContext(void 0); |
| FrameworkContext.displayName = "FrameworkContext"; |
| function useFrameworkContext() { |
| let context = React7.useContext(FrameworkContext); |
| invariant2( |
| context, |
| "You must render this element inside a <HydratedRouter> element" |
| ); |
| return context; |
| } |
| function usePrefetchBehavior(prefetch, theirElementProps) { |
| let frameworkContext = React7.useContext(FrameworkContext); |
| let [maybePrefetch, setMaybePrefetch] = React7.useState(false); |
| let [shouldPrefetch, setShouldPrefetch] = React7.useState(false); |
| let { onFocus, onBlur, onMouseEnter, onMouseLeave, onTouchStart } = theirElementProps; |
| let ref = React7.useRef(null); |
| React7.useEffect(() => { |
| if (prefetch === "render") { |
| setShouldPrefetch(true); |
| } |
| if (prefetch === "viewport") { |
| let callback = (entries) => { |
| entries.forEach((entry) => { |
| setShouldPrefetch(entry.isIntersecting); |
| }); |
| }; |
| let observer = new IntersectionObserver(callback, { threshold: 0.5 }); |
| if (ref.current) observer.observe(ref.current); |
| return () => { |
| observer.disconnect(); |
| }; |
| } |
| }, [prefetch]); |
| React7.useEffect(() => { |
| if (maybePrefetch) { |
| let id = setTimeout(() => { |
| setShouldPrefetch(true); |
| }, 100); |
| return () => { |
| clearTimeout(id); |
| }; |
| } |
| }, [maybePrefetch]); |
| let setIntent = () => { |
| setMaybePrefetch(true); |
| }; |
| let cancelIntent = () => { |
| setMaybePrefetch(false); |
| setShouldPrefetch(false); |
| }; |
| if (!frameworkContext) { |
| return [false, ref, {}]; |
| } |
| if (prefetch !== "intent") { |
| return [shouldPrefetch, ref, {}]; |
| } |
| return [ |
| shouldPrefetch, |
| ref, |
| { |
| onFocus: composeEventHandlers(onFocus, setIntent), |
| onBlur: composeEventHandlers(onBlur, cancelIntent), |
| onMouseEnter: composeEventHandlers(onMouseEnter, setIntent), |
| onMouseLeave: composeEventHandlers(onMouseLeave, cancelIntent), |
| onTouchStart: composeEventHandlers(onTouchStart, setIntent) |
| } |
| ]; |
| } |
| function composeEventHandlers(theirHandler, ourHandler) { |
| return (event) => { |
| theirHandler && theirHandler(event); |
| if (!event.defaultPrevented) { |
| ourHandler(event); |
| } |
| }; |
| } |
| function getActiveMatches(matches, errors, isSpaMode) { |
| if (isSpaMode && !isHydrated) { |
| return [matches[0]]; |
| } |
| if (errors) { |
| let errorIdx = matches.findIndex((m) => errors[m.route.id] !== void 0); |
| return matches.slice(0, errorIdx + 1); |
| } |
| return matches; |
| } |
| var CRITICAL_CSS_DATA_ATTRIBUTE = "data-react-router-critical-css"; |
| function Links({ nonce, crossOrigin }) { |
| let { isSpaMode, manifest, routeModules, criticalCss } = useFrameworkContext(); |
| let { errors, matches: routerMatches } = useDataRouterStateContext(); |
| let matches = getActiveMatches(routerMatches, errors, isSpaMode); |
| let keyedLinks = React7.useMemo( |
| () => getKeyedLinksForMatches(matches, routeModules, manifest), |
| [matches, routeModules, manifest] |
| ); |
| return React7.createElement(React7.Fragment, null, typeof criticalCss === "string" ? React7.createElement( |
| "style", |
| { |
| ...{ [CRITICAL_CSS_DATA_ATTRIBUTE]: "" }, |
| nonce, |
| dangerouslySetInnerHTML: { __html: criticalCss } |
| } |
| ) : null, typeof criticalCss === "object" ? React7.createElement( |
| "link", |
| { |
| ...{ [CRITICAL_CSS_DATA_ATTRIBUTE]: "" }, |
| rel: "stylesheet", |
| href: criticalCss.href, |
| nonce, |
| crossOrigin |
| } |
| ) : null, keyedLinks.map( |
| ({ key, link }) => isPageLinkDescriptor(link) ? React7.createElement( |
| PrefetchPageLinks, |
| { |
| key, |
| nonce, |
| ...link, |
| crossOrigin: _nullishCoalesce(link.crossOrigin, () => ( crossOrigin)) |
| } |
| ) : React7.createElement( |
| "link", |
| { |
| key, |
| nonce, |
| ...link, |
| crossOrigin: _nullishCoalesce(link.crossOrigin, () => ( crossOrigin)) |
| } |
| ) |
| )); |
| } |
| function PrefetchPageLinks({ page, ...linkProps }) { |
| let rsc = useIsRSCRouterContext(); |
| let { router } = useDataRouterContext2(); |
| let matches = React7.useMemo( |
| () => matchRoutes(router.routes, page, router.basename), |
| [router.routes, page, router.basename] |
| ); |
| if (!matches) { |
| return null; |
| } |
| if (rsc) { |
| return React7.createElement(RSCPrefetchPageLinksImpl, { page, matches, ...linkProps }); |
| } |
| return React7.createElement(PrefetchPageLinksImpl, { page, matches, ...linkProps }); |
| } |
| function useKeyedPrefetchLinks(matches) { |
| let { manifest, routeModules } = useFrameworkContext(); |
| let [keyedPrefetchLinks, setKeyedPrefetchLinks] = React7.useState([]); |
| React7.useEffect(() => { |
| let interrupted = false; |
| void getKeyedPrefetchLinks(matches, manifest, routeModules).then( |
| (links) => { |
| if (!interrupted) { |
| setKeyedPrefetchLinks(links); |
| } |
| } |
| ); |
| return () => { |
| interrupted = true; |
| }; |
| }, [matches, manifest, routeModules]); |
| return keyedPrefetchLinks; |
| } |
| function RSCPrefetchPageLinksImpl({ |
| page, |
| matches: nextMatches, |
| ...linkProps |
| }) { |
| let location = useLocation(); |
| let { future } = useFrameworkContext(); |
| let { basename } = useDataRouterContext2(); |
| let dataHrefs = React7.useMemo(() => { |
| if (page === location.pathname + location.search + location.hash) { |
| return []; |
| } |
| let url = singleFetchUrl( |
| page, |
| basename, |
| future.unstable_trailingSlashAwareDataRequests, |
| "rsc" |
| ); |
| let hasSomeRoutesWithShouldRevalidate = false; |
| let targetRoutes = []; |
| for (let match of nextMatches) { |
| if (typeof match.route.shouldRevalidate === "function") { |
| hasSomeRoutesWithShouldRevalidate = true; |
| } else { |
| targetRoutes.push(match.route.id); |
| } |
| } |
| if (hasSomeRoutesWithShouldRevalidate && targetRoutes.length > 0) { |
| url.searchParams.set("_routes", targetRoutes.join(",")); |
| } |
| return [url.pathname + url.search]; |
| }, [ |
| basename, |
| future.unstable_trailingSlashAwareDataRequests, |
| page, |
| location, |
| nextMatches |
| ]); |
| return React7.createElement(React7.Fragment, null, dataHrefs.map((href) => React7.createElement("link", { key: href, rel: "prefetch", as: "fetch", href, ...linkProps }))); |
| } |
| function PrefetchPageLinksImpl({ |
| page, |
| matches: nextMatches, |
| ...linkProps |
| }) { |
| let location = useLocation(); |
| let { future, manifest, routeModules } = useFrameworkContext(); |
| let { basename } = useDataRouterContext2(); |
| let { loaderData, matches } = useDataRouterStateContext(); |
| let newMatchesForData = React7.useMemo( |
| () => getNewMatchesForLinks( |
| page, |
| nextMatches, |
| matches, |
| manifest, |
| location, |
| "data" |
| ), |
| [page, nextMatches, matches, manifest, location] |
| ); |
| let newMatchesForAssets = React7.useMemo( |
| () => getNewMatchesForLinks( |
| page, |
| nextMatches, |
| matches, |
| manifest, |
| location, |
| "assets" |
| ), |
| [page, nextMatches, matches, manifest, location] |
| ); |
| let dataHrefs = React7.useMemo(() => { |
| if (page === location.pathname + location.search + location.hash) { |
| return []; |
| } |
| let routesParams = new Set(); |
| let foundOptOutRoute = false; |
| nextMatches.forEach((m) => { |
| let manifestRoute = manifest.routes[m.route.id]; |
| if (!manifestRoute || !manifestRoute.hasLoader) { |
| return; |
| } |
| if (!newMatchesForData.some((m2) => m2.route.id === m.route.id) && m.route.id in loaderData && _optionalChain([routeModules, 'access', _123 => _123[m.route.id], 'optionalAccess', _124 => _124.shouldRevalidate])) { |
| foundOptOutRoute = true; |
| } else if (manifestRoute.hasClientLoader) { |
| foundOptOutRoute = true; |
| } else { |
| routesParams.add(m.route.id); |
| } |
| }); |
| if (routesParams.size === 0) { |
| return []; |
| } |
| let url = singleFetchUrl( |
| page, |
| basename, |
| future.unstable_trailingSlashAwareDataRequests, |
| "data" |
| ); |
| if (foundOptOutRoute && routesParams.size > 0) { |
| url.searchParams.set( |
| "_routes", |
| nextMatches.filter((m) => routesParams.has(m.route.id)).map((m) => m.route.id).join(",") |
| ); |
| } |
| return [url.pathname + url.search]; |
| }, [ |
| basename, |
| future.unstable_trailingSlashAwareDataRequests, |
| loaderData, |
| location, |
| manifest, |
| newMatchesForData, |
| nextMatches, |
| page, |
| routeModules |
| ]); |
| let moduleHrefs = React7.useMemo( |
| () => getModuleLinkHrefs(newMatchesForAssets, manifest), |
| [newMatchesForAssets, manifest] |
| ); |
| let keyedPrefetchLinks = useKeyedPrefetchLinks(newMatchesForAssets); |
| return React7.createElement(React7.Fragment, null, dataHrefs.map((href) => React7.createElement("link", { key: href, rel: "prefetch", as: "fetch", href, ...linkProps })), moduleHrefs.map((href) => React7.createElement("link", { key: href, rel: "modulepreload", href, ...linkProps })), keyedPrefetchLinks.map(({ key, link }) => ( |
| |
| |
| React7.createElement( |
| "link", |
| { |
| key, |
| nonce: linkProps.nonce, |
| ...link, |
| crossOrigin: _nullishCoalesce(link.crossOrigin, () => ( linkProps.crossOrigin)) |
| } |
| ) |
| ))); |
| } |
| function Meta() { |
| let { isSpaMode, routeModules } = useFrameworkContext(); |
| let { |
| errors, |
| matches: routerMatches, |
| loaderData |
| } = useDataRouterStateContext(); |
| let location = useLocation(); |
| let _matches = getActiveMatches(routerMatches, errors, isSpaMode); |
| let error = null; |
| if (errors) { |
| error = errors[_matches[_matches.length - 1].route.id]; |
| } |
| let meta = []; |
| let leafMeta = null; |
| let matches = []; |
| for (let i = 0; i < _matches.length; i++) { |
| let _match = _matches[i]; |
| let routeId = _match.route.id; |
| let data2 = loaderData[routeId]; |
| let params = _match.params; |
| let routeModule = routeModules[routeId]; |
| let routeMeta = []; |
| let match = { |
| id: routeId, |
| data: data2, |
| loaderData: data2, |
| meta: [], |
| params: _match.params, |
| pathname: _match.pathname, |
| handle: _match.route.handle, |
| error |
| }; |
| matches[i] = match; |
| if (_optionalChain([routeModule, 'optionalAccess', _125 => _125.meta])) { |
| routeMeta = typeof routeModule.meta === "function" ? routeModule.meta({ |
| data: data2, |
| loaderData: data2, |
| params, |
| location, |
| matches, |
| error |
| }) : Array.isArray(routeModule.meta) ? [...routeModule.meta] : routeModule.meta; |
| } else if (leafMeta) { |
| routeMeta = [...leafMeta]; |
| } |
| routeMeta = routeMeta || []; |
| if (!Array.isArray(routeMeta)) { |
| throw new Error( |
| "The route at " + _match.route.path + " returns an invalid value. All route meta functions must return an array of meta objects.\n\nTo reference the meta function API, see https://reactrouter.com/start/framework/route-module#meta" |
| ); |
| } |
| match.meta = routeMeta; |
| matches[i] = match; |
| meta = [...routeMeta]; |
| leafMeta = meta; |
| } |
| return React7.createElement(React7.Fragment, null, meta.flat().map((metaProps) => { |
| if (!metaProps) { |
| return null; |
| } |
| if ("tagName" in metaProps) { |
| let { tagName, ...rest } = metaProps; |
| if (!isValidMetaTag(tagName)) { |
| console.warn( |
| `A meta object uses an invalid tagName: ${tagName}. Expected either 'link' or 'meta'` |
| ); |
| return null; |
| } |
| let Comp = tagName; |
| return React7.createElement(Comp, { key: JSON.stringify(rest), ...rest }); |
| } |
| if ("title" in metaProps) { |
| return React7.createElement("title", { key: "title" }, String(metaProps.title)); |
| } |
| if ("charset" in metaProps) { |
| _nullishCoalesce(metaProps.charSet, () => ( (metaProps.charSet = metaProps.charset))); |
| delete metaProps.charset; |
| } |
| if ("charSet" in metaProps && metaProps.charSet != null) { |
| return typeof metaProps.charSet === "string" ? React7.createElement("meta", { key: "charSet", charSet: metaProps.charSet }) : null; |
| } |
| if ("script:ld+json" in metaProps) { |
| try { |
| let json = JSON.stringify(metaProps["script:ld+json"]); |
| return React7.createElement( |
| "script", |
| { |
| key: `script:ld+json:${json}`, |
| type: "application/ld+json", |
| dangerouslySetInnerHTML: { __html: escapeHtml(json) } |
| } |
| ); |
| } catch (err) { |
| return null; |
| } |
| } |
| return React7.createElement("meta", { key: JSON.stringify(metaProps), ...metaProps }); |
| })); |
| } |
| function isValidMetaTag(tagName) { |
| return typeof tagName === "string" && /^(meta|link)$/.test(tagName); |
| } |
| var isHydrated = false; |
| function setIsHydrated() { |
| isHydrated = true; |
| } |
| function Scripts(scriptProps) { |
| let { |
| manifest, |
| serverHandoffString, |
| isSpaMode, |
| renderMeta, |
| routeDiscovery, |
| ssr |
| } = useFrameworkContext(); |
| let { router, static: isStatic, staticContext } = useDataRouterContext2(); |
| let { matches: routerMatches } = useDataRouterStateContext(); |
| let isRSCRouterContext = useIsRSCRouterContext(); |
| let enableFogOfWar = isFogOfWarEnabled(routeDiscovery, ssr); |
| if (renderMeta) { |
| renderMeta.didRenderScripts = true; |
| } |
| let matches = getActiveMatches(routerMatches, null, isSpaMode); |
| React7.useEffect(() => { |
| setIsHydrated(); |
| }, []); |
| let initialScripts = React7.useMemo(() => { |
| if (isRSCRouterContext) { |
| return null; |
| } |
| let streamScript = "window.__reactRouterContext.stream = new ReadableStream({start(controller){window.__reactRouterContext.streamController = controller;}}).pipeThrough(new TextEncoderStream());"; |
| let contextScript = staticContext ? `window.__reactRouterContext = ${serverHandoffString};${streamScript}` : " "; |
| let routeModulesScript = !isStatic ? " " : `${_optionalChain([manifest, 'access', _126 => _126.hmr, 'optionalAccess', _127 => _127.runtime]) ? `import ${JSON.stringify(manifest.hmr.runtime)};` : ""}${!enableFogOfWar ? `import ${JSON.stringify(manifest.url)}` : ""}; |
| ${matches.map((match, routeIndex) => { |
| let routeVarName = `route${routeIndex}`; |
| let manifestEntry = manifest.routes[match.route.id]; |
| invariant2(manifestEntry, `Route ${match.route.id} not found in manifest`); |
| let { |
| clientActionModule, |
| clientLoaderModule, |
| clientMiddlewareModule, |
| hydrateFallbackModule, |
| module |
| } = manifestEntry; |
| let chunks = [ |
| ...clientActionModule ? [ |
| { |
| module: clientActionModule, |
| varName: `${routeVarName}_clientAction` |
| } |
| ] : [], |
| ...clientLoaderModule ? [ |
| { |
| module: clientLoaderModule, |
| varName: `${routeVarName}_clientLoader` |
| } |
| ] : [], |
| ...clientMiddlewareModule ? [ |
| { |
| module: clientMiddlewareModule, |
| varName: `${routeVarName}_clientMiddleware` |
| } |
| ] : [], |
| ...hydrateFallbackModule ? [ |
| { |
| module: hydrateFallbackModule, |
| varName: `${routeVarName}_HydrateFallback` |
| } |
| ] : [], |
| { module, varName: `${routeVarName}_main` } |
| ]; |
| if (chunks.length === 1) { |
| return `import * as ${routeVarName} from ${JSON.stringify(module)};`; |
| } |
| let chunkImportsSnippet = chunks.map((chunk) => `import * as ${chunk.varName} from "${chunk.module}";`).join("\n"); |
| let mergedChunksSnippet = `const ${routeVarName} = {${chunks.map((chunk) => `...${chunk.varName}`).join(",")}};`; |
| return [chunkImportsSnippet, mergedChunksSnippet].join("\n"); |
| }).join("\n")} |
| ${enableFogOfWar ? ( |
| // Inline a minimal manifest with the SSR matches |
| `window.__reactRouterManifest = ${JSON.stringify( |
| getPartialManifest(manifest, router), |
| null, |
| 2 |
| )};` |
| ) : ""} |
| window.__reactRouterRouteModules = {${matches.map((match, index) => `${JSON.stringify(match.route.id)}:route${index}`).join(",")}}; |
| |
| import(${JSON.stringify(manifest.entry.module)});`; |
| return React7.createElement(React7.Fragment, null, React7.createElement( |
| "script", |
| { |
| ...scriptProps, |
| suppressHydrationWarning: true, |
| dangerouslySetInnerHTML: { __html: contextScript }, |
| type: void 0 |
| } |
| ), React7.createElement( |
| "script", |
| { |
| ...scriptProps, |
| suppressHydrationWarning: true, |
| dangerouslySetInnerHTML: { __html: routeModulesScript }, |
| type: "module", |
| async: true |
| } |
| )); |
| }, []); |
| let preloads = isHydrated || isRSCRouterContext ? [] : dedupe( |
| manifest.entry.imports.concat( |
| getModuleLinkHrefs(matches, manifest, { |
| includeHydrateFallback: true |
| }) |
| ) |
| ); |
| let sri = typeof manifest.sri === "object" ? manifest.sri : {}; |
| warnOnce( |
| !isRSCRouterContext, |
| "The <Scripts /> element is a no-op when using RSC and can be safely removed." |
| ); |
| return isHydrated || isRSCRouterContext ? null : React7.createElement(React7.Fragment, null, typeof manifest.sri === "object" ? React7.createElement( |
| "script", |
| { |
| ...scriptProps, |
| "rr-importmap": "", |
| type: "importmap", |
| suppressHydrationWarning: true, |
| dangerouslySetInnerHTML: { |
| __html: JSON.stringify({ |
| integrity: sri |
| }) |
| } |
| } |
| ) : null, !enableFogOfWar ? React7.createElement( |
| "link", |
| { |
| rel: "modulepreload", |
| href: manifest.url, |
| crossOrigin: scriptProps.crossOrigin, |
| integrity: sri[manifest.url], |
| suppressHydrationWarning: true |
| } |
| ) : null, React7.createElement( |
| "link", |
| { |
| rel: "modulepreload", |
| href: manifest.entry.module, |
| crossOrigin: scriptProps.crossOrigin, |
| integrity: sri[manifest.entry.module], |
| suppressHydrationWarning: true |
| } |
| ), preloads.map((path) => React7.createElement( |
| "link", |
| { |
| key: path, |
| rel: "modulepreload", |
| href: path, |
| crossOrigin: scriptProps.crossOrigin, |
| integrity: sri[path], |
| suppressHydrationWarning: true |
| } |
| )), initialScripts); |
| } |
| function dedupe(array) { |
| return [...new Set(array)]; |
| } |
| function mergeRefs(...refs) { |
| return (value) => { |
| refs.forEach((ref) => { |
| if (typeof ref === "function") { |
| ref(value); |
| } else if (ref != null) { |
| ref.current = value; |
| } |
| }); |
| }; |
| } |
|
|
| |
| var RemixErrorBoundary = class extends React8.Component { |
| constructor(props) { |
| super(props); |
| this.state = { error: props.error || null, location: props.location }; |
| } |
| static getDerivedStateFromError(error) { |
| return { error }; |
| } |
| static getDerivedStateFromProps(props, state) { |
| if (state.location !== props.location) { |
| return { error: props.error || null, location: props.location }; |
| } |
| return { error: props.error || state.error, location: state.location }; |
| } |
| render() { |
| if (this.state.error) { |
| return React8.createElement( |
| RemixRootDefaultErrorBoundary, |
| { |
| error: this.state.error, |
| isOutsideRemixApp: true |
| } |
| ); |
| } else { |
| return this.props.children; |
| } |
| } |
| }; |
| function RemixRootDefaultErrorBoundary({ |
| error, |
| isOutsideRemixApp |
| }) { |
| console.error(error); |
| let heyDeveloper = React8.createElement( |
| "script", |
| { |
| dangerouslySetInnerHTML: { |
| __html: ` |
| console.log( |
| "\u{1F4BF} Hey developer \u{1F44B}. You can provide a way better UX than this when your app throws errors. Check out https://reactrouter.com/how-to/error-boundary for more information." |
| ); |
| ` |
| } |
| } |
| ); |
| if (isRouteErrorResponse(error)) { |
| return React8.createElement(BoundaryShell, { title: "Unhandled Thrown Response!" }, React8.createElement("h1", { style: { fontSize: "24px" } }, error.status, " ", error.statusText), ENABLE_DEV_WARNINGS ? heyDeveloper : null); |
| } |
| let errorInstance; |
| if (error instanceof Error) { |
| errorInstance = error; |
| } else { |
| let errorString = error == null ? "Unknown Error" : typeof error === "object" && "toString" in error ? error.toString() : JSON.stringify(error); |
| errorInstance = new Error(errorString); |
| } |
| return React8.createElement( |
| BoundaryShell, |
| { |
| title: "Application Error!", |
| isOutsideRemixApp |
| }, |
| React8.createElement("h1", { style: { fontSize: "24px" } }, "Application Error"), |
| React8.createElement( |
| "pre", |
| { |
| style: { |
| padding: "2rem", |
| background: "hsla(10, 50%, 50%, 0.1)", |
| color: "red", |
| overflow: "auto" |
| } |
| }, |
| errorInstance.stack |
| ), |
| heyDeveloper |
| ); |
| } |
| function BoundaryShell({ |
| title, |
| renderScripts, |
| isOutsideRemixApp, |
| children |
| }) { |
| let { routeModules } = useFrameworkContext(); |
| if (_optionalChain([routeModules, 'access', _128 => _128.root, 'optionalAccess', _129 => _129.Layout]) && !isOutsideRemixApp) { |
| return children; |
| } |
| return React8.createElement("html", { lang: "en" }, React8.createElement("head", null, React8.createElement("meta", { charSet: "utf-8" }), React8.createElement( |
| "meta", |
| { |
| name: "viewport", |
| content: "width=device-width,initial-scale=1,viewport-fit=cover" |
| } |
| ), React8.createElement("title", null, title)), React8.createElement("body", null, React8.createElement("main", { style: { fontFamily: "system-ui, sans-serif", padding: "2rem" } }, children, renderScripts ? React8.createElement(Scripts, null) : null))); |
| } |
|
|
| |
|
|
| var USE_OPTIMISTIC = "useOptimistic"; |
| var useOptimisticImpl = React9[USE_OPTIMISTIC]; |
| var stableUseOptimisticSetter = () => void 0; |
| function useOptimisticSafe(val) { |
| if (useOptimisticImpl) { |
| return useOptimisticImpl(val); |
| } else { |
| return [val, stableUseOptimisticSetter]; |
| } |
| } |
| function mapRouteProperties(route) { |
| let updates = { |
| |
| |
| hasErrorBoundary: route.hasErrorBoundary || route.ErrorBoundary != null || route.errorElement != null |
| }; |
| if (route.Component) { |
| if (ENABLE_DEV_WARNINGS) { |
| if (route.element) { |
| warning( |
| false, |
| "You should not include both `Component` and `element` on your route - `Component` will be used." |
| ); |
| } |
| } |
| Object.assign(updates, { |
| element: React9.createElement(route.Component), |
| Component: void 0 |
| }); |
| } |
| if (route.HydrateFallback) { |
| if (ENABLE_DEV_WARNINGS) { |
| if (route.hydrateFallbackElement) { |
| warning( |
| false, |
| "You should not include both `HydrateFallback` and `hydrateFallbackElement` on your route - `HydrateFallback` will be used." |
| ); |
| } |
| } |
| Object.assign(updates, { |
| hydrateFallbackElement: React9.createElement(route.HydrateFallback), |
| HydrateFallback: void 0 |
| }); |
| } |
| if (route.ErrorBoundary) { |
| if (ENABLE_DEV_WARNINGS) { |
| if (route.errorElement) { |
| warning( |
| false, |
| "You should not include both `ErrorBoundary` and `errorElement` on your route - `ErrorBoundary` will be used." |
| ); |
| } |
| } |
| Object.assign(updates, { |
| errorElement: React9.createElement(route.ErrorBoundary), |
| ErrorBoundary: void 0 |
| }); |
| } |
| return updates; |
| } |
| var hydrationRouteProperties = [ |
| "HydrateFallback", |
| "hydrateFallbackElement" |
| ]; |
| function createMemoryRouter(routes, opts) { |
| return createRouter({ |
| basename: _optionalChain([opts, 'optionalAccess', _130 => _130.basename]), |
| getContext: _optionalChain([opts, 'optionalAccess', _131 => _131.getContext]), |
| future: _optionalChain([opts, 'optionalAccess', _132 => _132.future]), |
| history: createMemoryHistory({ |
| initialEntries: _optionalChain([opts, 'optionalAccess', _133 => _133.initialEntries]), |
| initialIndex: _optionalChain([opts, 'optionalAccess', _134 => _134.initialIndex]) |
| }), |
| hydrationData: _optionalChain([opts, 'optionalAccess', _135 => _135.hydrationData]), |
| routes, |
| hydrationRouteProperties, |
| mapRouteProperties, |
| dataStrategy: _optionalChain([opts, 'optionalAccess', _136 => _136.dataStrategy]), |
| patchRoutesOnNavigation: _optionalChain([opts, 'optionalAccess', _137 => _137.patchRoutesOnNavigation]), |
| unstable_instrumentations: _optionalChain([opts, 'optionalAccess', _138 => _138.unstable_instrumentations]) |
| }).initialize(); |
| } |
| var Deferred2 = class { |
| constructor() { |
| this.status = "pending"; |
| this.promise = new Promise((resolve, reject) => { |
| this.resolve = (value) => { |
| if (this.status === "pending") { |
| this.status = "resolved"; |
| resolve(value); |
| } |
| }; |
| this.reject = (reason) => { |
| if (this.status === "pending") { |
| this.status = "rejected"; |
| reject(reason); |
| } |
| }; |
| }); |
| } |
| }; |
| function RouterProvider({ |
| router, |
| flushSync: reactDomFlushSyncImpl, |
| onError, |
| unstable_useTransitions |
| }) { |
| let unstable_rsc = useIsRSCRouterContext(); |
| unstable_useTransitions = unstable_rsc || unstable_useTransitions; |
| let [_state, setStateImpl] = React9.useState(router.state); |
| let [state, setOptimisticState] = useOptimisticSafe(_state); |
| let [pendingState, setPendingState] = React9.useState(); |
| let [vtContext, setVtContext] = React9.useState({ |
| isTransitioning: false |
| }); |
| let [renderDfd, setRenderDfd] = React9.useState(); |
| let [transition, setTransition] = React9.useState(); |
| let [interruption, setInterruption] = React9.useState(); |
| let fetcherData = React9.useRef( new Map()); |
| let setState = React9.useCallback( |
| (newState, { deletedFetchers, newErrors, flushSync, viewTransitionOpts }) => { |
| if (newErrors && onError) { |
| Object.values(newErrors).forEach( |
| (error) => onError(error, { |
| location: newState.location, |
| params: _nullishCoalesce(_optionalChain([newState, 'access', _139 => _139.matches, 'access', _140 => _140[0], 'optionalAccess', _141 => _141.params]), () => ( {})), |
| unstable_pattern: getRoutePattern(newState.matches) |
| }) |
| ); |
| } |
| newState.fetchers.forEach((fetcher, key) => { |
| if (fetcher.data !== void 0) { |
| fetcherData.current.set(key, fetcher.data); |
| } |
| }); |
| deletedFetchers.forEach((key) => fetcherData.current.delete(key)); |
| warnOnce( |
| flushSync === false || reactDomFlushSyncImpl != null, |
| 'You provided the `flushSync` option to a router update, but you are not using the `<RouterProvider>` from `react-router/dom` so `ReactDOM.flushSync()` is unavailable. Please update your app to `import { RouterProvider } from "react-router/dom"` and ensure you have `react-dom` installed as a dependency to use the `flushSync` option.' |
| ); |
| let isViewTransitionAvailable = router.window != null && router.window.document != null && typeof router.window.document.startViewTransition === "function"; |
| warnOnce( |
| viewTransitionOpts == null || isViewTransitionAvailable, |
| "You provided the `viewTransition` option to a router update, but you do not appear to be running in a DOM environment as `window.startViewTransition` is not available." |
| ); |
| if (!viewTransitionOpts || !isViewTransitionAvailable) { |
| if (reactDomFlushSyncImpl && flushSync) { |
| reactDomFlushSyncImpl(() => setStateImpl(newState)); |
| } else if (unstable_useTransitions === false) { |
| setStateImpl(newState); |
| } else { |
| React9.startTransition(() => { |
| if (unstable_useTransitions === true) { |
| setOptimisticState((s) => getOptimisticRouterState(s, newState)); |
| } |
| setStateImpl(newState); |
| }); |
| } |
| return; |
| } |
| if (reactDomFlushSyncImpl && flushSync) { |
| reactDomFlushSyncImpl(() => { |
| if (transition) { |
| _optionalChain([renderDfd, 'optionalAccess', _142 => _142.resolve, 'call', _143 => _143()]); |
| transition.skipTransition(); |
| } |
| setVtContext({ |
| isTransitioning: true, |
| flushSync: true, |
| currentLocation: viewTransitionOpts.currentLocation, |
| nextLocation: viewTransitionOpts.nextLocation |
| }); |
| }); |
| let t = router.window.document.startViewTransition(() => { |
| reactDomFlushSyncImpl(() => setStateImpl(newState)); |
| }); |
| t.finished.finally(() => { |
| reactDomFlushSyncImpl(() => { |
| setRenderDfd(void 0); |
| setTransition(void 0); |
| setPendingState(void 0); |
| setVtContext({ isTransitioning: false }); |
| }); |
| }); |
| reactDomFlushSyncImpl(() => setTransition(t)); |
| return; |
| } |
| if (transition) { |
| _optionalChain([renderDfd, 'optionalAccess', _144 => _144.resolve, 'call', _145 => _145()]); |
| transition.skipTransition(); |
| setInterruption({ |
| state: newState, |
| currentLocation: viewTransitionOpts.currentLocation, |
| nextLocation: viewTransitionOpts.nextLocation |
| }); |
| } else { |
| setPendingState(newState); |
| setVtContext({ |
| isTransitioning: true, |
| flushSync: false, |
| currentLocation: viewTransitionOpts.currentLocation, |
| nextLocation: viewTransitionOpts.nextLocation |
| }); |
| } |
| }, |
| [ |
| router.window, |
| reactDomFlushSyncImpl, |
| transition, |
| renderDfd, |
| unstable_useTransitions, |
| setOptimisticState, |
| onError |
| ] |
| ); |
| React9.useLayoutEffect(() => router.subscribe(setState), [router, setState]); |
| let initialized = state.initialized; |
| React9.useLayoutEffect(() => { |
| if (!initialized && router.state.initialized) { |
| setState(router.state, { |
| deletedFetchers: [], |
| flushSync: false, |
| newErrors: null |
| }); |
| } |
| }, [initialized, setState, router.state]); |
| React9.useEffect(() => { |
| if (vtContext.isTransitioning && !vtContext.flushSync) { |
| setRenderDfd(new Deferred2()); |
| } |
| }, [vtContext]); |
| React9.useEffect(() => { |
| if (renderDfd && pendingState && router.window) { |
| let newState = pendingState; |
| let renderPromise = renderDfd.promise; |
| let transition2 = router.window.document.startViewTransition(async () => { |
| if (unstable_useTransitions === false) { |
| setStateImpl(newState); |
| } else { |
| React9.startTransition(() => { |
| if (unstable_useTransitions === true) { |
| setOptimisticState((s) => getOptimisticRouterState(s, newState)); |
| } |
| setStateImpl(newState); |
| }); |
| } |
| await renderPromise; |
| }); |
| transition2.finished.finally(() => { |
| setRenderDfd(void 0); |
| setTransition(void 0); |
| setPendingState(void 0); |
| setVtContext({ isTransitioning: false }); |
| }); |
| setTransition(transition2); |
| } |
| }, [ |
| pendingState, |
| renderDfd, |
| router.window, |
| unstable_useTransitions, |
| setOptimisticState |
| ]); |
| React9.useEffect(() => { |
| if (renderDfd && pendingState && state.location.key === pendingState.location.key) { |
| renderDfd.resolve(); |
| } |
| }, [renderDfd, transition, state.location, pendingState]); |
| React9.useEffect(() => { |
| if (!vtContext.isTransitioning && interruption) { |
| setPendingState(interruption.state); |
| setVtContext({ |
| isTransitioning: true, |
| flushSync: false, |
| currentLocation: interruption.currentLocation, |
| nextLocation: interruption.nextLocation |
| }); |
| setInterruption(void 0); |
| } |
| }, [vtContext.isTransitioning, interruption]); |
| let navigator = React9.useMemo(() => { |
| return { |
| createHref: router.createHref, |
| encodeLocation: router.encodeLocation, |
| go: (n) => router.navigate(n), |
| push: (to, state2, opts) => router.navigate(to, { |
| state: state2, |
| preventScrollReset: _optionalChain([opts, 'optionalAccess', _146 => _146.preventScrollReset]) |
| }), |
| replace: (to, state2, opts) => router.navigate(to, { |
| replace: true, |
| state: state2, |
| preventScrollReset: _optionalChain([opts, 'optionalAccess', _147 => _147.preventScrollReset]) |
| }) |
| }; |
| }, [router]); |
| let basename = router.basename || "/"; |
| let dataRouterContext = React9.useMemo( |
| () => ({ |
| router, |
| navigator, |
| static: false, |
| basename, |
| onError |
| }), |
| [router, navigator, basename, onError] |
| ); |
| return React9.createElement(React9.Fragment, null, React9.createElement(DataRouterContext.Provider, { value: dataRouterContext }, React9.createElement(DataRouterStateContext.Provider, { value: state }, React9.createElement(FetchersContext.Provider, { value: fetcherData.current }, React9.createElement(ViewTransitionContext.Provider, { value: vtContext }, React9.createElement( |
| Router, |
| { |
| basename, |
| location: state.location, |
| navigationType: state.historyAction, |
| navigator, |
| unstable_useTransitions |
| }, |
| React9.createElement( |
| MemoizedDataRoutes, |
| { |
| routes: router.routes, |
| future: router.future, |
| state, |
| isStatic: false, |
| onError |
| } |
| ) |
| ))))), null); |
| } |
| function getOptimisticRouterState(currentState, newState) { |
| return { |
| |
| |
| |
| ...currentState, |
| |
| |
| navigation: newState.navigation.state !== "idle" ? newState.navigation : currentState.navigation, |
| revalidation: newState.revalidation !== "idle" ? newState.revalidation : currentState.revalidation, |
| actionData: newState.navigation.state !== "submitting" ? newState.actionData : currentState.actionData, |
| fetchers: newState.fetchers |
| }; |
| } |
| var MemoizedDataRoutes = React9.memo(DataRoutes); |
| function DataRoutes({ |
| routes, |
| future, |
| state, |
| isStatic, |
| onError |
| }) { |
| return useRoutesImpl(routes, void 0, { state, isStatic, onError, future }); |
| } |
| function MemoryRouter({ |
| basename, |
| children, |
| initialEntries, |
| initialIndex, |
| unstable_useTransitions |
| }) { |
| let historyRef = React9.useRef(); |
| if (historyRef.current == null) { |
| historyRef.current = createMemoryHistory({ |
| initialEntries, |
| initialIndex, |
| v5Compat: true |
| }); |
| } |
| let history = historyRef.current; |
| let [state, setStateImpl] = React9.useState({ |
| action: history.action, |
| location: history.location |
| }); |
| let setState = React9.useCallback( |
| (newState) => { |
| if (unstable_useTransitions === false) { |
| setStateImpl(newState); |
| } else { |
| React9.startTransition(() => setStateImpl(newState)); |
| } |
| }, |
| [unstable_useTransitions] |
| ); |
| React9.useLayoutEffect(() => history.listen(setState), [history, setState]); |
| return React9.createElement( |
| Router, |
| { |
| basename, |
| children, |
| location: state.location, |
| navigationType: state.action, |
| navigator: history, |
| unstable_useTransitions |
| } |
| ); |
| } |
| function Navigate({ |
| to, |
| replace: replace2, |
| state, |
| relative |
| }) { |
| invariant( |
| useInRouterContext(), |
| |
| |
| `<Navigate> may be used only in the context of a <Router> component.` |
| ); |
| let { static: isStatic } = React9.useContext(NavigationContext); |
| warning( |
| !isStatic, |
| `<Navigate> must not be used on the initial render in a <StaticRouter>. This is a no-op, but you should modify your code so the <Navigate> is only ever rendered in response to some user interaction or state change.` |
| ); |
| let { matches } = React9.useContext(RouteContext); |
| let { pathname: locationPathname } = useLocation(); |
| let navigate = useNavigate(); |
| let path = resolveTo( |
| to, |
| getResolveToMatches(matches), |
| locationPathname, |
| relative === "path" |
| ); |
| let jsonPath = JSON.stringify(path); |
| React9.useEffect(() => { |
| navigate(JSON.parse(jsonPath), { replace: replace2, state, relative }); |
| }, [navigate, jsonPath, relative, replace2, state]); |
| return null; |
| } |
| function Outlet(props) { |
| return useOutlet(props.context); |
| } |
| function Route(props) { |
| invariant( |
| false, |
| `A <Route> is only ever to be used as the child of <Routes> element, never rendered directly. Please wrap your <Route> in a <Routes>.` |
| ); |
| } |
| function Router({ |
| basename: basenameProp = "/", |
| children = null, |
| location: locationProp, |
| navigationType = "POP" /* Pop */, |
| navigator, |
| static: staticProp = false, |
| unstable_useTransitions |
| }) { |
| invariant( |
| !useInRouterContext(), |
| `You cannot render a <Router> inside another <Router>. You should never have more than one in your app.` |
| ); |
| let basename = basenameProp.replace(/^\/*/, "/"); |
| let navigationContext = React9.useMemo( |
| () => ({ |
| basename, |
| navigator, |
| static: staticProp, |
| unstable_useTransitions, |
| future: {} |
| }), |
| [basename, navigator, staticProp, unstable_useTransitions] |
| ); |
| if (typeof locationProp === "string") { |
| locationProp = parsePath(locationProp); |
| } |
| let { |
| pathname = "/", |
| search = "", |
| hash = "", |
| state = null, |
| key = "default", |
| unstable_mask |
| } = locationProp; |
| let locationContext = React9.useMemo(() => { |
| let trailingPathname = stripBasename(pathname, basename); |
| if (trailingPathname == null) { |
| return null; |
| } |
| return { |
| location: { |
| pathname: trailingPathname, |
| search, |
| hash, |
| state, |
| key, |
| unstable_mask |
| }, |
| navigationType |
| }; |
| }, [ |
| basename, |
| pathname, |
| search, |
| hash, |
| state, |
| key, |
| navigationType, |
| unstable_mask |
| ]); |
| warning( |
| locationContext != null, |
| `<Router basename="${basename}"> is not able to match the URL "${pathname}${search}${hash}" because it does not start with the basename, so the <Router> won't render anything.` |
| ); |
| if (locationContext == null) { |
| return null; |
| } |
| return React9.createElement(NavigationContext.Provider, { value: navigationContext }, React9.createElement(LocationContext.Provider, { children, value: locationContext })); |
| } |
| function Routes({ |
| children, |
| location |
| }) { |
| return useRoutes(createRoutesFromChildren(children), location); |
| } |
| function Await({ |
| children, |
| errorElement, |
| resolve |
| }) { |
| let dataRouterContext = React9.useContext(DataRouterContext); |
| let dataRouterStateContext = React9.useContext(DataRouterStateContext); |
| let onError = React9.useCallback( |
| (error, errorInfo) => { |
| if (dataRouterContext && dataRouterContext.onError && dataRouterStateContext) { |
| dataRouterContext.onError(error, { |
| location: dataRouterStateContext.location, |
| params: _optionalChain([dataRouterStateContext, 'access', _148 => _148.matches, 'access', _149 => _149[0], 'optionalAccess', _150 => _150.params]) || {}, |
| unstable_pattern: getRoutePattern(dataRouterStateContext.matches), |
| errorInfo |
| }); |
| } |
| }, |
| [dataRouterContext, dataRouterStateContext] |
| ); |
| return React9.createElement( |
| AwaitErrorBoundary, |
| { |
| resolve, |
| errorElement, |
| onError |
| }, |
| React9.createElement(ResolveAwait, null, children) |
| ); |
| } |
| var AwaitErrorBoundary = class extends React9.Component { |
| constructor(props) { |
| super(props); |
| this.state = { error: null }; |
| } |
| static getDerivedStateFromError(error) { |
| return { error }; |
| } |
| componentDidCatch(error, errorInfo) { |
| if (this.props.onError) { |
| this.props.onError(error, errorInfo); |
| } else { |
| console.error( |
| "<Await> caught the following error during render", |
| error, |
| errorInfo |
| ); |
| } |
| } |
| render() { |
| let { children, errorElement, resolve } = this.props; |
| let promise = null; |
| let status = 0 ; |
| if (!(resolve instanceof Promise)) { |
| status = 1 ; |
| promise = Promise.resolve(); |
| Object.defineProperty(promise, "_tracked", { get: () => true }); |
| Object.defineProperty(promise, "_data", { get: () => resolve }); |
| } else if (this.state.error) { |
| status = 2 ; |
| let renderError = this.state.error; |
| promise = Promise.reject().catch(() => { |
| }); |
| Object.defineProperty(promise, "_tracked", { get: () => true }); |
| Object.defineProperty(promise, "_error", { get: () => renderError }); |
| } else if (resolve._tracked) { |
| promise = resolve; |
| status = "_error" in promise ? 2 : "_data" in promise ? 1 : 0 ; |
| } else { |
| status = 0 ; |
| Object.defineProperty(resolve, "_tracked", { get: () => true }); |
| promise = resolve.then( |
| (data2) => Object.defineProperty(resolve, "_data", { get: () => data2 }), |
| (error) => { |
| _optionalChain([this, 'access', _151 => _151.props, 'access', _152 => _152.onError, 'optionalCall', _153 => _153(error)]); |
| Object.defineProperty(resolve, "_error", { get: () => error }); |
| } |
| ); |
| } |
| if (status === 2 && !errorElement) { |
| throw promise._error; |
| } |
| if (status === 2 ) { |
| return React9.createElement(AwaitContext.Provider, { value: promise, children: errorElement }); |
| } |
| if (status === 1 ) { |
| return React9.createElement(AwaitContext.Provider, { value: promise, children }); |
| } |
| throw promise; |
| } |
| }; |
| function ResolveAwait({ |
| children |
| }) { |
| let data2 = useAsyncValue(); |
| let toRender = typeof children === "function" ? children(data2) : children; |
| return React9.createElement(React9.Fragment, null, toRender); |
| } |
| function createRoutesFromChildren(children, parentPath = []) { |
| let routes = []; |
| React9.Children.forEach(children, (element, index) => { |
| if (!React9.isValidElement(element)) { |
| return; |
| } |
| let treePath = [...parentPath, index]; |
| if (element.type === React9.Fragment) { |
| routes.push.apply( |
| routes, |
| createRoutesFromChildren(element.props.children, treePath) |
| ); |
| return; |
| } |
| invariant( |
| element.type === Route, |
| `[${typeof element.type === "string" ? element.type : element.type.name}] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>` |
| ); |
| invariant( |
| !element.props.index || !element.props.children, |
| "An index route cannot have child routes." |
| ); |
| let route = { |
| id: element.props.id || treePath.join("-"), |
| caseSensitive: element.props.caseSensitive, |
| element: element.props.element, |
| Component: element.props.Component, |
| index: element.props.index, |
| path: element.props.path, |
| middleware: element.props.middleware, |
| loader: element.props.loader, |
| action: element.props.action, |
| hydrateFallbackElement: element.props.hydrateFallbackElement, |
| HydrateFallback: element.props.HydrateFallback, |
| errorElement: element.props.errorElement, |
| ErrorBoundary: element.props.ErrorBoundary, |
| hasErrorBoundary: element.props.hasErrorBoundary === true || element.props.ErrorBoundary != null || element.props.errorElement != null, |
| shouldRevalidate: element.props.shouldRevalidate, |
| handle: element.props.handle, |
| lazy: element.props.lazy |
| }; |
| if (element.props.children) { |
| route.children = createRoutesFromChildren( |
| element.props.children, |
| treePath |
| ); |
| } |
| routes.push(route); |
| }); |
| return routes; |
| } |
| var createRoutesFromElements = createRoutesFromChildren; |
| function renderMatches(matches) { |
| return _renderMatches(matches); |
| } |
| function useRouteComponentProps() { |
| return { |
| params: useParams(), |
| loaderData: useLoaderData(), |
| actionData: useActionData(), |
| matches: useMatches() |
| }; |
| } |
| function WithComponentProps({ |
| children |
| }) { |
| const props = useRouteComponentProps(); |
| return React9.cloneElement(children, props); |
| } |
| function withComponentProps(Component4) { |
| return function WithComponentProps2() { |
| const props = useRouteComponentProps(); |
| return React9.createElement(Component4, props); |
| }; |
| } |
| function useHydrateFallbackProps() { |
| return { |
| params: useParams(), |
| loaderData: useLoaderData(), |
| actionData: useActionData() |
| }; |
| } |
| function WithHydrateFallbackProps({ |
| children |
| }) { |
| const props = useHydrateFallbackProps(); |
| return React9.cloneElement(children, props); |
| } |
| function withHydrateFallbackProps(HydrateFallback) { |
| return function WithHydrateFallbackProps2() { |
| const props = useHydrateFallbackProps(); |
| return React9.createElement(HydrateFallback, props); |
| }; |
| } |
| function useErrorBoundaryProps() { |
| return { |
| params: useParams(), |
| loaderData: useLoaderData(), |
| actionData: useActionData(), |
| error: useRouteError() |
| }; |
| } |
| function WithErrorBoundaryProps({ |
| children |
| }) { |
| const props = useErrorBoundaryProps(); |
| return React9.cloneElement(children, props); |
| } |
| function withErrorBoundaryProps(ErrorBoundary) { |
| return function WithErrorBoundaryProps2() { |
| const props = useErrorBoundaryProps(); |
| return React9.createElement(ErrorBoundary, props); |
| }; |
| } |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| exports.Action = Action; exports.createMemoryHistory = createMemoryHistory; exports.createBrowserHistory = createBrowserHistory; exports.createHashHistory = createHashHistory; exports.invariant = invariant; exports.warning = warning; exports.createPath = createPath; exports.parsePath = parsePath; exports.createContext = createContext; exports.RouterContextProvider = RouterContextProvider; exports.convertRoutesToDataRoutes = convertRoutesToDataRoutes; exports.matchRoutes = matchRoutes; exports.generatePath = generatePath; exports.matchPath = matchPath; exports.stripBasename = stripBasename; exports.resolvePath = resolvePath; exports.resolveTo = resolveTo; exports.joinPaths = joinPaths; exports.data = data; exports.redirect = redirect; exports.redirectDocument = redirectDocument; exports.replace = replace; exports.ErrorResponseImpl = ErrorResponseImpl; exports.isRouteErrorResponse = isRouteErrorResponse; exports.parseToInfo = parseToInfo; exports.escapeHtml = escapeHtml; exports.encode = encode; exports.instrumentHandler = instrumentHandler; exports.IDLE_NAVIGATION = IDLE_NAVIGATION; exports.IDLE_FETCHER = IDLE_FETCHER; exports.IDLE_BLOCKER = IDLE_BLOCKER; exports.createRouter = createRouter; exports.createStaticHandler = createStaticHandler; exports.getStaticContextFromError = getStaticContextFromError; exports.invalidProtocols = invalidProtocols; exports.isDataWithResponseInit = isDataWithResponseInit; exports.isResponse = isResponse; exports.isRedirectStatusCode = isRedirectStatusCode; exports.isRedirectResponse = isRedirectResponse; exports.isMutationMethod = isMutationMethod; exports.createRequestInit = createRequestInit; exports.SingleFetchRedirectSymbol = SingleFetchRedirectSymbol; exports.SINGLE_FETCH_REDIRECT_STATUS = SINGLE_FETCH_REDIRECT_STATUS; exports.NO_BODY_STATUS_CODES = NO_BODY_STATUS_CODES; exports.StreamTransfer = StreamTransfer; exports.getTurboStreamSingleFetchDataStrategy = getTurboStreamSingleFetchDataStrategy; exports.getSingleFetchDataStrategyImpl = getSingleFetchDataStrategyImpl; exports.stripIndexParam = stripIndexParam; exports.singleFetchUrl = singleFetchUrl; exports.decodeViaTurboStream = decodeViaTurboStream; exports.DataRouterContext = DataRouterContext; exports.DataRouterStateContext = DataRouterStateContext; exports.RSCRouterContext = RSCRouterContext; exports.ViewTransitionContext = ViewTransitionContext; exports.FetchersContext = FetchersContext; exports.AwaitContextProvider = AwaitContextProvider; exports.NavigationContext = NavigationContext; exports.LocationContext = LocationContext; exports.RouteContext = RouteContext; exports.ENABLE_DEV_WARNINGS = ENABLE_DEV_WARNINGS; exports.warnOnce = warnOnce; exports.decodeRedirectErrorDigest = decodeRedirectErrorDigest; exports.decodeRouteErrorResponseDigest = decodeRouteErrorResponseDigest; exports.useHref = useHref; exports.useInRouterContext = useInRouterContext; exports.useLocation = useLocation; exports.useNavigationType = useNavigationType; exports.useMatch = useMatch; exports.useNavigate = useNavigate; exports.useOutletContext = useOutletContext; exports.useOutlet = useOutlet; exports.useParams = useParams; exports.useResolvedPath = useResolvedPath; exports.useRoutes = useRoutes; exports.useRouteId = useRouteId; exports.useNavigation = useNavigation; exports.useRevalidator = useRevalidator; exports.useMatches = useMatches; exports.useLoaderData = useLoaderData; exports.useRouteLoaderData = useRouteLoaderData; exports.useActionData = useActionData; exports.useRouteError = useRouteError; exports.useAsyncValue = useAsyncValue; exports.useAsyncError = useAsyncError; exports.useBlocker = useBlocker; exports.useRoute = useRoute; exports.RemixErrorBoundary = RemixErrorBoundary; exports.createServerRoutes = createServerRoutes; exports.createClientRoutesWithHMRRevalidationOptOut = createClientRoutesWithHMRRevalidationOptOut; exports.noActionDefinedError = noActionDefinedError; exports.createClientRoutes = createClientRoutes; exports.shouldHydrateRouteLoader = shouldHydrateRouteLoader; exports.getPatchRoutesOnNavigationFunction = getPatchRoutesOnNavigationFunction; exports.useFogOFWarDiscovery = useFogOFWarDiscovery; exports.getManifestPath = getManifestPath; exports.FrameworkContext = FrameworkContext; exports.usePrefetchBehavior = usePrefetchBehavior; exports.CRITICAL_CSS_DATA_ATTRIBUTE = CRITICAL_CSS_DATA_ATTRIBUTE; exports.Links = Links; exports.PrefetchPageLinks = PrefetchPageLinks; exports.Meta = Meta; exports.setIsHydrated = setIsHydrated; exports.Scripts = Scripts; exports.mergeRefs = mergeRefs; exports.mapRouteProperties = mapRouteProperties; exports.hydrationRouteProperties = hydrationRouteProperties; exports.createMemoryRouter = createMemoryRouter; exports.RouterProvider = RouterProvider; exports.DataRoutes = DataRoutes; exports.MemoryRouter = MemoryRouter; exports.Navigate = Navigate; exports.Outlet = Outlet; exports.Route = Route; exports.Router = Router; exports.Routes = Routes; exports.Await = Await; exports.createRoutesFromChildren = createRoutesFromChildren; exports.createRoutesFromElements = createRoutesFromElements; exports.renderMatches = renderMatches; exports.WithComponentProps = WithComponentProps; exports.withComponentProps = withComponentProps; exports.WithHydrateFallbackProps = WithHydrateFallbackProps; exports.withHydrateFallbackProps = withHydrateFallbackProps; exports.WithErrorBoundaryProps = WithErrorBoundaryProps; exports.withErrorBoundaryProps = withErrorBoundaryProps; |
|
|