feat(site): Deploy to edge (#8873)

* Try edge

* Fix errors

* Improvements

* Minor fixes

* Simplify docs layout logic

* Persist session true

* try regions all

* Push new promise-based infra

* pnpm install

* Remote debugging

* Refine

* try to disable prerender for examples

* text

* Weird hack

* url

* log params

* Try param matcher

* try some restructuring

* Leftover

* remove console log

* More async, remove node-fetch

* Fix

* New fixes

* Undo changes

* back to site-kit next 18
pull/8927/head
Puru Vijay 2 years ago committed by GitHub
parent 76baa07879
commit 70426be84a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -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

@ -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==}

@ -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",

@ -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)}`
);

@ -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();

@ -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();

@ -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\`

@ -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));

@ -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;

@ -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 }
});

@ -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<import('./types').BlogData>} */
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,

@ -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<import('./types').DocsData>} */
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;

@ -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<import('./types').ExamplesData>}
*/
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')
});
}

@ -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<import('./types').TutorialData>}
*/
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')
});
}
}

@ -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'))

@ -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);

@ -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 })));

@ -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' }
});
}

@ -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');

@ -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);
}

@ -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())
};
}

@ -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);

@ -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
}
});
};
}

@ -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: {

@ -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()
});
}

@ -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);

@ -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())
};
}

@ -1,2 +0,0 @@
// This page now exists solely for redirect, prerendering triggers the `handleMissingID`
export const prerender = false;

@ -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);

@ -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);

@ -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<import('@sveltejs/site-kit').NavigationLink[]>}
*/
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,

@ -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 })));

@ -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: {

@ -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 };
}
}

Loading…
Cancel
Save