From c2b51b1b2d4bb7a80625af7ea2a0bd4eae291d24 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 8 Oct 2024 13:34:38 -0400 Subject: [PATCH 1/5] invalidate snippet cache when code changes --- .../site-kit/src/lib/markdown/renderer.ts | 51 ++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/packages/site-kit/src/lib/markdown/renderer.ts b/packages/site-kit/src/lib/markdown/renderer.ts index f6d5b4c549..bc9d3e6ba1 100644 --- a/packages/site-kit/src/lib/markdown/renderer.ts +++ b/packages/site-kit/src/lib/markdown/renderer.ts @@ -8,6 +8,7 @@ import { codeToHtml, createCssVariablesTheme } from 'shiki'; import { transformerTwoslash } from '@shikijs/twoslash'; import { SHIKI_LANGUAGE_MAP, escape, normalizeSlugify, smart_quotes, transform } from './utils'; import type { Modules } from './index'; +import { fileURLToPath } from 'node:url'; interface SnippetOptions { file: string | null; @@ -508,6 +509,40 @@ function find_nearest_node_modules(file: string): string | null { return null; } +/** + * Get the `mtime` of the most recently modified file in a dependency graph, + * excluding imports from `node_modules` + */ +function get_mtime(file: string, seen = new Set()) { + if (seen.has(file)) return -1; + seen.add(file); + + let mtime = +fs.statSync(file).mtime; + const content = fs.readFileSync(file, 'utf-8'); + + for (const [_, source] of content.matchAll(/^import(?:.+?\s+from\s+)?['"](.+)['"];?$/gm)) { + if (source[0] !== '.') continue; + + let resolved = path.resolve(file, '..', source); + if (!fs.existsSync(resolved)) resolved += '.ts'; + if (!fs.existsSync(resolved)) + throw new Error(`Could not resolve ${source} relative to ${file}`); + + mtime = Math.max(mtime, get_mtime(resolved, seen)); + } + + return mtime; +} + +const mtime = get_mtime(fileURLToPath(import.meta.url)); + +// rough-and-ready way to invalidate the snippet cache when we update this file +// or utils.ts. A more complete solution would +// const mtime = Math.max( +// +fs.statSync(fileURLToPath(import.meta.url)).mtime, +// +fs.statSync(fileURLToPath(new URL('./utils.ts', import.meta.url))).mtime +// ); + /** * Utility function to work with code snippet caching. * @@ -526,12 +561,26 @@ async function create_snippet_cache(should: boolean) { const cache = new Map(); const directory = find_nearest_node_modules(import.meta.url) + '/.snippets'; + if (fs.existsSync(directory)) { + for (const dir of fs.readdirSync(directory)) { + if (!fs.statSync(`${directory}/${dir}`).isDirectory() || +dir < mtime) { + fs.rmSync(`${directory}/${dir}`, { force: true, recursive: true }); + } + } + } else { + fs.mkdirSync(directory); + } + + try { + fs.mkdirSync(`${directory}/${mtime}`); + } catch {} + function get_file(source: string) { const hash = createHash('sha256'); hash.update(source); const digest = hash.digest().toString('base64').replace(/\//g, '-'); - return `${directory}/${digest}.html`; + return `${directory}/${mtime}/${digest}.html`; } return { From 6861ca0735cc3b5ad683b1eed53a5c3db35b1ea6 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 8 Oct 2024 13:38:29 -0400 Subject: [PATCH 2/5] incorporate lockfile --- packages/site-kit/src/lib/markdown/renderer.ts | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/packages/site-kit/src/lib/markdown/renderer.ts b/packages/site-kit/src/lib/markdown/renderer.ts index bc9d3e6ba1..1099763574 100644 --- a/packages/site-kit/src/lib/markdown/renderer.ts +++ b/packages/site-kit/src/lib/markdown/renderer.ts @@ -534,14 +534,10 @@ function get_mtime(file: string, seen = new Set()) { return mtime; } -const mtime = get_mtime(fileURLToPath(import.meta.url)); - -// rough-and-ready way to invalidate the snippet cache when we update this file -// or utils.ts. A more complete solution would -// const mtime = Math.max( -// +fs.statSync(fileURLToPath(import.meta.url)).mtime, -// +fs.statSync(fileURLToPath(new URL('./utils.ts', import.meta.url))).mtime -// ); +const mtime = Math.max( + get_mtime(fileURLToPath(import.meta.url)), + +fs.statSync('../../pnpm-lock.yaml').mtime +); /** * Utility function to work with code snippet caching. From 1345031ef3f34bf34092e7263651815c594d3e48 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 8 Oct 2024 13:49:43 -0400 Subject: [PATCH 3/5] drive-by fix --- packages/site-kit/src/lib/markdown/renderer.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/site-kit/src/lib/markdown/renderer.ts b/packages/site-kit/src/lib/markdown/renderer.ts index 1099763574..9118f3b6f1 100644 --- a/packages/site-kit/src/lib/markdown/renderer.ts +++ b/packages/site-kit/src/lib/markdown/renderer.ts @@ -726,7 +726,15 @@ async function syntax_highlight({ html = await codeToHtml(source, { lang: 'ts', theme, - transformers: [transformerTwoslash({})] + transformers: [ + transformerTwoslash({ + twoslashOptions: { + compilerOptions: { + types: ['svelte', '@sveltejs/kit'] + } + } + }) + ] }); } catch (e) { console.error(`Error compiling snippet in ${filename}`); From c988485d0c7caa8fde0b43fa17ac99808efa230a Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 8 Oct 2024 14:01:31 -0400 Subject: [PATCH 4/5] use mtimeMs --- packages/site-kit/src/lib/markdown/renderer.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/site-kit/src/lib/markdown/renderer.ts b/packages/site-kit/src/lib/markdown/renderer.ts index 9118f3b6f1..618bef04fc 100644 --- a/packages/site-kit/src/lib/markdown/renderer.ts +++ b/packages/site-kit/src/lib/markdown/renderer.ts @@ -517,7 +517,7 @@ function get_mtime(file: string, seen = new Set()) { if (seen.has(file)) return -1; seen.add(file); - let mtime = +fs.statSync(file).mtime; + let mtime = fs.statSync(file).mtimeMs; const content = fs.readFileSync(file, 'utf-8'); for (const [_, source] of content.matchAll(/^import(?:.+?\s+from\s+)?['"](.+)['"];?$/gm)) { @@ -536,7 +536,7 @@ function get_mtime(file: string, seen = new Set()) { const mtime = Math.max( get_mtime(fileURLToPath(import.meta.url)), - +fs.statSync('../../pnpm-lock.yaml').mtime + fs.statSync('../../pnpm-lock.yaml').mtimeMs ); /** From 464abece0a35681197313cdde8010c0e7caff0f2 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 8 Oct 2024 14:31:11 -0400 Subject: [PATCH 5/5] belt and braces --- packages/site-kit/src/lib/markdown/renderer.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/site-kit/src/lib/markdown/renderer.ts b/packages/site-kit/src/lib/markdown/renderer.ts index 618bef04fc..1b9f38419a 100644 --- a/packages/site-kit/src/lib/markdown/renderer.ts +++ b/packages/site-kit/src/lib/markdown/renderer.ts @@ -536,6 +536,7 @@ function get_mtime(file: string, seen = new Set()) { const mtime = Math.max( get_mtime(fileURLToPath(import.meta.url)), + fs.statSync('node_modules').mtimeMs, fs.statSync('../../pnpm-lock.yaml').mtimeMs );