UNPKG

one

Version:

One is a new React Framework that makes Vite serve both native and web.

333 lines (332 loc) 14.3 kB
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, { getLoaderTimingHistory: () => getLoaderTimingHistory, refetchLoader: () => refetchLoader, refetchMatchLoader: () => refetchMatchLoader, resetLoaderState: () => resetLoaderState, useLoader: () => useLoader, useLoaderState: () => useLoaderState }); module.exports = __toCommonJS(useLoader_exports); var import_react = require("react"), import_registry = require("./devtools/registry"), import_hooks = require("./hooks"), import_notFoundState = require("./notFoundState"), import_imperative_api = require("./router/imperative-api"), import_router = require("./router/router"), import_useMatches = require("./useMatches"), 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 loaderTimingHistory = [], MAX_TIMING_HISTORY = 50, recordLoaderTiming = process.env.NODE_ENV === "development" ? (entry) => { loaderTimingHistory.unshift(entry), loaderTimingHistory.length > MAX_TIMING_HISTORY && loaderTimingHistory.pop(), typeof window < "u" && typeof CustomEvent < "u" && (window.dispatchEvent(new CustomEvent("one-loader-timing", { detail: entry })), entry.error && window.dispatchEvent( new CustomEvent("one-error", { detail: { error: { message: entry.error, name: "LoaderError" }, route: { pathname: entry.path }, timestamp: Date.now(), type: "loader" } }) )); } : void 0; function getLoaderTimingHistory() { return loaderTimingHistory; } (0, import_registry.registerDevtoolsFunction)("getLoaderTimingHistory", getLoaderTimingHistory); (0, import_registry.registerDevtoolsFunction)("recordLoaderTiming", recordLoaderTiming); const loaderState = {}, subscribers = /* @__PURE__ */ new Set(); function updateState(path, updates) { loaderState[path] = { ...loaderState[path], ...updates }, subscribers.forEach((callback) => { callback(); }); } function subscribe(callback) { return subscribers.add(callback), () => subscribers.delete(callback); } function getLoaderState(path, preloadedData2) { return loaderState[path] || (loaderState[path] = { data: preloadedData2, error: void 0, promise: void 0, state: "idle", hasLoadedOnce: !!preloadedData2 }), loaderState[path]; } async function refetchLoader(pathname2) { const startTime2 = performance.now(); updateState(pathname2, { state: "loading", error: null }); try { const cacheBust = `${Date.now()}`, loaderJSUrl2 = (0, import_cleanUrl.getLoaderPath)(pathname2, !0, cacheBust), moduleLoadStart2 = performance.now(), module2 = await (0, import_dynamicImport.dynamicImport)(loaderJSUrl2)?.catch(() => null), moduleLoadTime2 = performance.now() - moduleLoadStart2; if (!module2?.loader) { updateState(pathname2, { data: void 0, state: "idle", hasLoadedOnce: !0 }); return; } const executionStart2 = performance.now(), result2 = await module2.loader(), executionTime2 = performance.now() - executionStart2, totalTime2 = performance.now() - startTime2; if (result2?.__oneRedirect) { recordLoaderTiming?.({ path: pathname2, startTime: startTime2, moduleLoadTime: moduleLoadTime2, executionTime: executionTime2, totalTime: totalTime2, source: "refetch" }), updateState(pathname2, { data: void 0, state: "idle", hasLoadedOnce: !0 }), import_imperative_api.router.replace(result2.__oneRedirect); return; } if (result2?.__oneError === 404) { recordLoaderTiming?.({ path: pathname2, startTime: startTime2, moduleLoadTime: moduleLoadTime2, executionTime: executionTime2, totalTime: totalTime2, source: "refetch" }); const notFoundRoute = (0, import_notFoundState.findNearestNotFoundRoute)(pathname2, import_router.routeNode); (0, import_notFoundState.setNotFoundState)({ notFoundPath: result2.__oneNotFoundPath || "/+not-found", notFoundRouteNode: notFoundRoute || void 0, originalPath: pathname2 }); return; } updateState(pathname2, { data: result2, state: "idle", timestamp: Date.now(), hasLoadedOnce: !0 }); const currentMatches = (0, import_useMatches.getClientMatchesSnapshot)(), pageMatch = currentMatches[currentMatches.length - 1], normalizedPathname = pathname2.replace(/\/$/, "") || "/", normalizedMatchPathname = (pageMatch?.pathname || "").replace(/\/$/, "") || "/"; pageMatch && normalizedMatchPathname === normalizedPathname && (0, import_useMatches.updateMatchLoaderData)(pageMatch.routeId, result2), recordLoaderTiming?.({ path: pathname2, startTime: startTime2, moduleLoadTime: moduleLoadTime2, executionTime: executionTime2, totalTime: totalTime2, source: "refetch" }); } catch (err) { const totalTime2 = performance.now() - startTime2; throw updateState(pathname2, { error: err, state: "idle" }), recordLoaderTiming?.({ path: pathname2, startTime: startTime2, totalTime: totalTime2, error: err instanceof Error ? err.message : String(err), source: "refetch" }), err; } } process.env.NODE_ENV === "development" && typeof window < "u" && (window.__oneRefetchLoader = refetchLoader); async function refetchMatchLoader(routeId, currentPath2) { const cacheBust = `${Date.now()}`, loaderJSUrl2 = (0, import_cleanUrl.getLoaderPath)(currentPath2, !0, cacheBust), module2 = await (0, import_dynamicImport.dynamicImport)(loaderJSUrl2)?.catch(() => null); if (!module2?.loader) return; const result2 = await module2.loader(); result2?.__oneRedirect || result2?.__oneError || (0, import_useMatches.updateMatchLoaderData)(routeId, result2); } function useLoaderState(loader) { const { loaderProps: loaderPropsFromServerContext, loaderData: loaderDataFromServerContext } = (0, import_one_server_only.useServerContext)() || {}, params = (0, import_hooks.useParams)(), pathname = (0, import_hooks.usePathname)(), currentPath = pathname.replace(/\/index$/, "").replace(/\/$/, "") || "/"; if (typeof window > "u" && loader) return { data: useAsyncFn( loader, loaderPropsFromServerContext || { path: pathname, params } ), refetch: async () => { }, state: "idle" }; const matchRouteId = loader ? (() => { const result2 = loader(); return typeof result2 == "string" && result2.startsWith("./") ? result2 : null; })() : null, clientMatches = (0, import_react.useSyncExternalStore)( import_useMatches.subscribeToClientMatches, import_useMatches.getClientMatchesSnapshot, import_useMatches.getClientMatchesSnapshot ), serverContextPath = loaderPropsFromServerContext?.path, preloadedData = serverContextPath === currentPath ? loaderDataFromServerContext : void 0, loaderStateEntry = (0, import_react.useSyncExternalStore)( subscribe, () => getLoaderState(currentPath, preloadedData), () => getLoaderState(currentPath, preloadedData) ), refetch = (0, import_react.useCallback)(() => refetchLoader(currentPath), [currentPath]); if (matchRouteId) { const match = clientMatches.find((m) => m.routeId === matchRouteId), isPageMatch = clientMatches.length > 0 && clientMatches[clientMatches.length - 1]?.routeId === matchRouteId, matchPathNormalized = (match?.pathname || "").replace(/\/$/, "") || "/", matchPathFresh = !isPageMatch || matchPathNormalized === currentPath; if (match && match.loaderData != null && matchPathFresh) return { data: match.loaderData, // refetch updates both loaderState (for useLoaderState() consumers without a loader) // and the match entry (for this component and useMatches consumers) refetch: async () => { await refetchLoader(currentPath); const fresh = loaderState[currentPath]; fresh?.data != null && (0, import_useMatches.updateMatchLoaderData)(matchRouteId, fresh.data); }, state: loaderStateEntry.state }; } if (!loader) return { refetch, state: loaderStateEntry.state }; if (!loaderStateEntry.data && !loaderStateEntry.promise && !loaderStateEntry.hasLoadedOnce && loader) { const resolvedPreloadData = import_router.preloadedLoaderData[currentPath]; if (resolvedPreloadData != null) delete import_router.preloadedLoaderData[currentPath], delete import_router.preloadingLoader[currentPath], loaderStateEntry.data = resolvedPreloadData, loaderStateEntry.hasLoadedOnce = !0; else if (import_router.preloadingLoader[currentPath]) { const promise2 = import_router.preloadingLoader[currentPath].then((val) => { delete import_router.preloadingLoader[currentPath], delete import_router.preloadedLoaderData[currentPath], val != null ? updateState(currentPath, { data: val, hasLoadedOnce: !0, promise: void 0 }) : updateState(currentPath, { promise: void 0 }); }).catch((err) => { console.error("Error running loader()", err), delete import_router.preloadingLoader[currentPath], updateState(currentPath, { error: err, promise: void 0 }); }); loaderStateEntry.promise = promise2; } else { const loadData = async () => { const startTime = performance.now(); try { const loaderJSUrl = (0, import_cleanUrl.getLoaderPath)(currentPath, !0), moduleLoadStart = performance.now(), module = await (0, import_dynamicImport.dynamicImport)(loaderJSUrl)?.catch(() => null), moduleLoadTime = performance.now() - moduleLoadStart; if (!module?.loader) { updateState(currentPath, { data: void 0, hasLoadedOnce: !0, promise: void 0 }); return; } const executionStart = performance.now(), result = await module.loader(), executionTime = performance.now() - executionStart, totalTime = performance.now() - startTime; if (result?.__oneRedirect) { recordLoaderTiming?.({ path: currentPath, startTime, moduleLoadTime, executionTime, totalTime, source: "initial" }), updateState(currentPath, { data: void 0, hasLoadedOnce: !0, promise: void 0 }), import_imperative_api.router.replace(result.__oneRedirect); return; } if (result?.__oneError === 404) { recordLoaderTiming?.({ path: currentPath, startTime, moduleLoadTime, executionTime, totalTime, source: "initial" }); const notFoundRoute = (0, import_notFoundState.findNearestNotFoundRoute)(currentPath, import_router.routeNode); (0, import_notFoundState.setNotFoundState)({ notFoundPath: result.__oneNotFoundPath || "/+not-found", notFoundRouteNode: notFoundRoute || void 0, originalPath: currentPath }); return; } updateState(currentPath, { data: result, hasLoadedOnce: !0, promise: void 0 }), recordLoaderTiming?.({ path: currentPath, startTime, moduleLoadTime, executionTime, totalTime, source: "initial" }); } catch (err) { const totalTime2 = performance.now() - startTime; updateState(currentPath, { error: err, promise: void 0 }), recordLoaderTiming?.({ path: currentPath, startTime, totalTime: totalTime2, error: err instanceof Error ? err.message : String(err), source: "initial" }); } }, promise = loadData(); loaderStateEntry.promise = promise; } } if (loader) { if (loaderStateEntry.error && !loaderStateEntry.hasLoadedOnce) throw loaderStateEntry.error; if (loaderStateEntry.data === void 0 && loaderStateEntry.promise && !loaderStateEntry.hasLoadedOnce) throw loaderStateEntry.promise; return { data: loaderStateEntry.data, refetch, state: loaderStateEntry.state }; } else return { refetch, state: loaderStateEntry.state }; } function useLoader(loader2) { const { data: data2 } = useLoaderState(loader2); return data2; } const results = /* @__PURE__ */ new Map(), started = /* @__PURE__ */ new Map(); function resetLoaderState() { results.clear(), started.clear(); } 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