Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

build: Prerender dynamic routes to provide all entries during SSG #86

Merged
merged 6 commits into from
Nov 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
submodules: true
submodules: "recursive"
lfs: false
- name: Build And Deploy
id: builddeploy
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
submodules: true
submodules: "recursive"
lfs: false
- name: Build And Deploy
id: builddeploy
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/building.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ jobs:
with:
ref: ${{ github.event.pull_request.head.ref }}
fetch-depth: 0
submodules: "recursive"

- uses: actions/setup-node@v4
with:
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ jobs:
with:
ref: ${{ github.event.pull_request.head.ref }}
fetch-depth: 0
submodules: "recursive"

- uses: actions/setup-node@v4
with:
Expand Down
27 changes: 11 additions & 16 deletions src/lib/features/ebd-form-header.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -20,34 +20,28 @@
currentEbd: string,
availableEbds: string[],
): string {
const formattedCurrentEbd = currentEbd.replace(/[_-]/g, "").toLowerCase();
return (
availableEbds.find(
(ebd) => ebd.replace(/[_-]/g, "").toLowerCase() === formattedCurrentEbd,
) || ""
);
if (!currentEbd || !availableEbds.length) return "";
return availableEbds.find((ebd) => ebd === currentEbd) || "";
}

// new format version <select> only causes ebd <select> to reset to placeholder
function handleFormatVersionSelect(event: CustomEvent<string>) {
const newFormatVersion = event.detail;
if (newFormatVersion !== currentFormatVersion) {
currentFormatVersion = newFormatVersion;
currentEbd = "";
currentEbd = ""; // Just reset the EBD selection
}
}

// ebd <select> is required for redirect and URL update
// [...ebd] exists only as a combination of /ebd/<formatversion>/<ebd>/
function handleEbdSelect(event: CustomEvent<string>) {
const newEbd = event.detail;
if (newEbd !== currentEbd) {
currentEbd = newEbd;
updateUrl(currentFormatVersion, newEbd);
}
}

function updateUrl(formatVersion: string, ebd: string) {
const formattedEbd = ebd.replace(/_/g, "");
if (formatVersion && ebd) {
goto(`${base}/ebd/${formatVersion}/${formattedEbd}`);
if (currentFormatVersion && newEbd) {
goto(`${base}/ebd/${currentFormatVersion}/${newEbd}`);
}
}
}
</script>
Expand All @@ -73,12 +67,13 @@
<EbdSelect
ebds={currentEbds}
{selectedEbd}
disabled={!currentFormatVersion}
on:select={handleEbdSelect}
/>
</div>
</div>
<div class="ml-auto">
<ExportButton {currentFormatVersion} {currentEbd} />
<ExportButton {currentFormatVersion} currentEbd={selectedEbd} />
</div>
</nav>
</header>
5 changes: 2 additions & 3 deletions src/lib/features/export-button.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@
if (!isExportReady || !currentFormatVersion || !currentEbd) return;

isExportReady = false;
const ebdFile = `E_${currentEbd.slice(1)}`;
const ebdPath = `${base}/ebd/${currentFormatVersion}/${ebdFile}.svg`;
const ebdPath = `${base}/ebd/${currentFormatVersion}/${currentEbd}.svg`;

