diff --git a/sites/svelte.dev/src/lib/server/blog/index.js b/sites/svelte.dev/src/lib/server/blog/index.js index 23bca26233..40bbf4ef48 100644 --- a/sites/svelte.dev/src/lib/server/blog/index.js +++ b/sites/svelte.dev/src/lib/server/blog/index.js @@ -1,6 +1,5 @@ // @ts-check import { extractFrontmatter } from '@sveltejs/site-kit/markdown'; -import fs from 'node:fs'; import { CONTENT_BASE_PATHS } from '../../../constants.js'; import { render_content } from '../renderer.js'; @@ -23,16 +22,18 @@ export async function get_processed_blog_post(blog_data, slug) { const BLOG_NAME_REGEX = /^(\d{4}-\d{2}-\d{2})-(.+)\.md$/; -/** @returns {import('./types').BlogData} */ -export function get_blog_data(base = CONTENT_BASE_PATHS.BLOG) { +/** @returns {Promise} */ +export async function get_blog_data(base = CONTENT_BASE_PATHS.BLOG) { + const { readdir, readFile } = await import('node:fs/promises'); + /** @type {import('./types').BlogData} */ const blog_posts = []; - for (const file of fs.readdirSync(base).reverse()) { + for (const file of (await readdir(base)).reverse()) { if (!BLOG_NAME_REGEX.test(file)) continue; const { date, date_formatted, slug } = get_date_and_slug(file); - const { metadata, body } = extractFrontmatter(fs.readFileSync(`${base}/${file}`, 'utf-8')); + const { metadata, body } = extractFrontmatter(await readFile(`${base}/${file}`, 'utf-8')); blog_posts.push({ date, diff --git a/sites/svelte.dev/src/lib/server/docs/index.js b/sites/svelte.dev/src/lib/server/docs/index.js index b88c975c19..eef9e4e2a9 100644 --- a/sites/svelte.dev/src/lib/server/docs/index.js +++ b/sites/svelte.dev/src/lib/server/docs/index.js @@ -6,7 +6,6 @@ import { normalizeSlugify, removeMarkdown } from '@sveltejs/site-kit/markdown'; -import fs from 'node:fs'; import { CONTENT_BASE_PATHS } from '../../../constants.js'; import { render_content } from '../renderer'; @@ -29,12 +28,14 @@ export async function get_parsed_docs(docs_data, slug) { return null; } -/** @return {import('./types').DocsData} */ -export function get_docs_data(base = CONTENT_BASE_PATHS.DOCS) { +/** @return {Promise} */ +export async function get_docs_data(base = CONTENT_BASE_PATHS.DOCS) { + const { readdir, readFile } = await import('node:fs/promises'); + /** @type {import('./types').DocsData} */ const docs_data = []; - for (const category_dir of fs.readdirSync(base)) { + for (const category_dir of await readdir(base)) { const match = /\d{2}-(.+)/.exec(category_dir); if (!match) continue; @@ -42,7 +43,7 @@ export function get_docs_data(base = CONTENT_BASE_PATHS.DOCS) { // Read the meta.json const { title: category_title, draft = 'false' } = JSON.parse( - fs.readFileSync(`${base}/${category_dir}/meta.json`, 'utf-8') + await readFile(`${base}/${category_dir}/meta.json`, 'utf-8') ); if (draft === 'true') continue; @@ -54,7 +55,7 @@ export function get_docs_data(base = CONTENT_BASE_PATHS.DOCS) { pages: [] }; - for (const filename of fs.readdirSync(`${base}/${category_dir}`)) { + for (const filename of await readdir(`${base}/${category_dir}`)) { if (filename === 'meta.json') continue; const match = /\d{2}-(.+)/.exec(filename); if (!match) continue; @@ -62,7 +63,7 @@ export function get_docs_data(base = CONTENT_BASE_PATHS.DOCS) { const page_slug = match[1].replace('.md', ''); const page_data = extractFrontmatter( - fs.readFileSync(`${base}/${category_dir}/${filename}`, 'utf-8') + await readFile(`${base}/${category_dir}/${filename}`, 'utf-8') ); if (page_data.metadata.draft === 'true') continue; diff --git a/sites/svelte.dev/src/lib/server/tutorial/index.js b/sites/svelte.dev/src/lib/server/tutorial/index.js index e6e15db443..955a789e65 100644 --- a/sites/svelte.dev/src/lib/server/tutorial/index.js +++ b/sites/svelte.dev/src/lib/server/tutorial/index.js @@ -1,5 +1,4 @@ import { extractFrontmatter } from '@sveltejs/site-kit/markdown'; -import fs from 'node:fs'; import { CONTENT_BASE_PATHS } from '../../../constants.js'; import { render_content } from '../renderer.js'; @@ -23,24 +22,27 @@ export async function get_parsed_tutorial(tutorial_data, slug) { } /** - * @returns {import('./types').TutorialData} + * @returns {Promise} */ -export function get_tutorial_data(base = CONTENT_BASE_PATHS.TUTORIAL) { +export async function get_tutorial_data(base = CONTENT_BASE_PATHS.TUTORIAL) { + const { readdir, readFile, stat } = await import('node:fs/promises'); + const tutorials = []; - for (const subdir of fs.readdirSync(base)) { + for (const subdir of await readdir(base)) { const section = { title: '', // Initialise with empty slug: subdir.split('-').slice(1).join('-'), tutorials: [] }; - if (!(fs.statSync(`${base}/${subdir}`).isDirectory() || subdir.endsWith('meta.json'))) continue; + if (!((await stat(`${base}/${subdir}`)).isDirectory() || subdir.endsWith('meta.json'))) + continue; if (!subdir.endsWith('meta.json')) - section.title = JSON.parse(fs.readFileSync(`${base}/${subdir}/meta.json`, 'utf-8')).title; + section.title = JSON.parse(await readFile(`${base}/${subdir}/meta.json`, 'utf-8')).title; - for (const section_dir of fs.readdirSync(`${base}/${subdir}`)) { + for (const section_dir of await readdir(`${base}/${subdir}`)) { const match = /\d{2}-(.+)/.exec(section_dir); if (!match) continue; @@ -49,22 +51,22 @@ export function get_tutorial_data(base = CONTENT_BASE_PATHS.TUTORIAL) { const tutorial_base_dir = `${base}/${subdir}/${section_dir}`; // Read the file, get frontmatter - const contents = fs.readFileSync(`${tutorial_base_dir}/text.md`, 'utf-8'); + const contents = await readFile(`${tutorial_base_dir}/text.md`, 'utf-8'); const { metadata, body } = extractFrontmatter(contents); // Get the contents of the apps. const completion_states_data = { initial: [], complete: [] }; - for (const app_dir of fs.readdirSync(tutorial_base_dir)) { + for (const app_dir of await readdir(tutorial_base_dir)) { if (!app_dir.startsWith('app-')) continue; const app_dir_path = `${tutorial_base_dir}/${app_dir}`; - const app_contents = fs.readdirSync(app_dir_path, 'utf-8'); + const app_contents = await readdir(app_dir_path, 'utf-8'); for (const file of app_contents) { completion_states_data[app_dir === 'app-a' ? 'initial' : 'complete'].push({ name: file, type: file.split('.').at(-1), - content: fs.readFileSync(`${app_dir_path}/${file}`, 'utf-8') + content: await readFile(`${app_dir_path}/${file}`, 'utf-8') }); } } diff --git a/sites/svelte.dev/src/routes/blog/+page.server.js b/sites/svelte.dev/src/routes/blog/+page.server.js index 7a4bc7eac3..367fc36e70 100644 --- a/sites/svelte.dev/src/routes/blog/+page.server.js +++ b/sites/svelte.dev/src/routes/blog/+page.server.js @@ -4,6 +4,6 @@ export const prerender = true; export async function load() { return { - posts: get_blog_list(get_blog_data()) + posts: get_blog_list(await get_blog_data()) }; } diff --git a/sites/svelte.dev/src/routes/blog/[slug]/+page.server.js b/sites/svelte.dev/src/routes/blog/[slug]/+page.server.js index 012fb27ea5..cf5bbfcf70 100644 --- a/sites/svelte.dev/src/routes/blog/[slug]/+page.server.js +++ b/sites/svelte.dev/src/routes/blog/[slug]/+page.server.js @@ -4,7 +4,7 @@ import { error } from '@sveltejs/kit'; export const prerender = true; export async function load({ params }) { - const post = get_processed_blog_post(get_blog_data(), params.slug); + const post = get_processed_blog_post(await get_blog_data(), params.slug); if (!post) throw error(404); diff --git a/sites/svelte.dev/src/routes/blog/[slug]/card.png/+server.js b/sites/svelte.dev/src/routes/blog/[slug]/card.png/+server.js index fdd971b100..e8456a6fca 100644 --- a/sites/svelte.dev/src/routes/blog/[slug]/card.png/+server.js +++ b/sites/svelte.dev/src/routes/blog/[slug]/card.png/+server.js @@ -11,8 +11,8 @@ const width = 1200; export const prerender = true; -export const GET = async ({ params }) => { - const post = await get_processed_blog_post(get_blog_data(), params.slug); +export async function GET({ params }) { + const post = await get_processed_blog_post(await get_blog_data(), params.slug); if (!post) throw error(404); @@ -48,4 +48,4 @@ export const GET = async ({ params }) => { 'cache-control': 'public, max-age=600' // cache for 10 minutes } }); -}; +} diff --git a/sites/svelte.dev/src/routes/blog/rss.xml/+server.js b/sites/svelte.dev/src/routes/blog/rss.xml/+server.js index 3d279b5286..9cbbdac840 100644 --- a/sites/svelte.dev/src/routes/blog/rss.xml/+server.js +++ b/sites/svelte.dev/src/routes/blog/rss.xml/+server.js @@ -58,7 +58,7 @@ const get_rss = (posts) => .trim(); export async function GET() { - const posts = get_blog_list(get_blog_data()); + const posts = get_blog_list(await get_blog_data()); return new Response(get_rss(posts), { headers: { diff --git a/sites/svelte.dev/src/routes/docs/+layout.server.js b/sites/svelte.dev/src/routes/docs/+layout.server.js index c7bfa54e70..c584e0a8ce 100644 --- a/sites/svelte.dev/src/routes/docs/+layout.server.js +++ b/sites/svelte.dev/src/routes/docs/+layout.server.js @@ -10,6 +10,6 @@ export async function load({ url }) { const { get_docs_data, get_docs_list } = await import('$lib/server/docs/index.js'); return { - sections: get_docs_list(get_docs_data()) + sections: get_docs_list(await get_docs_data()) }; } diff --git a/sites/svelte.dev/src/routes/docs/[slug]/+page.server.js b/sites/svelte.dev/src/routes/docs/[slug]/+page.server.js index 5f808a1ca8..2d06cbb987 100644 --- a/sites/svelte.dev/src/routes/docs/[slug]/+page.server.js +++ b/sites/svelte.dev/src/routes/docs/[slug]/+page.server.js @@ -4,7 +4,7 @@ import { error } from '@sveltejs/kit'; export const prerender = true; export async function load({ params }) { - const processed_page = await get_parsed_docs(get_docs_data(), params.slug); + const processed_page = await get_parsed_docs(await get_docs_data(), params.slug); if (!processed_page) throw error(404); diff --git a/sites/svelte.dev/src/routes/nav.json/+server.js b/sites/svelte.dev/src/routes/nav.json/+server.js index 7709d26439..c943b09799 100644 --- a/sites/svelte.dev/src/routes/nav.json/+server.js +++ b/sites/svelte.dev/src/routes/nav.json/+server.js @@ -14,13 +14,16 @@ export const GET = async () => { * @returns {Promise} */ async function get_nav_list() { - const docs_list = get_docs_list(get_docs_data()); + const [docs_list, blog_list] = await Promise.all([ + get_docs_list(await get_docs_data()), + get_blog_list(await get_blog_data()) + ]); + const processed_docs_list = docs_list.map(({ title, pages }) => ({ title, sections: pages.map(({ title, path }) => ({ title, path })) })); - const blog_list = get_blog_list(get_blog_data()); const processed_blog_list = [ { title: 'Blog', diff --git a/sites/svelte.dev/src/routes/tutorial/[slug]/+page.server.js b/sites/svelte.dev/src/routes/tutorial/[slug]/+page.server.js index 678c11a2ca..59bc318022 100644 --- a/sites/svelte.dev/src/routes/tutorial/[slug]/+page.server.js +++ b/sites/svelte.dev/src/routes/tutorial/[slug]/+page.server.js @@ -10,7 +10,7 @@ export const prerender = true; export async function load({ params }) { if (params.slug === 'local-transitions') throw redirect(307, '/tutorial/global-transitions'); - const tutorial_data = get_tutorial_data(); + const tutorial_data = await get_tutorial_data(); const tutorials_list = get_tutorial_list(tutorial_data); const tutorial = await get_parsed_tutorial(tutorial_data, params.slug); @@ -25,7 +25,7 @@ export async function load({ params }) { } export async function entries() { - const tutorials_list = get_tutorial_list(get_tutorial_data()); + const tutorials_list = get_tutorial_list(await get_tutorial_data()); const slugs = tutorials_list .map(({ tutorials }) => tutorials) .flatMap((val) => val.map(({ slug }) => ({ slug }))); diff --git a/sites/svelte.dev/svelte.config.js b/sites/svelte.dev/svelte.config.js index c0f386a3b7..a30609723d 100644 --- a/sites/svelte.dev/svelte.config.js +++ b/sites/svelte.dev/svelte.config.js @@ -4,7 +4,10 @@ import adapter from '@sveltejs/adapter-vercel'; /** @type {import('@sveltejs/kit').Config} */ export default { kit: { - adapter: adapter({ runtime: 'edge' }) + adapter: adapter({ runtime: 'edge' }), + prerender: { + concurrency: 3 + } }, vitePlugin: {