mirror of
https://github.com/getpaseo/paseo.git
synced 2026-07-29 12:01:31 +00:00
perf(website): avoid blocking root render on GitHub
This commit is contained in:
@@ -49,16 +49,20 @@ interface ReleaseInfo {
|
|||||||
windowsArm64Asset: string | null;
|
windowsArm64Asset: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fallbackVersion = websitePackage.version.replace(/-.*$/, "");
|
||||||
|
const fallbackRelease: ReleaseInfo = {
|
||||||
|
version: fallbackVersion,
|
||||||
|
windowsX64Asset: `Paseo-Setup-${fallbackVersion}.exe`,
|
||||||
|
windowsArm64Asset: null,
|
||||||
|
};
|
||||||
const GITHUB_RELEASES_URL = "https://api.github.com/repos/getpaseo/paseo/releases?per_page=10";
|
const GITHUB_RELEASES_URL = "https://api.github.com/repos/getpaseo/paseo/releases?per_page=10";
|
||||||
|
const RELEASE_REFRESH_MS = 60_000;
|
||||||
|
|
||||||
|
let cachedRelease = fallbackRelease;
|
||||||
|
let cachedReleaseAt = 0;
|
||||||
|
let refreshReleasePromise: Promise<void> | null = null;
|
||||||
|
|
||||||
async function fetchLatestReadyRelease(): Promise<ReleaseInfo> {
|
async function fetchLatestReadyRelease(): Promise<ReleaseInfo> {
|
||||||
const fallbackVersion = websitePackage.version.replace(/-.*$/, "");
|
|
||||||
const fallback: ReleaseInfo = {
|
|
||||||
version: fallbackVersion,
|
|
||||||
windowsX64Asset: `Paseo-Setup-${fallbackVersion}.exe`,
|
|
||||||
windowsArm64Asset: null,
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await fetch(GITHUB_RELEASES_URL, {
|
const res = await fetch(GITHUB_RELEASES_URL, {
|
||||||
headers: {
|
headers: {
|
||||||
@@ -74,11 +78,11 @@ async function fetchLatestReadyRelease(): Promise<ReleaseInfo> {
|
|||||||
cacheKey: "github-releases-latest",
|
cacheKey: "github-releases-latest",
|
||||||
},
|
},
|
||||||
} as RequestInit);
|
} as RequestInit);
|
||||||
if (!res.ok) return fallback;
|
if (!res.ok) return fallbackRelease;
|
||||||
|
|
||||||
const releases = (await res.json()) as GitHubRelease[];
|
const releases = (await res.json()) as GitHubRelease[];
|
||||||
const ready = releases.find((r) => !r.prerelease && !r.draft && hasRequiredAssets(r));
|
const ready = releases.find((r) => !r.prerelease && !r.draft && hasRequiredAssets(r));
|
||||||
if (!ready) return fallback;
|
if (!ready) return fallbackRelease;
|
||||||
const win = pickWindowsAssets(ready.assets);
|
const win = pickWindowsAssets(ready.assets);
|
||||||
return {
|
return {
|
||||||
version: versionFromTag(ready.tag_name),
|
version: versionFromTag(ready.tag_name),
|
||||||
@@ -86,10 +90,28 @@ async function fetchLatestReadyRelease(): Promise<ReleaseInfo> {
|
|||||||
windowsArm64Asset: win.arm64,
|
windowsArm64Asset: win.arm64,
|
||||||
};
|
};
|
||||||
} catch {
|
} catch {
|
||||||
return fallback;
|
return fallbackRelease;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function refreshLatestRelease(): Promise<void> {
|
||||||
|
refreshReleasePromise ??= fetchLatestReadyRelease()
|
||||||
|
.then((release) => {
|
||||||
|
cachedRelease = release;
|
||||||
|
cachedReleaseAt = Date.now();
|
||||||
|
return undefined;
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
refreshReleasePromise = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
return refreshReleasePromise;
|
||||||
|
}
|
||||||
|
|
||||||
export const getLatestRelease = createServerFn({ method: "GET" }).handler(async () => {
|
export const getLatestRelease = createServerFn({ method: "GET" }).handler(async () => {
|
||||||
return fetchLatestReadyRelease();
|
if (Date.now() - cachedReleaseAt > RELEASE_REFRESH_MS) {
|
||||||
|
void refreshLatestRelease();
|
||||||
|
}
|
||||||
|
|
||||||
|
return cachedRelease;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -11,6 +11,11 @@ function formatStars(count: number): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const GITHUB_REPO_URL = "https://api.github.com/repos/getpaseo/paseo";
|
const GITHUB_REPO_URL = "https://api.github.com/repos/getpaseo/paseo";
|
||||||
|
const STAR_REFRESH_MS = 60_000;
|
||||||
|
|
||||||
|
let cachedStars = "";
|
||||||
|
let cachedStarsAt = 0;
|
||||||
|
let refreshStarsPromise: Promise<void> | null = null;
|
||||||
|
|
||||||
async function fetchStarCount(): Promise<string> {
|
async function fetchStarCount(): Promise<string> {
|
||||||
try {
|
try {
|
||||||
@@ -34,7 +39,26 @@ async function fetchStarCount(): Promise<string> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function refreshStarCount(): Promise<void> {
|
||||||
|
refreshStarsPromise ??= fetchStarCount()
|
||||||
|
.then((stars) => {
|
||||||
|
if (stars) {
|
||||||
|
cachedStars = stars;
|
||||||
|
cachedStarsAt = Date.now();
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
refreshStarsPromise = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
return refreshStarsPromise;
|
||||||
|
}
|
||||||
|
|
||||||
export const getStarCount = createServerFn({ method: "GET" }).handler(async () => {
|
export const getStarCount = createServerFn({ method: "GET" }).handler(async () => {
|
||||||
const stars = await fetchStarCount();
|
if (Date.now() - cachedStarsAt > STAR_REFRESH_MS) {
|
||||||
return { stars };
|
void refreshStarCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
return { stars: cachedStars };
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user