From 346fdb3b756faa5ef1333488a1564026fef1232f Mon Sep 17 00:00:00 2001 From: Christoph Urlacher Date: Mon, 3 Feb 2025 22:34:07 +0100 Subject: [PATCH] Skeleton: Fetch static data (teams/drivers/races/substitutions) in global layout asynchronously --- src/routes/+layout.server.ts | 83 +++++- src/routes/data/raceresults/+page.server.ts | 44 --- src/routes/data/raceresults/+page.svelte | 32 +- src/routes/data/season/+layout.server.ts | 83 ------ src/routes/data/season/drivers/+page.svelte | 11 +- src/routes/data/season/races/+page.svelte | 5 +- .../data/season/substitutions/+page.svelte | 8 +- src/routes/data/season/teams/+page.svelte | 16 +- src/routes/data/users/+page.server.ts | 14 - src/routes/data/users/+page.svelte | 2 +- src/routes/racepicks/+page.server.ts | 46 +-- src/routes/racepicks/+page.svelte | 278 +++++++++--------- 12 files changed, 259 insertions(+), 363 deletions(-) delete mode 100644 src/routes/data/season/+layout.server.ts diff --git a/src/routes/+layout.server.ts b/src/routes/+layout.server.ts index d2f4377..ac0c404 100644 --- a/src/routes/+layout.server.ts +++ b/src/routes/+layout.server.ts @@ -1,3 +1,4 @@ +import type { Driver, Graphic, Race, Substitution, Team } from "$lib/schema"; import type { LayoutServerLoad } from "./$types"; // On each page load (every route), this function runs serverside. @@ -6,14 +7,82 @@ import type { LayoutServerLoad } from "./$types"; // It will populate the "user" attribute of each page's "data" object, // so each page has access to the current user (or knows if no one is signed in). export const load: LayoutServerLoad = ({ locals }) => { - if (locals.user) { - return { - user: locals.user, - admin: locals.user.admin, - }; - } + const fetch_graphics = async (): Promise => { + const graphics: Graphic[] = await locals.pb + .collection("graphics") + .getFullList({ fetch: fetch }); + + graphics.map((graphic: Graphic) => { + graphic.file_url = locals.pb.files.getURL(graphic, graphic.file); + }); + + return graphics; + }; + + const fetch_teams = async (): Promise => { + const teams: Team[] = await locals.pb.collection("teams").getFullList({ + sort: "+name", + fetch: fetch, + }); + + teams.map((team: Team) => { + team.banner_url = locals.pb.files.getURL(team, team.banner); + team.logo_url = locals.pb.files.getURL(team, team.logo); + }); + + return teams; + }; + + const fetch_drivers = async (): Promise => { + const drivers: Driver[] = await locals.pb.collection("drivers").getFullList({ + sort: "+code", + fetch: fetch, + }); + + drivers.map((driver: Driver) => { + driver.headshot_url = locals.pb.files.getURL(driver, driver.headshot); + }); + + return drivers; + }; + + const fetch_races = async (): Promise => { + const races: Race[] = await locals.pb.collection("races").getFullList({ + sort: "+step", + fetch: fetch, + }); + + races.map((race: Race) => { + race.pictogram_url = locals.pb.files.getURL(race, race.pictogram); + }); + + return races; + }; + + const fetch_substitutions = async (): Promise => { + const substitutions: Substitution[] = await locals.pb.collection("substitutions").getFullList({ + expand: "race", + fetch: fetch, + }); + + // Sort by race step (ascending) + substitutions.sort( + (a: Substitution, b: Substitution) => a.expand.race.step - b.expand.race.step, + ); + + return substitutions; + }; return { - user: undefined, + // User information + user: locals.user, + admin: locals.user?.admin ?? false, + + // Return static data asynchronously + graphics: fetch_graphics(), + teams: fetch_teams(), + drivers: fetch_drivers(), + races: fetch_races(), + substitutions: fetch_substitutions(), }; }; diff --git a/src/routes/data/raceresults/+page.server.ts b/src/routes/data/raceresults/+page.server.ts index ff24fae..a929134 100644 --- a/src/routes/data/raceresults/+page.server.ts +++ b/src/routes/data/raceresults/+page.server.ts @@ -49,51 +49,7 @@ export const load: PageServerLoad = async ({ fetch, locals }) => { return raceresults; }; - // TODO: Duplicated code from data/season/+layout.server.ts and racepicks/+page.server.ts - const fetch_races = async (): Promise => { - const races: Race[] = await locals.pb.collection("races").getFullList({ - sort: "+step", - fetch: fetch, - }); - - races.map((race: Race) => { - race.pictogram_url = locals.pb.files.getURL(race, race.pictogram); - }); - - return races; - }; - - // TODO: Duplicated code from data/season/+layout.server.ts and racepicks/+page.server.ts - const fetch_drivers = async (): Promise => { - const drivers: Driver[] = await locals.pb.collection("drivers").getFullList({ - sort: "+code", - fetch: fetch, - }); - - drivers.map((driver: Driver) => { - driver.headshot_url = locals.pb.files.getURL(driver, driver.headshot); - }); - - return drivers; - }; - - // TODO: Duplicated code from racepicks/+page.server.ts + users/+page.server.ts - const fetch_graphics = async (): Promise => { - const graphics: Graphic[] = await locals.pb - .collection("graphics") - .getFullList({ fetch: fetch }); - - graphics.map((graphic: Graphic) => { - graphic.file_url = locals.pb.files.getURL(graphic, graphic.file); - }); - - return graphics; - }; - return { results: await fetch_raceresults(), - races: await fetch_races(), - drivers: await fetch_drivers(), - graphics: await fetch_graphics(), }; }; diff --git a/src/routes/data/raceresults/+page.svelte b/src/routes/data/raceresults/+page.svelte index 65ce809..9af05f5 100644 --- a/src/routes/data/raceresults/+page.svelte +++ b/src/routes/data/raceresults/+page.svelte @@ -12,28 +12,30 @@ data_value_name: "race", label: "Step", valuefun: async (value: string): Promise => - `${get_by_value(data.races, "id", value)?.step}`, + `${get_by_value(await data.races, "id", value)?.step}`, }, { data_value_name: "race", label: "Race", valuefun: async (value: string): Promise => - `${get_by_value(data.races, "id", value)?.name}`, + `${get_by_value(await data.races, "id", value)?.name}`, }, { data_value_name: "race", label: "Guessed", valuefun: async (value: string): Promise => - `P${get_by_value(data.races, "id", value)?.pxx}`, + `P${get_by_value(await data.races, "id", value)?.pxx}`, }, { data_value_name: "pxxs", label: "Standing", valuefun: async (value: string): Promise => { const pxxs_array: string[] = value.toString().split(","); - const pxxs_codes: string[] = pxxs_array.map( - (id: string, index: number) => - `${get_by_value(data.drivers, "id", id)?.code ?? "Invalid"}`, + const pxxs_codes: string[] = await Promise.all( + pxxs_array.map( + async (id: string, index: number) => + `${get_by_value(await data.drivers, "id", id)?.code ?? "Invalid"}`, + ), ); return pxxs_codes.join(""); @@ -46,9 +48,11 @@ if (value.length === 0 || value === "") return ""; const dnfs_array: string[] = value.toString().split(","); - const dnfs_codes: string[] = dnfs_array.map( - (id: string) => - `${get_by_value(data.drivers, "id", id)?.code ?? "Invalid"}`, + const dnfs_codes: string[] = await Promise.all( + dnfs_array.map( + async (id: string) => + `${get_by_value(await data.drivers, "id", id)?.code ?? "Invalid"}`, + ), ); return dnfs_codes.join(""); @@ -64,8 +68,8 @@ component: "raceResultCard", meta: { disable_inputs: !data.admin, - drivers: data.drivers, - races: data.races, + drivers: await data.drivers, + races: await data.races, result: get_by_value(data.results, "id", id), }, }; @@ -73,14 +77,14 @@ modalStore.trigger(modalSettings); }; - const create_result_handler = (event: Event) => { + const create_result_handler = async (event: Event) => { const modalSettings: ModalSettings = { type: "component", component: "raceResultCard", meta: { disable_inputs: !data.admin, - drivers: data.drivers, - races: data.races, + drivers: await data.drivers, + races: await data.races, require_inputs: true, }, }; diff --git a/src/routes/data/season/+layout.server.ts b/src/routes/data/season/+layout.server.ts deleted file mode 100644 index de93acd..0000000 --- a/src/routes/data/season/+layout.server.ts +++ /dev/null @@ -1,83 +0,0 @@ -import type { Team, Driver, Race, Substitution, Graphic } from "$lib/schema"; -import type { LayoutServerLoad } from "./$types"; - -// This "load" function runs serverside only, as it's located inside +layout.server.ts -export const load: LayoutServerLoad = async ({ fetch, locals }) => { - // TODO: Duplicated code from racepicks/+page.server.ts + users/+page.server.ts - const fetch_graphics = async (): Promise => { - const graphics: Graphic[] = await locals.pb - .collection("graphics") - .getFullList({ fetch: fetch }); - - graphics.map((graphic: Graphic) => { - graphic.file_url = locals.pb.files.getURL(graphic, graphic.file); - }); - - return graphics; - }; - - const fetch_teams = async (): Promise => { - const teams: Team[] = await locals.pb.collection("teams").getFullList({ - sort: "+name", - fetch: fetch, - }); - - teams.map((team: Team) => { - team.banner_url = locals.pb.files.getURL(team, team.banner); - team.logo_url = locals.pb.files.getURL(team, team.logo); - }); - - return teams; - }; - - // TODO: Duplicated code from racepicks/+page.server.ts and data/raceresults/+page.server.ts - const fetch_drivers = async (): Promise => { - const drivers: Driver[] = await locals.pb.collection("drivers").getFullList({ - sort: "+code", - fetch: fetch, - }); - - drivers.map((driver: Driver) => { - driver.headshot_url = locals.pb.files.getURL(driver, driver.headshot); - }); - - return drivers; - }; - - // TODO: Duplicated code from racepicks/+page.server.ts and data/raceresults/+page.server.ts - const fetch_races = async (): Promise => { - const races: Race[] = await locals.pb.collection("races").getFullList({ - sort: "+step", - fetch: fetch, - }); - - races.map((race: Race) => { - race.pictogram_url = locals.pb.files.getURL(race, race.pictogram); - }); - - return races; - }; - - const fetch_substitutions = async (): Promise => { - const substitutions: Substitution[] = await locals.pb.collection("substitutions").getFullList({ - expand: "race", - fetch: fetch, - }); - - // Sort by race step (ascending) - substitutions.sort((a, b) => a.expand.race.step - b.expand.race.step); - - return substitutions; - }; - - return { - // Graphics and teams are awaited, since those are visible on page load. - graphics: await fetch_graphics(), - teams: await fetch_teams(), - - // The rest is streamed gradually, since the user has to switch pages to need them. - drivers: fetch_drivers(), - races: fetch_races(), - substitutions: fetch_substitutions(), - }; -}; diff --git a/src/routes/data/season/drivers/+page.svelte b/src/routes/data/season/drivers/+page.svelte index 940cc41..6fbd6a5 100644 --- a/src/routes/data/season/drivers/+page.svelte +++ b/src/routes/data/season/drivers/+page.svelte @@ -1,6 +1,6 @@