one
Version:
One is a new React Framework that makes Vite serve both native and web.
550 lines (548 loc) • 22.4 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: true
});
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
get: () => from[key],
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
});
}
return to;
};
var __toCommonJS = mod => __copyProps(__defProp({}, "__esModule", {
value: true
}), mod);
var useLoader_exports = {};
__export(useLoader_exports, {
getLoaderTimingHistory: () => getLoaderTimingHistory,
refetchLoader: () => refetchLoader,
refetchMatchLoader: () => refetchMatchLoader,
resetLoaderState: () => resetLoaderState,
setSSRLoaderData: () => import_ssrLoaderData2.setSSRLoaderData,
useLoader: () => useLoader,
useLoaderState: () => useLoaderState
});
module.exports = __toCommonJS(useLoader_exports);
var import_react = require("react");
var import_registry = require("./devtools/registry.native.js");
var import_hooks = require("./hooks.native.js");
var import_notFoundState = require("./notFoundState.native.js");
var import_Route = require("./router/Route.native.js");
var import_matchers = require("./router/matchers.native.js");
var import_imperative_api = require("./router/imperative-api.native.js");
var import_router = require("./router/router.native.js");
var import_ssrLoaderData = require("./server/ssrLoaderData.native.js");
var import_useMatches = require("./useMatches.native.js");
var import_cleanUrl = require("./utils/cleanUrl.native.js");
var import_constants = require("./constants.native.js");
var import_dynamicImport = require("./utils/dynamicImport.native.js");
var import_weakKey = require("./utils/weakKey.native.js");
var import_one_server_only = require("./vite/one-server-only.native.js");
var import_ssrLoaderData2 = require("./server/ssrLoaderData.native.js");
function _instanceof(left, right) {
if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) return !!right[Symbol.hasInstance](left);else return left instanceof right;
}
var LOADER_TIMEOUT = process.env.ONE_LOADER_TIMEOUT_MS ? +process.env.ONE_LOADER_TIMEOUT_MS : 6e4;
var loaderTimingHistory = [];
var MAX_TIMING_HISTORY = 50;
var recordLoaderTiming = process.env.NODE_ENV === "development" ? function (entry) {
loaderTimingHistory.unshift(entry);
if (loaderTimingHistory.length > MAX_TIMING_HISTORY) loaderTimingHistory.pop();
if (typeof window !== "undefined" && typeof CustomEvent !== "undefined") {
window.dispatchEvent(new CustomEvent("one-loader-timing", {
detail: entry
}));
if (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);
var loaderState = {};
var subscribers = /* @__PURE__ */new Set();
function updateState(path, updates) {
loaderState[path] = {
...loaderState[path],
...updates
};
subscribers.forEach(function (callback) {
callback();
});
}
function subscribe(callback) {
subscribers.add(callback);
return function () {
return subscribers.delete(callback);
};
}
function getLoaderState(path, preloadedData2) {
if (!loaderState[path]) loaderState[path] = {
data: preloadedData2,
error: void 0,
promise: void 0,
state: "idle",
hasLoadedOnce: !!preloadedData2
};
return loaderState[path];
}
async function refetchLoader(pathname2) {
var startTime2 = performance.now();
updateState(pathname2, {
state: "loading",
error: null
});
try {
var _dynamicImport2;
var cacheBust = `${Date.now()}`;
var loaderJSUrl2 = (0, import_cleanUrl.getLoaderPath)(pathname2, true, cacheBust);
var moduleLoadStart2 = performance.now();
var module2 = await ((_dynamicImport2 = (0, import_dynamicImport.dynamicImport)(loaderJSUrl2)) === null || _dynamicImport2 === void 0 ? void 0 : _dynamicImport2.catch(function () {
return null;
}));
var moduleLoadTime2 = performance.now() - moduleLoadStart2;
if (!(module2 === null || module2 === void 0 ? void 0 : module2.loader)) {
updateState(pathname2, {
data: void 0,
state: "idle",
hasLoadedOnce: true
});
return;
}
var executionStart2 = performance.now();
var result2 = await module2.loader();
var executionTime2 = performance.now() - executionStart2;
var totalTime2 = performance.now() - startTime2;
if (result2 === null || result2 === void 0 ? void 0 : result2.__oneRedirect) {
recordLoaderTiming === null || recordLoaderTiming === void 0 || recordLoaderTiming({
path: pathname2,
startTime: startTime2,
moduleLoadTime: moduleLoadTime2,
executionTime: executionTime2,
totalTime: totalTime2,
source: "refetch"
});
updateState(pathname2, {
data: void 0,
state: "idle",
hasLoadedOnce: true
});
import_imperative_api.router.replace(result2.__oneRedirect);
return;
}
if ((result2 === null || result2 === void 0 ? void 0 : result2.__oneError) === 404) {
recordLoaderTiming === null || recordLoaderTiming === void 0 || recordLoaderTiming({
path: pathname2,
startTime: startTime2,
moduleLoadTime: moduleLoadTime2,
executionTime: executionTime2,
totalTime: totalTime2,
source: "refetch"
});
var notFoundRoute2 = (0, import_notFoundState.findNearestNotFoundRoute)(pathname2, import_router.routeNode);
(0, import_notFoundState.setNotFoundState)({
notFoundPath: result2.__oneNotFoundPath || "/+not-found",
notFoundRouteNode: notFoundRoute2 || void 0,
originalPath: pathname2
});
return;
}
updateState(pathname2, {
data: result2,
state: "idle",
timestamp: Date.now(),
hasLoadedOnce: true
});
var currentMatches = (0, import_useMatches.getClientMatchesSnapshot)();
var pageMatch = currentMatches[currentMatches.length - 1];
var normalizedPathname = pathname2.replace(/\/$/, "") || "/";
var normalizedMatchPathname = ((pageMatch === null || pageMatch === void 0 ? void 0 : pageMatch.pathname) || "").replace(/\/$/, "") || "/";
if (pageMatch && normalizedMatchPathname === normalizedPathname) (0, import_useMatches.updateMatchLoaderData)(pageMatch.routeId, result2);
recordLoaderTiming === null || recordLoaderTiming === void 0 || recordLoaderTiming({
path: pathname2,
startTime: startTime2,
moduleLoadTime: moduleLoadTime2,
executionTime: executionTime2,
totalTime: totalTime2,
source: "refetch"
});
} catch (err) {
var totalTime1 = performance.now() - startTime2;
updateState(pathname2, {
error: err,
state: "idle"
});
recordLoaderTiming === null || recordLoaderTiming === void 0 || recordLoaderTiming({
path: pathname2,
startTime: startTime2,
totalTime: totalTime1,
error: _instanceof(err, Error) ? err.message : String(err),
source: "refetch"
});
throw err;
}
}
if (process.env.NODE_ENV === "development" && typeof window !== "undefined") window.__oneRefetchLoader = refetchLoader;
async function refetchMatchLoader(routeId, currentPath2) {
var _dynamicImport2;
var cacheBust = `${Date.now()}`;
var loaderJSUrl2 = (0, import_cleanUrl.getLoaderPath)(currentPath2, true, cacheBust);
var module2 = await ((_dynamicImport2 = (0, import_dynamicImport.dynamicImport)(loaderJSUrl2)) === null || _dynamicImport2 === void 0 ? void 0 : _dynamicImport2.catch(function () {
return null;
}));
if (!(module2 === null || module2 === void 0 ? void 0 : module2.loader)) return;
var result2 = await module2.loader();
if ((result2 === null || result2 === void 0 ? void 0 : result2.__oneRedirect) || (result2 === null || result2 === void 0 ? void 0 : result2.__oneError)) return;
(0, import_useMatches.updateMatchLoaderData)(routeId, result2);
}
function useLoaderState(loader) {
var {
loaderProps: loaderPropsFromServerContext,
loaderData: loaderDataFromServerContext
} = (0, import_one_server_only.useServerContext)() || {};
var params = (0, import_hooks.useParams)();
var pathname = (0, import_hooks.usePathname)();
var currentPath = pathname.replace(/\/index$/, "").replace(/\/$/, "") || "/";
if (typeof window === "undefined") {
if (loader) {
if (import_ssrLoaderData.ssrLoaderData.has(loader)) return {
data: import_ssrLoaderData.ssrLoaderData.get(loader),
refetch: async function () {},
state: "idle"
};
var serverContext = (0, import_one_server_only.useServerContext)();
if (serverContext === null || serverContext === void 0 ? void 0 : serverContext.matches) {
var contextKey = (0, import_Route.useContextKey)();
var match = serverContext.matches.find(function (m) {
return (0, import_matchers.getContextKey)(m.routeId) === contextKey;
});
if (match && match.loaderData !== void 0) return {
data: match.loaderData,
refetch: async function () {},
state: "idle"
};
}
return {
data: useAsyncFn(loader, loaderPropsFromServerContext || {
path: pathname,
params
}),
refetch: async function () {},
state: "idle"
};
}
if (loaderDataFromServerContext !== void 0) return {
data: loaderDataFromServerContext,
refetch: async function () {},
state: "idle"
};
}
var matchRouteId = loader ? function () {
var result2 = loader();
return typeof result2 === "string" && result2.startsWith("./") ? result2 : null;
}() : null;
var clientMatches = (0, import_react.useSyncExternalStore)(import_useMatches.subscribeToClientMatches, import_useMatches.getClientMatchesSnapshot, import_useMatches.getClientMatchesSnapshot);
var serverContextPath = loaderPropsFromServerContext === null || loaderPropsFromServerContext === void 0 ? void 0 : loaderPropsFromServerContext.path;
var preloadedData = serverContextPath === currentPath ? loaderDataFromServerContext : void 0;
var loaderStateEntry = (0, import_react.useSyncExternalStore)(subscribe, function () {
return getLoaderState(currentPath, preloadedData);
}, function () {
return getLoaderState(currentPath, preloadedData);
});
var refetch = (0, import_react.useCallback)(function () {
return refetchLoader(currentPath);
}, [currentPath]);
if (matchRouteId) {
var _clientMatches_;
var match = clientMatches.find(function (m) {
return m.routeId === matchRouteId;
});
var isPageMatch = clientMatches.length > 0 && ((_clientMatches_ = clientMatches[clientMatches.length - 1]) === null || _clientMatches_ === void 0 ? void 0 : _clientMatches_.routeId) === matchRouteId;
var matchPathNormalized = ((match === null || match === void 0 ? void 0 : match.pathname) || "").replace(/\/$/, "") || "/";
var matchPathFresh = !isPageMatch || matchPathNormalized === currentPath;
if (match && match.loaderData != null && matchPathFresh) return {
data: match.loaderData,
refetch: async function () {
await refetchLoader(currentPath);
var fresh = loaderState[currentPath];
if ((fresh === null || fresh === void 0 ? void 0 : 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) {
var resolvedPreloadData = import_router.preloadedLoaderData[currentPath];
if (resolvedPreloadData != null) {
delete import_router.preloadedLoaderData[currentPath];
delete import_router.preloadingLoader[currentPath];
loaderStateEntry.data = resolvedPreloadData;
loaderStateEntry.hasLoadedOnce = true;
} else if (import_router.preloadingLoader[currentPath]) {
var promise = import_router.preloadingLoader[currentPath].then(function (val) {
delete import_router.preloadingLoader[currentPath];
delete import_router.preloadedLoaderData[currentPath];
if (val != null) updateState(currentPath, {
data: val,
hasLoadedOnce: true,
promise: void 0
});else updateState(currentPath, {
promise: void 0
});
}).catch(function (err) {
console.error(`Error running loader()`, err);
delete import_router.preloadingLoader[currentPath];
updateState(currentPath, {
error: err,
promise: void 0
});
});
loaderStateEntry.promise = promise;
} else {
var loadData = async function () {
var startTime = performance.now();
try {
var _dynamicImport;
var nativeLoaderJSUrl;
if (process.env.NODE_ENV === "development") nativeLoaderJSUrl = `${(0, import_cleanUrl.getLoaderPath)(currentPath, true)}?platform=native`;else {
var {
getURL
} = require("./getURL.native.js");
nativeLoaderJSUrl = `${getURL()}/assets/${currentPath.slice(1).replace(/\/$/, "").replaceAll("_", "__").replaceAll("/", "_")}${import_constants.LOADER_JS_POSTFIX_UNCACHED.replace(".js", ".native.js")}`;
}
try {
var moduleLoadStart = performance.now();
var controller = new AbortController();
var timeoutId = setTimeout(function () {
return controller.abort();
}, LOADER_TIMEOUT);
var loaderJsCode;
try {
var loaderJsCodeResp = await fetch(nativeLoaderJSUrl, {
signal: controller.signal
});
if (!loaderJsCodeResp.ok) throw new Error(`Response not ok: ${loaderJsCodeResp.status}`);
loaderJsCode = await loaderJsCodeResp.text();
} finally {
clearTimeout(timeoutId);
}
var result = eval(`() => { var exports = {}; ${loaderJsCode}; return exports; }`)();
var moduleLoadTime = performance.now() - moduleLoadStart;
if (typeof result.loader !== "function") throw new Error("Loader code isn't exporting a `loader` function");
var executionStart = performance.now();
var data = await result.loader();
var executionTime = performance.now() - executionStart;
var totalTime = performance.now() - startTime;
if (data === null || data === void 0 ? void 0 : data.__oneRedirect) {
recordLoaderTiming === null || recordLoaderTiming === void 0 || recordLoaderTiming({
path: currentPath,
startTime,
moduleLoadTime,
executionTime,
totalTime,
source: "initial"
});
updateState(currentPath, {
data: void 0,
hasLoadedOnce: true,
promise: void 0
});
import_imperative_api.router.replace(data.__oneRedirect);
return;
}
if ((data === null || data === void 0 ? void 0 : data.__oneError) === 404) {
recordLoaderTiming === null || recordLoaderTiming === void 0 || recordLoaderTiming({
path: currentPath,
startTime,
moduleLoadTime,
executionTime,
totalTime,
source: "initial"
});
var notFoundRoute = (0, import_notFoundState.findNearestNotFoundRoute)(currentPath, import_router.routeNode);
(0, import_notFoundState.setNotFoundState)({
notFoundPath: data.__oneNotFoundPath || "/+not-found",
notFoundRouteNode: notFoundRoute || void 0,
originalPath: currentPath
});
return;
}
updateState(currentPath, {
data,
hasLoadedOnce: true,
promise: void 0
});
recordLoaderTiming === null || recordLoaderTiming === void 0 || recordLoaderTiming({
path: currentPath,
startTime,
moduleLoadTime,
executionTime,
totalTime,
source: "initial"
});
return;
} catch (e) {
console.error(`[one] native loader error for ${currentPath}:`, _instanceof(e, Error) ? e.message : e, `url: ${nativeLoaderJSUrl}`);
var totalTime = performance.now() - startTime;
updateState(currentPath, {
data: {},
promise: void 0
});
recordLoaderTiming === null || recordLoaderTiming === void 0 || recordLoaderTiming({
path: currentPath,
startTime,
totalTime,
error: _instanceof(e, Error) ? e.message : String(e),
source: "initial"
});
return;
}
var loaderJSUrl = (0, import_cleanUrl.getLoaderPath)(currentPath, true);
var moduleLoadStart = performance.now();
var module = await ((_dynamicImport = (0, import_dynamicImport.dynamicImport)(loaderJSUrl)) === null || _dynamicImport === void 0 ? void 0 : _dynamicImport.catch(function () {
return null;
}));
var moduleLoadTime = performance.now() - moduleLoadStart;
if (!(module === null || module === void 0 ? void 0 : module.loader)) {
updateState(currentPath, {
data: void 0,
hasLoadedOnce: true,
promise: void 0
});
return;
}
var executionStart = performance.now();
var result = await module.loader();
var executionTime = performance.now() - executionStart;
var totalTime = performance.now() - startTime;
if (result === null || result === void 0 ? void 0 : result.__oneRedirect) {
recordLoaderTiming === null || recordLoaderTiming === void 0 || recordLoaderTiming({
path: currentPath,
startTime,
moduleLoadTime,
executionTime,
totalTime,
source: "initial"
});
updateState(currentPath, {
data: void 0,
hasLoadedOnce: true,
promise: void 0
});
import_imperative_api.router.replace(result.__oneRedirect);
return;
}
if ((result === null || result === void 0 ? void 0 : result.__oneError) === 404) {
recordLoaderTiming === null || recordLoaderTiming === void 0 || recordLoaderTiming({
path: currentPath,
startTime,
moduleLoadTime,
executionTime,
totalTime,
source: "initial"
});
var 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: true,
promise: void 0
});
recordLoaderTiming === null || recordLoaderTiming === void 0 || recordLoaderTiming({
path: currentPath,
startTime,
moduleLoadTime,
executionTime,
totalTime,
source: "initial"
});
} catch (err) {
var totalTime = performance.now() - startTime;
updateState(currentPath, {
error: err,
promise: void 0
});
recordLoaderTiming === null || recordLoaderTiming === void 0 || recordLoaderTiming({
path: currentPath,
startTime,
totalTime,
error: _instanceof(err, Error) ? err.message : String(err),
source: "initial"
});
}
};
var promise = loadData();
loaderStateEntry.promise = promise;
}
}
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
};
}
function useLoader(loader2) {
var {
data: data2
} = useLoaderState(loader2);
return data2;
}
var results = /* @__PURE__ */new Map();
var started = /* @__PURE__ */new Map();
function resetLoaderState() {
results.clear();
started.clear();
}
function useAsyncFn(val, props) {
var key = (val ? (0, import_weakKey.weakKey)(val) : "") + JSON.stringify(props);
if (val) {
if (!started.get(key)) {
started.set(key, true);
var next = val(props);
if (_instanceof(next, Promise)) next = next.then(function (final) {
results.set(key, final);
}).catch(function (err) {
console.error(`Error running loader()`, err);
results.set(key, void 0);
});
results.set(key, next);
}
}
var current = results.get(key);
if (_instanceof(current, Promise)) throw current;
return current;
}
//# sourceMappingURL=useLoader.native.js.map