one
Version:
One is a new React Framework that makes Vite serve both native and web.
79 lines (78 loc) • 4.2 kB
JavaScript
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: !0 });
}, __copyProps = (to, from, except, desc) => {
if (from && typeof from == "object" || typeof from == "function")
for (let key of __getOwnPropNames(from))
!__hasOwnProp.call(to, key) && key !== except && __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: !0 }), mod);
var useLoader_exports = {};
__export(useLoader_exports, {
useLoader: () => useLoader
});
module.exports = __toCommonJS(useLoader_exports);
var import_react = require("react"), import_hooks = require("./hooks"), import_href = require("./link/href"), import_router = require("./router/router"), import_cleanUrl = require("./utils/cleanUrl"), import_dynamicImport = require("./utils/dynamicImport"), import_weakKey = require("./utils/weakKey"), import_one_server_only = require("./vite/one-server-only");
const promises = {}, errors = {}, loadedData = {};
function useLoader(loader) {
const { loaderProps: loaderPropsFromServerContext, loaderData: loaderDataFromServerContext } = (0, import_one_server_only.useServerContext)() || {};
if (typeof window > "u")
return useAsyncFn(
loader,
loaderPropsFromServerContext || {
path: (0, import_hooks.usePathname)(),
params: (0, import_hooks.useActiveParams)()
}
);
const params = (0, import_hooks.useParams)(), pathname = (0, import_hooks.usePathname)(), currentPath = (0, import_href.resolveHref)({ pathname, params }).replace(/index$/, "").replace(/\?.*/, ""), preloadedData = loaderPropsFromServerContext?.path === currentPath ? loaderDataFromServerContext : void 0, currentData = (0, import_react.useRef)(preloadedData);
if ((0, import_react.useEffect)(() => {
preloadedData && (loadedData[currentPath] = preloadedData);
}, [preloadedData]), errors[currentPath])
throw errors[currentPath];
const loaded = loadedData[currentPath];
if (typeof loaded < "u")
return loaded;
if (!preloadedData) {
if (import_router.preloadingLoader[currentPath] && (typeof import_router.preloadingLoader[currentPath] == "function" && (import_router.preloadingLoader[currentPath] = import_router.preloadingLoader[currentPath]()), promises[currentPath] = import_router.preloadingLoader[currentPath].then((val) => {
loadedData[currentPath] = val;
}).catch((err) => {
console.error("Error loading loader", err), errors[currentPath] = err, delete promises[currentPath], delete import_router.preloadingLoader[currentPath];
})), !promises[currentPath]) {
const getData = async () => {
const loaderJSUrl = (0, import_cleanUrl.getLoaderPath)(currentPath, !0);
try {
const response = await (async () => await (0, import_dynamicImport.dynamicImport)(loaderJSUrl))();
return loadedData[currentPath] = response.loader(), loadedData[currentPath];
} catch (err) {
return console.error(`Error calling loader: ${err}`), errors[currentPath] = err, delete promises[currentPath], null;
}
};
promises[currentPath] = getData();
}
throw promises[currentPath];
}
return currentData.current;
}
const results = /* @__PURE__ */ new Map(), started = /* @__PURE__ */ new Map();
function useAsyncFn(val, props) {
const key = (val ? (0, import_weakKey.weakKey)(val) : "") + JSON.stringify(props);
if (val && !started.get(key)) {
started.set(key, !0);
let next = val(props);
next instanceof Promise && (next = next.then((final) => {
results.set(key, final);
}).catch((err) => {
console.error("Error running loader()", err), results.set(key, void 0);
})), results.set(key, next);
}
const current = results.get(key);
if (current instanceof Promise)
throw current;
return current;
}
//# sourceMappingURL=useLoader.js.map