try {
const response = await fetch(ebdPath);
Expand All @@ -33,7 +32,7 @@
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = `EBD_E_${currentEbd.slice(1)}_${currentFormatVersion}.svg`;
a.download = `${currentFormatVersion}-${currentEbd}.svg`;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
Expand Down
2 changes: 1 addition & 1 deletion src/routes/+layout.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export const prerender = "auto"; // skips prerendering [dynamic routes].
export const prerender = true; // requires all possible entries of [dynamic routes] to be known at build time (see src/server/prerender-entries.ts)
export const trailingSlash = "always";

export const ssr = true;
Expand Down
3 changes: 1 addition & 2 deletions src/routes/ebd/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@
function handleEbdSelect(event: CustomEvent<string>) {
selectedEbd = event.detail;
if (selectedFormatVersion && selectedEbd) {
const formattedEbd = selectedEbd.replace(/_/g, "");
goto(`${base}/ebd/${selectedFormatVersion}/${formattedEbd}`);
goto(`${base}/ebd/${selectedFormatVersion}/${selectedEbd}`);
}
}
</script>
Expand Down
22 changes: 22 additions & 0 deletions src/routes/ebd/[...ebd]/+page.server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { getFormatVersions } from "../../../server/format-version-loader";
import { prerenderEntries } from "../../../server/prerender-entries";
import type { PageServerLoad } from "./$types";

export function entries() {
const routes = prerenderEntries();
return routes.map((route) => ({
ebd: route.ebd,
}));
}

export const load: PageServerLoad = async ({ params }) => {
const [formatVersion, ebdFile] = params.ebd.split("/");
const availableVersions = getFormatVersions();
const version = availableVersions.find((v) => v.code === formatVersion);

return {
formatVersion: version,
ebdFile,
svgPath: `/ebd/${formatVersion}/${ebdFile}.svg`,
};
};
3 changes: 1 addition & 2 deletions src/routes/ebd/[...ebd]/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@

isLoading = true;
error = null;
const ebdFile = `E_${ebdKey.slice(1)}`;
const ebdPath = `${base}/ebd/${formatVersion}/${ebdFile}.svg`;
const ebdPath = `${base}/ebd/${formatVersion}/${ebdKey}.svg`;

try {
const response = await fetch(ebdPath);
Expand Down
38 changes: 11 additions & 27 deletions src/server/ebd-loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,48 +6,32 @@ const skippedFormatVersionToInsteadFormatVersionMap: Record<string, string> = {
FV2410: "FV2404",
};

function tryReadDir(path: string) {
try {
return readdirSync(path);
} catch {
return null;
}
}

// fetch submodule data from either /static/ebd (sveltekit "dev server") or /build/ebd (sveltekit "preview")
export function getEbds(): Record<string, string[]> {
const staticPath = join(process.cwd(), "static", "ebd");
const buildPath = join(process.cwd(), "build", "ebd");
const ebds: Record<string, string[]> = {};

const basePath = tryReadDir(staticPath) ? staticPath : buildPath;
const formatVersions = tryReadDir(basePath);

if (!formatVersions) {
console.error("submodule data not found.");
return {};
}

try {
const formatVersions = readdirSync(staticPath, { withFileTypes: true })
.filter((dirent) => dirent.isDirectory() && dirent.name.startsWith("FV"))
.map((dirent) => dirent.name);

for (const formatVersion of formatVersions) {
if (skippedFormatVersionToInsteadFormatVersionMap[formatVersion]) {
continue;
}

const versionPath = join(basePath, formatVersion);
const files = tryReadDir(versionPath);
const versionPath = join(staticPath, formatVersion);
const files = readdirSync(versionPath);

if (files) {
ebds[formatVersion] = files
.filter((file) => file.endsWith(".svg"))
.map((file) => file.replace(".svg", ""))
.sort((a, b) => a.localeCompare(b));
}
ebds[formatVersion] = files
.filter((file) => file.endsWith(".svg"))
.map((file) => file.replace(".svg", ""))
.sort((a, b) => a.localeCompare(b));
}

return ebds;
} catch (error) {
console.error("Error loading EBDs", error);
console.error("error reading EBDs from submodule:", error);
return {};
}
}
56 changes: 23 additions & 33 deletions src/server/format-version-loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,43 +39,33 @@ function formatVersion(version: string): FormatVersion {
};
}

function tryReadDir(path: string) {
try {
return readdirSync(path, { withFileTypes: true });
} catch {
return null;
}
}

// fetch submodule data from either /static/ebd (sveltekit "dev server") or /build/ebd (sveltekit "preview")
export function getFormatVersions(): FormatVersion[] {
const staticPath = join(process.cwd(), "static", "ebd");
const buildPath = join(process.cwd(), "build", "ebd");

const dirents = tryReadDir(staticPath) || tryReadDir(buildPath);
try {
const dirents = readdirSync(staticPath, { withFileTypes: true });
const uniqueFormatVersion = new Set<string>();

if (!dirents) {
console.error("submodule data not found.");
return dirents
.filter((dirent) => dirent.isDirectory())
.map((dirent) => formatVersion(dirent.name))
.filter((version) => {
if (
Object.keys(skippedFormatVersionToInsteadFormatVersionMap).includes(
version.code,
)
) {
return false;
}
if (uniqueFormatVersion.has(version.code)) {
return false;
}
uniqueFormatVersion.add(version.code);
return true;
})
.sort((a, b) => b.code.localeCompare(a.code));
} catch (error) {
console.error("error reading format versions from submodule:", error);
return [];
}

const uniqueFormatVersion = new Set<string>();
return dirents
.filter((dirent) => dirent.isDirectory())
.map((dirent) => formatVersion(dirent.name))
.filter((version) => {
if (
Object.keys(skippedFormatVersionToInsteadFormatVersionMap).includes(
version.code,
)
) {
return false;
}
if (uniqueFormatVersion.has(version.code)) {
return false;
}
uniqueFormatVersion.add(version.code);
return true;
})
.sort((a, b) => b.code.localeCompare(a.code));
}
40 changes: 40 additions & 0 deletions src/server/prerender-entries.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { readdirSync } from "fs";
import { join } from "path";

import { getEbds } from "./ebd-loader";
import { getFormatVersions } from "./format-version-loader";

export function prerenderEntries() {
const staticPath = join(process.cwd(), "static", "ebd");
const buildPath = join(process.cwd(), "build", "ebd");
const basePath = readdirSync(staticPath) ? staticPath : buildPath;

const formatVersions = getFormatVersions();
const ebds = getEbds();

const entries = [];
const formatVersionCounts: Record<string, number> = {};

for (const formatVersion of formatVersions) {
const ebdList = ebds[formatVersion.code] || [];
formatVersionCounts[formatVersion.code] = ebdList.length;

for (const ebd of ebdList) {
entries.push({
ebd: `${formatVersion.code}/${ebd}`,
filePath: join(basePath, formatVersion.code, `${ebd}.svg`),
});
}
}

// logging summary for local development ($ npm run build)
console.log("\nEBD Prerender Summary:");
console.log(`Base path: ${basePath}`);
console.log(`Total routes: ${entries.length}`);
Object.entries(formatVersionCounts)
.sort(([a], [b]) => b.localeCompare(a))
.forEach(([fv, count]) => console.log(`${fv}: ${count} routes`));
console.log("");

return entries;
}
Loading