@modern-js/runtime-utils
Version:
A Progressive React Framework for modern web development.
143 lines (142 loc) • 5.42 kB
JavaScript
import { jsx as _jsx } from "react/jsx-runtime";
import { LOADER_REPORTER_NAME } from "@modern-js/utils/universal/constants";
import { Suspense } from "react";
import { Outlet, Route, createRoutesFromElements } from "react-router-dom";
import { time } from "../time";
import { getAsyncLocalStorage } from "../universal/async_storage";
import { DeferredData, activeDeferreds as originalActiveDeferreds } from "./deferreds";
const privateDefer = (data) => {
return new DeferredData(data);
};
const transformNestedRoutes = (routes) => {
const routeElements = [];
for (const route of routes) {
const routeElement = renderNestedRoute(route);
routeElements.push(routeElement);
}
return createRoutesFromElements(routeElements);
};
const renderNestedRoute = (nestedRoute, options = {}) => {
const { children, index, id, component, isRoot, lazyImport, config, handle } = nestedRoute;
const Component = component;
const { parent, props = {} } = options;
const routeProps = {
caseSensitive: nestedRoute.caseSensitive,
path: nestedRoute.path,
id: nestedRoute.id,
loader: createLoader(nestedRoute),
action: nestedRoute.action,
hasErrorBoundary: nestedRoute.hasErrorBoundary,
shouldRevalidate: nestedRoute.shouldRevalidate,
handle: {
...handle,
...typeof config === "object" ? config === null || config === void 0 ? void 0 : config.handle : {}
},
index: nestedRoute.index,
element: nestedRoute.element,
errorElement: nestedRoute.errorElement
};
if (nestedRoute.error) {
const errorElement = /* @__PURE__ */ _jsx(nestedRoute.error, {});
routeProps.errorElement = errorElement;
}
let element;
if (Component) {
if ((parent === null || parent === void 0 ? void 0 : parent.loading) && lazyImport) {
const Loading = parent.loading;
if (isLoadableComponent(Component)) {
element = /* @__PURE__ */ _jsx(Component, {
fallback: /* @__PURE__ */ _jsx(Loading, {})
});
} else {
element = /* @__PURE__ */ _jsx(Suspense, {
fallback: /* @__PURE__ */ _jsx(Loading, {}),
children: /* @__PURE__ */ _jsx(Component, {})
});
}
} else if (isLoadableComponent(Component) && lazyImport) {
element = /* @__PURE__ */ _jsx(Component, {});
} else if (isRoot) {
element = /* @__PURE__ */ _jsx(Component, {
...props
});
} else if (lazyImport) {
element = /* @__PURE__ */ _jsx(Suspense, {
fallback: null,
children: /* @__PURE__ */ _jsx(Component, {})
});
} else {
element = /* @__PURE__ */ _jsx(Component, {});
}
} else {
nestedRoute.loading = parent === null || parent === void 0 ? void 0 : parent.loading;
routeProps.element = /* @__PURE__ */ _jsx(Outlet, {});
}
if (element) {
routeProps.element = element;
}
const childElements = children === null || children === void 0 ? void 0 : children.map((childRoute) => {
return renderNestedRoute(childRoute, {
parent: nestedRoute
});
});
const routeElement = index ? /* @__PURE__ */ _jsx(Route, {
...routeProps,
index: true
}, id) : /* @__PURE__ */ _jsx(Route, {
...routeProps,
index: false,
children: childElements
}, id);
return routeElement;
};
function isPlainObject(value) {
return value != null && typeof value === "object" && Object.getPrototypeOf(value) === Object.prototype;
}
function createLoader(route) {
const { loader } = route;
if (loader) {
return async (args) => {
if (typeof route.lazyImport === "function") {
route.lazyImport();
}
const end = time();
const res = await loader(args);
const isRouterV7 = process.env._MODERN_ROUTER_VERSION === "v7";
if (isRouterV7) {
let activeDeferreds = null;
if (typeof document === "undefined") {
var _getAsyncLocalStorage_useContext, _getAsyncLocalStorage;
activeDeferreds = (_getAsyncLocalStorage = getAsyncLocalStorage()) === null || _getAsyncLocalStorage === void 0 ? void 0 : (_getAsyncLocalStorage_useContext = _getAsyncLocalStorage.useContext()) === null || _getAsyncLocalStorage_useContext === void 0 ? void 0 : _getAsyncLocalStorage_useContext.activeDeferreds;
} else {
activeDeferreds = originalActiveDeferreds;
}
if (isPlainObject(res)) {
const deferredData = privateDefer(res);
activeDeferreds.set(route.id, deferredData);
}
}
const cost = end();
if (typeof document === "undefined") {
var _route_id, _storage_useContext_monitors;
const storage = getAsyncLocalStorage();
storage === null || storage === void 0 ? void 0 : (_storage_useContext_monitors = storage.useContext().monitors) === null || _storage_useContext_monitors === void 0 ? void 0 : _storage_useContext_monitors.timing(`${LOADER_REPORTER_NAME}-${(_route_id = route.id) === null || _route_id === void 0 ? void 0 : _route_id.replace(/\//g, "_")}`, cost);
}
return res;
};
} else {
return () => {
if (typeof route.lazyImport === "function") {
route.lazyImport();
}
return null;
};
}
}
function isLoadableComponent(component) {
return component && component.displayName === "Loadable" && component.preload && typeof component.preload === "function";
}
export {
renderNestedRoute,
transformNestedRoutes
};