This repository has been archived by the owner on Aug 3, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 153
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use server routes to supply client data
Re-building and re-deploying the site every thirty minutes just to update data is very expensive and hurts user experience by constantly blowing out the client's cache without meaningful changes to the bundle. Even ignoring that, hardcoding changing data, even though it would be rebuilt eventually is considered a very bad practice. Overall, this all feels like a terrible hack. This commit should address this issue by removing client data generation logic and instead creating the supply logic using Nitro server cached routes that will refresh on the server every thirty minutes unless there's a re-deploy due to actual changes.
- Loading branch information
Showing
9 changed files
with
166 additions
and
156 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
const homepageRefreshInterval = 60 * 10 // 10 minutes | ||
|
||
export async function useHomepageProjects() { | ||
const state = useNuxtApp().$homepageState | ||
const projects = state.projects | ||
const lastFetchedAt = state.lastFetchedAt.value | ||
const now = Date.now() / 1000 | ||
if (now - lastFetchedAt >= homepageRefreshInterval) { | ||
await projects.refresh() | ||
state.lastFetchedAt.value = now | ||
} | ||
return projects.data | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
export function useTags() { | ||
return useFetch('/api/tags', { | ||
transform(data) { | ||
return { | ||
...data, | ||
projectTypes: [ | ||
{ | ||
actual: 'mod', | ||
id: 'mod', | ||
display: 'mod', | ||
}, | ||
{ | ||
actual: 'mod', | ||
id: 'plugin', | ||
display: 'plugin', | ||
}, | ||
{ | ||
actual: 'mod', | ||
id: 'datapack', | ||
display: 'data pack', | ||
}, | ||
{ | ||
actual: 'shader', | ||
id: 'shader', | ||
display: 'shader', | ||
}, | ||
{ | ||
actual: 'resourcepack', | ||
id: 'resourcepack', | ||
display: 'resource pack', | ||
}, | ||
{ | ||
actual: 'modpack', | ||
id: 'modpack', | ||
display: 'modpack', | ||
}, | ||
], | ||
loaderData: { | ||
pluginLoaders: ['bukkit', 'spigot', 'paper', 'purpur', 'sponge', 'folia'], | ||
pluginPlatformLoaders: ['bungeecord', 'waterfall', 'velocity'], | ||
allPluginLoaders: [ | ||
'bukkit', | ||
'spigot', | ||
'paper', | ||
'purpur', | ||
'sponge', | ||
'bungeecord', | ||
'waterfall', | ||
'velocity', | ||
'folia', | ||
], | ||
dataPackLoaders: ['datapack'], | ||
modLoaders: ['forge', 'fabric', 'quilt', 'liteloader', 'modloader', 'rift'], | ||
}, | ||
projectViewModes: ['list', 'grid', 'gallery'], | ||
approvedStatuses: ['approved', 'archived', 'unlisted', 'private'], | ||
rejectedStatuses: ['rejected', 'withheld'], | ||
staffRoles: ['moderator', 'admin'], | ||
} | ||
}, | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -102,74 +102,6 @@ export default defineNuxtConfig({ | |
], | ||
}, | ||
hooks: { | ||
async 'build:before'() { | ||
// 30 minutes | ||
const TTL = 30 * 60 * 1000 | ||
|
||
let state: { | ||
lastGenerated?: string | ||
apiUrl?: string | ||
categories?: any[] | ||
loaders?: any[] | ||
gameVersions?: any[] | ||
donationPlatforms?: any[] | ||
reportTypes?: any[] | ||
} = {} | ||
let homePageProjects: any[] = [] | ||
|
||
try { | ||
state = JSON.parse(await fs.readFile('./generated/state.json', 'utf8')) | ||
homePageProjects = JSON.parse(await fs.readFile('./generated/homepage.json', 'utf8')) | ||
} catch { | ||
// File doesn't exist, create folder | ||
await fs.mkdir('./generated', { recursive: true }) | ||
} | ||
|
||
const API_URL = getApiUrl() | ||
|
||
if ( | ||
// Skip regeneration if within TTL... | ||
state.lastGenerated && | ||
new Date(state.lastGenerated).getTime() + TTL > new Date().getTime() && | ||
// ...but only if the API URL is the same | ||
state.apiUrl === API_URL && | ||
homePageProjects.length !== 0 | ||
) { | ||
return | ||
} | ||
|
||
state.lastGenerated = new Date().toISOString() | ||
|
||
state.apiUrl = API_URL | ||
|
||
const headers = { | ||
headers: { | ||
'user-agent': 'Knossos generator ([email protected])', | ||
}, | ||
} | ||
|
||
const [categories, loaders, gameVersions, donationPlatforms, reportTypes, projects] = | ||
await Promise.all([ | ||
$fetch(`${API_URL}tag/category`, headers), | ||
$fetch(`${API_URL}tag/loader`, headers), | ||
$fetch(`${API_URL}tag/game_version`, headers), | ||
$fetch(`${API_URL}tag/donation_platform`, headers), | ||
$fetch(`${API_URL}tag/report_type`, headers), | ||
$fetch(`${API_URL}projects_random?count=40`, headers), | ||
]) | ||
|
||
state.categories = categories | ||
state.loaders = loaders | ||
state.gameVersions = gameVersions | ||
state.donationPlatforms = donationPlatforms | ||
state.reportTypes = reportTypes | ||
homePageProjects = projects | ||
|
||
await fs.writeFile('./generated/state.json', JSON.stringify(state)) | ||
await fs.writeFile('./generated/homepage.json', JSON.stringify(homePageProjects)) | ||
|
||
console.log('Tags generated!') | ||
}, | ||
'pages:extend'(routes) { | ||
routes.splice( | ||
routes.findIndex((x) => x.name === 'search-searchProjectType'), | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,17 @@ | ||
export default defineNuxtPlugin(async (nuxtApp) => { | ||
export default defineNuxtPlugin(async () => { | ||
const authStore = await useAuth() | ||
await useUser() | ||
const cosmeticsStore = useCosmetics() | ||
const tagsStore = useTags() | ||
const tagsStore = await useTags() | ||
|
||
nuxtApp.provide('auth', authStore.value) | ||
nuxtApp.provide('cosmetics', cosmeticsStore.value) | ||
nuxtApp.provide('tag', tagsStore.value) | ||
nuxtApp.provide('notify', (notif) => addNotification(notif)) | ||
return { | ||
provide: { | ||
auth: authStore.value, | ||
cosmetics: cosmeticsStore.value, | ||
tag: tagsStore.data.value, | ||
notify(value) { | ||
addNotification(value) | ||
}, | ||
}, | ||
} | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
// Provider for the `useHomepageProjects` composable. | ||
export default defineNuxtPlugin(() => ({ | ||
provide: { | ||
homepageState: { | ||
projects: useFetch('/api/homepage'), | ||
lastFetchedAt: useState('homepageLastFetchedAt', () => Date.now() / 1000), | ||
}, | ||
}, | ||
})) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
export default defineCachedEventHandler( | ||
() => { | ||
const { apiBaseUrl } = useRuntimeConfig() | ||
|
||
return $fetch(`/projects_random?count=40`, { | ||
baseURL: apiBaseUrl, | ||
headers: { | ||
'user-agent': 'Nuxt Knossos ([email protected])', | ||
}, | ||
}) | ||
}, | ||
{ | ||
maxAge: 30 * 60, | ||
name: 'homepage', | ||
} | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
export default defineCachedEventHandler( | ||
async () => { | ||
const { apiBaseUrl } = useRuntimeConfig() | ||
|
||
const opts = { | ||
baseURL: apiBaseUrl, | ||
headers: { | ||
'user-agent': 'Nuxt Knossos ([email protected])', | ||
}, | ||
} | ||
|
||
const [categories, loaders, gameVersions, donationPlatforms, reportTypes] = await Promise.all([ | ||
$fetch(`tag/category`, opts), | ||
$fetch(`tag/loader`, opts), | ||
$fetch(`tag/game_version`, opts), | ||
$fetch(`tag/donation_platform`, opts), | ||
$fetch(`tag/report_type`, opts), | ||
]) | ||
|
||
return { | ||
categories, | ||
loaders, | ||
gameVersions, | ||
donationPlatforms, | ||
reportTypes, | ||
} | ||
}, | ||
{ | ||
// 30 min in seconds | ||
maxAge: 30 * 60, | ||
name: 'tags', | ||
} | ||
) |