diff --git a/documentation/docs/02-template-syntax/05-element-directives.md b/documentation/docs/02-template-syntax/05-element-directives.md index 9fa3196094..9df73c8c07 100644 --- a/documentation/docs/02-template-syntax/05-element-directives.md +++ b/documentation/docs/02-template-syntax/05-element-directives.md @@ -521,7 +521,7 @@ Transitions are local by default (in Svelte 3, they were global by default). Loc {/if} ``` -> By default intro transitions will not play on first render. You can modify this behaviour by setting `intro: true` when you [create a component](/docs#run-time-client-side-component-api) and marking the transition as `global`. +> By default intro transitions will not play on first render. You can modify this behaviour by setting `intro: true` when you [create a component](/docs/client-side-component-api) and marking the transition as `global`. ## Transition parameters diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e641f90334..734a548d88 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -158,7 +158,7 @@ importers: version: 2.26.0 '@sveltejs/repl': specifier: 0.5.0-next.11 - version: 0.5.0-next.11(@codemirror/lang-html@6.4.5)(@codemirror/search@6.5.0)(@lezer/common@1.0.3)(@lezer/javascript@1.4.3)(@lezer/lr@1.3.7)(@sveltejs/kit@1.21.0)(svelte@packages+svelte) + version: 0.5.0-next.11(@codemirror/lang-html@6.4.5)(@codemirror/search@6.5.0)(@lezer/common@1.0.3)(@lezer/javascript@1.4.3)(@lezer/lr@1.3.7)(@sveltejs/kit@1.22.0)(svelte@packages+svelte) cookie: specifier: ^0.5.0 version: 0.5.0 @@ -180,22 +180,25 @@ importers: version: 2.4.1 '@sveltejs/adapter-vercel': specifier: ^3.0.1 - version: 3.0.1(@sveltejs/kit@1.21.0) + version: 3.0.1(@sveltejs/kit@1.22.0) '@sveltejs/kit': - specifier: ^1.21.0 - version: 1.21.0(svelte@packages+svelte)(vite@4.3.9) + specifier: ^1.22.0 + version: 1.22.0(svelte@packages+svelte)(vite@4.3.9) '@sveltejs/site-kit': specifier: 6.0.0-next.20 - version: 6.0.0-next.20(@sveltejs/kit@1.21.0)(svelte@packages+svelte) + version: 6.0.0-next.20(@sveltejs/kit@1.22.0)(svelte@packages+svelte) '@sveltejs/vite-plugin-svelte': specifier: ^2.4.2 version: 2.4.2(svelte@packages+svelte)(vite@4.3.9) + '@types/cookie': + specifier: ^0.5.1 + version: 0.5.1 '@types/marked': specifier: ^5.0.0 version: 5.0.0 '@types/node': - specifier: ^20.3.2 - version: 20.3.2 + specifier: ^20.3.3 + version: 20.3.3 '@types/prettier': specifier: ^2.7.3 version: 2.7.3 @@ -209,14 +212,11 @@ importers: specifier: ^0.22.8 version: 0.22.8 magic-string: - specifier: ^0.30.0 - version: 0.30.0 + specifier: ^0.30.1 + version: 0.30.1 marked: specifier: ^5.1.0 version: 5.1.0 - node-fetch: - specifier: ^3.3.1 - version: 3.3.1 prettier: specifier: ^2.8.8 version: 2.8.8 @@ -258,7 +258,7 @@ importers: version: 5.1.6 vite: specifier: ^4.3.9 - version: 4.3.9(@types/node@20.3.2)(sass@1.63.6) + version: 4.3.9(@types/node@20.3.3)(sass@1.63.6) vite-imagetools: specifier: ^5.0.4 version: 5.0.4 @@ -1690,12 +1690,12 @@ packages: - supports-color dev: false - /@sveltejs/adapter-vercel@3.0.1(@sveltejs/kit@1.21.0): + /@sveltejs/adapter-vercel@3.0.1(@sveltejs/kit@1.22.0): resolution: {integrity: sha512-PBY3YRm7Q7Prax07mxD/rvcho2CntGkYncAIkz2DtG5NTcVG5JZ1RM627it5zYYtc2/RB3YjMkZuCMBqDCiPkA==} peerDependencies: '@sveltejs/kit': ^1.5.0 dependencies: - '@sveltejs/kit': 1.21.0(svelte@packages+svelte)(vite@4.3.9) + '@sveltejs/kit': 1.22.0(svelte@packages+svelte)(vite@4.3.9) '@vercel/nft': 0.22.6 esbuild: 0.17.19 transitivePeerDependencies: @@ -1723,8 +1723,8 @@ packages: typescript: 5.1.3 dev: true - /@sveltejs/kit@1.21.0(svelte@packages+svelte)(vite@4.3.9): - resolution: {integrity: sha512-CBsYoI34SjtOQp0eG85dmVnvTR3Pjs8VgAQhO0CgQja9BIorKl808F1X8EunPhCcyek5r5lKQE1Mmbi0RuzHqA==} + /@sveltejs/kit@1.22.0(svelte@packages+svelte)(vite@4.3.9): + resolution: {integrity: sha512-LQhM7CvTaO7OopQffFMuJ2n1lBhfYJKVO2Rujc+/473Yb8jb1mpJm59q5Avbx29kcz8N9lvYUyRP3FXc63VIFA==} engines: {node: ^16.14 || >=18} hasBin: true requiresBuild: true @@ -1738,18 +1738,18 @@ packages: devalue: 4.3.2 esm-env: 1.0.0 kleur: 4.1.5 - magic-string: 0.30.0 + magic-string: 0.30.1 mime: 3.0.0 sade: 1.8.1 set-cookie-parser: 2.6.0 sirv: 2.0.3 svelte: link:packages/svelte undici: 5.22.1 - vite: 4.3.9(@types/node@20.3.2)(sass@1.63.6) + vite: 4.3.9(@types/node@20.3.3)(sass@1.63.6) transitivePeerDependencies: - supports-color - /@sveltejs/repl@0.5.0-next.11(@codemirror/lang-html@6.4.5)(@codemirror/search@6.5.0)(@lezer/common@1.0.3)(@lezer/javascript@1.4.3)(@lezer/lr@1.3.7)(@sveltejs/kit@1.21.0)(svelte@packages+svelte): + /@sveltejs/repl@0.5.0-next.11(@codemirror/lang-html@6.4.5)(@codemirror/search@6.5.0)(@lezer/common@1.0.3)(@lezer/javascript@1.4.3)(@lezer/lr@1.3.7)(@sveltejs/kit@1.22.0)(svelte@packages+svelte): resolution: {integrity: sha512-bZ7WmmwwujhO1b1r7hN5Lt4z/Y4J3Bfx1DHiITOLshHTPgEU9XNOdq2JzSmN4DIWhmU0T/OVZ53XyXpaR1KTWA==} peerDependencies: svelte: ^3.54.0 || ^4.0.0-next.0 || ^4.0.0 @@ -1770,7 +1770,7 @@ packages: '@replit/codemirror-lang-svelte': 6.0.0(@codemirror/autocomplete@6.8.1)(@codemirror/lang-css@6.2.0)(@codemirror/lang-html@6.4.5)(@codemirror/lang-javascript@6.1.9)(@codemirror/language@6.8.0)(@codemirror/state@6.2.1)(@codemirror/view@6.14.0)(@lezer/common@1.0.3)(@lezer/highlight@1.1.6)(@lezer/javascript@1.4.3)(@lezer/lr@1.3.7) '@rich_harris/svelte-split-pane': 1.1.1(svelte@packages+svelte) '@rollup/browser': 3.25.3 - '@sveltejs/site-kit': 5.2.2(@sveltejs/kit@1.21.0)(svelte@packages+svelte) + '@sveltejs/site-kit': 5.2.2(@sveltejs/kit@1.22.0)(svelte@packages+svelte) acorn: 8.9.0 codemirror: 6.0.1(@lezer/common@1.0.3) esm-env: 1.0.0 @@ -1788,25 +1788,25 @@ packages: - '@sveltejs/kit' dev: false - /@sveltejs/site-kit@5.2.2(@sveltejs/kit@1.21.0)(svelte@packages+svelte): + /@sveltejs/site-kit@5.2.2(@sveltejs/kit@1.22.0)(svelte@packages+svelte): resolution: {integrity: sha512-XLLxVUV/dYytCsUeODAkjtzlaIBSn1kdcH5U36OuN7gMsPEHDy5L/dsWjf1/vDln3JStH5lqZPEN8Fovm33KhA==} peerDependencies: '@sveltejs/kit': ^1.0.0 svelte: ^3.54.0 dependencies: - '@sveltejs/kit': 1.21.0(svelte@packages+svelte)(vite@4.3.9) + '@sveltejs/kit': 1.22.0(svelte@packages+svelte)(vite@4.3.9) esm-env: 1.0.0 svelte: link:packages/svelte svelte-local-storage-store: 0.4.0(svelte@packages+svelte) dev: false - /@sveltejs/site-kit@6.0.0-next.20(@sveltejs/kit@1.21.0)(svelte@packages+svelte): + /@sveltejs/site-kit@6.0.0-next.20(@sveltejs/kit@1.22.0)(svelte@packages+svelte): resolution: {integrity: sha512-tWT/pKdCFxY+Wsayoj287AcNOYsm0EW5fiOsSSVseEK+62R1KcWHcioSgm1Fk12HOUgFcYnskaJ9JOo+p7+9/w==} peerDependencies: '@sveltejs/kit': ^1.20.0 svelte: ^4.0.0 dependencies: - '@sveltejs/kit': 1.21.0(svelte@packages+svelte)(vite@4.3.9) + '@sveltejs/kit': 1.22.0(svelte@packages+svelte)(vite@4.3.9) esm-env: 1.0.0 svelte: link:packages/svelte svelte-local-storage-store: 0.5.0(svelte@packages+svelte) @@ -1823,7 +1823,7 @@ packages: '@sveltejs/vite-plugin-svelte': 2.4.2(svelte@packages+svelte)(vite@4.3.9) debug: 4.3.4 svelte: link:packages/svelte - vite: 4.3.9(@types/node@20.3.2)(sass@1.63.6) + vite: 4.3.9(@types/node@20.3.3)(sass@1.63.6) transitivePeerDependencies: - supports-color @@ -1838,10 +1838,10 @@ packages: debug: 4.3.4 deepmerge: 4.3.1 kleur: 4.1.5 - magic-string: 0.30.0 + magic-string: 0.30.1 svelte: link:packages/svelte svelte-hmr: 0.15.2(svelte@packages+svelte) - vite: 4.3.9(@types/node@20.3.2)(sass@1.63.6) + vite: 4.3.9(@types/node@20.3.3)(sass@1.63.6) vitefu: 0.2.4(vite@4.3.9) transitivePeerDependencies: - supports-color @@ -1915,8 +1915,8 @@ packages: resolution: {integrity: sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g==} dev: true - /@types/node@20.3.2: - resolution: {integrity: sha512-vOBLVQeCQfIcF/2Y7eKFTqrMnizK5lRNQ7ykML/5RuwVXVWxYkgwS7xbt4B6fKCUPgbSL5FSsjHQpaGQP/dQmw==} + /@types/node@20.3.3: + resolution: {integrity: sha512-wheIYdr4NYML61AjC8MKj/2jrR/kDQri/CIpVoZwldwhnIrD/j9jIU5bJ8yBKuB2VhpFV7Ab6G2XkBjv9r9Zzw==} /@types/normalize-package-data@2.4.1: resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} @@ -1949,7 +1949,7 @@ packages: /@types/websocket@1.0.5: resolution: {integrity: sha512-NbsqiNX9CnEfC1Z0Vf4mE1SgAJ07JnRYcNex7AJ9zAVzmiGHmjKFEk7O4TJIsgv2B1sLEb6owKFZrACwdYngsQ==} dependencies: - '@types/node': 20.3.2 + '@types/node': 20.3.3 dev: false /@typescript-eslint/eslint-plugin@5.60.0(@typescript-eslint/parser@5.60.1)(eslint@8.43.0)(typescript@5.1.6): @@ -2300,7 +2300,7 @@ packages: /@vitest/snapshot@0.31.4: resolution: {integrity: sha512-LemvNumL3NdWSmfVAMpXILGyaXPkZbG5tyl6+RQSdcHnTj6hvA49UAI8jzez9oQyE/FWLKRSNqTGzsHuk89LRA==} dependencies: - magic-string: 0.30.0 + magic-string: 0.30.1 pathe: 1.1.1 pretty-format: 27.5.1 dev: true @@ -2947,11 +2947,6 @@ packages: type: 1.2.0 dev: false - /data-uri-to-buffer@4.0.1: - resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} - engines: {node: '>= 12'} - dev: true - /data-urls@4.0.0: resolution: {integrity: sha512-/mMTei/JXPqvFqQtfyTowxmJVwr2PVAeCcDxyFf6LhoOu/09TX2OX3kb2wzi4DMXcfj4OItwDOnhl5oziPnT6g==} engines: {node: '>=14'} @@ -3602,14 +3597,6 @@ packages: engines: {node: '>=12'} dev: true - /fetch-blob@3.2.0: - resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} - engines: {node: ^12.20 || >= 14.13} - dependencies: - node-domexception: 1.0.0 - web-streams-polyfill: 3.2.1 - dev: true - /fflate@0.7.4: resolution: {integrity: sha512-5u2V/CDW15QM1XbbgS+0DfPxVB+jUKhWEKuuFuHncbk3tEEqzmoXL+2KyOFuKGqOnmdIy0/davWF1CkuwtibCw==} dev: true @@ -3699,13 +3686,6 @@ packages: mime-types: 2.1.35 dev: true - /formdata-polyfill@4.0.10: - resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} - engines: {node: '>=12.20.0'} - dependencies: - fetch-blob: 3.2.0 - dev: true - /fs-constants@1.0.0: resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} dev: true @@ -4561,6 +4541,12 @@ packages: dependencies: '@jridgewell/sourcemap-codec': 1.4.15 + /magic-string@0.30.1: + resolution: {integrity: sha512-mbVKXPmS0z0G4XqFDCTllmDQ6coZzn94aMlb0o/A4HEHJCKcanlDZwYJgwnkmgD3jyWhUgj9VsPrfd972yPffA==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + /make-dir@3.1.0: resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} engines: {node: '>=8'} @@ -4798,11 +4784,6 @@ packages: resolution: {integrity: sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==} dev: true - /node-domexception@1.0.0: - resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} - engines: {node: '>=10.5.0'} - dev: true - /node-fetch@2.6.11: resolution: {integrity: sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==} engines: {node: 4.x || >=6.0.0} @@ -4814,15 +4795,6 @@ packages: dependencies: whatwg-url: 5.0.0 - /node-fetch@3.3.1: - resolution: {integrity: sha512-cRVc/kyto/7E5shrWca1Wsea4y6tL9iYJE5FBCius3JQfb/4P4I295PfhgbJQBLTx6lATE4z+wK0rPM4VS2uow==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - data-uri-to-buffer: 4.0.1 - fetch-blob: 3.2.0 - formdata-polyfill: 4.0.10 - dev: true - /node-gyp-build@4.6.0: resolution: {integrity: sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==} hasBin: true @@ -6473,7 +6445,7 @@ packages: fsevents: 2.3.2 dev: true - /vite@4.3.9(@types/node@20.3.2)(sass@1.63.6): + /vite@4.3.9(@types/node@20.3.3)(sass@1.63.6): resolution: {integrity: sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==} engines: {node: ^14.18.0 || >=16.0.0} hasBin: true @@ -6498,7 +6470,7 @@ packages: terser: optional: true dependencies: - '@types/node': 20.3.2 + '@types/node': 20.3.3 esbuild: 0.17.19 postcss: 8.4.24 rollup: 3.25.1 @@ -6514,7 +6486,7 @@ packages: vite: optional: true dependencies: - vite: 4.3.9(@types/node@20.3.2)(sass@1.63.6) + vite: 4.3.9(@types/node@20.3.3)(sass@1.63.6) /vitest@0.31.4(happy-dom@9.20.3)(jsdom@21.1.2)(playwright@1.35.1): resolution: {integrity: sha512-GoV0VQPmWrUFOZSg3RpQAPN+LPmHg2/gxlMNJlyxJihkz6qReHDV6b0pPDcqFLNEPya4tWJ1pgwUNP9MLmUfvQ==} @@ -6613,11 +6585,6 @@ packages: defaults: 1.0.4 dev: true - /web-streams-polyfill@3.2.1: - resolution: {integrity: sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==} - engines: {node: '>= 8'} - dev: true - /webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} diff --git a/sites/svelte.dev/package.json b/sites/svelte.dev/package.json index 05abbd4b53..6b736faa3b 100644 --- a/sites/svelte.dev/package.json +++ b/sites/svelte.dev/package.json @@ -29,18 +29,18 @@ "devDependencies": { "@resvg/resvg-js": "^2.4.1", "@sveltejs/adapter-vercel": "^3.0.1", - "@sveltejs/kit": "^1.21.0", + "@sveltejs/kit": "^1.22.0", "@sveltejs/site-kit": "6.0.0-next.20", "@sveltejs/vite-plugin-svelte": "^2.4.2", + "@types/cookie": "^0.5.1", "@types/marked": "^5.0.0", - "@types/node": "^20.3.2", + "@types/node": "^20.3.3", "@types/prettier": "^2.7.3", "degit": "^2.8.4", "dotenv": "^16.3.1", "jimp": "^0.22.8", - "magic-string": "^0.30.0", + "magic-string": "^0.30.1", "marked": "^5.1.0", - "node-fetch": "^3.3.1", "prettier": "^2.8.8", "prettier-plugin-svelte": "^2.10.1", "sass": "^1.63.6", diff --git a/sites/svelte.dev/scripts/generate_examples.js b/sites/svelte.dev/scripts/generate_examples.js index bbdf05fae2..360cba79bd 100644 --- a/sites/svelte.dev/scripts/generate_examples.js +++ b/sites/svelte.dev/scripts/generate_examples.js @@ -1,16 +1,16 @@ import { fileURLToPath } from 'node:url'; import { get_examples_data } from '../src/lib/server/examples/index.js'; -import fs from 'node:fs'; +import { mkdir, writeFile } from 'node:fs/promises'; -const examples_data = get_examples_data( +const examples_data = await get_examples_data( fileURLToPath(new URL('../../../documentation/examples', import.meta.url)) ); try { - fs.mkdirSync(new URL('../src/lib/generated/', import.meta.url), { recursive: true }); + await mkdir(new URL('../src/lib/generated/', import.meta.url), { recursive: true }); } catch {} -fs.writeFileSync( +writeFile( new URL('../src/lib/generated/examples-data.js', import.meta.url), `export default ${JSON.stringify(examples_data)}` ); diff --git a/sites/svelte.dev/scripts/get_contributors.js b/sites/svelte.dev/scripts/get_contributors.js index 05392e4939..2949dea5df 100644 --- a/sites/svelte.dev/scripts/get_contributors.js +++ b/sites/svelte.dev/scripts/get_contributors.js @@ -1,28 +1,30 @@ +// @ts-check import 'dotenv/config'; -import fs from 'fs'; -import fetch from 'node-fetch'; import Jimp from 'jimp'; -import { dirname } from 'path'; -import { fileURLToPath } from 'url'; +import { stat, writeFile } from 'node:fs/promises'; +import { dirname } from 'node:path'; +import { fileURLToPath } from 'node:url'; const force = process.env.FORCE_UPDATE === 'true'; const __dirname = dirname(fileURLToPath(import.meta.url)); process.chdir(__dirname); -const outputFile = `../src/routes/_components/Supporters/contributors.js`; -if (!force && fs.existsSync(outputFile)) { - console.info(`[update/contributors] ${outputFile} exists. Skipping`); - process.exit(0); -} +// ../src/routes/_components/Supporters/contributors.js +const outputFile = new URL(`../src/routes/_components/Supporters/contributors.js`, import.meta.url); -const base = `https://api.github.com/repos/sveltejs/svelte/contributors`; -const { GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET } = process.env; +try { + if (!force && (await stat(outputFile))) { + console.info(`[update/contributors] ${outputFile} exists. Skipping`); + process.exit(0); + } +} catch { + const base = `https://api.github.com/repos/sveltejs/svelte/contributors`; + const { GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET } = process.env; -const MAX = 24; -const SIZE = 128; + const MAX = 24; + const SIZE = 128; -async function main() { const contributors = []; let page = 1; @@ -32,6 +34,8 @@ async function main() { ); const list = await res.json(); + if (!Array.isArray(list)) throw new Error('Expected an array'); + if (list.length === 0) break; contributors.push(...list); @@ -51,13 +55,19 @@ async function main() { const image_data = await fetch(author.avatar_url); const buffer = await image_data.arrayBuffer(); + // @ts-ignore const image = await Jimp.read(buffer); image.resize(SIZE, SIZE); sprite.composite(image, i * SIZE, 0); } - await sprite.quality(80).write(`../src/routes/_components/Supporters/contributors.jpg`); + await sprite + .quality(80) + .writeAsync( + new URL(`../src/routes/_components/Supporters/contributors.jpeg`, import.meta.url).pathname + ); + // TODO: Optimizing the static/contributors.jpg image should probably get automated as well console.log( 'remember to additionally optimize the resulting /static/contributors.jpg image file via e.g. https://squoosh.app ' @@ -65,7 +75,5 @@ async function main() { const str = `[\n\t${authors.map((a) => `'${a.login}'`).join(',\n\t')}\n]`; - fs.writeFileSync(outputFile, `export default ${str};`); + writeFile(outputFile, `export default ${str};`); } - -main(); diff --git a/sites/svelte.dev/scripts/get_donors.js b/sites/svelte.dev/scripts/get_donors.js index bd8af280a1..6383548f3b 100644 --- a/sites/svelte.dev/scripts/get_donors.js +++ b/sites/svelte.dev/scripts/get_donors.js @@ -1,28 +1,31 @@ +// @ts-check import 'dotenv/config'; -import fs from 'fs'; -import fetch from 'node-fetch'; import Jimp from 'jimp'; -import { dirname } from 'path'; -import { fileURLToPath } from 'url'; +import { stat, writeFile } from 'node:fs/promises'; +import { dirname } from 'node:path'; +import { fileURLToPath } from 'node:url'; const force = process.env.FORCE_UPDATE === 'true'; const __dirname = dirname(fileURLToPath(import.meta.url)); process.chdir(__dirname); -const outputFile = `../src/routes/_components/Supporters/donors.js`; -if (!force && fs.existsSync(outputFile)) { - console.info(`[update/donors] ${outputFile} exists. Skipping`); - process.exit(0); -} +const outputFile = new URL(`../src/routes/_components/Supporters/donors.js`, import.meta.url); -const MAX = 24; -const SIZE = 128; +try { + if (!force && (await stat(outputFile))) { + console.info(`[update/donors] ${outputFile} exists. Skipping`); + process.exit(0); + } +} catch { + const MAX = 24; + const SIZE = 128; -async function main() { const res = await fetch('https://opencollective.com/svelte/members/all.json'); const donors = await res.json(); + if (!Array.isArray(donors)) throw new Error('Expected an array'); + const unique = new Map(); donors.forEach((d) => unique.set(d.profile, d)); @@ -39,6 +42,7 @@ async function main() { try { const image_data = await fetch(backer.image); const buffer = await image_data.arrayBuffer(); + // @ts-ignore const image = await Jimp.read(buffer); image.resize(SIZE, SIZE); included.push({ backer, image }); @@ -52,7 +56,11 @@ async function main() { sprite.composite(included[i].image, i * SIZE, 0); } - await sprite.quality(80).write(`../src/routes/_components/Supporters/donors.jpg`); + await sprite + .quality(80) + .writeAsync( + new URL(`../src/routes/_components/Supporters/donors.jpg`, import.meta.url).pathname + ); // TODO: Optimizing the static/donors.jpg image should probably get automated as well console.log( 'remember to additionally optimize the resulting /static/donors.jpg image file via e.g. https://squoosh.app ' @@ -60,7 +68,5 @@ async function main() { const str = `[\n\t${included.map((a) => `${JSON.stringify(a.backer.name)}`).join(',\n\t')}\n]`; - fs.writeFileSync(outputFile, `export default ${str};`); + writeFile(outputFile, `export default ${str};`); } - -main(); diff --git a/sites/svelte.dev/scripts/type-gen/index.js b/sites/svelte.dev/scripts/type-gen/index.js index 0959ac8309..18c82f19b0 100644 --- a/sites/svelte.dev/scripts/type-gen/index.js +++ b/sites/svelte.dev/scripts/type-gen/index.js @@ -1,5 +1,5 @@ // @ts-check -import fs from 'node:fs'; +import { mkdir, readFile, writeFile } from 'node:fs/promises'; import path from 'node:path'; import prettier from 'prettier'; import ts from 'typescript'; @@ -236,12 +236,12 @@ function strip_origin(str) { /** * @param {string} file */ -function read_d_ts_file(file) { +async function read_d_ts_file(file) { const resolved = path.resolve('../../packages/svelte', file); // We can't use JSDoc comments inside JSDoc, so we would get ts(7031) errors if // we didn't ignore this error specifically for `/// file:` code examples - const str = fs.readFileSync(resolved, 'utf-8'); + const str = await readFile(resolved, 'utf-8'); return str.replace(/(\s*\*\s*)```js([\s\S]+?)```/g, (match, prefix, code) => { return `${prefix}\`\`\`js${prefix}// @errors: 7031${code}\`\`\``; @@ -249,7 +249,7 @@ function read_d_ts_file(file) { } { - const code = read_d_ts_file('types/index.d.ts'); + const code = await read_d_ts_file('types/index.d.ts'); const node = ts.createSourceFile('index.d.ts', code, ts.ScriptTarget.Latest, true); for (const statement of node.statements) { @@ -296,10 +296,10 @@ $: { } try { - fs.mkdirSync(new URL('../../src/lib/generated', import.meta.url), { recursive: true }); + await mkdir(new URL('../../src/lib/generated', import.meta.url), { recursive: true }); } catch {} -fs.writeFileSync( +writeFile( new URL('../../src/lib/generated/type-info.js', import.meta.url), ` /* This file is generated by running \`pnpm generate\` diff --git a/sites/svelte.dev/scripts/update_template.js b/sites/svelte.dev/scripts/update_template.js index a54a3acb06..2d371e1f65 100644 --- a/sites/svelte.dev/scripts/update_template.js +++ b/sites/svelte.dev/scripts/update_template.js @@ -1,7 +1,8 @@ +// @ts-check +import { lstat, readFile, stat, writeFile } from 'node:fs/promises'; +import path, { dirname } from 'node:path'; +import { fileURLToPath } from 'node:url'; import sh from 'shelljs'; -import fs from 'fs'; -import path, { dirname } from 'path'; -import { fileURLToPath } from 'url'; const force = process.env.FORCE_UPDATE === 'true'; @@ -9,28 +10,34 @@ const __dirname = dirname(fileURLToPath(import.meta.url)); sh.cd(path.join(__dirname, '..')); const outputFile = 'static/svelte-app.json'; -if (!force && fs.existsSync(outputFile)) { - console.info(`[update/template] ${outputFile} exists. Skipping`); - process.exit(0); -} - -// fetch svelte app -sh.rm('-rf', 'scripts/svelte-app'); -sh.exec('npx degit sveltejs/template scripts/svelte-app'); - -// remove src (will be recreated client-side) and node_modules -sh.rm('-rf', 'scripts/svelte-app/src'); -sh.rm('-rf', 'scripts/svelte-app/node_modules'); -// build svelte-app.json -const appPath = 'scripts/svelte-app'; -const files = []; - -for (const path of sh.find(appPath).filter((p) => fs.lstatSync(p).isFile())) { - const bytes = fs.readFileSync(path); - const string = bytes.toString(); - const data = bytes.compare(Buffer.from(string)) === 0 ? string : [...bytes]; - files.push({ path: path.slice(appPath.length + 1), data }); +try { + if (!force && (await stat(outputFile))) { + console.info(`[update/template] ${outputFile} exists. Skipping`); + process.exit(0); + } +} catch { + // fetch svelte app + sh.rm('-rf', 'scripts/svelte-app'); + sh.exec('npx degit sveltejs/template scripts/svelte-app'); + + // remove src (will be recreated client-side) and node_modules + sh.rm('-rf', 'scripts/svelte-app/src'); + sh.rm('-rf', 'scripts/svelte-app/node_modules'); + + // build svelte-app.json + const appPath = 'scripts/svelte-app'; + const files = []; + + for (const path of sh.find(appPath)) { + // Skip directories + if (!(await lstat(path)).isFile()) continue; + + const bytes = await readFile(path); + const string = bytes.toString(); + const data = bytes.compare(Buffer.from(string)) === 0 ? string : [...bytes]; + files.push({ path: path.slice(appPath.length + 1), data }); + } + + writeFile(outputFile, JSON.stringify(files)); } - -fs.writeFileSync(outputFile, JSON.stringify(files)); diff --git a/sites/svelte.dev/src/lib/components/ReplWidget.svelte b/sites/svelte.dev/src/lib/components/ReplWidget.svelte index a650c86985..9884c429a7 100644 --- a/sites/svelte.dev/src/lib/components/ReplWidget.svelte +++ b/sites/svelte.dev/src/lib/components/ReplWidget.svelte @@ -26,7 +26,7 @@ } if (gist) { - fetch(`/repl/${gist}.json`) + fetch(`/repl/api/${gist}.json`) .then((r) => r.json()) .then((data) => { const { description, components } = data; diff --git a/sites/svelte.dev/src/lib/db/client.js b/sites/svelte.dev/src/lib/db/client.js index 241629edbd..b5a5437781 100644 --- a/sites/svelte.dev/src/lib/db/client.js +++ b/sites/svelte.dev/src/lib/db/client.js @@ -4,4 +4,7 @@ import { createClient } from '@supabase/supabase-js'; export const client = (!dev || (SUPABASE_URL && SUPABASE_KEY)) && - createClient(SUPABASE_URL, SUPABASE_KEY, { global: { fetch } }); + createClient(SUPABASE_URL, SUPABASE_KEY, { + global: { fetch }, + auth: { persistSession: false } + }); 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 f6efe70f33..eef9e4e2a9 100644 --- a/sites/svelte.dev/src/lib/server/docs/index.js +++ b/sites/svelte.dev/src/lib/server/docs/index.js @@ -1,14 +1,11 @@ import { base as app_base } from '$app/paths'; -import { modules } from '$lib/generated/type-info.js'; import { escape, extractFrontmatter, markedTransform, normalizeSlugify, - removeMarkdown, - replaceExportTypePlaceholders + removeMarkdown } from '@sveltejs/site-kit/markdown'; -import fs from 'node:fs'; import { CONTENT_BASE_PATHS } from '../../../constants.js'; import { render_content } from '../renderer'; @@ -31,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; @@ -44,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; @@ -56,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; @@ -64,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/examples/index.js b/sites/svelte.dev/src/lib/server/examples/index.js index df525e7881..0ca9347dfb 100644 --- a/sites/svelte.dev/src/lib/server/examples/index.js +++ b/sites/svelte.dev/src/lib/server/examples/index.js @@ -1,5 +1,4 @@ import { CONTENT_BASE_PATHS } from '../../../constants.js'; -import fs from 'node:fs'; /** * @param {import('./types').ExamplesData} examples_data @@ -18,25 +17,28 @@ export function get_example(examples_data, slug) { } /** - * @returns {import('./types').ExamplesData} + * @returns {Promise} */ -export function get_examples_data(base = CONTENT_BASE_PATHS.EXAMPLES) { +export async function get_examples_data(base = CONTENT_BASE_PATHS.EXAMPLES) { + const { readdir, stat, readFile } = await import('node:fs/promises'); + const examples = []; - 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('-'), examples: [] }; - 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 ?? 'Embeds'; + JSON.parse(await readFile(`${base}/${subdir}/meta.json`, 'utf-8')).title ?? 'Embeds'; - 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; @@ -46,17 +48,17 @@ export function get_examples_data(base = CONTENT_BASE_PATHS.EXAMPLES) { // Get title for const example_title = JSON.parse( - fs.readFileSync(`${example_base_dir}/meta.json`, 'utf-8') + await readFile(`${example_base_dir}/meta.json`, 'utf-8') ).title; const files = []; - for (const file of fs - .readdirSync(example_base_dir) - .filter((file) => !file.endsWith('meta.json'))) { + for (const file of (await readdir(example_base_dir)).filter( + (file) => !file.endsWith('meta.json') + )) { files.push({ name: file, type: file.split('.').at(-1), - content: fs.readFileSync(`${example_base_dir}/${file}`, 'utf-8') + content: await readFile(`${example_base_dir}/${file}`, 'utf-8') }); } 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/(authed)/+layout.server.js b/sites/svelte.dev/src/routes/(authed)/+layout.server.js index 08bd6091a7..6271b50b3b 100644 --- a/sites/svelte.dev/src/routes/(authed)/+layout.server.js +++ b/sites/svelte.dev/src/routes/(authed)/+layout.server.js @@ -1,5 +1,12 @@ import * as session from '$lib/db/session'; +/** @type {import('@sveltejs/adapter-vercel').Config} */ +export const config = { + // regions: ['pdx1', 'sfo1', 'cle1', 'iad1'], + regions: 'all', + runtime: 'edge' +}; + export async function load({ request }) { return { user: session.from_cookie(request.headers.get('cookie')) diff --git a/sites/svelte.dev/src/routes/(authed)/repl/[id]/+page.server.js b/sites/svelte.dev/src/routes/(authed)/repl/[id]/+page.server.js index 5731e79309..5d80a583f3 100644 --- a/sites/svelte.dev/src/routes/(authed)/repl/[id]/+page.server.js +++ b/sites/svelte.dev/src/routes/(authed)/repl/[id]/+page.server.js @@ -1,7 +1,7 @@ import { error } from '@sveltejs/kit'; export async function load({ fetch, params, url }) { - const res = await fetch(`/repl/${params.id}.json`); + const res = await fetch(`/repl/api/${params.id}.json`); if (!res.ok) { throw error(res.status); diff --git a/sites/svelte.dev/src/routes/(authed)/repl/[id].json/+server.js b/sites/svelte.dev/src/routes/(authed)/repl/api/[id].json/+server.js similarity index 94% rename from sites/svelte.dev/src/routes/(authed)/repl/[id].json/+server.js rename to sites/svelte.dev/src/routes/(authed)/repl/api/[id].json/+server.js index f2e632f1ad..90ac4ad79a 100644 --- a/sites/svelte.dev/src/routes/(authed)/repl/[id].json/+server.js +++ b/sites/svelte.dev/src/routes/(authed)/repl/api/[id].json/+server.js @@ -61,7 +61,7 @@ export async function GET({ params }) { if (dev && !client) { // in dev with no local Supabase configured, proxy to production // this lets us at least load saved REPLs - const res = await fetch(`https://svelte.dev/repl/${params.id}.json`); + const res = await fetch(`https://svelte.dev/repl/api/${params.id}.json`); // returning the response directly results in a bizarre // content encoding error, so we create a new one @@ -95,6 +95,8 @@ export async function GET({ params }) { } export async function entries() { + const { get_examples_list } = await import('$lib/server/examples/index.js'); + return get_examples_list(examples_data) .map(({ examples }) => examples) .flatMap((val) => val.map(({ slug }) => ({ id: slug }))); diff --git a/sites/svelte.dev/src/routes/(authed)/repl/local/[...path]/+server.js b/sites/svelte.dev/src/routes/(authed)/repl/local/[...path]/+server.js index 1d5ce18fa1..f141ee2021 100644 --- a/sites/svelte.dev/src/routes/(authed)/repl/local/[...path]/+server.js +++ b/sites/svelte.dev/src/routes/(authed)/repl/local/[...path]/+server.js @@ -1,14 +1,15 @@ -import { readFileSync } from 'fs'; -import { join } from 'path'; import { env } from '$env/dynamic/private'; const local_svelte_path = env.LOCAL_SVELTE_PATH || '../../../svelte'; -export function GET({ params: { path } }) { +export async function GET({ params: { path } }) { if (import.meta.env.PROD || ('/' + path).includes('/.')) { return new Response(undefined, { status: 403 }); } - return new Response(readFileSync(join(local_svelte_path, path)), { + + const { readFile } = await import('node:fs/promises'); + + return new Response(await readFile(`${local_svelte_path}/${path}`), { headers: { 'Content-Type': 'text/javascript' } }); } diff --git a/sites/svelte.dev/src/routes/auth/callback/+server.js b/sites/svelte.dev/src/routes/auth/callback/+server.js index ca4dede4a9..84c120c9ee 100644 --- a/sites/svelte.dev/src/routes/auth/callback/+server.js +++ b/sites/svelte.dev/src/routes/auth/callback/+server.js @@ -1,6 +1,5 @@ import { uneval } from 'devalue'; import * as cookie from 'cookie'; -import { stringify } from 'querystring'; import * as session from '$lib/db/session'; import { oauth, client_id, client_secret } from '../_config.js'; @@ -9,11 +8,11 @@ export async function GET({ url }) { // Trade "code" for "access_token" const r1 = await fetch( `${oauth}/access_token?` + - stringify({ + new URLSearchParams({ code: url.searchParams.get('code'), client_id, client_secret - }) + }).toString() ); const access_token = new URLSearchParams(await r1.text()).get('access_token'); diff --git a/sites/svelte.dev/src/routes/auth/login/+server.js b/sites/svelte.dev/src/routes/auth/login/+server.js index a4f8f6fbfd..83b7a7f730 100644 --- a/sites/svelte.dev/src/routes/auth/login/+server.js +++ b/sites/svelte.dev/src/routes/auth/login/+server.js @@ -1,16 +1,15 @@ -import { stringify } from 'querystring'; import { redirect } from '@sveltejs/kit'; -import { oauth, client_id } from '../_config.js'; +import { client_id, oauth } from '../_config.js'; export const GET = client_id ? ({ url }) => { const Location = `${oauth}/authorize?` + - stringify({ + new URLSearchParams({ scope: 'read:user', client_id, redirect_uri: `${url.origin}/auth/callback` - }); + }).toString(); throw redirect(302, Location); } 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/content.json/+server.js b/sites/svelte.dev/src/routes/content.json/+server.js index 223891ad0c..75659752c9 100644 --- a/sites/svelte.dev/src/routes/content.json/+server.js +++ b/sites/svelte.dev/src/routes/content.json/+server.js @@ -3,8 +3,8 @@ import { json } from '@sveltejs/kit'; export const prerender = true; -export function GET() { +export async function GET() { return json({ - blocks: content() + blocks: await content() }); } diff --git a/sites/svelte.dev/src/routes/content.json/content.server.js b/sites/svelte.dev/src/routes/content.json/content.server.js index b2453af5ac..5dc2355fda 100644 --- a/sites/svelte.dev/src/routes/content.json/content.server.js +++ b/sites/svelte.dev/src/routes/content.json/content.server.js @@ -6,9 +6,8 @@ import { removeMarkdown, replaceExportTypePlaceholders } from '@sveltejs/site-kit/markdown'; -import fs from 'node:fs'; -import path from 'node:path'; -import glob from 'tiny-glob/sync.js'; +import { readFile } from 'node:fs/promises'; +import glob from 'tiny-glob'; import { CONTENT_BASE } from '../../constants.js'; const base = CONTENT_BASE; @@ -18,22 +17,26 @@ function get_href(parts) { return parts.length > 1 ? `/docs/${parts[0]}#${parts.at(-1)}` : `/docs/${parts[0]}`; } -export function content() { +/** @param {string} path */ +function path_basename(path) { + return path.split(/[\\/]/).pop(); +} + +export async function content() { /** @type {import('@sveltejs/site-kit/search').Block[]} */ const blocks = []; const breadcrumbs = []; - for (const file of glob('**/*.md', { cwd: `${base}/docs` })) { - const basename = path.basename(file); + for (const file of await glob('**/*.md', { cwd: `${base}/docs` })) { + const basename = path_basename(file); const match = /\d{2}-(.+)\.md/.exec(basename); if (!match) continue; const slug = match[1]; const filepath = `${base}/docs/${file}`; - // const markdown = replace_placeholders(fs.readFileSync(filepath, 'utf-8')); - const markdown = replaceExportTypePlaceholders(fs.readFileSync(filepath, 'utf-8'), modules); + const markdown = replaceExportTypePlaceholders(await readFile(filepath, 'utf-8'), modules); const { body, metadata } = extractFrontmatter(markdown); diff --git a/sites/svelte.dev/src/routes/docs/+layout.server.js b/sites/svelte.dev/src/routes/docs/+layout.server.js index 0be275db14..c584e0a8ce 100644 --- a/sites/svelte.dev/src/routes/docs/+layout.server.js +++ b/sites/svelte.dev/src/routes/docs/+layout.server.js @@ -1,9 +1,15 @@ -import { get_docs_data, get_docs_list } from '$lib/server/docs/index.js'; - export const prerender = true; -export function load({ url }) { +export async function load({ url }) { + if (url.pathname === '/docs') { + return { + sections: [] + }; + } + + const { get_docs_data, get_docs_list } = await import('$lib/server/docs/index.js'); + return { - sections: url.pathname === '/docs' ? [] : get_docs_list(get_docs_data()) + sections: get_docs_list(await get_docs_data()) }; } diff --git a/sites/svelte.dev/src/routes/docs/+page.server.js b/sites/svelte.dev/src/routes/docs/+page.server.js deleted file mode 100644 index 2ac91da507..0000000000 --- a/sites/svelte.dev/src/routes/docs/+page.server.js +++ /dev/null @@ -1,2 +0,0 @@ -// This page now exists solely for redirect, prerendering triggers the `handleMissingID` -export const prerender = false; 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/examples/[slug]/+page.server.js b/sites/svelte.dev/src/routes/examples/[slug]/+page.server.js index d7c39af2a5..64589cc408 100644 --- a/sites/svelte.dev/src/routes/examples/[slug]/+page.server.js +++ b/sites/svelte.dev/src/routes/examples/[slug]/+page.server.js @@ -1,10 +1,9 @@ -import { get_example, get_examples_data, get_examples_list } from '$lib/server/examples/index.js'; +import { get_example, get_examples_list } from '$lib/server/examples/index.js'; +import examples_data from '$lib/generated/examples-data.js'; export const prerender = true; export async function load({ params }) { - const examples_data = get_examples_data(); - const examples_list = get_examples_list(examples_data); const example = get_example(examples_data, params.slug); diff --git a/sites/svelte.dev/src/routes/nav.json/+server.js b/sites/svelte.dev/src/routes/nav.json/+server.js index 3ba9192ffb..c943b09799 100644 --- a/sites/svelte.dev/src/routes/nav.json/+server.js +++ b/sites/svelte.dev/src/routes/nav.json/+server.js @@ -1,6 +1,7 @@ import { get_blog_data, get_blog_list } from '$lib/server/blog/index.js'; import { get_docs_data, get_docs_list } from '$lib/server/docs/index.js'; -import { get_examples_data, get_examples_list } from '$lib/server/examples/index.js'; +import { get_examples_list } from '$lib/server/examples/index.js'; +import examples_data from '$lib/generated/examples-data.js'; import { json } from '@sveltejs/kit'; export const prerender = true; @@ -13,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', @@ -32,7 +36,7 @@ async function get_nav_list() { } ]; - const examples_list = get_examples_list(get_examples_data()); + const examples_list = get_examples_list(examples_data); const processed_examples_list = examples_list .map(({ title, examples }) => ({ title, 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 fd067f826e..fa8a49ff82 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() + adapter: adapter({ runtime: 'edge' }), + prerender: { + concurrency: 10 + } }, vitePlugin: { diff --git a/sites/svelte.dev/vite.config.js b/sites/svelte.dev/vite.config.js index 424b1f9d06..4eabf145f5 100644 --- a/sites/svelte.dev/vite.config.js +++ b/sites/svelte.dev/vite.config.js @@ -1,5 +1,5 @@ import { sveltekit } from '@sveltejs/kit/vite'; -import * as fs from 'fs'; +import { readFile } from 'node:fs/promises'; const plugins = [raw(['.ttf']), sveltekit()]; @@ -25,9 +25,9 @@ if (!process.versions.webcontainer) { function raw(ext) { return { name: 'vite-plugin-raw', - transform(_, id) { + async transform(_, id) { if (ext.some((e) => id.endsWith(e))) { - const buffer = fs.readFileSync(id); + const buffer = await readFile(id); return { code: `export default ${JSON.stringify(buffer)}`, map: null }; } }