Keep bunext sitemap alive while sitemap exports query the DB

Bun's SQL client (mariadb/mysql adapters, Bun 1.3.14) doesn't keep the
event loop alive for a query on an idle connection, so a second dynamic
route's sitemap export querying the DB made the command exit silently.
Hold the loop open with a timer during generation, and log what a stuck
run is waiting on.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
2026-10-15 09:00:40 +01:00
co-authored by Claude Opus 5.5
parent 23a309005a
commit 40c17f903e
7 changed files with 153 additions and 37 deletions
+29
View File
@@ -217,6 +217,35 @@ describe("bunext sitemap", () => {
);
});
it("waits for sitemap exports that don't keep the event loop alive", async () => {
// Like Bun's SQL client querying on an idle connection: the
// promise settles, but nothing holds the process open meanwhile.
const unrefServerFile = (paths: string[]) =>
`export const sitemap = () => new Promise((resolve) => {
setTimeout(() => resolve(${JSON.stringify(paths)}), 50).unref();
});`;
writeConfig(`{ origin: "https://example.com" }`);
writeProjectFile(
"src/pages/blog/[slug].server.ts",
unrefServerFile(["/blog/a"]),
);
writeProjectFile(
"src/pages/docs/[slug].tsx",
"export default () => null",
);
writeProjectFile(
"src/pages/docs/[slug].server.ts",
unrefServerFile(["/docs/a"]),
);
const res = await runSitemap();
expect(res.exit_code).toBe(0);
expect(locs(readOutput())).toContain("https://example.com/blog/a");
expect(locs(readOutput())).toContain("https://example.com/docs/a");
});
it("exits with code 1 when config additional_paths throws", async () => {
writeConfig(`{
sitemap: {