From 1e18609a781d36a9d658179db9297d2ffbae37b5 Mon Sep 17 00:00:00 2001
From: Stanislav Khromov
Date: Tue, 10 Dec 2024 00:19:48 +0100
Subject: [PATCH 01/49] wip
---
.../svelte.dev/src/routes/llms.txt/+server.ts | 66 +++++++++++++++++++
1 file changed, 66 insertions(+)
create mode 100644 apps/svelte.dev/src/routes/llms.txt/+server.ts
diff --git a/apps/svelte.dev/src/routes/llms.txt/+server.ts b/apps/svelte.dev/src/routes/llms.txt/+server.ts
new file mode 100644
index 0000000000..121aed068e
--- /dev/null
+++ b/apps/svelte.dev/src/routes/llms.txt/+server.ts
@@ -0,0 +1,66 @@
+import { read } from '$app/server';
+import type { RequestHandler } from './$types';
+
+// Import all markdown files
+const docs = import.meta.glob('../../../content/docs/**/*.md', {
+ eager: true,
+ query: '?raw'
+});
+
+// Sort function to ensure correct order (svelte -> kit -> cli)
+function getSectionPriority(path: string): number {
+ if (path.includes('/docs/svelte/')) return 0;
+ if (path.includes('/docs/kit/')) return 1;
+ if (path.includes('/docs/cli/')) return 2;
+ return 3;
+}
+
+export const GET: RequestHandler = async () => {
+ let content = '';
+
+ // Get all file paths and sort them
+ const paths = Object.keys(docs).sort((a, b) => {
+ const priorityA = getSectionPriority(a);
+ const priorityB = getSectionPriority(b);
+ if (priorityA !== priorityB) return priorityA - priorityB;
+ return a.localeCompare(b);
+ });
+
+ let currentSection = '';
+
+ // Process each file
+ for (const path of paths) {
+ // Determine section
+ let section = '';
+ if (path.includes('/docs/svelte/')) section = 'SVELTE DOCS';
+ else if (path.includes('/docs/kit/')) section = 'SVELTEKIT DOCS';
+ else if (path.includes('/docs/cli/')) section = 'CLI DOCS';
+ else continue; // Skip other content
+
+ // Add section header if we're entering a new section
+ if (section !== currentSection) {
+ if (currentSection) content += '\n\n';
+ content += '=====================================\n';
+ content += `============ ${section} ===========\n`;
+ content += '=====================================\n\n';
+ currentSection = section;
+ }
+
+ // Add file path and content
+ content += `File: ${path.replace('../../../content/', '')}\n\n`;
+ content += docs[path];
+ content += '\n\n-------------------\n\n';
+ }
+
+ const headers: HeadersInit = {
+ 'Content-Type': 'text/plain; charset=utf-8',
+ 'Cache-Control': 'public, max-age=3600'
+ };
+
+ return new Response(content, {
+ status: 200,
+ headers
+ });
+};
+
+export const prerender = true;
From d665b8697583abf0e2b554b94cf44e9a9944c81b Mon Sep 17 00:00:00 2001
From: Stanislav Khromov
Date: Tue, 10 Dec 2024 00:20:51 +0100
Subject: [PATCH 02/49] Update +server.ts
---
apps/svelte.dev/src/routes/llms.txt/+server.ts | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/apps/svelte.dev/src/routes/llms.txt/+server.ts b/apps/svelte.dev/src/routes/llms.txt/+server.ts
index 121aed068e..5d7738cfd6 100644
--- a/apps/svelte.dev/src/routes/llms.txt/+server.ts
+++ b/apps/svelte.dev/src/routes/llms.txt/+server.ts
@@ -1,8 +1,7 @@
-import { read } from '$app/server';
import type { RequestHandler } from './$types';
// Import all markdown files
-const docs = import.meta.glob('../../../content/docs/**/*.md', {
+const docs = import.meta.glob<{ default: string }>('../../../content/docs/**/*.md', {
eager: true,
query: '?raw'
});
@@ -48,7 +47,7 @@ export const GET: RequestHandler = async () => {
// Add file path and content
content += `File: ${path.replace('../../../content/', '')}\n\n`;
- content += docs[path];
+ content += docs[path].default; // Access the default export to get the actual content
content += '\n\n-------------------\n\n';
}
From d6041cefda5b916108fa3b622e35c099dd712f5f Mon Sep 17 00:00:00 2001
From: Stanislav Khromov
Date: Tue, 10 Dec 2024 00:27:17 +0100
Subject: [PATCH 03/49] Update +server.ts
---
.../svelte.dev/src/routes/llms.txt/+server.ts | 50 ++++++++++++-------
1 file changed, 33 insertions(+), 17 deletions(-)
diff --git a/apps/svelte.dev/src/routes/llms.txt/+server.ts b/apps/svelte.dev/src/routes/llms.txt/+server.ts
index 5d7738cfd6..89289a9bc3 100644
--- a/apps/svelte.dev/src/routes/llms.txt/+server.ts
+++ b/apps/svelte.dev/src/routes/llms.txt/+server.ts
@@ -1,5 +1,7 @@
import type { RequestHandler } from './$types';
+const PREFIX = 'This is the complete developer documentation for Svelte and SvelteKit.';
+
// Import all markdown files
const docs = import.meta.glob<{ default: string }>('../../../content/docs/**/*.md', {
eager: true,
@@ -14,16 +16,32 @@ function getSectionPriority(path: string): number {
return 3;
}
+function comparePaths(a: string, b: string): number {
+ // First compare by section
+ const priorityA = getSectionPriority(a);
+ const priorityB = getSectionPriority(b);
+ if (priorityA !== priorityB) return priorityA - priorityB;
+
+ // Get directory paths
+ const dirA = a.split('/').slice(0, -1).join('/');
+ const dirB = b.split('/').slice(0, -1).join('/');
+
+ // If in the same directory, prioritize index.md
+ if (dirA === dirB) {
+ if (a.endsWith('index.md')) return -1;
+ if (b.endsWith('index.md')) return 1;
+ return a.localeCompare(b);
+ }
+
+ // Otherwise sort by directory path
+ return dirA.localeCompare(dirB);
+}
+
export const GET: RequestHandler = async () => {
- let content = '';
+ let content = `${PREFIX}\n\n`;
// Get all file paths and sort them
- const paths = Object.keys(docs).sort((a, b) => {
- const priorityA = getSectionPriority(a);
- const priorityB = getSectionPriority(b);
- if (priorityA !== priorityB) return priorityA - priorityB;
- return a.localeCompare(b);
- });
+ const paths = Object.keys(docs).sort(comparePaths);
let currentSection = '';
@@ -31,24 +49,22 @@ export const GET: RequestHandler = async () => {
for (const path of paths) {
// Determine section
let section = '';
- if (path.includes('/docs/svelte/')) section = 'SVELTE DOCS';
- else if (path.includes('/docs/kit/')) section = 'SVELTEKIT DOCS';
- else if (path.includes('/docs/cli/')) section = 'CLI DOCS';
+ if (path.includes('/docs/svelte/')) section = 'Svelte documentation';
+ else if (path.includes('/docs/kit/')) section = 'SvelteKit documentation';
+ else if (path.includes('/docs/cli/')) section = 'Svelte CLI documentation';
else continue; // Skip other content
// Add section header if we're entering a new section
if (section !== currentSection) {
- if (currentSection) content += '\n\n';
- content += '=====================================\n';
- content += `============ ${section} ===========\n`;
- content += '=====================================\n\n';
+ if (currentSection) content += '\n';
+ content += `# Start of ${section}\n\n`;
currentSection = section;
}
// Add file path and content
- content += `File: ${path.replace('../../../content/', '')}\n\n`;
- content += docs[path].default; // Access the default export to get the actual content
- content += '\n\n-------------------\n\n';
+ content += `## ${path.replace('../../../content/', '')}\n\n`;
+ content += docs[path].default;
+ content += '\n';
}
const headers: HeadersInit = {
From b74efcac2381865875832fd14651562686df5db7 Mon Sep 17 00:00:00 2001
From: Stanislav Khromov
Date: Tue, 10 Dec 2024 21:57:46 +0100
Subject: [PATCH 04/49] wip
---
.../routes/docs/[...path]/llms.txt/+server.ts | 46 +++++++++++++++++++
1 file changed, 46 insertions(+)
create mode 100644 apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts
diff --git a/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts b/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts
new file mode 100644
index 0000000000..444fc81c34
--- /dev/null
+++ b/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts
@@ -0,0 +1,46 @@
+import type { RequestHandler } from './$types';
+// TODO: figure this out
+// import { index } from '$lib/server/content';
+import { error, json } from '@sveltejs/kit';
+
+const packages = ['svelte', 'kit', 'cli'];
+
+export const prerender = true;
+
+function filterDocs(allDocs: Record, type: string) {
+ const typePathMap = {
+ svelte: '/docs/svelte/',
+ kit: '/docs/kit/',
+ cli: '/docs/cli/'
+ } as const;
+
+ return Object.entries(allDocs).reduce(
+ (filtered, [path, content]) => {
+ if (path.includes(typePathMap[type as keyof typeof typePathMap])) {
+ filtered[path] = content;
+ }
+ return filtered;
+ },
+ {} as Record
+ );
+}
+
+export const GET: RequestHandler = async ({ params }) => {
+ const currentPackage = params.path;
+
+ if (!packages.includes(currentPackage)) {
+ error(404, {
+ message: 'Not Found'
+ });
+ }
+
+ const headers: HeadersInit = {
+ 'Content-Type': 'text/plain; charset=utf-8',
+ 'Cache-Control': 'public, max-age=3600'
+ };
+
+ return new Response('hello', {
+ status: 200,
+ headers
+ });
+};
From 437464f23c0019eb52f30b439df53c0db3713223 Mon Sep 17 00:00:00 2001
From: Stanislav Khromov
Date: Tue, 10 Dec 2024 22:04:33 +0100
Subject: [PATCH 05/49] wip
---
.../routes/docs/[...path]/llms.txt/+server.ts | 93 ++++++++++++++-----
1 file changed, 71 insertions(+), 22 deletions(-)
diff --git a/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts b/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts
index 444fc81c34..8a2d7cfd00 100644
--- a/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts
+++ b/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts
@@ -1,46 +1,95 @@
import type { RequestHandler } from './$types';
-// TODO: figure this out
-// import { index } from '$lib/server/content';
-import { error, json } from '@sveltejs/kit';
+import { error } from '@sveltejs/kit';
-const packages = ['svelte', 'kit', 'cli'];
+const PREFIX = 'This is the filtered developer documentation for Svelte and SvelteKit.';
-export const prerender = true;
+const packages = ['svelte', 'kit', 'cli'] as const;
+type Package = (typeof packages)[number];
+
+const docs = import.meta.glob('../../../../../content/docs/**/*.md', {
+ eager: true,
+ query: '?raw'
+});
-function filterDocs(allDocs: Record, type: string) {
+function filterDocs(allDocs: Record, type: Package) {
const typePathMap = {
- svelte: '/docs/svelte/',
- kit: '/docs/kit/',
- cli: '/docs/cli/'
+ svelte: 'svelte',
+ kit: 'kit',
+ cli: 'cli'
} as const;
return Object.entries(allDocs).reduce(
(filtered, [path, content]) => {
- if (path.includes(typePathMap[type as keyof typeof typePathMap])) {
+ const normalizedPath = path.toLowerCase();
+ if (normalizedPath.includes(`/docs/${typePathMap[type]}/`)) {
filtered[path] = content;
}
return filtered;
},
- {} as Record
+ {} as Record
);
}
+function sortPaths(paths: string[]): string[] {
+ return paths.sort((a, b) => {
+ // Get directory paths
+ const dirA = a.split('/').slice(0, -1).join('/');
+ const dirB = b.split('/').slice(0, -1).join('/');
+
+ // If in the same directory, prioritize index.md
+ if (dirA === dirB) {
+ if (a.endsWith('index.md')) return -1;
+ if (b.endsWith('index.md')) return 1;
+ return a.localeCompare(b);
+ }
+
+ // Otherwise sort by directory path
+ return dirA.localeCompare(dirB);
+ });
+}
+
+function generateContent(filteredDocs: Record, type: Package): string {
+ let content = `${PREFIX}\n\n# ${type} Documentation\n\n`;
+
+ // Get all file paths and sort them
+ const paths = sortPaths(Object.keys(filteredDocs));
+
+ // Log for debugging
+ console.log('Filtered paths:', paths);
+
+ // Process each file
+ for (const path of paths) {
+ content += `## ${path.replace('../../../../../content/', '')}\n\n`;
+ content += filteredDocs[path].default;
+ content += '\n\n';
+ }
+
+ return content;
+}
+
export const GET: RequestHandler = async ({ params }) => {
- const currentPackage = params.path;
+ // Extract the first part of the path (svelte, kit, or cli)
+ const [packageType] = params.path.split('/');
- if (!packages.includes(currentPackage)) {
- error(404, {
- message: 'Not Found'
- });
+ if (!packages.includes(packageType as Package)) {
+ error(404, 'Not Found');
}
- const headers: HeadersInit = {
- 'Content-Type': 'text/plain; charset=utf-8',
- 'Cache-Control': 'public, max-age=3600'
- };
+ const filteredDocs = filterDocs(docs, packageType as Package);
- return new Response('hello', {
+ if (Object.keys(filteredDocs).length === 0) {
+ error(404, 'No documentation found for this package');
+ }
+
+ const content = generateContent(filteredDocs, packageType as Package);
+
+ return new Response(content, {
status: 200,
- headers
+ headers: {
+ 'Content-Type': 'text/plain; charset=utf-8',
+ 'Cache-Control': 'public, max-age=3600'
+ }
});
};
+
+export const prerender = true;
From 15ed068412308c61ddb3fc7bc8a1c96ddd004c4e Mon Sep 17 00:00:00 2001
From: Stanislav Khromov
Date: Tue, 10 Dec 2024 22:07:27 +0100
Subject: [PATCH 06/49] Update +server.ts
---
.../svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts b/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts
index 8a2d7cfd00..247a3cfbfb 100644
--- a/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts
+++ b/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts
@@ -8,7 +8,8 @@ type Package = (typeof packages)[number];
const docs = import.meta.glob('../../../../../content/docs/**/*.md', {
eager: true,
- query: '?raw'
+ query: '?raw',
+ import: 'default'
});
function filterDocs(allDocs: Record, type: Package) {
@@ -60,7 +61,7 @@ function generateContent(filteredDocs: Record, type: Package): s
// Process each file
for (const path of paths) {
content += `## ${path.replace('../../../../../content/', '')}\n\n`;
- content += filteredDocs[path].default;
+ content += filteredDocs[path];
content += '\n\n';
}
From 98a9f907aac8b037d62817e8ca33b2f987a2da00 Mon Sep 17 00:00:00 2001
From: Stanislav Khromov
Date: Tue, 10 Dec 2024 22:36:20 +0100
Subject: [PATCH 07/49] Update +server.ts
---
.../routes/docs/[...path]/llms.txt/+server.ts | 64 +++++++++----------
1 file changed, 30 insertions(+), 34 deletions(-)
diff --git a/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts b/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts
index 247a3cfbfb..bab5d3846a 100644
--- a/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts
+++ b/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts
@@ -1,76 +1,74 @@
import type { RequestHandler } from './$types';
+import type { EntryGenerator } from './$types';
import { error } from '@sveltejs/kit';
-const PREFIX = 'This is the filtered developer documentation for Svelte and SvelteKit.';
-
const packages = ['svelte', 'kit', 'cli'] as const;
type Package = (typeof packages)[number];
+export const prerender = true;
+
+export const entries: EntryGenerator = () => {
+ return packages.map((type) => ({ path: type }));
+};
+
const docs = import.meta.glob('../../../../../content/docs/**/*.md', {
eager: true,
query: '?raw',
import: 'default'
});
-function filterDocs(allDocs: Record, type: Package) {
- const typePathMap = {
- svelte: 'svelte',
- kit: 'kit',
- cli: 'cli'
- } as const;
-
- return Object.entries(allDocs).reduce(
- (filtered, [path, content]) => {
- const normalizedPath = path.toLowerCase();
- if (normalizedPath.includes(`/docs/${typePathMap[type]}/`)) {
- filtered[path] = content;
- }
- return filtered;
- },
- {} as Record
- );
+function getPrefix(type: Package): string {
+ const names = {
+ svelte: 'Svelte',
+ kit: 'SvelteKit',
+ cli: 'Svelte CLI'
+ };
+ return `This is the developer documentation for ${names[type]}.`;
+}
+
+function filterDocs(allDocs: Record, type: Package): Record {
+ const filtered: Record = {};
+
+ for (const [path, content] of Object.entries(allDocs)) {
+ if (path.toLowerCase().includes(`/docs/${type}/`)) {
+ filtered[path] = content;
+ }
+ }
+
+ return filtered;
}
function sortPaths(paths: string[]): string[] {
return paths.sort((a, b) => {
- // Get directory paths
const dirA = a.split('/').slice(0, -1).join('/');
const dirB = b.split('/').slice(0, -1).join('/');
- // If in the same directory, prioritize index.md
if (dirA === dirB) {
if (a.endsWith('index.md')) return -1;
if (b.endsWith('index.md')) return 1;
return a.localeCompare(b);
}
- // Otherwise sort by directory path
return dirA.localeCompare(dirB);
});
}
function generateContent(filteredDocs: Record, type: Package): string {
- let content = `${PREFIX}\n\n# ${type} Documentation\n\n`;
+ let content = `${getPrefix(type)}\n\n`;
- // Get all file paths and sort them
const paths = sortPaths(Object.keys(filteredDocs));
- // Log for debugging
- console.log('Filtered paths:', paths);
-
- // Process each file
for (const path of paths) {
- content += `## ${path.replace('../../../../../content/', '')}\n\n`;
+ content += `# ${path.replace('../../../../../content/', '')}\n\n`;
content += filteredDocs[path];
- content += '\n\n';
+ content += '\n';
}
return content;
}
export const GET: RequestHandler = async ({ params }) => {
- // Extract the first part of the path (svelte, kit, or cli)
- const [packageType] = params.path.split('/');
+ const packageType = params.path;
if (!packages.includes(packageType as Package)) {
error(404, 'Not Found');
@@ -92,5 +90,3 @@ export const GET: RequestHandler = async ({ params }) => {
}
});
};
-
-export const prerender = true;
From 16046c0264a8916848a8bd9a6760bac693bba825 Mon Sep 17 00:00:00 2001
From: Stanislav Khromov
Date: Tue, 10 Dec 2024 22:41:02 +0100
Subject: [PATCH 08/49] wip
---
apps/svelte.dev/src/lib/server/content.ts | 6 ++++++
apps/svelte.dev/src/lib/server/llm-content.ts | 0
.../src/routes/docs/[...path]/llms.txt/+server.ts | 11 +++--------
3 files changed, 9 insertions(+), 8 deletions(-)
create mode 100644 apps/svelte.dev/src/lib/server/llm-content.ts
diff --git a/apps/svelte.dev/src/lib/server/content.ts b/apps/svelte.dev/src/lib/server/content.ts
index 45f0d4b0b2..d41745dd7e 100644
--- a/apps/svelte.dev/src/lib/server/content.ts
+++ b/apps/svelte.dev/src/lib/server/content.ts
@@ -14,6 +14,12 @@ const assets = import.meta.glob('../../../content/**/+assets/**', {
import: 'default'
});
+export const documentsContent = import.meta.glob('../../../content/**/*.md', {
+ eager: true,
+ query: '?raw',
+ import: 'default'
+});
+
// https://github.com/vitejs/vite/issues/17453
export const index = await create_index(documents, assets, '../../../content', read);
diff --git a/apps/svelte.dev/src/lib/server/llm-content.ts b/apps/svelte.dev/src/lib/server/llm-content.ts
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts b/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts
index bab5d3846a..2c94a49b0c 100644
--- a/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts
+++ b/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts
@@ -1,6 +1,7 @@
import type { RequestHandler } from './$types';
import type { EntryGenerator } from './$types';
import { error } from '@sveltejs/kit';
+import { documentsContent } from '$lib/server/content';
const packages = ['svelte', 'kit', 'cli'] as const;
type Package = (typeof packages)[number];
@@ -11,12 +12,6 @@ export const entries: EntryGenerator = () => {
return packages.map((type) => ({ path: type }));
};
-const docs = import.meta.glob('../../../../../content/docs/**/*.md', {
- eager: true,
- query: '?raw',
- import: 'default'
-});
-
function getPrefix(type: Package): string {
const names = {
svelte: 'Svelte',
@@ -59,7 +54,7 @@ function generateContent(filteredDocs: Record, type: Package): s
const paths = sortPaths(Object.keys(filteredDocs));
for (const path of paths) {
- content += `# ${path.replace('../../../../../content/', '')}\n\n`;
+ content += `# ${path.replace('../../../content/', '')}\n\n`;
content += filteredDocs[path];
content += '\n';
}
@@ -74,7 +69,7 @@ export const GET: RequestHandler = async ({ params }) => {
error(404, 'Not Found');
}
- const filteredDocs = filterDocs(docs, packageType as Package);
+ const filteredDocs = filterDocs(documentsContent, packageType as Package);
if (Object.keys(filteredDocs).length === 0) {
error(404, 'No documentation found for this package');
From c2534f9acefcd14b4e3033db5e24168a32b09423 Mon Sep 17 00:00:00 2001
From: Stanislav Khromov
Date: Tue, 10 Dec 2024 22:46:48 +0100
Subject: [PATCH 09/49] cleanup
---
apps/svelte.dev/src/lib/server/content.ts | 56 ++++++++++++++++
.../routes/docs/[...path]/llms.txt/+server.ts | 65 +++----------------
2 files changed, 65 insertions(+), 56 deletions(-)
diff --git a/apps/svelte.dev/src/lib/server/content.ts b/apps/svelte.dev/src/lib/server/content.ts
index d41745dd7e..b2dbdc9c2a 100644
--- a/apps/svelte.dev/src/lib/server/content.ts
+++ b/apps/svelte.dev/src/lib/server/content.ts
@@ -129,3 +129,59 @@ function create_docs() {
export const docs = create_docs();
export const examples = index.examples.children;
+
+function sortPaths(paths: string[]): string[] {
+ return paths.sort((a, b) => {
+ const dirA = a.split('/').slice(0, -1).join('/');
+ const dirB = b.split('/').slice(0, -1).join('/');
+
+ if (dirA === dirB) {
+ if (a.endsWith('index.md')) return -1;
+ if (b.endsWith('index.md')) return 1;
+ return a.localeCompare(b);
+ }
+
+ return dirA.localeCompare(dirB);
+ });
+}
+
+export const packages = ['svelte', 'kit', 'cli'] as const;
+export type Package = (typeof packages)[number];
+
+function getDocumentationTitle(type: Package): string {
+ const names = {
+ svelte: 'Svelte',
+ kit: 'SvelteKit',
+ cli: 'Svelte CLI'
+ };
+ return `This is the developer documentation for ${names[type]}.`;
+}
+
+export function filterDocsByPackage(
+ allDocs: Record,
+ type: Package
+): Record {
+ const filtered: Record = {};
+
+ for (const [path, content] of Object.entries(allDocs)) {
+ if (path.toLowerCase().includes(`/docs/${type}/`)) {
+ filtered[path] = content;
+ }
+ }
+
+ return filtered;
+}
+
+export function generateLlmContent(filteredDocs: Record, type: Package): string {
+ let content = `${getDocumentationTitle(type)}\n\n`;
+
+ const paths = sortPaths(Object.keys(filteredDocs));
+
+ for (const path of paths) {
+ content += `# ${path.replace('../../../content/', '')}\n\n`;
+ content += filteredDocs[path];
+ content += '\n';
+ }
+
+ return content;
+}
diff --git a/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts b/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts
index 2c94a49b0c..137c0f3135 100644
--- a/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts
+++ b/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts
@@ -1,10 +1,13 @@
import type { RequestHandler } from './$types';
import type { EntryGenerator } from './$types';
import { error } from '@sveltejs/kit';
-import { documentsContent } from '$lib/server/content';
-
-const packages = ['svelte', 'kit', 'cli'] as const;
-type Package = (typeof packages)[number];
+import {
+ documentsContent,
+ filterDocsByPackage,
+ generateLlmContent,
+ packages,
+ type Package
+} from '$lib/server/content';
export const prerender = true;
@@ -12,56 +15,6 @@ export const entries: EntryGenerator = () => {
return packages.map((type) => ({ path: type }));
};
-function getPrefix(type: Package): string {
- const names = {
- svelte: 'Svelte',
- kit: 'SvelteKit',
- cli: 'Svelte CLI'
- };
- return `This is the developer documentation for ${names[type]}.`;
-}
-
-function filterDocs(allDocs: Record, type: Package): Record {
- const filtered: Record = {};
-
- for (const [path, content] of Object.entries(allDocs)) {
- if (path.toLowerCase().includes(`/docs/${type}/`)) {
- filtered[path] = content;
- }
- }
-
- return filtered;
-}
-
-function sortPaths(paths: string[]): string[] {
- return paths.sort((a, b) => {
- const dirA = a.split('/').slice(0, -1).join('/');
- const dirB = b.split('/').slice(0, -1).join('/');
-
- if (dirA === dirB) {
- if (a.endsWith('index.md')) return -1;
- if (b.endsWith('index.md')) return 1;
- return a.localeCompare(b);
- }
-
- return dirA.localeCompare(dirB);
- });
-}
-
-function generateContent(filteredDocs: Record, type: Package): string {
- let content = `${getPrefix(type)}\n\n`;
-
- const paths = sortPaths(Object.keys(filteredDocs));
-
- for (const path of paths) {
- content += `# ${path.replace('../../../content/', '')}\n\n`;
- content += filteredDocs[path];
- content += '\n';
- }
-
- return content;
-}
-
export const GET: RequestHandler = async ({ params }) => {
const packageType = params.path;
@@ -69,13 +22,13 @@ export const GET: RequestHandler = async ({ params }) => {
error(404, 'Not Found');
}
- const filteredDocs = filterDocs(documentsContent, packageType as Package);
+ const filteredDocs = filterDocsByPackage(documentsContent, packageType as Package);
if (Object.keys(filteredDocs).length === 0) {
error(404, 'No documentation found for this package');
}
- const content = generateContent(filteredDocs, packageType as Package);
+ const content = generateLlmContent(filteredDocs, packageType as Package);
return new Response(content, {
status: 200,
From 0d295843868bd76bbb058b01bf085f747176e786 Mon Sep 17 00:00:00 2001
From: Stanislav Khromov
Date: Tue, 10 Dec 2024 22:48:58 +0100
Subject: [PATCH 10/49] wip
---
apps/svelte.dev/src/lib/server/llm-content.ts | 0
apps/svelte.dev/src/routes/llms.txt/+server.ts | 13 ++++---------
2 files changed, 4 insertions(+), 9 deletions(-)
delete mode 100644 apps/svelte.dev/src/lib/server/llm-content.ts
diff --git a/apps/svelte.dev/src/lib/server/llm-content.ts b/apps/svelte.dev/src/lib/server/llm-content.ts
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/apps/svelte.dev/src/routes/llms.txt/+server.ts b/apps/svelte.dev/src/routes/llms.txt/+server.ts
index 89289a9bc3..a759d6e9ea 100644
--- a/apps/svelte.dev/src/routes/llms.txt/+server.ts
+++ b/apps/svelte.dev/src/routes/llms.txt/+server.ts
@@ -1,12 +1,7 @@
import type { RequestHandler } from './$types';
+import { documentsContent } from '$lib/server/content';
-const PREFIX = 'This is the complete developer documentation for Svelte and SvelteKit.';
-
-// Import all markdown files
-const docs = import.meta.glob<{ default: string }>('../../../content/docs/**/*.md', {
- eager: true,
- query: '?raw'
-});
+const PREFIX = 'This is the abridged developer documentation for Svelte and SvelteKit.';
// Sort function to ensure correct order (svelte -> kit -> cli)
function getSectionPriority(path: string): number {
@@ -41,7 +36,7 @@ export const GET: RequestHandler = async () => {
let content = `${PREFIX}\n\n`;
// Get all file paths and sort them
- const paths = Object.keys(docs).sort(comparePaths);
+ const paths = Object.keys(documentsContent).sort(comparePaths);
let currentSection = '';
@@ -63,7 +58,7 @@ export const GET: RequestHandler = async () => {
// Add file path and content
content += `## ${path.replace('../../../content/', '')}\n\n`;
- content += docs[path].default;
+ content += documentsContent[path];
content += '\n';
}
From 6d05a5a8543270796d37e6b5adc1a7ace0ee7b91 Mon Sep 17 00:00:00 2001
From: Stanislav Khromov
Date: Tue, 10 Dec 2024 22:52:24 +0100
Subject: [PATCH 11/49] refactor
---
apps/svelte.dev/src/lib/server/content.ts | 17 +++++++++-
.../svelte.dev/src/routes/llms.txt/+server.ts | 33 ++-----------------
2 files changed, 18 insertions(+), 32 deletions(-)
diff --git a/apps/svelte.dev/src/lib/server/content.ts b/apps/svelte.dev/src/lib/server/content.ts
index b2dbdc9c2a..797f038f8d 100644
--- a/apps/svelte.dev/src/lib/server/content.ts
+++ b/apps/svelte.dev/src/lib/server/content.ts
@@ -130,17 +130,32 @@ export const docs = create_docs();
export const examples = index.examples.children;
-function sortPaths(paths: string[]): string[] {
+function getSectionPriority(path: string): number {
+ if (path.includes('/docs/svelte/')) return 0;
+ if (path.includes('/docs/kit/')) return 1;
+ if (path.includes('/docs/cli/')) return 2;
+ return 3;
+}
+
+export function sortPaths(paths: string[]): string[] {
return paths.sort((a, b) => {
+ // First compare by section priority
+ const priorityA = getSectionPriority(a);
+ const priorityB = getSectionPriority(b);
+ if (priorityA !== priorityB) return priorityA - priorityB;
+
+ // Get directory paths
const dirA = a.split('/').slice(0, -1).join('/');
const dirB = b.split('/').slice(0, -1).join('/');
+ // If in the same directory, prioritize index.md
if (dirA === dirB) {
if (a.endsWith('index.md')) return -1;
if (b.endsWith('index.md')) return 1;
return a.localeCompare(b);
}
+ // Otherwise sort by directory path
return dirA.localeCompare(dirB);
});
}
diff --git a/apps/svelte.dev/src/routes/llms.txt/+server.ts b/apps/svelte.dev/src/routes/llms.txt/+server.ts
index a759d6e9ea..630061d38c 100644
--- a/apps/svelte.dev/src/routes/llms.txt/+server.ts
+++ b/apps/svelte.dev/src/routes/llms.txt/+server.ts
@@ -1,42 +1,13 @@
import type { RequestHandler } from './$types';
-import { documentsContent } from '$lib/server/content';
+import { documentsContent, sortPaths } from '$lib/server/content';
const PREFIX = 'This is the abridged developer documentation for Svelte and SvelteKit.';
-// Sort function to ensure correct order (svelte -> kit -> cli)
-function getSectionPriority(path: string): number {
- if (path.includes('/docs/svelte/')) return 0;
- if (path.includes('/docs/kit/')) return 1;
- if (path.includes('/docs/cli/')) return 2;
- return 3;
-}
-
-function comparePaths(a: string, b: string): number {
- // First compare by section
- const priorityA = getSectionPriority(a);
- const priorityB = getSectionPriority(b);
- if (priorityA !== priorityB) return priorityA - priorityB;
-
- // Get directory paths
- const dirA = a.split('/').slice(0, -1).join('/');
- const dirB = b.split('/').slice(0, -1).join('/');
-
- // If in the same directory, prioritize index.md
- if (dirA === dirB) {
- if (a.endsWith('index.md')) return -1;
- if (b.endsWith('index.md')) return 1;
- return a.localeCompare(b);
- }
-
- // Otherwise sort by directory path
- return dirA.localeCompare(dirB);
-}
-
export const GET: RequestHandler = async () => {
let content = `${PREFIX}\n\n`;
// Get all file paths and sort them
- const paths = Object.keys(documentsContent).sort(comparePaths);
+ const paths = sortPaths(Object.keys(documentsContent));
let currentSection = '';
From 464630fcb49a09b85a72b8b2a8924c77fa7c8727 Mon Sep 17 00:00:00 2001
From: Stanislav Khromov
Date: Tue, 10 Dec 2024 22:58:03 +0100
Subject: [PATCH 12/49] cleanupo
---
apps/svelte.dev/src/lib/server/content.ts | 19 ++++++++++------
.../svelte.dev/src/routes/llms.txt/+server.ts | 22 +++++++++----------
2 files changed, 23 insertions(+), 18 deletions(-)
diff --git a/apps/svelte.dev/src/lib/server/content.ts b/apps/svelte.dev/src/lib/server/content.ts
index 797f038f8d..765ccd3479 100644
--- a/apps/svelte.dev/src/lib/server/content.ts
+++ b/apps/svelte.dev/src/lib/server/content.ts
@@ -163,13 +163,18 @@ export function sortPaths(paths: string[]): string[] {
export const packages = ['svelte', 'kit', 'cli'] as const;
export type Package = (typeof packages)[number];
-function getDocumentationTitle(type: Package): string {
- const names = {
- svelte: 'Svelte',
- kit: 'SvelteKit',
- cli: 'Svelte CLI'
- };
- return `This is the developer documentation for ${names[type]}.`;
+const documentationNames = {
+ svelte: 'Svelte',
+ kit: 'SvelteKit',
+ cli: 'Svelte CLI'
+};
+
+export function getDocumentationTitle(type: Package): string {
+ return `This is the developer documentation for ${documentationNames[type]}.`;
+}
+
+export function getDocumentationStartTitle(type: Package): string {
+ return `# Start of ${documentationNames[type]} documentation`;
}
export function filterDocsByPackage(
diff --git a/apps/svelte.dev/src/routes/llms.txt/+server.ts b/apps/svelte.dev/src/routes/llms.txt/+server.ts
index 630061d38c..6603a7cb9a 100644
--- a/apps/svelte.dev/src/routes/llms.txt/+server.ts
+++ b/apps/svelte.dev/src/routes/llms.txt/+server.ts
@@ -1,33 +1,33 @@
import type { RequestHandler } from './$types';
-import { documentsContent, sortPaths } from '$lib/server/content';
+import {
+ documentsContent,
+ getDocumentationStartTitle,
+ getDocumentationTitle,
+ sortPaths
+} from '$lib/server/content';
const PREFIX = 'This is the abridged developer documentation for Svelte and SvelteKit.';
export const GET: RequestHandler = async () => {
let content = `${PREFIX}\n\n`;
- // Get all file paths and sort them
const paths = sortPaths(Object.keys(documentsContent));
let currentSection = '';
- // Process each file
for (const path of paths) {
- // Determine section
let section = '';
- if (path.includes('/docs/svelte/')) section = 'Svelte documentation';
- else if (path.includes('/docs/kit/')) section = 'SvelteKit documentation';
- else if (path.includes('/docs/cli/')) section = 'Svelte CLI documentation';
- else continue; // Skip other content
+ if (path.includes('/docs/svelte/')) section = `${getDocumentationStartTitle('svelte')}`;
+ else if (path.includes('/docs/kit/')) section = `${getDocumentationStartTitle('kit')}`;
+ else if (path.includes('/docs/cli/')) section = `${getDocumentationStartTitle('cli')}`;
+ else continue;
- // Add section header if we're entering a new section
if (section !== currentSection) {
if (currentSection) content += '\n';
- content += `# Start of ${section}\n\n`;
+ content += `${section}\n\n`;
currentSection = section;
}
- // Add file path and content
content += `## ${path.replace('../../../content/', '')}\n\n`;
content += documentsContent[path];
content += '\n';
From 42388876aefc4bec6c22c386c81bb53fe2bd7f88 Mon Sep 17 00:00:00 2001
From: Stanislav Khromov
Date: Tue, 10 Dec 2024 22:59:37 +0100
Subject: [PATCH 13/49] Update +server.ts
---
apps/svelte.dev/src/routes/llms.txt/+server.ts | 13 ++++---------
1 file changed, 4 insertions(+), 9 deletions(-)
diff --git a/apps/svelte.dev/src/routes/llms.txt/+server.ts b/apps/svelte.dev/src/routes/llms.txt/+server.ts
index 6603a7cb9a..249b65f484 100644
--- a/apps/svelte.dev/src/routes/llms.txt/+server.ts
+++ b/apps/svelte.dev/src/routes/llms.txt/+server.ts
@@ -1,10 +1,5 @@
import type { RequestHandler } from './$types';
-import {
- documentsContent,
- getDocumentationStartTitle,
- getDocumentationTitle,
- sortPaths
-} from '$lib/server/content';
+import { documentsContent, getDocumentationStartTitle, sortPaths } from '$lib/server/content';
const PREFIX = 'This is the abridged developer documentation for Svelte and SvelteKit.';
@@ -17,9 +12,9 @@ export const GET: RequestHandler = async () => {
for (const path of paths) {
let section = '';
- if (path.includes('/docs/svelte/')) section = `${getDocumentationStartTitle('svelte')}`;
- else if (path.includes('/docs/kit/')) section = `${getDocumentationStartTitle('kit')}`;
- else if (path.includes('/docs/cli/')) section = `${getDocumentationStartTitle('cli')}`;
+ if (path.includes('/docs/svelte/')) section = getDocumentationStartTitle('svelte');
+ else if (path.includes('/docs/kit/')) section = getDocumentationStartTitle('kit');
+ else if (path.includes('/docs/cli/')) section = getDocumentationStartTitle('cli');
else continue;
if (section !== currentSection) {
From d4943341e1138813c8cc9ffd93232b137073e6c9 Mon Sep 17 00:00:00 2001
From: Stanislav Khromov
Date: Tue, 10 Dec 2024 23:01:00 +0100
Subject: [PATCH 14/49] Update content.ts
---
apps/svelte.dev/src/lib/server/content.ts | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/apps/svelte.dev/src/lib/server/content.ts b/apps/svelte.dev/src/lib/server/content.ts
index 765ccd3479..828b8d1cf1 100644
--- a/apps/svelte.dev/src/lib/server/content.ts
+++ b/apps/svelte.dev/src/lib/server/content.ts
@@ -163,18 +163,18 @@ export function sortPaths(paths: string[]): string[] {
export const packages = ['svelte', 'kit', 'cli'] as const;
export type Package = (typeof packages)[number];
-const documentationNames = {
+const DOCUMENTATION_NAMES: Record = {
svelte: 'Svelte',
kit: 'SvelteKit',
cli: 'Svelte CLI'
};
export function getDocumentationTitle(type: Package): string {
- return `This is the developer documentation for ${documentationNames[type]}.`;
+ return `This is the developer documentation for ${DOCUMENTATION_NAMES[type]}.`;
}
export function getDocumentationStartTitle(type: Package): string {
- return `# Start of ${documentationNames[type]} documentation`;
+ return `# Start of ${DOCUMENTATION_NAMES[type]} documentation`;
}
export function filterDocsByPackage(
From 4315f7ab2ee6c0becbe0df14a5724de397843e7a Mon Sep 17 00:00:00 2001
From: Stanislav Khromov
Date: Tue, 10 Dec 2024 23:02:49 +0100
Subject: [PATCH 15/49] wip
---
apps/svelte.dev/src/lib/server/content.ts | 24 +++++++++++++
.../svelte.dev/src/routes/llms.txt/+server.ts | 36 ++++---------------
2 files changed, 30 insertions(+), 30 deletions(-)
diff --git a/apps/svelte.dev/src/lib/server/content.ts b/apps/svelte.dev/src/lib/server/content.ts
index 828b8d1cf1..07e03fc7cb 100644
--- a/apps/svelte.dev/src/lib/server/content.ts
+++ b/apps/svelte.dev/src/lib/server/content.ts
@@ -205,3 +205,27 @@ export function generateLlmContent(filteredDocs: Record, type: P
return content;
}
+
+export function generateCombinedContent(documentsContent: Record): string {
+ let content = '';
+ let currentSection = '';
+ const paths = sortPaths(Object.keys(documentsContent));
+
+ for (const path of paths) {
+ const docType = packages.find((pkg) => path.includes(`/docs/${pkg}/`));
+ if (!docType) continue;
+
+ const section = getDocumentationStartTitle(docType);
+ if (section !== currentSection) {
+ if (currentSection) content += '\n';
+ content += `${section}\n\n`;
+ currentSection = section;
+ }
+
+ content += `## ${path.replace('../../../content/', '')}\n\n`;
+ content += documentsContent[path];
+ content += '\n';
+ }
+
+ return content;
+}
diff --git a/apps/svelte.dev/src/routes/llms.txt/+server.ts b/apps/svelte.dev/src/routes/llms.txt/+server.ts
index 249b65f484..8e6cbef44d 100644
--- a/apps/svelte.dev/src/routes/llms.txt/+server.ts
+++ b/apps/svelte.dev/src/routes/llms.txt/+server.ts
@@ -1,41 +1,17 @@
import type { RequestHandler } from './$types';
-import { documentsContent, getDocumentationStartTitle, sortPaths } from '$lib/server/content';
+import { documentsContent, generateCombinedContent } from '$lib/server/content';
const PREFIX = 'This is the abridged developer documentation for Svelte and SvelteKit.';
export const GET: RequestHandler = async () => {
- let content = `${PREFIX}\n\n`;
-
- const paths = sortPaths(Object.keys(documentsContent));
-
- let currentSection = '';
-
- for (const path of paths) {
- let section = '';
- if (path.includes('/docs/svelte/')) section = getDocumentationStartTitle('svelte');
- else if (path.includes('/docs/kit/')) section = getDocumentationStartTitle('kit');
- else if (path.includes('/docs/cli/')) section = getDocumentationStartTitle('cli');
- else continue;
-
- if (section !== currentSection) {
- if (currentSection) content += '\n';
- content += `${section}\n\n`;
- currentSection = section;
- }
-
- content += `## ${path.replace('../../../content/', '')}\n\n`;
- content += documentsContent[path];
- content += '\n';
- }
-
- const headers: HeadersInit = {
- 'Content-Type': 'text/plain; charset=utf-8',
- 'Cache-Control': 'public, max-age=3600'
- };
+ const content = `${PREFIX}\n\n${generateCombinedContent(documentsContent)}`;
return new Response(content, {
status: 200,
- headers
+ headers: {
+ 'Content-Type': 'text/plain; charset=utf-8',
+ 'Cache-Control': 'public, max-age=3600'
+ }
});
};
From 7bb3ebd0b846e4d034cbf30b606c84715c19bfce Mon Sep 17 00:00:00 2001
From: Stanislav Khromov
Date: Tue, 10 Dec 2024 23:05:38 +0100
Subject: [PATCH 16/49] Create +server.ts
---
.../src/routes/llms-full.txt/+server.ts | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
create mode 100644 apps/svelte.dev/src/routes/llms-full.txt/+server.ts
diff --git a/apps/svelte.dev/src/routes/llms-full.txt/+server.ts b/apps/svelte.dev/src/routes/llms-full.txt/+server.ts
new file mode 100644
index 0000000000..fca5eb6168
--- /dev/null
+++ b/apps/svelte.dev/src/routes/llms-full.txt/+server.ts
@@ -0,0 +1,18 @@
+import type { RequestHandler } from './$types';
+import { documentsContent, generateCombinedContent } from '$lib/server/content';
+
+const PREFIX = 'This is the full developer documentation for Svelte and SvelteKit.';
+
+export const GET: RequestHandler = async () => {
+ const content = `${PREFIX}\n\n${generateCombinedContent(documentsContent)}`;
+
+ return new Response(content, {
+ status: 200,
+ headers: {
+ 'Content-Type': 'text/plain; charset=utf-8',
+ 'Cache-Control': 'public, max-age=3600'
+ }
+ });
+};
+
+export const prerender = true;
From 8612605bf65a4ff0c3e69709c7a9016d99d0fde3 Mon Sep 17 00:00:00 2001
From: Stanislav Khromov
Date: Tue, 10 Dec 2024 23:39:07 +0100
Subject: [PATCH 17/49] minimize llms.txt
---
apps/svelte.dev/src/lib/server/content.ts | 101 +++++++++++++++++-
.../svelte.dev/src/routes/llms.txt/+server.ts | 9 +-
2 files changed, 105 insertions(+), 5 deletions(-)
diff --git a/apps/svelte.dev/src/lib/server/content.ts b/apps/svelte.dev/src/lib/server/content.ts
index 07e03fc7cb..a9c155fe5a 100644
--- a/apps/svelte.dev/src/lib/server/content.ts
+++ b/apps/svelte.dev/src/lib/server/content.ts
@@ -192,21 +192,111 @@ export function filterDocsByPackage(
return filtered;
}
-export function generateLlmContent(filteredDocs: Record, type: Package): string {
+interface MinimizeOptions {
+ removeLegacy: boolean;
+ removeNoteBlocks: boolean;
+ removeDetailsBlocks: boolean;
+ removePlaygroundLinks: boolean;
+ removePrettierIgnore: boolean;
+ normalizeWhitespace: boolean;
+}
+
+const defaultOptions: MinimizeOptions = {
+ removeLegacy: false,
+ removeNoteBlocks: false,
+ removeDetailsBlocks: false,
+ removePlaygroundLinks: false,
+ removePrettierIgnore: false,
+ normalizeWhitespace: false
+};
+
+function removeQuoteBlocks(content: string, blockType: string): string {
+ return content
+ .split('\n')
+ .reduce((acc: string[], line: string, index: number, lines: string[]) => {
+ // If we find a block (with or without additional text), skip it and all subsequent blockquote lines
+ if (line.trim().startsWith(`> [!${blockType}]`)) {
+ // Skip all subsequent lines that are part of the blockquote
+ let i = index;
+ while (i < lines.length && (lines[i].startsWith('>') || lines[i].trim() === '')) {
+ i++;
+ }
+ // Update the index to skip all these lines
+ index = i - 1;
+ return acc;
+ }
+
+ // Only add the line if it's not being skipped
+ acc.push(line);
+ return acc;
+ }, [])
+ .join('\n');
+}
+
+function minimizeContent(content: string, options?: Partial): string {
+ // Merge with defaults, but only for properties that are defined
+ const settings: MinimizeOptions = options ? { ...defaultOptions, ...options } : defaultOptions;
+
+ let minimized = content;
+
+ if (settings.removeLegacy) {
+ minimized = removeQuoteBlocks(minimized, 'LEGACY');
+ }
+
+ if (settings.removeNoteBlocks) {
+ minimized = removeQuoteBlocks(minimized, 'NOTE');
+ }
+
+ if (settings.removeDetailsBlocks) {
+ minimized = removeQuoteBlocks(minimized, 'DETAILS');
+ }
+
+ if (settings.removePlaygroundLinks) {
+ // Replace playground URLs with /[link] but keep the original link text
+ minimized = minimized.replace(/\[([^\]]+)\]\(\/playground[^)]+\)/g, '[$1](/REMOVED)');
+ }
+
+ if (settings.removePrettierIgnore) {
+ minimized = minimized
+ .split('\n')
+ .filter((line) => line.trim() !== '')
+ .join('\n');
+ }
+
+ if (settings.normalizeWhitespace) {
+ minimized = minimized.replace(/\s+/g, ' ');
+ }
+
+ minimized = minimized.trim();
+
+ return minimized;
+}
+
+export function generateLlmContent(
+ filteredDocs: Record,
+ type: Package,
+ minimizeOptions?: Partial
+): string {
let content = `${getDocumentationTitle(type)}\n\n`;
const paths = sortPaths(Object.keys(filteredDocs));
for (const path of paths) {
content += `# ${path.replace('../../../content/', '')}\n\n`;
- content += filteredDocs[path];
+ const docContent = minimizeOptions
+ ? minimizeContent(filteredDocs[path], minimizeOptions)
+ : filteredDocs[path];
+ content += docContent;
content += '\n';
}
return content;
}
-export function generateCombinedContent(documentsContent: Record): string {
+export function generateCombinedContent(
+ documentsContent: Record,
+ minimizeOptions?: Partial
+): string {
let content = '';
let currentSection = '';
const paths = sortPaths(Object.keys(documentsContent));
@@ -223,7 +313,10 @@ export function generateCombinedContent(documentsContent: Record
}
content += `## ${path.replace('../../../content/', '')}\n\n`;
- content += documentsContent[path];
+ const docContent = minimizeOptions
+ ? minimizeContent(documentsContent[path], minimizeOptions)
+ : documentsContent[path];
+ content += docContent;
content += '\n';
}
diff --git a/apps/svelte.dev/src/routes/llms.txt/+server.ts b/apps/svelte.dev/src/routes/llms.txt/+server.ts
index 8e6cbef44d..08c3db8661 100644
--- a/apps/svelte.dev/src/routes/llms.txt/+server.ts
+++ b/apps/svelte.dev/src/routes/llms.txt/+server.ts
@@ -4,7 +4,14 @@ import { documentsContent, generateCombinedContent } from '$lib/server/content';
const PREFIX = 'This is the abridged developer documentation for Svelte and SvelteKit.';
export const GET: RequestHandler = async () => {
- const content = `${PREFIX}\n\n${generateCombinedContent(documentsContent)}`;
+ const content = `${PREFIX}\n\n${generateCombinedContent(documentsContent, {
+ removeLegacy: true,
+ removeNoteBlocks: true,
+ removeDetailsBlocks: true,
+ removePlaygroundLinks: true,
+ removePrettierIgnore: true,
+ normalizeWhitespace: true
+ })}`;
return new Response(content, {
status: 200,
From 8b2544ce9131c7067dbaeb2cb6a3144eb6e50d9d Mon Sep 17 00:00:00 2001
From: Stanislav Khromov
Date: Tue, 10 Dec 2024 23:52:50 +0100
Subject: [PATCH 18/49] Filter llms.txt
---
apps/svelte.dev/package.json | 1 +
apps/svelte.dev/src/lib/server/content.ts | 16 ++++++++
.../svelte.dev/src/routes/llms.txt/+server.ts | 41 +++++++++++++++----
pnpm-lock.yaml | 11 +++++
4 files changed, 61 insertions(+), 8 deletions(-)
diff --git a/apps/svelte.dev/package.json b/apps/svelte.dev/package.json
index 54a05f92d9..d08543e290 100644
--- a/apps/svelte.dev/package.json
+++ b/apps/svelte.dev/package.json
@@ -68,6 +68,7 @@
"lightningcss": "^1.25.1",
"magic-string": "^0.30.11",
"marked": "^14.1.2",
+ "minimatch": "^10.0.1",
"prettier": "^3.3.2",
"prettier-plugin-svelte": "^3.2.4",
"satori": "^0.10.13",
diff --git a/apps/svelte.dev/src/lib/server/content.ts b/apps/svelte.dev/src/lib/server/content.ts
index a9c155fe5a..d99520c481 100644
--- a/apps/svelte.dev/src/lib/server/content.ts
+++ b/apps/svelte.dev/src/lib/server/content.ts
@@ -1,6 +1,8 @@
+import { dev } from '$app/environment';
import { read } from '$app/server';
import type { Document } from '@sveltejs/site-kit';
import { create_index } from '@sveltejs/site-kit/server/content';
+import { minimatch } from 'minimatch';
const documents = import.meta.glob('../../../content/**/*.md', {
eager: true,
@@ -272,6 +274,16 @@ function minimizeContent(content: string, options?: Partial): s
return minimized;
}
+function shouldIncludeFile(filename: string, ignore: string[] = []): boolean {
+ const shouldIgnore = ignore.some((pattern) => minimatch(filename, pattern));
+ if (shouldIgnore) {
+ if (dev) console.log(`❌ Ignored by pattern: ${filename}`);
+ return false;
+ }
+
+ return true;
+}
+
export function generateLlmContent(
filteredDocs: Record,
type: Package,
@@ -295,6 +307,7 @@ export function generateLlmContent(
export function generateCombinedContent(
documentsContent: Record,
+ ignore: string[] = [],
minimizeOptions?: Partial
): string {
let content = '';
@@ -302,6 +315,9 @@ export function generateCombinedContent(
const paths = sortPaths(Object.keys(documentsContent));
for (const path of paths) {
+ // Skip files that match ignore patterns
+ if (!shouldIncludeFile(path, ignore)) continue;
+
const docType = packages.find((pkg) => path.includes(`/docs/${pkg}/`));
if (!docType) continue;
diff --git a/apps/svelte.dev/src/routes/llms.txt/+server.ts b/apps/svelte.dev/src/routes/llms.txt/+server.ts
index 08c3db8661..05b344a870 100644
--- a/apps/svelte.dev/src/routes/llms.txt/+server.ts
+++ b/apps/svelte.dev/src/routes/llms.txt/+server.ts
@@ -4,14 +4,39 @@ import { documentsContent, generateCombinedContent } from '$lib/server/content';
const PREFIX = 'This is the abridged developer documentation for Svelte and SvelteKit.';
export const GET: RequestHandler = async () => {
- const content = `${PREFIX}\n\n${generateCombinedContent(documentsContent, {
- removeLegacy: true,
- removeNoteBlocks: true,
- removeDetailsBlocks: true,
- removePlaygroundLinks: true,
- removePrettierIgnore: true,
- normalizeWhitespace: true
- })}`;
+ const content = `${PREFIX}\n\n${generateCombinedContent(
+ documentsContent,
+ [
+ // Svelte ignores
+ '../../../content/docs/svelte/07-misc/04-custom-elements.md',
+ '../../../content/docs/svelte/07-misc/06-v4-migration-guide.md',
+ '../../../content/docs/svelte/07-misc/07-v5-migration-guide.md',
+ '../../../content/docs/svelte/07-misc/99-faq.md',
+ '../../../content/docs/svelte/07-misc/xx-reactivity-indepth.md',
+ '../../../content/docs/svelte/98-reference/21-svelte-legacy.md',
+ '../../../content/docs/svelte/99-legacy/**/*.md',
+ '../../../content/docs/svelte/98-reference/30-runtime-errors.md',
+ '../../../content/docs/svelte/98-reference/30-runtime-warnings.md',
+ '../../../content/docs/svelte/98-reference/30-compiler-errors.md',
+ '../../../content/docs/svelte/98-reference/30-compiler-warnings.md',
+ '**/xx-*.md',
+
+ // SvelteKit ignores
+ '../../../content/docs/kit/25-build-and-deploy/*adapter-*.md',
+ '../../../content/docs/kit/25-build-and-deploy/99-writing-adapters.md',
+ '../../../content/docs/kit/30-advanced/70-packaging.md',
+ '../../../content/docs/kit/40-best-practices/05-performance.md',
+ '../../../content/docs/kit/60-appendix/**/*.md'
+ ],
+ {
+ removeLegacy: true,
+ removeNoteBlocks: true,
+ removeDetailsBlocks: true,
+ removePlaygroundLinks: true,
+ removePrettierIgnore: true,
+ normalizeWhitespace: true
+ }
+ )}`;
return new Response(content, {
status: 200,
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 63b89c9313..6745e92bd7 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -162,6 +162,9 @@ importers:
marked:
specifier: ^14.1.2
version: 14.1.2
+ minimatch:
+ specifier: ^10.0.1
+ version: 10.0.1
prettier:
specifier: ^3.3.2
version: 3.3.2
@@ -2452,6 +2455,10 @@ packages:
resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==}
engines: {node: '>=4'}
+ minimatch@10.0.1:
+ resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==}
+ engines: {node: 20 || >=22}
+
minimatch@3.1.2:
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
@@ -5358,6 +5365,10 @@ snapshots:
min-indent@1.0.1: {}
+ minimatch@10.0.1:
+ dependencies:
+ brace-expansion: 2.0.1
+
minimatch@3.1.2:
dependencies:
brace-expansion: 1.1.11
From 02dbf8d7dd1fe64c84cd1ee8b00099031d8a512f Mon Sep 17 00:00:00 2001
From: Stanislav Khromov
Date: Wed, 11 Dec 2024 00:16:07 +0100
Subject: [PATCH 19/49] clean up
---
apps/svelte.dev/src/lib/server/content.ts | 66 +++++++++----------
.../routes/docs/[...path]/llms.txt/+server.ts | 6 +-
.../src/routes/llms-full.txt/+server.ts | 7 +-
.../svelte.dev/src/routes/llms.txt/+server.ts | 14 ++--
4 files changed, 45 insertions(+), 48 deletions(-)
diff --git a/apps/svelte.dev/src/lib/server/content.ts b/apps/svelte.dev/src/lib/server/content.ts
index d99520c481..74b2632daf 100644
--- a/apps/svelte.dev/src/lib/server/content.ts
+++ b/apps/svelte.dev/src/lib/server/content.ts
@@ -284,54 +284,48 @@ function shouldIncludeFile(filename: string, ignore: string[] = []): boolean {
return true;
}
-export function generateLlmContent(
- filteredDocs: Record,
- type: Package,
- minimizeOptions?: Partial
-): string {
- let content = `${getDocumentationTitle(type)}\n\n`;
-
- const paths = sortPaths(Object.keys(filteredDocs));
-
- for (const path of paths) {
- content += `# ${path.replace('../../../content/', '')}\n\n`;
- const docContent = minimizeOptions
- ? minimizeContent(filteredDocs[path], minimizeOptions)
- : filteredDocs[path];
- content += docContent;
- content += '\n';
- }
-
- return content;
+interface GenerateContentOptions {
+ prefix?: string;
+ ignore?: string[];
+ minimize?: Partial;
+ package?: Package;
}
-export function generateCombinedContent(
- documentsContent: Record,
- ignore: string[] = [],
- minimizeOptions?: Partial
+export function generateContent(
+ docs: Record,
+ options: GenerateContentOptions = {}
): string {
+ const { prefix, ignore = [], minimize: minimizeOptions, package: pkg } = options;
+
let content = '';
+ if (prefix) {
+ content = `${prefix}\n\n`;
+ }
+
let currentSection = '';
- const paths = sortPaths(Object.keys(documentsContent));
+ const paths = sortPaths(Object.keys(docs));
for (const path of paths) {
- // Skip files that match ignore patterns
if (!shouldIncludeFile(path, ignore)) continue;
- const docType = packages.find((pkg) => path.includes(`/docs/${pkg}/`));
- if (!docType) continue;
-
- const section = getDocumentationStartTitle(docType);
- if (section !== currentSection) {
- if (currentSection) content += '\n';
- content += `${section}\n\n`;
- currentSection = section;
+ // If a specific package is provided, only include its docs
+ if (pkg) {
+ if (!path.includes(`/docs/${pkg}/`)) continue;
+ } else {
+ // For combined content, only include paths that match any package
+ const docType = packages.find((p) => path.includes(`/docs/${p}/`));
+ if (!docType) continue;
+
+ const section = getDocumentationStartTitle(docType);
+ if (section !== currentSection) {
+ if (currentSection) content += '\n';
+ content += `${section}\n\n`;
+ currentSection = section;
+ }
}
content += `## ${path.replace('../../../content/', '')}\n\n`;
- const docContent = minimizeOptions
- ? minimizeContent(documentsContent[path], minimizeOptions)
- : documentsContent[path];
+ const docContent = minimizeOptions ? minimizeContent(docs[path], minimizeOptions) : docs[path];
content += docContent;
content += '\n';
}
diff --git a/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts b/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts
index 137c0f3135..d1c667e43b 100644
--- a/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts
+++ b/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts
@@ -4,7 +4,8 @@ import { error } from '@sveltejs/kit';
import {
documentsContent,
filterDocsByPackage,
- generateLlmContent,
+ generateContent,
+ getDocumentationTitle,
packages,
type Package
} from '$lib/server/content';
@@ -28,7 +29,8 @@ export const GET: RequestHandler = async ({ params }) => {
error(404, 'No documentation found for this package');
}
- const content = generateLlmContent(filteredDocs, packageType as Package);
+ const PREFIX = `${getDocumentationTitle(packageType)}`;
+ const content = `${PREFIX}\n\n${generateContent(filteredDocs)}`;
return new Response(content, {
status: 200,
diff --git a/apps/svelte.dev/src/routes/llms-full.txt/+server.ts b/apps/svelte.dev/src/routes/llms-full.txt/+server.ts
index fca5eb6168..aa6d4d5e3d 100644
--- a/apps/svelte.dev/src/routes/llms-full.txt/+server.ts
+++ b/apps/svelte.dev/src/routes/llms-full.txt/+server.ts
@@ -1,10 +1,11 @@
import type { RequestHandler } from './$types';
-import { documentsContent, generateCombinedContent } from '$lib/server/content';
+import { documentsContent, generateContent } from '$lib/server/content';
-const PREFIX = 'This is the full developer documentation for Svelte and SvelteKit.';
+const PREFIX =
+ 'This is the full developer documentation for Svelte and SvelteKit.';
export const GET: RequestHandler = async () => {
- const content = `${PREFIX}\n\n${generateCombinedContent(documentsContent)}`;
+ const content = `${PREFIX}\n\n${generateContent(documentsContent)}`;
return new Response(content, {
status: 200,
diff --git a/apps/svelte.dev/src/routes/llms.txt/+server.ts b/apps/svelte.dev/src/routes/llms.txt/+server.ts
index 05b344a870..0c04159b3d 100644
--- a/apps/svelte.dev/src/routes/llms.txt/+server.ts
+++ b/apps/svelte.dev/src/routes/llms.txt/+server.ts
@@ -1,12 +1,12 @@
import type { RequestHandler } from './$types';
-import { documentsContent, generateCombinedContent } from '$lib/server/content';
+import { documentsContent, generateContent } from '$lib/server/content';
-const PREFIX = 'This is the abridged developer documentation for Svelte and SvelteKit.';
+const PREFIX =
+ 'This is the abridged developer documentation for Svelte and SvelteKit.';
export const GET: RequestHandler = async () => {
- const content = `${PREFIX}\n\n${generateCombinedContent(
- documentsContent,
- [
+ const content = `${PREFIX}\n\n${generateContent(documentsContent, {
+ ignore: [
// Svelte ignores
'../../../content/docs/svelte/07-misc/04-custom-elements.md',
'../../../content/docs/svelte/07-misc/06-v4-migration-guide.md',
@@ -28,7 +28,7 @@ export const GET: RequestHandler = async () => {
'../../../content/docs/kit/40-best-practices/05-performance.md',
'../../../content/docs/kit/60-appendix/**/*.md'
],
- {
+ minimize: {
removeLegacy: true,
removeNoteBlocks: true,
removeDetailsBlocks: true,
@@ -36,7 +36,7 @@ export const GET: RequestHandler = async () => {
removePrettierIgnore: true,
normalizeWhitespace: true
}
- )}`;
+ })}`;
return new Response(content, {
status: 200,
From 7d894031471a80b13855895e509dbb20e63b869b Mon Sep 17 00:00:00 2001
From: Stanislav Khromov
Date: Wed, 11 Dec 2024 20:24:51 +0100
Subject: [PATCH 20/49] package
---
pnpm-lock.yaml | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 92b888e62c..7e5b02febd 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -2582,6 +2582,10 @@ packages:
engines: {node: '>=10.0.0'}
hasBin: true
+ minimatch@10.0.1:
+ resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==}
+ engines: {node: 20 || >=22}
+
minimatch@3.1.2:
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
@@ -5643,6 +5647,10 @@ snapshots:
mime@3.0.0: {}
+ minimatch@10.0.1:
+ dependencies:
+ brace-expansion: 2.0.1
+
minimatch@3.1.2:
dependencies:
brace-expansion: 1.1.11
From 918b6277f98a9b18b7e1a03475f54d3833f93cf1 Mon Sep 17 00:00:00 2001
From: Stanislav Khromov
Date: Wed, 11 Dec 2024 20:29:35 +0100
Subject: [PATCH 21/49] chore: naming
---
apps/svelte.dev/src/lib/server/content.ts | 20 +++++++++----------
.../routes/docs/[...path]/llms.txt/+server.ts | 4 ++--
.../src/routes/llms-full.txt/+server.ts | 4 ++--
.../svelte.dev/src/routes/llms.txt/+server.ts | 4 ++--
4 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/apps/svelte.dev/src/lib/server/content.ts b/apps/svelte.dev/src/lib/server/content.ts
index 74b2632daf..08d03107c2 100644
--- a/apps/svelte.dev/src/lib/server/content.ts
+++ b/apps/svelte.dev/src/lib/server/content.ts
@@ -132,18 +132,18 @@ export const docs = create_docs();
export const examples = index.examples.children;
-function getSectionPriority(path: string): number {
+function getDocumentationSectionPriority(path: string): number {
if (path.includes('/docs/svelte/')) return 0;
if (path.includes('/docs/kit/')) return 1;
if (path.includes('/docs/cli/')) return 2;
return 3;
}
-export function sortPaths(paths: string[]): string[] {
+export function sortDocumentationPaths(paths: string[]): string[] {
return paths.sort((a, b) => {
// First compare by section priority
- const priorityA = getSectionPriority(a);
- const priorityB = getSectionPriority(b);
+ const priorityA = getDocumentationSectionPriority(a);
+ const priorityB = getDocumentationSectionPriority(b);
if (priorityA !== priorityB) return priorityA - priorityB;
// Get directory paths
@@ -274,7 +274,7 @@ function minimizeContent(content: string, options?: Partial): s
return minimized;
}
-function shouldIncludeFile(filename: string, ignore: string[] = []): boolean {
+function shouldIncludeFileLlmDocs(filename: string, ignore: string[] = []): boolean {
const shouldIgnore = ignore.some((pattern) => minimatch(filename, pattern));
if (shouldIgnore) {
if (dev) console.log(`❌ Ignored by pattern: ${filename}`);
@@ -284,16 +284,16 @@ function shouldIncludeFile(filename: string, ignore: string[] = []): boolean {
return true;
}
-interface GenerateContentOptions {
+interface GenerateLlmContentOptions {
prefix?: string;
ignore?: string[];
minimize?: Partial;
package?: Package;
}
-export function generateContent(
+export function generateLlmContent(
docs: Record,
- options: GenerateContentOptions = {}
+ options: GenerateLlmContentOptions = {}
): string {
const { prefix, ignore = [], minimize: minimizeOptions, package: pkg } = options;
@@ -303,10 +303,10 @@ export function generateContent(
}
let currentSection = '';
- const paths = sortPaths(Object.keys(docs));
+ const paths = sortDocumentationPaths(Object.keys(docs));
for (const path of paths) {
- if (!shouldIncludeFile(path, ignore)) continue;
+ if (!shouldIncludeFileLlmDocs(path, ignore)) continue;
// If a specific package is provided, only include its docs
if (pkg) {
diff --git a/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts b/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts
index d1c667e43b..9a1b1447df 100644
--- a/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts
+++ b/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts
@@ -4,7 +4,7 @@ import { error } from '@sveltejs/kit';
import {
documentsContent,
filterDocsByPackage,
- generateContent,
+ generateLlmContent,
getDocumentationTitle,
packages,
type Package
@@ -30,7 +30,7 @@ export const GET: RequestHandler = async ({ params }) => {
}
const PREFIX = `${getDocumentationTitle(packageType)}`;
- const content = `${PREFIX}\n\n${generateContent(filteredDocs)}`;
+ const content = `${PREFIX}\n\n${generateLlmContent(filteredDocs)}`;
return new Response(content, {
status: 200,
diff --git a/apps/svelte.dev/src/routes/llms-full.txt/+server.ts b/apps/svelte.dev/src/routes/llms-full.txt/+server.ts
index aa6d4d5e3d..510b9442df 100644
--- a/apps/svelte.dev/src/routes/llms-full.txt/+server.ts
+++ b/apps/svelte.dev/src/routes/llms-full.txt/+server.ts
@@ -1,11 +1,11 @@
import type { RequestHandler } from './$types';
-import { documentsContent, generateContent } from '$lib/server/content';
+import { documentsContent, generateLlmContent } from '$lib/server/content';
const PREFIX =
'This is the full developer documentation for Svelte and SvelteKit.';
export const GET: RequestHandler = async () => {
- const content = `${PREFIX}\n\n${generateContent(documentsContent)}`;
+ const content = `${PREFIX}\n\n${generateLlmContent(documentsContent)}`;
return new Response(content, {
status: 200,
diff --git a/apps/svelte.dev/src/routes/llms.txt/+server.ts b/apps/svelte.dev/src/routes/llms.txt/+server.ts
index 0c04159b3d..75cad6de7d 100644
--- a/apps/svelte.dev/src/routes/llms.txt/+server.ts
+++ b/apps/svelte.dev/src/routes/llms.txt/+server.ts
@@ -1,11 +1,11 @@
import type { RequestHandler } from './$types';
-import { documentsContent, generateContent } from '$lib/server/content';
+import { documentsContent, generateLlmContent } from '$lib/server/content';
const PREFIX =
'This is the abridged developer documentation for Svelte and SvelteKit.';
export const GET: RequestHandler = async () => {
- const content = `${PREFIX}\n\n${generateContent(documentsContent, {
+ const content = `${PREFIX}\n\n${generateLlmContent(documentsContent, {
ignore: [
// Svelte ignores
'../../../content/docs/svelte/07-misc/04-custom-elements.md',
From b327991455edd4010499d97941677733d4a73704 Mon Sep 17 00:00:00 2001
From: Stanislav Khromov
Date: Wed, 11 Dec 2024 20:59:31 +0100
Subject: [PATCH 22/49] Update +server.ts
---
apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts b/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts
index 9a1b1447df..4fef4b2f2d 100644
--- a/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts
+++ b/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts
@@ -29,7 +29,7 @@ export const GET: RequestHandler = async ({ params }) => {
error(404, 'No documentation found for this package');
}
- const PREFIX = `${getDocumentationTitle(packageType)}`;
+ const PREFIX = `${getDocumentationTitle(packageType as Package)}`;
const content = `${PREFIX}\n\n${generateLlmContent(filteredDocs)}`;
return new Response(content, {
From e51cf30ae47e12cba3fb073df15eb104369e223e Mon Sep 17 00:00:00 2001
From: Stanislav Khromov
Date: Wed, 11 Dec 2024 21:06:29 +0100
Subject: [PATCH 23/49] Dynamic path names
---
apps/svelte.dev/src/lib/server/content.ts | 70 ++++++++++++-----------
1 file changed, 38 insertions(+), 32 deletions(-)
diff --git a/apps/svelte.dev/src/lib/server/content.ts b/apps/svelte.dev/src/lib/server/content.ts
index 08d03107c2..ffba77597e 100644
--- a/apps/svelte.dev/src/lib/server/content.ts
+++ b/apps/svelte.dev/src/lib/server/content.ts
@@ -130,39 +130,15 @@ function create_docs() {
export const docs = create_docs();
-export const examples = index.examples.children;
+// Automatically determine packages from the docs directory structure
+export const packages = Array.from(
+ new Set(
+ Object.keys(docs.topics)
+ .map((topic) => topic.split('/')[1])
+ .filter(Boolean)
+ )
+) as const;
-function getDocumentationSectionPriority(path: string): number {
- if (path.includes('/docs/svelte/')) return 0;
- if (path.includes('/docs/kit/')) return 1;
- if (path.includes('/docs/cli/')) return 2;
- return 3;
-}
-
-export function sortDocumentationPaths(paths: string[]): string[] {
- return paths.sort((a, b) => {
- // First compare by section priority
- const priorityA = getDocumentationSectionPriority(a);
- const priorityB = getDocumentationSectionPriority(b);
- if (priorityA !== priorityB) return priorityA - priorityB;
-
- // Get directory paths
- const dirA = a.split('/').slice(0, -1).join('/');
- const dirB = b.split('/').slice(0, -1).join('/');
-
- // If in the same directory, prioritize index.md
- if (dirA === dirB) {
- if (a.endsWith('index.md')) return -1;
- if (b.endsWith('index.md')) return 1;
- return a.localeCompare(b);
- }
-
- // Otherwise sort by directory path
- return dirA.localeCompare(dirB);
- });
-}
-
-export const packages = ['svelte', 'kit', 'cli'] as const;
export type Package = (typeof packages)[number];
const DOCUMENTATION_NAMES: Record = {
@@ -332,3 +308,33 @@ export function generateLlmContent(
return content;
}
+
+function getDocumentationSectionPriority(path: string): number {
+ if (path.includes('/docs/svelte/')) return 0;
+ if (path.includes('/docs/kit/')) return 1;
+ if (path.includes('/docs/cli/')) return 2;
+ return 3;
+}
+
+export function sortDocumentationPaths(paths: string[]): string[] {
+ return paths.sort((a, b) => {
+ // First compare by section priority
+ const priorityA = getDocumentationSectionPriority(a);
+ const priorityB = getDocumentationSectionPriority(b);
+ if (priorityA !== priorityB) return priorityA - priorityB;
+
+ // Get directory paths
+ const dirA = a.split('/').slice(0, -1).join('/');
+ const dirB = b.split('/').slice(0, -1).join('/');
+
+ // If in the same directory, prioritize index.md
+ if (dirA === dirB) {
+ if (a.endsWith('index.md')) return -1;
+ if (b.endsWith('index.md')) return 1;
+ return a.localeCompare(b);
+ }
+
+ // Otherwise sort by directory path
+ return dirA.localeCompare(dirB);
+ });
+}
From ea0c646270f4348b28a4ba095389a47dab44ad35 Mon Sep 17 00:00:00 2001
From: Stanislav Khromov
Date: Wed, 11 Dec 2024 21:09:23 +0100
Subject: [PATCH 24/49] clean up
---
apps/svelte.dev/src/lib/server/content.ts | 13 +++++--------
.../src/routes/docs/[...path]/llms.txt/+server.ts | 9 ++++-----
2 files changed, 9 insertions(+), 13 deletions(-)
diff --git a/apps/svelte.dev/src/lib/server/content.ts b/apps/svelte.dev/src/lib/server/content.ts
index ffba77597e..e245037a6d 100644
--- a/apps/svelte.dev/src/lib/server/content.ts
+++ b/apps/svelte.dev/src/lib/server/content.ts
@@ -130,34 +130,31 @@ function create_docs() {
export const docs = create_docs();
-// Automatically determine packages from the docs directory structure
export const packages = Array.from(
new Set(
Object.keys(docs.topics)
.map((topic) => topic.split('/')[1])
.filter(Boolean)
)
-) as const;
+);
-export type Package = (typeof packages)[number];
-
-const DOCUMENTATION_NAMES: Record = {
+const DOCUMENTATION_NAMES: Record = {
svelte: 'Svelte',
kit: 'SvelteKit',
cli: 'Svelte CLI'
};
-export function getDocumentationTitle(type: Package): string {
+export function getDocumentationTitle(type: string): string {
return `This is the developer documentation for ${DOCUMENTATION_NAMES[type]}.`;
}
-export function getDocumentationStartTitle(type: Package): string {
+export function getDocumentationStartTitle(type: string): string {
return `# Start of ${DOCUMENTATION_NAMES[type]} documentation`;
}
export function filterDocsByPackage(
allDocs: Record,
- type: Package
+ type: string
): Record {
const filtered: Record = {};
diff --git a/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts b/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts
index 4fef4b2f2d..7b947aaca5 100644
--- a/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts
+++ b/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts
@@ -6,8 +6,7 @@ import {
filterDocsByPackage,
generateLlmContent,
getDocumentationTitle,
- packages,
- type Package
+ packages
} from '$lib/server/content';
export const prerender = true;
@@ -19,17 +18,17 @@ export const entries: EntryGenerator = () => {
export const GET: RequestHandler = async ({ params }) => {
const packageType = params.path;
- if (!packages.includes(packageType as Package)) {
+ if (!packages.includes(packageType)) {
error(404, 'Not Found');
}
- const filteredDocs = filterDocsByPackage(documentsContent, packageType as Package);
+ const filteredDocs = filterDocsByPackage(documentsContent, packageType);
if (Object.keys(filteredDocs).length === 0) {
error(404, 'No documentation found for this package');
}
- const PREFIX = `${getDocumentationTitle(packageType as Package)}`;
+ const PREFIX = `${getDocumentationTitle(packageType)}`;
const content = `${PREFIX}\n\n${generateLlmContent(filteredDocs)}`;
return new Response(content, {
From 08f1aea6307366a425abcce11267b7a8938a0d17 Mon Sep 17 00:00:00 2001
From: Stanislav Khromov
Date: Wed, 11 Dec 2024 21:12:28 +0100
Subject: [PATCH 25/49] fix
---
apps/svelte.dev/src/lib/server/content.ts | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/apps/svelte.dev/src/lib/server/content.ts b/apps/svelte.dev/src/lib/server/content.ts
index e245037a6d..8949589cfd 100644
--- a/apps/svelte.dev/src/lib/server/content.ts
+++ b/apps/svelte.dev/src/lib/server/content.ts
@@ -129,6 +129,7 @@ function create_docs() {
}
export const docs = create_docs();
+export const examples = index.examples.children;
export const packages = Array.from(
new Set(
@@ -261,7 +262,7 @@ interface GenerateLlmContentOptions {
prefix?: string;
ignore?: string[];
minimize?: Partial;
- package?: Package;
+ package?: string;
}
export function generateLlmContent(
From c1e57a2f8339c21b06d2346802ce72326df8a831 Mon Sep 17 00:00:00 2001
From: Simon Holthausen
Date: Thu, 12 Dec 2024 10:09:53 +0100
Subject: [PATCH 26/49] under_score
---
apps/svelte.dev/src/lib/server/content.ts | 38 +++++++++----------
.../routes/docs/[...path]/llms.txt/+server.ts | 14 +++----
.../src/routes/llms-full.txt/+server.ts | 4 +-
.../svelte.dev/src/routes/llms.txt/+server.ts | 4 +-
4 files changed, 30 insertions(+), 30 deletions(-)
diff --git a/apps/svelte.dev/src/lib/server/content.ts b/apps/svelte.dev/src/lib/server/content.ts
index 4812a68881..cbac0db452 100644
--- a/apps/svelte.dev/src/lib/server/content.ts
+++ b/apps/svelte.dev/src/lib/server/content.ts
@@ -19,7 +19,7 @@ const assets = import.meta.glob(
}
);
-export const documentsContent = import.meta.glob('../../../content/**/*.md', {
+export const documents_content = import.meta.glob('../../../content/**/*.md', {
eager: true,
query: '?raw',
import: 'default'
@@ -148,15 +148,15 @@ const DOCUMENTATION_NAMES: Record = {
cli: 'Svelte CLI'
};
-export function getDocumentationTitle(type: string): string {
+export function get_documentation_title(type: string): string {
return `This is the developer documentation for ${DOCUMENTATION_NAMES[type]}.`;
}
-export function getDocumentationStartTitle(type: string): string {
+export function get_documentation_start_title(type: string): string {
return `# Start of ${DOCUMENTATION_NAMES[type]} documentation`;
}
-export function filterDocsByPackage(
+export function filter_docs_by_package(
allDocs: Record,
type: string
): Record {
@@ -189,7 +189,7 @@ const defaultOptions: MinimizeOptions = {
normalizeWhitespace: false
};
-function removeQuoteBlocks(content: string, blockType: string): string {
+function remove_quote_blocks(content: string, blockType: string): string {
return content
.split('\n')
.reduce((acc: string[], line: string, index: number, lines: string[]) => {
@@ -212,22 +212,22 @@ function removeQuoteBlocks(content: string, blockType: string): string {
.join('\n');
}
-function minimizeContent(content: string, options?: Partial): string {
+function minimize_content(content: string, options?: Partial): string {
// Merge with defaults, but only for properties that are defined
const settings: MinimizeOptions = options ? { ...defaultOptions, ...options } : defaultOptions;
let minimized = content;
if (settings.removeLegacy) {
- minimized = removeQuoteBlocks(minimized, 'LEGACY');
+ minimized = remove_quote_blocks(minimized, 'LEGACY');
}
if (settings.removeNoteBlocks) {
- minimized = removeQuoteBlocks(minimized, 'NOTE');
+ minimized = remove_quote_blocks(minimized, 'NOTE');
}
if (settings.removeDetailsBlocks) {
- minimized = removeQuoteBlocks(minimized, 'DETAILS');
+ minimized = remove_quote_blocks(minimized, 'DETAILS');
}
if (settings.removePlaygroundLinks) {
@@ -251,7 +251,7 @@ function minimizeContent(content: string, options?: Partial): s
return minimized;
}
-function shouldIncludeFileLlmDocs(filename: string, ignore: string[] = []): boolean {
+function should_include_file_llm_docs(filename: string, ignore: string[] = []): boolean {
const shouldIgnore = ignore.some((pattern) => minimatch(filename, pattern));
if (shouldIgnore) {
if (dev) console.log(`❌ Ignored by pattern: ${filename}`);
@@ -268,7 +268,7 @@ interface GenerateLlmContentOptions {
package?: string;
}
-export function generateLlmContent(
+export function generate_llm_content(
docs: Record,
options: GenerateLlmContentOptions = {}
): string {
@@ -280,10 +280,10 @@ export function generateLlmContent(
}
let currentSection = '';
- const paths = sortDocumentationPaths(Object.keys(docs));
+ const paths = sort_documentation_paths(Object.keys(docs));
for (const path of paths) {
- if (!shouldIncludeFileLlmDocs(path, ignore)) continue;
+ if (!should_include_file_llm_docs(path, ignore)) continue;
// If a specific package is provided, only include its docs
if (pkg) {
@@ -293,7 +293,7 @@ export function generateLlmContent(
const docType = packages.find((p) => path.includes(`/docs/${p}/`));
if (!docType) continue;
- const section = getDocumentationStartTitle(docType);
+ const section = get_documentation_start_title(docType);
if (section !== currentSection) {
if (currentSection) content += '\n';
content += `${section}\n\n`;
@@ -302,7 +302,7 @@ export function generateLlmContent(
}
content += `## ${path.replace('../../../content/', '')}\n\n`;
- const docContent = minimizeOptions ? minimizeContent(docs[path], minimizeOptions) : docs[path];
+ const docContent = minimizeOptions ? minimize_content(docs[path], minimizeOptions) : docs[path];
content += docContent;
content += '\n';
}
@@ -310,18 +310,18 @@ export function generateLlmContent(
return content;
}
-function getDocumentationSectionPriority(path: string): number {
+function get_documentation_section_priority(path: string): number {
if (path.includes('/docs/svelte/')) return 0;
if (path.includes('/docs/kit/')) return 1;
if (path.includes('/docs/cli/')) return 2;
return 3;
}
-export function sortDocumentationPaths(paths: string[]): string[] {
+export function sort_documentation_paths(paths: string[]): string[] {
return paths.sort((a, b) => {
// First compare by section priority
- const priorityA = getDocumentationSectionPriority(a);
- const priorityB = getDocumentationSectionPriority(b);
+ const priorityA = get_documentation_section_priority(a);
+ const priorityB = get_documentation_section_priority(b);
if (priorityA !== priorityB) return priorityA - priorityB;
// Get directory paths
diff --git a/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts b/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts
index 7b947aaca5..af963d07eb 100644
--- a/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts
+++ b/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts
@@ -2,10 +2,10 @@ import type { RequestHandler } from './$types';
import type { EntryGenerator } from './$types';
import { error } from '@sveltejs/kit';
import {
- documentsContent,
- filterDocsByPackage,
- generateLlmContent,
- getDocumentationTitle,
+ documents_content,
+ filter_docs_by_package,
+ generate_llm_content,
+ get_documentation_title,
packages
} from '$lib/server/content';
@@ -22,14 +22,14 @@ export const GET: RequestHandler = async ({ params }) => {
error(404, 'Not Found');
}
- const filteredDocs = filterDocsByPackage(documentsContent, packageType);
+ const filteredDocs = filter_docs_by_package(documents_content, packageType);
if (Object.keys(filteredDocs).length === 0) {
error(404, 'No documentation found for this package');
}
- const PREFIX = `${getDocumentationTitle(packageType)}`;
- const content = `${PREFIX}\n\n${generateLlmContent(filteredDocs)}`;
+ const PREFIX = `${get_documentation_title(packageType)}`;
+ const content = `${PREFIX}\n\n${generate_llm_content(filteredDocs)}`;
return new Response(content, {
status: 200,
diff --git a/apps/svelte.dev/src/routes/llms-full.txt/+server.ts b/apps/svelte.dev/src/routes/llms-full.txt/+server.ts
index 510b9442df..e3553b73c6 100644
--- a/apps/svelte.dev/src/routes/llms-full.txt/+server.ts
+++ b/apps/svelte.dev/src/routes/llms-full.txt/+server.ts
@@ -1,11 +1,11 @@
import type { RequestHandler } from './$types';
-import { documentsContent, generateLlmContent } from '$lib/server/content';
+import { documents_content, generate_llm_content } from '$lib/server/content';
const PREFIX =
'This is the full developer documentation for Svelte and SvelteKit.';
export const GET: RequestHandler = async () => {
- const content = `${PREFIX}\n\n${generateLlmContent(documentsContent)}`;
+ const content = `${PREFIX}\n\n${generate_llm_content(documents_content)}`;
return new Response(content, {
status: 200,
diff --git a/apps/svelte.dev/src/routes/llms.txt/+server.ts b/apps/svelte.dev/src/routes/llms.txt/+server.ts
index 75cad6de7d..47d7a0f1f8 100644
--- a/apps/svelte.dev/src/routes/llms.txt/+server.ts
+++ b/apps/svelte.dev/src/routes/llms.txt/+server.ts
@@ -1,11 +1,11 @@
import type { RequestHandler } from './$types';
-import { documentsContent, generateLlmContent } from '$lib/server/content';
+import { documents_content, generate_llm_content } from '$lib/server/content';
const PREFIX =
'This is the abridged developer documentation for Svelte and SvelteKit.';
export const GET: RequestHandler = async () => {
- const content = `${PREFIX}\n\n${generateLlmContent(documentsContent, {
+ const content = `${PREFIX}\n\n${generate_llm_content(documents_content, {
ignore: [
// Svelte ignores
'../../../content/docs/svelte/07-misc/04-custom-elements.md',
From 190ff052f228022b5e9ac9f6fdaaaab90b6a9415 Mon Sep 17 00:00:00 2001
From: Simon Holthausen
Date: Thu, 12 Dec 2024 10:17:05 +0100
Subject: [PATCH 27/49] code style
---
.../routes/docs/[...path]/llms.txt/+server.ts | 22 +++++++++----------
.../src/routes/llms-full.txt/+server.ts | 12 ++++------
.../svelte.dev/src/routes/llms.txt/+server.ts | 13 +++++------
3 files changed, 19 insertions(+), 28 deletions(-)
diff --git a/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts b/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts
index af963d07eb..08d99f139a 100644
--- a/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts
+++ b/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts
@@ -1,5 +1,3 @@
-import type { RequestHandler } from './$types';
-import type { EntryGenerator } from './$types';
import { error } from '@sveltejs/kit';
import {
documents_content,
@@ -11,25 +9,25 @@ import {
export const prerender = true;
-export const entries: EntryGenerator = () => {
+export function entries() {
return packages.map((type) => ({ path: type }));
-};
+}
-export const GET: RequestHandler = async ({ params }) => {
- const packageType = params.path;
+export function GET({ params }) {
+ const package_type = params.path;
- if (!packages.includes(packageType)) {
+ if (!packages.includes(package_type)) {
error(404, 'Not Found');
}
- const filteredDocs = filter_docs_by_package(documents_content, packageType);
+ const filtered_docs = filter_docs_by_package(documents_content, package_type);
- if (Object.keys(filteredDocs).length === 0) {
+ if (Object.keys(filtered_docs).length === 0) {
error(404, 'No documentation found for this package');
}
- const PREFIX = `${get_documentation_title(packageType)}`;
- const content = `${PREFIX}\n\n${generate_llm_content(filteredDocs)}`;
+ const prefix = `${get_documentation_title(package_type)}`;
+ const content = `${prefix}\n\n${generate_llm_content(filtered_docs)}`;
return new Response(content, {
status: 200,
@@ -38,4 +36,4 @@ export const GET: RequestHandler = async ({ params }) => {
'Cache-Control': 'public, max-age=3600'
}
});
-};
+}
diff --git a/apps/svelte.dev/src/routes/llms-full.txt/+server.ts b/apps/svelte.dev/src/routes/llms-full.txt/+server.ts
index e3553b73c6..9a5b8a1747 100644
--- a/apps/svelte.dev/src/routes/llms-full.txt/+server.ts
+++ b/apps/svelte.dev/src/routes/llms-full.txt/+server.ts
@@ -1,11 +1,9 @@
-import type { RequestHandler } from './$types';
import { documents_content, generate_llm_content } from '$lib/server/content';
-const PREFIX =
- 'This is the full developer documentation for Svelte and SvelteKit.';
+export const prerender = true;
-export const GET: RequestHandler = async () => {
- const content = `${PREFIX}\n\n${generate_llm_content(documents_content)}`;
+export function GET() {
+ const content = `This is the full developer documentation for Svelte and SvelteKit.\n\n${generate_llm_content(documents_content)}`;
return new Response(content, {
status: 200,
@@ -14,6 +12,4 @@ export const GET: RequestHandler = async () => {
'Cache-Control': 'public, max-age=3600'
}
});
-};
-
-export const prerender = true;
+}
diff --git a/apps/svelte.dev/src/routes/llms.txt/+server.ts b/apps/svelte.dev/src/routes/llms.txt/+server.ts
index 47d7a0f1f8..d6c2e19c2e 100644
--- a/apps/svelte.dev/src/routes/llms.txt/+server.ts
+++ b/apps/svelte.dev/src/routes/llms.txt/+server.ts
@@ -1,11 +1,7 @@
-import type { RequestHandler } from './$types';
import { documents_content, generate_llm_content } from '$lib/server/content';
-const PREFIX =
- 'This is the abridged developer documentation for Svelte and SvelteKit.';
-
-export const GET: RequestHandler = async () => {
- const content = `${PREFIX}\n\n${generate_llm_content(documents_content, {
+export function GET() {
+ const main_content = generate_llm_content(documents_content, {
ignore: [
// Svelte ignores
'../../../content/docs/svelte/07-misc/04-custom-elements.md',
@@ -36,7 +32,8 @@ export const GET: RequestHandler = async () => {
removePrettierIgnore: true,
normalizeWhitespace: true
}
- })}`;
+ });
+ const content = `This is the abridged developer documentation for Svelte and SvelteKit.\n\n${main_content}`;
return new Response(content, {
status: 200,
@@ -45,6 +42,6 @@ export const GET: RequestHandler = async () => {
'Cache-Control': 'public, max-age=3600'
}
});
-};
+}
export const prerender = true;
From 72a1fd18ff32415363fe32036f0f77bb440b1c7e Mon Sep 17 00:00:00 2001
From: Simon Holthausen
Date: Thu, 12 Dec 2024 11:02:17 +0100
Subject: [PATCH 28/49] use real document titles, filter out empty files
---
apps/svelte.dev/src/lib/server/content.ts | 64 +++++++------------
.../routes/docs/[...path]/llms.txt/+server.ts | 22 ++-----
.../src/routes/llms-full.txt/+server.ts | 4 +-
.../svelte.dev/src/routes/llms.txt/+server.ts | 4 +-
4 files changed, 32 insertions(+), 62 deletions(-)
diff --git a/apps/svelte.dev/src/lib/server/content.ts b/apps/svelte.dev/src/lib/server/content.ts
index cbac0db452..0ea10dfb03 100644
--- a/apps/svelte.dev/src/lib/server/content.ts
+++ b/apps/svelte.dev/src/lib/server/content.ts
@@ -19,12 +19,6 @@ const assets = import.meta.glob(
}
);
-export const documents_content = import.meta.glob('../../../content/**/*.md', {
- eager: true,
- query: '?raw',
- import: 'default'
-});
-
// https://github.com/vitejs/vite/issues/17453
export const index = await create_index(documents, assets, '../../../content', read);
@@ -156,21 +150,6 @@ export function get_documentation_start_title(type: string): string {
return `# Start of ${DOCUMENTATION_NAMES[type]} documentation`;
}
-export function filter_docs_by_package(
- allDocs: Record,
- type: string
-): Record {
- const filtered: Record = {};
-
- for (const [path, content] of Object.entries(allDocs)) {
- if (path.toLowerCase().includes(`/docs/${type}/`)) {
- filtered[path] = content;
- }
- }
-
- return filtered;
-}
-
interface MinimizeOptions {
removeLegacy: boolean;
removeNoteBlocks: boolean;
@@ -268,10 +247,7 @@ interface GenerateLlmContentOptions {
package?: string;
}
-export function generate_llm_content(
- docs: Record,
- options: GenerateLlmContentOptions = {}
-): string {
+export function generate_llm_content(options: GenerateLlmContentOptions = {}): string {
const { prefix, ignore = [], minimize: minimizeOptions, package: pkg } = options;
let content = '';
@@ -279,30 +255,34 @@ export function generate_llm_content(
content = `${prefix}\n\n`;
}
- let currentSection = '';
- const paths = sort_documentation_paths(Object.keys(docs));
+ let current_section = '';
+ const paths = sort_documentation_paths();
for (const path of paths) {
if (!should_include_file_llm_docs(path, ignore)) continue;
// If a specific package is provided, only include its docs
if (pkg) {
- if (!path.includes(`/docs/${pkg}/`)) continue;
+ if (!path.includes(`docs/${pkg}/`)) continue;
} else {
// For combined content, only include paths that match any package
- const docType = packages.find((p) => path.includes(`/docs/${p}/`));
- if (!docType) continue;
+ const doc_type = packages.find((p) => path.includes(`docs/${p}/`));
+ if (!doc_type) continue;
- const section = get_documentation_start_title(docType);
- if (section !== currentSection) {
- if (currentSection) content += '\n';
+ const section = get_documentation_start_title(doc_type);
+ if (section !== current_section) {
+ if (current_section) content += '\n';
content += `${section}\n\n`;
- currentSection = section;
+ current_section = section;
}
}
- content += `## ${path.replace('../../../content/', '')}\n\n`;
- const docContent = minimizeOptions ? minimize_content(docs[path], minimizeOptions) : docs[path];
+ const docContent = minimizeOptions
+ ? minimize_content(index[path].body, minimizeOptions)
+ : index[path].body;
+ if (docContent.trim() === '') continue;
+
+ content += `\n# ${index[path].metadata.title}\n\n`;
content += docContent;
content += '\n';
}
@@ -311,14 +291,16 @@ export function generate_llm_content(
}
function get_documentation_section_priority(path: string): number {
- if (path.includes('/docs/svelte/')) return 0;
- if (path.includes('/docs/kit/')) return 1;
- if (path.includes('/docs/cli/')) return 2;
+ if (path.includes('docs/svelte/')) return 0;
+ if (path.includes('docs/kit/')) return 1;
+ if (path.includes('docs/cli/')) return 2;
return 3;
}
-export function sort_documentation_paths(paths: string[]): string[] {
- return paths.sort((a, b) => {
+function sort_documentation_paths(): string[] {
+ return Object.keys(index).sort((a, b) => {
+ a = index[a].file;
+ b = index[b].file;
// First compare by section priority
const priorityA = get_documentation_section_priority(a);
const priorityB = get_documentation_section_priority(b);
diff --git a/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts b/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts
index 08d99f139a..b66d43318a 100644
--- a/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts
+++ b/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts
@@ -1,11 +1,5 @@
import { error } from '@sveltejs/kit';
-import {
- documents_content,
- filter_docs_by_package,
- generate_llm_content,
- get_documentation_title,
- packages
-} from '$lib/server/content';
+import { generate_llm_content, get_documentation_title, packages } from '$lib/server/content';
export const prerender = true;
@@ -14,20 +8,14 @@ export function entries() {
}
export function GET({ params }) {
- const package_type = params.path;
+ const pkg = params.path;
- if (!packages.includes(package_type)) {
+ if (!packages.includes(pkg)) {
error(404, 'Not Found');
}
- const filtered_docs = filter_docs_by_package(documents_content, package_type);
-
- if (Object.keys(filtered_docs).length === 0) {
- error(404, 'No documentation found for this package');
- }
-
- const prefix = `${get_documentation_title(package_type)}`;
- const content = `${prefix}\n\n${generate_llm_content(filtered_docs)}`;
+ const prefix = `${get_documentation_title(pkg)}`;
+ const content = `${prefix}\n\n${generate_llm_content({ package: pkg })}`;
return new Response(content, {
status: 200,
diff --git a/apps/svelte.dev/src/routes/llms-full.txt/+server.ts b/apps/svelte.dev/src/routes/llms-full.txt/+server.ts
index 9a5b8a1747..b5f9bcae4b 100644
--- a/apps/svelte.dev/src/routes/llms-full.txt/+server.ts
+++ b/apps/svelte.dev/src/routes/llms-full.txt/+server.ts
@@ -1,9 +1,9 @@
-import { documents_content, generate_llm_content } from '$lib/server/content';
+import { generate_llm_content } from '$lib/server/content';
export const prerender = true;
export function GET() {
- const content = `This is the full developer documentation for Svelte and SvelteKit.\n\n${generate_llm_content(documents_content)}`;
+ const content = `This is the full developer documentation for Svelte and SvelteKit.\n\n${generate_llm_content()}`;
return new Response(content, {
status: 200,
diff --git a/apps/svelte.dev/src/routes/llms.txt/+server.ts b/apps/svelte.dev/src/routes/llms.txt/+server.ts
index d6c2e19c2e..3c583fd755 100644
--- a/apps/svelte.dev/src/routes/llms.txt/+server.ts
+++ b/apps/svelte.dev/src/routes/llms.txt/+server.ts
@@ -1,7 +1,7 @@
-import { documents_content, generate_llm_content } from '$lib/server/content';
+import { generate_llm_content } from '$lib/server/content';
export function GET() {
- const main_content = generate_llm_content(documents_content, {
+ const main_content = generate_llm_content({
ignore: [
// Svelte ignores
'../../../content/docs/svelte/07-misc/04-custom-elements.md',
From aaee7c6a74a24368708c26f8210fab0576c3f053 Mon Sep 17 00:00:00 2001
From: Stanislav Khromov
Date: Thu, 12 Dec 2024 23:18:20 +0100
Subject: [PATCH 29/49] move llms.txt to llms-small.txt
---
.../svelte.dev/src/routes/{llms.txt => llms-small.txt}/+server.ts | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename apps/svelte.dev/src/routes/{llms.txt => llms-small.txt}/+server.ts (100%)
diff --git a/apps/svelte.dev/src/routes/llms.txt/+server.ts b/apps/svelte.dev/src/routes/llms-small.txt/+server.ts
similarity index 100%
rename from apps/svelte.dev/src/routes/llms.txt/+server.ts
rename to apps/svelte.dev/src/routes/llms-small.txt/+server.ts
From a7f0f8df25c467d0bfe8d4d4c099599f9a10fdab Mon Sep 17 00:00:00 2001
From: Stanislav Khromov
Date: Fri, 13 Dec 2024 00:09:40 +0100
Subject: [PATCH 30/49] llms.txt index
---
apps/svelte.dev/src/lib/server/content.ts | 2 +-
.../svelte.dev/src/routes/llms.txt/+server.ts | 39 +++++++++++++++++++
2 files changed, 40 insertions(+), 1 deletion(-)
create mode 100644 apps/svelte.dev/src/routes/llms.txt/+server.ts
diff --git a/apps/svelte.dev/src/lib/server/content.ts b/apps/svelte.dev/src/lib/server/content.ts
index 0ea10dfb03..2f0c3b7d91 100644
--- a/apps/svelte.dev/src/lib/server/content.ts
+++ b/apps/svelte.dev/src/lib/server/content.ts
@@ -136,7 +136,7 @@ export const packages = Array.from(
)
);
-const DOCUMENTATION_NAMES: Record = {
+export const DOCUMENTATION_NAMES: Record = {
svelte: 'Svelte',
kit: 'SvelteKit',
cli: 'Svelte CLI'
diff --git a/apps/svelte.dev/src/routes/llms.txt/+server.ts b/apps/svelte.dev/src/routes/llms.txt/+server.ts
new file mode 100644
index 0000000000..7d554957f5
--- /dev/null
+++ b/apps/svelte.dev/src/routes/llms.txt/+server.ts
@@ -0,0 +1,39 @@
+import { get_documentation_title, packages, DOCUMENTATION_NAMES } from '$lib/server/content';
+
+export const prerender = true;
+
+export function GET() {
+ const package_docs = packages
+ .map(
+ (pkg) =>
+ `- [${DOCUMENTATION_NAMES[pkg]} documentation](../docs/${pkg}/llms.txt): ${get_documentation_title(pkg)}`
+ )
+ .join('\n');
+
+ const content = `# Svelte Documentation for LLMs
+
+> This directory contains various forms of the Svelte documentation formatted for Large Language Models (LLMs).
+
+## Documentation Sets
+
+- [Abridged documentation](../llms-small.txt): A minimal version of the Svelte and SvelteKit documentation, with examples and non-essential content removed
+- [Complete documentation](../llms-full.txt): The complete Svelte and SvelteKit documentation including all examples and additional content
+
+## Individual Package Documentation
+
+${package_docs}
+
+## Notes
+
+- The abridged documentation excludes legacy compatibility notes, detailed examples, and supplementary information
+- The complete documentation includes all content from the official documentation
+- Package-specific documentation files contain only the content relevant to that package
+- The content is automatically generated from the same source as the official documentation`;
+
+ return new Response(content, {
+ headers: {
+ 'Content-Type': 'text/plain; charset=utf-8',
+ 'Cache-Control': 'public, max-age=3600'
+ }
+ });
+}
From c5fac955d438c5d170f82c2c715a4855db4173ac Mon Sep 17 00:00:00 2001
From: Stanislav Khromov
Date: Fri, 13 Dec 2024 00:10:15 +0100
Subject: [PATCH 31/49] Update +server.ts
---
apps/svelte.dev/src/routes/llms.txt/+server.ts | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/apps/svelte.dev/src/routes/llms.txt/+server.ts b/apps/svelte.dev/src/routes/llms.txt/+server.ts
index 7d554957f5..c743592bc9 100644
--- a/apps/svelte.dev/src/routes/llms.txt/+server.ts
+++ b/apps/svelte.dev/src/routes/llms.txt/+server.ts
@@ -1,12 +1,14 @@
import { get_documentation_title, packages, DOCUMENTATION_NAMES } from '$lib/server/content';
+const DOMAIN = 'https://svelte.dev';
+
export const prerender = true;
export function GET() {
const package_docs = packages
.map(
(pkg) =>
- `- [${DOCUMENTATION_NAMES[pkg]} documentation](../docs/${pkg}/llms.txt): ${get_documentation_title(pkg)}`
+ `- [${DOCUMENTATION_NAMES[pkg]} documentation](${DOMAIN}/docs/${pkg}/llms.txt): ${get_documentation_title(pkg)}`
)
.join('\n');
@@ -16,8 +18,8 @@ export function GET() {
## Documentation Sets
-- [Abridged documentation](../llms-small.txt): A minimal version of the Svelte and SvelteKit documentation, with examples and non-essential content removed
-- [Complete documentation](../llms-full.txt): The complete Svelte and SvelteKit documentation including all examples and additional content
+- [Abridged documentation](${DOMAIN}/llms-small.txt): A minimal version of the Svelte and SvelteKit documentation, with examples and non-essential content removed
+- [Complete documentation](${DOMAIN}/llms-full.txt): The complete Svelte and SvelteKit documentation including all examples and additional content
## Individual Package Documentation
From 29b472696aad07e94f03fa93d966369ff67f487c Mon Sep 17 00:00:00 2001
From: Stanislav Khromov
Date: Fri, 13 Dec 2024 00:10:47 +0100
Subject: [PATCH 32/49] Update +server.ts
---
apps/svelte.dev/src/routes/llms.txt/+server.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/svelte.dev/src/routes/llms.txt/+server.ts b/apps/svelte.dev/src/routes/llms.txt/+server.ts
index c743592bc9..0068b6adb5 100644
--- a/apps/svelte.dev/src/routes/llms.txt/+server.ts
+++ b/apps/svelte.dev/src/routes/llms.txt/+server.ts
@@ -14,7 +14,7 @@ export function GET() {
const content = `# Svelte Documentation for LLMs
-> This directory contains various forms of the Svelte documentation formatted for Large Language Models (LLMs).
+> Svelte is a UI framework that uses a compiler to let you write breathtakingly concise components that do minimal work in the browser, using languages you already know — HTML, CSS and JavaScript.
## Documentation Sets
From 9eeaca69bb0e1d11852ba4e3d216b71c312bb663 Mon Sep 17 00:00:00 2001
From: Stanislav Khromov
Date: Fri, 13 Dec 2024 00:14:58 +0100
Subject: [PATCH 33/49] Fix index
---
apps/svelte.dev/.env | 2 ++
apps/svelte.dev/src/routes/llms.txt/+server.ts | 9 ++++-----
2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/apps/svelte.dev/.env b/apps/svelte.dev/.env
index 9b1319a6f1..616fecf879 100644
--- a/apps/svelte.dev/.env
+++ b/apps/svelte.dev/.env
@@ -3,3 +3,5 @@ SUPABASE_KEY=
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=
+
+VERCEL_URL=http://localhost:5173
\ No newline at end of file
diff --git a/apps/svelte.dev/src/routes/llms.txt/+server.ts b/apps/svelte.dev/src/routes/llms.txt/+server.ts
index 0068b6adb5..f5788d3811 100644
--- a/apps/svelte.dev/src/routes/llms.txt/+server.ts
+++ b/apps/svelte.dev/src/routes/llms.txt/+server.ts
@@ -1,14 +1,13 @@
+import { VERCEL_URL } from '$env/static/private';
import { get_documentation_title, packages, DOCUMENTATION_NAMES } from '$lib/server/content';
-const DOMAIN = 'https://svelte.dev';
-
export const prerender = true;
export function GET() {
const package_docs = packages
.map(
(pkg) =>
- `- [${DOCUMENTATION_NAMES[pkg]} documentation](${DOMAIN}/docs/${pkg}/llms.txt): ${get_documentation_title(pkg)}`
+ `- [${DOCUMENTATION_NAMES[pkg]} documentation](${VERCEL_URL}/docs/${pkg}/llms.txt): ${get_documentation_title(pkg)}`
)
.join('\n');
@@ -18,8 +17,8 @@ export function GET() {
## Documentation Sets
-- [Abridged documentation](${DOMAIN}/llms-small.txt): A minimal version of the Svelte and SvelteKit documentation, with examples and non-essential content removed
-- [Complete documentation](${DOMAIN}/llms-full.txt): The complete Svelte and SvelteKit documentation including all examples and additional content
+- [Abridged documentation](${VERCEL_URL}/llms-small.txt): A minimal version of the Svelte and SvelteKit documentation, with examples and non-essential content removed
+- [Complete documentation](${VERCEL_URL}/llms-full.txt): The complete Svelte and SvelteKit documentation including all examples and additional content
## Individual Package Documentation
From 9c8469cbed2f05f8fc2ef1231e92ce33b3fc9df9 Mon Sep 17 00:00:00 2001
From: Stanislav Khromov
Date: Fri, 13 Dec 2024 00:22:10 +0100
Subject: [PATCH 34/49] fix
---
apps/svelte.dev/.env | 2 +-
apps/svelte.dev/src/routes/llms.txt/+server.ts | 8 +++++---
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/apps/svelte.dev/.env b/apps/svelte.dev/.env
index 616fecf879..7f5f4507ba 100644
--- a/apps/svelte.dev/.env
+++ b/apps/svelte.dev/.env
@@ -4,4 +4,4 @@ SUPABASE_KEY=
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=
-VERCEL_URL=http://localhost:5173
\ No newline at end of file
+VERCEL_URL=
\ No newline at end of file
diff --git a/apps/svelte.dev/src/routes/llms.txt/+server.ts b/apps/svelte.dev/src/routes/llms.txt/+server.ts
index f5788d3811..59c3b346a7 100644
--- a/apps/svelte.dev/src/routes/llms.txt/+server.ts
+++ b/apps/svelte.dev/src/routes/llms.txt/+server.ts
@@ -1,13 +1,15 @@
import { VERCEL_URL } from '$env/static/private';
import { get_documentation_title, packages, DOCUMENTATION_NAMES } from '$lib/server/content';
+const DOMAIN = VERCEL_URL ? `https://${VERCEL_URL}` : '';
+
export const prerender = true;
export function GET() {
const package_docs = packages
.map(
(pkg) =>
- `- [${DOCUMENTATION_NAMES[pkg]} documentation](${VERCEL_URL}/docs/${pkg}/llms.txt): ${get_documentation_title(pkg)}`
+ `- [${DOCUMENTATION_NAMES[pkg]} documentation](${DOMAIN}/docs/${pkg}/llms.txt): ${get_documentation_title(pkg)}`
)
.join('\n');
@@ -17,8 +19,8 @@ export function GET() {
## Documentation Sets
-- [Abridged documentation](${VERCEL_URL}/llms-small.txt): A minimal version of the Svelte and SvelteKit documentation, with examples and non-essential content removed
-- [Complete documentation](${VERCEL_URL}/llms-full.txt): The complete Svelte and SvelteKit documentation including all examples and additional content
+- [Abridged documentation](${DOMAIN}/llms-small.txt): A minimal version of the Svelte and SvelteKit documentation, with examples and non-essential content removed
+- [Complete documentation](${DOMAIN}/llms-full.txt): The complete Svelte and SvelteKit documentation including all examples and additional content
## Individual Package Documentation
From e9d7e70fdd72682b215ee3f0b21e78f30c75b26d Mon Sep 17 00:00:00 2001
From: Stanislav Khromov
Date: Fri, 13 Dec 2024 00:50:14 +0100
Subject: [PATCH 35/49] revert VERCEL_URL usage
---
apps/svelte.dev/.env | 4 +---
apps/svelte.dev/src/routes/llms.txt/+server.ts | 3 +--
2 files changed, 2 insertions(+), 5 deletions(-)
diff --git a/apps/svelte.dev/.env b/apps/svelte.dev/.env
index 7f5f4507ba..31fc509a46 100644
--- a/apps/svelte.dev/.env
+++ b/apps/svelte.dev/.env
@@ -2,6 +2,4 @@ SUPABASE_URL=
SUPABASE_KEY=
GITHUB_CLIENT_ID=
-GITHUB_CLIENT_SECRET=
-
-VERCEL_URL=
\ No newline at end of file
+GITHUB_CLIENT_SECRET=
\ No newline at end of file
diff --git a/apps/svelte.dev/src/routes/llms.txt/+server.ts b/apps/svelte.dev/src/routes/llms.txt/+server.ts
index 59c3b346a7..59362f229e 100644
--- a/apps/svelte.dev/src/routes/llms.txt/+server.ts
+++ b/apps/svelte.dev/src/routes/llms.txt/+server.ts
@@ -1,7 +1,6 @@
-import { VERCEL_URL } from '$env/static/private';
import { get_documentation_title, packages, DOCUMENTATION_NAMES } from '$lib/server/content';
-const DOMAIN = VERCEL_URL ? `https://${VERCEL_URL}` : '';
+const DOMAIN = `https://svelte.dev`;
export const prerender = true;
From 855a19784467ca53e14c788a9705368c9a493b31 Mon Sep 17 00:00:00 2001
From: Stanislav Khromov
Date: Fri, 13 Dec 2024 00:52:32 +0100
Subject: [PATCH 36/49] Update apps/svelte.dev/src/lib/server/content.ts
Co-authored-by: Rich Harris
---
apps/svelte.dev/src/lib/server/content.ts | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/apps/svelte.dev/src/lib/server/content.ts b/apps/svelte.dev/src/lib/server/content.ts
index 2f0c3b7d91..bc72415ef7 100644
--- a/apps/svelte.dev/src/lib/server/content.ts
+++ b/apps/svelte.dev/src/lib/server/content.ts
@@ -128,13 +128,7 @@ function create_docs() {
export const docs = create_docs();
export const examples = index.examples.children;
-export const packages = Array.from(
- new Set(
- Object.keys(docs.topics)
- .map((topic) => topic.split('/')[1])
- .filter(Boolean)
- )
-);
+export const packages = Object.keys(docs.topics).map((topic) => topic.split('/')[1]);
export const DOCUMENTATION_NAMES: Record = {
svelte: 'Svelte',
From f0c91cc55a78c4d5cf9c40f9af0f75188bedd421 Mon Sep 17 00:00:00 2001
From: Rich Harris
Date: Thu, 12 Dec 2024 19:18:29 -0500
Subject: [PATCH 37/49] move llm stuff into its own module
---
apps/svelte.dev/src/lib/server/content.ts | 190 -----------------
apps/svelte.dev/src/lib/server/llms.ts | 191 ++++++++++++++++++
.../routes/docs/[...path]/llms.txt/+server.ts | 2 +-
.../src/routes/llms-full.txt/+server.ts | 2 +-
.../src/routes/llms-small.txt/+server.ts | 2 +-
.../svelte.dev/src/routes/llms.txt/+server.ts | 2 +-
6 files changed, 195 insertions(+), 194 deletions(-)
create mode 100644 apps/svelte.dev/src/lib/server/llms.ts
diff --git a/apps/svelte.dev/src/lib/server/content.ts b/apps/svelte.dev/src/lib/server/content.ts
index bc72415ef7..fed156751e 100644
--- a/apps/svelte.dev/src/lib/server/content.ts
+++ b/apps/svelte.dev/src/lib/server/content.ts
@@ -1,8 +1,6 @@
-import { dev } from '$app/environment';
import { read } from '$app/server';
import type { Document } from '@sveltejs/site-kit';
import { create_index } from '@sveltejs/site-kit/server/content';
-import { minimatch } from 'minimatch';
const documents = import.meta.glob('../../../content/**/*.md', {
eager: true,
@@ -127,191 +125,3 @@ function create_docs() {
export const docs = create_docs();
export const examples = index.examples.children;
-
-export const packages = Object.keys(docs.topics).map((topic) => topic.split('/')[1]);
-
-export const DOCUMENTATION_NAMES: Record = {
- svelte: 'Svelte',
- kit: 'SvelteKit',
- cli: 'Svelte CLI'
-};
-
-export function get_documentation_title(type: string): string {
- return `This is the developer documentation for ${DOCUMENTATION_NAMES[type]}.`;
-}
-
-export function get_documentation_start_title(type: string): string {
- return `# Start of ${DOCUMENTATION_NAMES[type]} documentation`;
-}
-
-interface MinimizeOptions {
- removeLegacy: boolean;
- removeNoteBlocks: boolean;
- removeDetailsBlocks: boolean;
- removePlaygroundLinks: boolean;
- removePrettierIgnore: boolean;
- normalizeWhitespace: boolean;
-}
-
-const defaultOptions: MinimizeOptions = {
- removeLegacy: false,
- removeNoteBlocks: false,
- removeDetailsBlocks: false,
- removePlaygroundLinks: false,
- removePrettierIgnore: false,
- normalizeWhitespace: false
-};
-
-function remove_quote_blocks(content: string, blockType: string): string {
- return content
- .split('\n')
- .reduce((acc: string[], line: string, index: number, lines: string[]) => {
- // If we find a block (with or without additional text), skip it and all subsequent blockquote lines
- if (line.trim().startsWith(`> [!${blockType}]`)) {
- // Skip all subsequent lines that are part of the blockquote
- let i = index;
- while (i < lines.length && (lines[i].startsWith('>') || lines[i].trim() === '')) {
- i++;
- }
- // Update the index to skip all these lines
- index = i - 1;
- return acc;
- }
-
- // Only add the line if it's not being skipped
- acc.push(line);
- return acc;
- }, [])
- .join('\n');
-}
-
-function minimize_content(content: string, options?: Partial): string {
- // Merge with defaults, but only for properties that are defined
- const settings: MinimizeOptions = options ? { ...defaultOptions, ...options } : defaultOptions;
-
- let minimized = content;
-
- if (settings.removeLegacy) {
- minimized = remove_quote_blocks(minimized, 'LEGACY');
- }
-
- if (settings.removeNoteBlocks) {
- minimized = remove_quote_blocks(minimized, 'NOTE');
- }
-
- if (settings.removeDetailsBlocks) {
- minimized = remove_quote_blocks(minimized, 'DETAILS');
- }
-
- if (settings.removePlaygroundLinks) {
- // Replace playground URLs with /[link] but keep the original link text
- minimized = minimized.replace(/\[([^\]]+)\]\(\/playground[^)]+\)/g, '[$1](/REMOVED)');
- }
-
- if (settings.removePrettierIgnore) {
- minimized = minimized
- .split('\n')
- .filter((line) => line.trim() !== '')
- .join('\n');
- }
-
- if (settings.normalizeWhitespace) {
- minimized = minimized.replace(/\s+/g, ' ');
- }
-
- minimized = minimized.trim();
-
- return minimized;
-}
-
-function should_include_file_llm_docs(filename: string, ignore: string[] = []): boolean {
- const shouldIgnore = ignore.some((pattern) => minimatch(filename, pattern));
- if (shouldIgnore) {
- if (dev) console.log(`❌ Ignored by pattern: ${filename}`);
- return false;
- }
-
- return true;
-}
-
-interface GenerateLlmContentOptions {
- prefix?: string;
- ignore?: string[];
- minimize?: Partial;
- package?: string;
-}
-
-export function generate_llm_content(options: GenerateLlmContentOptions = {}): string {
- const { prefix, ignore = [], minimize: minimizeOptions, package: pkg } = options;
-
- let content = '';
- if (prefix) {
- content = `${prefix}\n\n`;
- }
-
- let current_section = '';
- const paths = sort_documentation_paths();
-
- for (const path of paths) {
- if (!should_include_file_llm_docs(path, ignore)) continue;
-
- // If a specific package is provided, only include its docs
- if (pkg) {
- if (!path.includes(`docs/${pkg}/`)) continue;
- } else {
- // For combined content, only include paths that match any package
- const doc_type = packages.find((p) => path.includes(`docs/${p}/`));
- if (!doc_type) continue;
-
- const section = get_documentation_start_title(doc_type);
- if (section !== current_section) {
- if (current_section) content += '\n';
- content += `${section}\n\n`;
- current_section = section;
- }
- }
-
- const docContent = minimizeOptions
- ? minimize_content(index[path].body, minimizeOptions)
- : index[path].body;
- if (docContent.trim() === '') continue;
-
- content += `\n# ${index[path].metadata.title}\n\n`;
- content += docContent;
- content += '\n';
- }
-
- return content;
-}
-
-function get_documentation_section_priority(path: string): number {
- if (path.includes('docs/svelte/')) return 0;
- if (path.includes('docs/kit/')) return 1;
- if (path.includes('docs/cli/')) return 2;
- return 3;
-}
-
-function sort_documentation_paths(): string[] {
- return Object.keys(index).sort((a, b) => {
- a = index[a].file;
- b = index[b].file;
- // First compare by section priority
- const priorityA = get_documentation_section_priority(a);
- const priorityB = get_documentation_section_priority(b);
- if (priorityA !== priorityB) return priorityA - priorityB;
-
- // Get directory paths
- const dirA = a.split('/').slice(0, -1).join('/');
- const dirB = b.split('/').slice(0, -1).join('/');
-
- // If in the same directory, prioritize index.md
- if (dirA === dirB) {
- if (a.endsWith('index.md')) return -1;
- if (b.endsWith('index.md')) return 1;
- return a.localeCompare(b);
- }
-
- // Otherwise sort by directory path
- return dirA.localeCompare(dirB);
- });
-}
diff --git a/apps/svelte.dev/src/lib/server/llms.ts b/apps/svelte.dev/src/lib/server/llms.ts
new file mode 100644
index 0000000000..9bc4a6199e
--- /dev/null
+++ b/apps/svelte.dev/src/lib/server/llms.ts
@@ -0,0 +1,191 @@
+import { minimatch } from 'minimatch';
+import { dev } from '$app/environment';
+import { docs, index } from './content';
+
+interface GenerateLlmContentOptions {
+ prefix?: string;
+ ignore?: string[];
+ minimize?: Partial;
+ package?: string;
+}
+
+export function generate_llm_content(options: GenerateLlmContentOptions = {}): string {
+ const { prefix, ignore = [], minimize: minimizeOptions, package: pkg } = options;
+
+ let content = '';
+ if (prefix) {
+ content = `${prefix}\n\n`;
+ }
+
+ let current_section = '';
+ const paths = sort_documentation_paths();
+
+ for (const path of paths) {
+ if (!should_include_file_llm_docs(path, ignore)) continue;
+
+ // If a specific package is provided, only include its docs
+ if (pkg) {
+ if (!path.includes(`docs/${pkg}/`)) continue;
+ } else {
+ // For combined content, only include paths that match any package
+ const doc_type = packages.find((p) => path.includes(`docs/${p}/`));
+ if (!doc_type) continue;
+
+ const section = get_documentation_start_title(doc_type);
+ if (section !== current_section) {
+ if (current_section) content += '\n';
+ content += `${section}\n\n`;
+ current_section = section;
+ }
+ }
+
+ const docContent = minimizeOptions
+ ? minimize_content(index[path].body, minimizeOptions)
+ : index[path].body;
+ if (docContent.trim() === '') continue;
+
+ content += `\n# ${index[path].metadata.title}\n\n`;
+ content += docContent;
+ content += '\n';
+ }
+
+ return content;
+}
+
+export const packages = Object.keys(docs.topics).map((topic) => topic.split('/')[1]);
+
+export const DOCUMENTATION_NAMES: Record = {
+ svelte: 'Svelte',
+ kit: 'SvelteKit',
+ cli: 'Svelte CLI'
+};
+
+export function get_documentation_title(type: string): string {
+ return `This is the developer documentation for ${DOCUMENTATION_NAMES[type]}.`;
+}
+
+export function get_documentation_start_title(type: string): string {
+ return `# Start of ${DOCUMENTATION_NAMES[type]} documentation`;
+}
+
+function minimize_content(content: string, options?: Partial): string {
+ // Merge with defaults, but only for properties that are defined
+ const settings: MinimizeOptions = options ? { ...defaultOptions, ...options } : defaultOptions;
+
+ let minimized = content;
+
+ if (settings.removeLegacy) {
+ minimized = remove_quote_blocks(minimized, 'LEGACY');
+ }
+
+ if (settings.removeNoteBlocks) {
+ minimized = remove_quote_blocks(minimized, 'NOTE');
+ }
+
+ if (settings.removeDetailsBlocks) {
+ minimized = remove_quote_blocks(minimized, 'DETAILS');
+ }
+
+ if (settings.removePlaygroundLinks) {
+ // Replace playground URLs with /[link] but keep the original link text
+ minimized = minimized.replace(/\[([^\]]+)\]\(\/playground[^)]+\)/g, '[$1](/REMOVED)');
+ }
+
+ if (settings.removePrettierIgnore) {
+ minimized = minimized
+ .split('\n')
+ .filter((line) => line.trim() !== '')
+ .join('\n');
+ }
+
+ if (settings.normalizeWhitespace) {
+ minimized = minimized.replace(/\s+/g, ' ');
+ }
+
+ minimized = minimized.trim();
+
+ return minimized;
+}
+
+function should_include_file_llm_docs(filename: string, ignore: string[] = []): boolean {
+ const shouldIgnore = ignore.some((pattern) => minimatch(filename, pattern));
+ if (shouldIgnore) {
+ if (dev) console.log(`❌ Ignored by pattern: ${filename}`);
+ return false;
+ }
+
+ return true;
+}
+
+function get_documentation_section_priority(path: string): number {
+ if (path.includes('docs/svelte/')) return 0;
+ if (path.includes('docs/kit/')) return 1;
+ if (path.includes('docs/cli/')) return 2;
+ return 3;
+}
+
+function sort_documentation_paths(): string[] {
+ return Object.keys(index).sort((a, b) => {
+ a = index[a].file;
+ b = index[b].file;
+ // First compare by section priority
+ const priorityA = get_documentation_section_priority(a);
+ const priorityB = get_documentation_section_priority(b);
+ if (priorityA !== priorityB) return priorityA - priorityB;
+
+ // Get directory paths
+ const dirA = a.split('/').slice(0, -1).join('/');
+ const dirB = b.split('/').slice(0, -1).join('/');
+
+ // If in the same directory, prioritize index.md
+ if (dirA === dirB) {
+ if (a.endsWith('index.md')) return -1;
+ if (b.endsWith('index.md')) return 1;
+ return a.localeCompare(b);
+ }
+
+ // Otherwise sort by directory path
+ return dirA.localeCompare(dirB);
+ });
+}
+
+interface MinimizeOptions {
+ removeLegacy: boolean;
+ removeNoteBlocks: boolean;
+ removeDetailsBlocks: boolean;
+ removePlaygroundLinks: boolean;
+ removePrettierIgnore: boolean;
+ normalizeWhitespace: boolean;
+}
+
+const defaultOptions: MinimizeOptions = {
+ removeLegacy: false,
+ removeNoteBlocks: false,
+ removeDetailsBlocks: false,
+ removePlaygroundLinks: false,
+ removePrettierIgnore: false,
+ normalizeWhitespace: false
+};
+
+function remove_quote_blocks(content: string, blockType: string): string {
+ return content
+ .split('\n')
+ .reduce((acc: string[], line: string, index: number, lines: string[]) => {
+ // If we find a block (with or without additional text), skip it and all subsequent blockquote lines
+ if (line.trim().startsWith(`> [!${blockType}]`)) {
+ // Skip all subsequent lines that are part of the blockquote
+ let i = index;
+ while (i < lines.length && (lines[i].startsWith('>') || lines[i].trim() === '')) {
+ i++;
+ }
+ // Update the index to skip all these lines
+ index = i - 1;
+ return acc;
+ }
+
+ // Only add the line if it's not being skipped
+ acc.push(line);
+ return acc;
+ }, [])
+ .join('\n');
+}
diff --git a/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts b/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts
index b66d43318a..64632b2f4d 100644
--- a/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts
+++ b/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts
@@ -1,5 +1,5 @@
import { error } from '@sveltejs/kit';
-import { generate_llm_content, get_documentation_title, packages } from '$lib/server/content';
+import { generate_llm_content, get_documentation_title, packages } from '$lib/server/llms';
export const prerender = true;
diff --git a/apps/svelte.dev/src/routes/llms-full.txt/+server.ts b/apps/svelte.dev/src/routes/llms-full.txt/+server.ts
index b5f9bcae4b..60f22c2a7b 100644
--- a/apps/svelte.dev/src/routes/llms-full.txt/+server.ts
+++ b/apps/svelte.dev/src/routes/llms-full.txt/+server.ts
@@ -1,4 +1,4 @@
-import { generate_llm_content } from '$lib/server/content';
+import { generate_llm_content } from '$lib/server/llms';
export const prerender = true;
diff --git a/apps/svelte.dev/src/routes/llms-small.txt/+server.ts b/apps/svelte.dev/src/routes/llms-small.txt/+server.ts
index 3c583fd755..cbd9c90f9d 100644
--- a/apps/svelte.dev/src/routes/llms-small.txt/+server.ts
+++ b/apps/svelte.dev/src/routes/llms-small.txt/+server.ts
@@ -1,4 +1,4 @@
-import { generate_llm_content } from '$lib/server/content';
+import { generate_llm_content } from '$lib/server/llms';
export function GET() {
const main_content = generate_llm_content({
diff --git a/apps/svelte.dev/src/routes/llms.txt/+server.ts b/apps/svelte.dev/src/routes/llms.txt/+server.ts
index 59362f229e..4969c4f765 100644
--- a/apps/svelte.dev/src/routes/llms.txt/+server.ts
+++ b/apps/svelte.dev/src/routes/llms.txt/+server.ts
@@ -1,4 +1,4 @@
-import { get_documentation_title, packages, DOCUMENTATION_NAMES } from '$lib/server/content';
+import { get_documentation_title, packages, DOCUMENTATION_NAMES } from '$lib/server/llms';
const DOMAIN = `https://svelte.dev`;
From 086c48fe3b1a9005d8b3777d9471acb2a9144b62 Mon Sep 17 00:00:00 2001
From: Rich Harris
Date: Thu, 12 Dec 2024 19:19:36 -0500
Subject: [PATCH 38/49] revert whitespace changes
---
apps/svelte.dev/.env | 2 +-
apps/svelte.dev/src/lib/server/content.ts | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/apps/svelte.dev/.env b/apps/svelte.dev/.env
index 31fc509a46..9b1319a6f1 100644
--- a/apps/svelte.dev/.env
+++ b/apps/svelte.dev/.env
@@ -2,4 +2,4 @@ SUPABASE_URL=
SUPABASE_KEY=
GITHUB_CLIENT_ID=
-GITHUB_CLIENT_SECRET=
\ No newline at end of file
+GITHUB_CLIENT_SECRET=
diff --git a/apps/svelte.dev/src/lib/server/content.ts b/apps/svelte.dev/src/lib/server/content.ts
index fed156751e..01c84c2ad6 100644
--- a/apps/svelte.dev/src/lib/server/content.ts
+++ b/apps/svelte.dev/src/lib/server/content.ts
@@ -124,4 +124,5 @@ function create_docs() {
}
export const docs = create_docs();
+
export const examples = index.examples.children;
From d7f9180fba724fc401912ac880e79674cacd312f Mon Sep 17 00:00:00 2001
From: Rich Harris
Date: Thu, 12 Dec 2024 19:21:04 -0500
Subject: [PATCH 39/49] snake_case
---
apps/svelte.dev/src/lib/server/llms.ts | 42 +++++++++----------
.../src/routes/llms-small.txt/+server.ts | 12 +++---
2 files changed, 27 insertions(+), 27 deletions(-)
diff --git a/apps/svelte.dev/src/lib/server/llms.ts b/apps/svelte.dev/src/lib/server/llms.ts
index 9bc4a6199e..3a54e82635 100644
--- a/apps/svelte.dev/src/lib/server/llms.ts
+++ b/apps/svelte.dev/src/lib/server/llms.ts
@@ -9,6 +9,15 @@ interface GenerateLlmContentOptions {
package?: string;
}
+interface MinimizeOptions {
+ remove_legacy: boolean;
+ remove_note_blocks: boolean;
+ remove_details_blocks: boolean;
+ remove_playground_links: boolean;
+ remove_prettier_ignore: boolean;
+ normalize_whitespace: boolean;
+}
+
export function generate_llm_content(options: GenerateLlmContentOptions = {}): string {
const { prefix, ignore = [], minimize: minimizeOptions, package: pkg } = options;
@@ -74,31 +83,31 @@ function minimize_content(content: string, options?: Partial):
let minimized = content;
- if (settings.removeLegacy) {
+ if (settings.remove_legacy) {
minimized = remove_quote_blocks(minimized, 'LEGACY');
}
- if (settings.removeNoteBlocks) {
+ if (settings.remove_note_blocks) {
minimized = remove_quote_blocks(minimized, 'NOTE');
}
- if (settings.removeDetailsBlocks) {
+ if (settings.remove_details_blocks) {
minimized = remove_quote_blocks(minimized, 'DETAILS');
}
- if (settings.removePlaygroundLinks) {
+ if (settings.remove_playground_links) {
// Replace playground URLs with /[link] but keep the original link text
minimized = minimized.replace(/\[([^\]]+)\]\(\/playground[^)]+\)/g, '[$1](/REMOVED)');
}
- if (settings.removePrettierIgnore) {
+ if (settings.remove_prettier_ignore) {
minimized = minimized
.split('\n')
.filter((line) => line.trim() !== '')
.join('\n');
}
- if (settings.normalizeWhitespace) {
+ if (settings.normalize_whitespace) {
minimized = minimized.replace(/\s+/g, ' ');
}
@@ -149,22 +158,13 @@ function sort_documentation_paths(): string[] {
});
}
-interface MinimizeOptions {
- removeLegacy: boolean;
- removeNoteBlocks: boolean;
- removeDetailsBlocks: boolean;
- removePlaygroundLinks: boolean;
- removePrettierIgnore: boolean;
- normalizeWhitespace: boolean;
-}
-
const defaultOptions: MinimizeOptions = {
- removeLegacy: false,
- removeNoteBlocks: false,
- removeDetailsBlocks: false,
- removePlaygroundLinks: false,
- removePrettierIgnore: false,
- normalizeWhitespace: false
+ remove_legacy: false,
+ remove_note_blocks: false,
+ remove_details_blocks: false,
+ remove_playground_links: false,
+ remove_prettier_ignore: false,
+ normalize_whitespace: false
};
function remove_quote_blocks(content: string, blockType: string): string {
diff --git a/apps/svelte.dev/src/routes/llms-small.txt/+server.ts b/apps/svelte.dev/src/routes/llms-small.txt/+server.ts
index cbd9c90f9d..133a7f53ff 100644
--- a/apps/svelte.dev/src/routes/llms-small.txt/+server.ts
+++ b/apps/svelte.dev/src/routes/llms-small.txt/+server.ts
@@ -25,12 +25,12 @@ export function GET() {
'../../../content/docs/kit/60-appendix/**/*.md'
],
minimize: {
- removeLegacy: true,
- removeNoteBlocks: true,
- removeDetailsBlocks: true,
- removePlaygroundLinks: true,
- removePrettierIgnore: true,
- normalizeWhitespace: true
+ remove_legacy: true,
+ remove_note_blocks: true,
+ remove_details_blocks: true,
+ remove_playground_links: true,
+ remove_prettier_ignore: true,
+ normalize_whitespace: true
}
});
const content = `This is the abridged developer documentation for Svelte and SvelteKit.\n\n${main_content}`;
From d541799c24511f414ade9624a0a402e7e04f384e Mon Sep 17 00:00:00 2001
From: Rich Harris
Date: Thu, 12 Dec 2024 19:22:12 -0500
Subject: [PATCH 40/49] tweak
---
apps/svelte.dev/src/lib/server/llms.ts | 17 ++++++++---------
1 file changed, 8 insertions(+), 9 deletions(-)
diff --git a/apps/svelte.dev/src/lib/server/llms.ts b/apps/svelte.dev/src/lib/server/llms.ts
index 3a54e82635..177bdf8350 100644
--- a/apps/svelte.dev/src/lib/server/llms.ts
+++ b/apps/svelte.dev/src/lib/server/llms.ts
@@ -19,22 +19,21 @@ interface MinimizeOptions {
}
export function generate_llm_content(options: GenerateLlmContentOptions = {}): string {
- const { prefix, ignore = [], minimize: minimizeOptions, package: pkg } = options;
-
let content = '';
- if (prefix) {
- content = `${prefix}\n\n`;
+
+ if (options.prefix) {
+ content = `${options.prefix}\n\n`;
}
let current_section = '';
const paths = sort_documentation_paths();
for (const path of paths) {
- if (!should_include_file_llm_docs(path, ignore)) continue;
+ if (!should_include_file_llm_docs(path, options.ignore)) continue;
// If a specific package is provided, only include its docs
- if (pkg) {
- if (!path.includes(`docs/${pkg}/`)) continue;
+ if (options.package) {
+ if (!path.includes(`docs/${options.package}/`)) continue;
} else {
// For combined content, only include paths that match any package
const doc_type = packages.find((p) => path.includes(`docs/${p}/`));
@@ -48,8 +47,8 @@ export function generate_llm_content(options: GenerateLlmContentOptions = {}): s
}
}
- const docContent = minimizeOptions
- ? minimize_content(index[path].body, minimizeOptions)
+ const docContent = options.minimize
+ ? minimize_content(index[path].body, options.minimize)
: index[path].body;
if (docContent.trim() === '') continue;
From 8137d82fbae0fc41a4e4b56b7fcbff6fe8dfcb95 Mon Sep 17 00:00:00 2001
From: Rich Harris
Date: Thu, 12 Dec 2024 19:26:10 -0500
Subject: [PATCH 41/49] snake_case etc
---
apps/svelte.dev/src/lib/server/llms.ts | 29 +++++++++++++-------------
1 file changed, 14 insertions(+), 15 deletions(-)
diff --git a/apps/svelte.dev/src/lib/server/llms.ts b/apps/svelte.dev/src/lib/server/llms.ts
index 177bdf8350..56c026b1e8 100644
--- a/apps/svelte.dev/src/lib/server/llms.ts
+++ b/apps/svelte.dev/src/lib/server/llms.ts
@@ -18,6 +18,15 @@ interface MinimizeOptions {
normalize_whitespace: boolean;
}
+const defaults: MinimizeOptions = {
+ remove_legacy: false,
+ remove_note_blocks: false,
+ remove_details_blocks: false,
+ remove_playground_links: false,
+ remove_prettier_ignore: false,
+ normalize_whitespace: false
+};
+
export function generate_llm_content(options: GenerateLlmContentOptions = {}): string {
let content = '';
@@ -47,13 +56,13 @@ export function generate_llm_content(options: GenerateLlmContentOptions = {}): s
}
}
- const docContent = options.minimize
+ const doc_content = options.minimize
? minimize_content(index[path].body, options.minimize)
: index[path].body;
- if (docContent.trim() === '') continue;
+ if (doc_content.trim() === '') continue;
content += `\n# ${index[path].metadata.title}\n\n`;
- content += docContent;
+ content += doc_content;
content += '\n';
}
@@ -78,7 +87,7 @@ export function get_documentation_start_title(type: string): string {
function minimize_content(content: string, options?: Partial): string {
// Merge with defaults, but only for properties that are defined
- const settings: MinimizeOptions = options ? { ...defaultOptions, ...options } : defaultOptions;
+ const settings: MinimizeOptions = { ...defaults, ...options };
let minimized = content;
@@ -116,8 +125,7 @@ function minimize_content(content: string, options?: Partial):
}
function should_include_file_llm_docs(filename: string, ignore: string[] = []): boolean {
- const shouldIgnore = ignore.some((pattern) => minimatch(filename, pattern));
- if (shouldIgnore) {
+ if (ignore.some((pattern) => minimatch(filename, pattern))) {
if (dev) console.log(`❌ Ignored by pattern: ${filename}`);
return false;
}
@@ -157,15 +165,6 @@ function sort_documentation_paths(): string[] {
});
}
-const defaultOptions: MinimizeOptions = {
- remove_legacy: false,
- remove_note_blocks: false,
- remove_details_blocks: false,
- remove_playground_links: false,
- remove_prettier_ignore: false,
- normalize_whitespace: false
-};
-
function remove_quote_blocks(content: string, blockType: string): string {
return content
.split('\n')
From edc5d43273e23aa05fce6f7c1e6800d280dcee1c Mon Sep 17 00:00:00 2001
From: Rich Harris
Date: Thu, 12 Dec 2024 19:36:35 -0500
Subject: [PATCH 42/49] make ignores work
---
apps/svelte.dev/src/lib/server/llms.ts | 6 ++--
.../src/routes/llms-small.txt/+server.ts | 33 +++++++++----------
2 files changed, 19 insertions(+), 20 deletions(-)
diff --git a/apps/svelte.dev/src/lib/server/llms.ts b/apps/svelte.dev/src/lib/server/llms.ts
index 56c026b1e8..f2d677737a 100644
--- a/apps/svelte.dev/src/lib/server/llms.ts
+++ b/apps/svelte.dev/src/lib/server/llms.ts
@@ -124,9 +124,9 @@ function minimize_content(content: string, options?: Partial):
return minimized;
}
-function should_include_file_llm_docs(filename: string, ignore: string[] = []): boolean {
- if (ignore.some((pattern) => minimatch(filename, pattern))) {
- if (dev) console.log(`❌ Ignored by pattern: ${filename}`);
+function should_include_file_llm_docs(path: string, ignore: string[] = []): boolean {
+ if (ignore.some((pattern) => minimatch(path, pattern))) {
+ if (dev) console.log(`❌ Ignored by pattern: ${path}`);
return false;
}
diff --git a/apps/svelte.dev/src/routes/llms-small.txt/+server.ts b/apps/svelte.dev/src/routes/llms-small.txt/+server.ts
index 133a7f53ff..cc613ce008 100644
--- a/apps/svelte.dev/src/routes/llms-small.txt/+server.ts
+++ b/apps/svelte.dev/src/routes/llms-small.txt/+server.ts
@@ -4,25 +4,24 @@ export function GET() {
const main_content = generate_llm_content({
ignore: [
// Svelte ignores
- '../../../content/docs/svelte/07-misc/04-custom-elements.md',
- '../../../content/docs/svelte/07-misc/06-v4-migration-guide.md',
- '../../../content/docs/svelte/07-misc/07-v5-migration-guide.md',
- '../../../content/docs/svelte/07-misc/99-faq.md',
- '../../../content/docs/svelte/07-misc/xx-reactivity-indepth.md',
- '../../../content/docs/svelte/98-reference/21-svelte-legacy.md',
- '../../../content/docs/svelte/99-legacy/**/*.md',
- '../../../content/docs/svelte/98-reference/30-runtime-errors.md',
- '../../../content/docs/svelte/98-reference/30-runtime-warnings.md',
- '../../../content/docs/svelte/98-reference/30-compiler-errors.md',
- '../../../content/docs/svelte/98-reference/30-compiler-warnings.md',
- '**/xx-*.md',
+ 'docs/svelte/legacy/**/*',
+ 'docs/svelte/misc/custom-elements',
+ 'docs/svelte/misc/v4-migration-guide',
+ 'docs/svelte/misc/v5-migration-guide',
+ 'docs/svelte/misc/faq',
+ 'docs/svelte/reference/compiler-errors',
+ 'docs/svelte/reference/compiler-warnings',
+ 'docs/svelte/reference/runtime-errors',
+ 'docs/svelte/reference/runtime-warnings',
+ 'docs/svelte/reference/svelte-legacy',
+ '**/xx-*',
// SvelteKit ignores
- '../../../content/docs/kit/25-build-and-deploy/*adapter-*.md',
- '../../../content/docs/kit/25-build-and-deploy/99-writing-adapters.md',
- '../../../content/docs/kit/30-advanced/70-packaging.md',
- '../../../content/docs/kit/40-best-practices/05-performance.md',
- '../../../content/docs/kit/60-appendix/**/*.md'
+ 'docs/kit/advanced/packaging',
+ 'docs/kit/appendix/**/*',
+ 'docs/kit/best-practices/performance',
+ 'docs/kit/build-and-deploy/*adapter-*',
+ 'docs/kit/build-and-deploy/writing-adapters'
],
minimize: {
remove_legacy: true,
From bdf0381b90eb9195af6f434175e5d81bb7d63966 Mon Sep 17 00:00:00 2001
From: Rich Harris
Date: Thu, 12 Dec 2024 19:54:27 -0500
Subject: [PATCH 43/49] simplify
---
apps/svelte.dev/src/lib/server/llms.ts | 105 ++++++------------
.../routes/docs/[...path]/llms.txt/+server.ts | 12 +-
.../src/routes/llms-full.txt/+server.ts | 4 +-
.../src/routes/llms-small.txt/+server.ts | 3 +-
.../svelte.dev/src/routes/llms.txt/+server.ts | 8 +-
5 files changed, 47 insertions(+), 85 deletions(-)
diff --git a/apps/svelte.dev/src/lib/server/llms.ts b/apps/svelte.dev/src/lib/server/llms.ts
index f2d677737a..2626eeca79 100644
--- a/apps/svelte.dev/src/lib/server/llms.ts
+++ b/apps/svelte.dev/src/lib/server/llms.ts
@@ -1,12 +1,12 @@
import { minimatch } from 'minimatch';
import { dev } from '$app/environment';
-import { docs, index } from './content';
+import { index } from './content';
interface GenerateLlmContentOptions {
prefix?: string;
ignore?: string[];
minimize?: Partial;
- package?: string;
+ sections: Section[];
}
interface MinimizeOptions {
@@ -18,6 +18,11 @@ interface MinimizeOptions {
normalize_whitespace: boolean;
}
+interface Section {
+ slug: string;
+ title: string;
+}
+
const defaults: MinimizeOptions = {
remove_legacy: false,
remove_note_blocks: false,
@@ -27,62 +32,48 @@ const defaults: MinimizeOptions = {
normalize_whitespace: false
};
-export function generate_llm_content(options: GenerateLlmContentOptions = {}): string {
+export function generate_llm_content(options: GenerateLlmContentOptions): string {
let content = '';
if (options.prefix) {
content = `${options.prefix}\n\n`;
}
- let current_section = '';
- const paths = sort_documentation_paths();
-
- for (const path of paths) {
- if (!should_include_file_llm_docs(path, options.ignore)) continue;
-
- // If a specific package is provided, only include its docs
- if (options.package) {
- if (!path.includes(`docs/${options.package}/`)) continue;
- } else {
- // For combined content, only include paths that match any package
- const doc_type = packages.find((p) => path.includes(`docs/${p}/`));
- if (!doc_type) continue;
-
- const section = get_documentation_start_title(doc_type);
- if (section !== current_section) {
- if (current_section) content += '\n';
- content += `${section}\n\n`;
- current_section = section;
- }
+ for (const section of options.sections) {
+ if (options.sections.length > 1) {
+ content += `${get_documentation_start_title(section)}\n\n`;
}
- const doc_content = options.minimize
- ? minimize_content(index[path].body, options.minimize)
- : index[path].body;
- if (doc_content.trim() === '') continue;
+ for (const [path, document] of Object.entries(index)) {
+ if (!path.startsWith(`docs/${section.slug}`)) continue;
+ if (!should_include_file_llm_docs(path, options.ignore)) continue;
+
+ const doc_content = options.minimize
+ ? minimize_content(document.body, options.minimize)
+ : document.body;
+ if (doc_content.trim() === '') continue;
- content += `\n# ${index[path].metadata.title}\n\n`;
- content += doc_content;
- content += '\n';
+ content += `\n# ${document.metadata.title}\n\n`;
+ content += doc_content;
+ content += '\n';
+ }
}
return content;
}
-export const packages = Object.keys(docs.topics).map((topic) => topic.split('/')[1]);
-
-export const DOCUMENTATION_NAMES: Record = {
- svelte: 'Svelte',
- kit: 'SvelteKit',
- cli: 'Svelte CLI'
-};
+export const sections: Section[] = [
+ { slug: 'svelte', title: 'Svelte' },
+ { slug: 'kit', title: 'SvelteKit' },
+ { slug: 'cli', title: 'the Svelte CLI' }
+];
-export function get_documentation_title(type: string): string {
- return `This is the developer documentation for ${DOCUMENTATION_NAMES[type]}.`;
+export function get_documentation_title(section: Section): string {
+ return `This is the developer documentation for ${section.title}.`;
}
-export function get_documentation_start_title(type: string): string {
- return `# Start of ${DOCUMENTATION_NAMES[type]} documentation`;
+export function get_documentation_start_title(section: Section): string {
+ return `# Start of ${section.title} documentation`;
}
function minimize_content(content: string, options?: Partial): string {
@@ -133,38 +124,6 @@ function should_include_file_llm_docs(path: string, ignore: string[] = []): bool
return true;
}
-function get_documentation_section_priority(path: string): number {
- if (path.includes('docs/svelte/')) return 0;
- if (path.includes('docs/kit/')) return 1;
- if (path.includes('docs/cli/')) return 2;
- return 3;
-}
-
-function sort_documentation_paths(): string[] {
- return Object.keys(index).sort((a, b) => {
- a = index[a].file;
- b = index[b].file;
- // First compare by section priority
- const priorityA = get_documentation_section_priority(a);
- const priorityB = get_documentation_section_priority(b);
- if (priorityA !== priorityB) return priorityA - priorityB;
-
- // Get directory paths
- const dirA = a.split('/').slice(0, -1).join('/');
- const dirB = b.split('/').slice(0, -1).join('/');
-
- // If in the same directory, prioritize index.md
- if (dirA === dirB) {
- if (a.endsWith('index.md')) return -1;
- if (b.endsWith('index.md')) return 1;
- return a.localeCompare(b);
- }
-
- // Otherwise sort by directory path
- return dirA.localeCompare(dirB);
- });
-}
-
function remove_quote_blocks(content: string, blockType: string): string {
return content
.split('\n')
diff --git a/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts b/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts
index 64632b2f4d..d757e502e0 100644
--- a/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts
+++ b/apps/svelte.dev/src/routes/docs/[...path]/llms.txt/+server.ts
@@ -1,21 +1,23 @@
import { error } from '@sveltejs/kit';
-import { generate_llm_content, get_documentation_title, packages } from '$lib/server/llms';
+import { generate_llm_content, get_documentation_title, sections } from '$lib/server/llms';
export const prerender = true;
export function entries() {
- return packages.map((type) => ({ path: type }));
+ return sections.map((section) => ({ path: section.slug }));
}
export function GET({ params }) {
const pkg = params.path;
- if (!packages.includes(pkg)) {
+ const section = sections.find((s) => s.slug === pkg);
+
+ if (!section) {
error(404, 'Not Found');
}
- const prefix = `${get_documentation_title(pkg)}`;
- const content = `${prefix}\n\n${generate_llm_content({ package: pkg })}`;
+ const prefix = `${get_documentation_title(section)}`;
+ const content = `${prefix}\n\n${generate_llm_content({ sections: [section] })}`;
return new Response(content, {
status: 200,
diff --git a/apps/svelte.dev/src/routes/llms-full.txt/+server.ts b/apps/svelte.dev/src/routes/llms-full.txt/+server.ts
index 60f22c2a7b..18f2518797 100644
--- a/apps/svelte.dev/src/routes/llms-full.txt/+server.ts
+++ b/apps/svelte.dev/src/routes/llms-full.txt/+server.ts
@@ -1,9 +1,9 @@
-import { generate_llm_content } from '$lib/server/llms';
+import { generate_llm_content, sections } from '$lib/server/llms';
export const prerender = true;
export function GET() {
- const content = `This is the full developer documentation for Svelte and SvelteKit.\n\n${generate_llm_content()}`;
+ const content = `This is the full developer documentation for Svelte and SvelteKit.\n\n${generate_llm_content({ sections })}`;
return new Response(content, {
status: 200,
diff --git a/apps/svelte.dev/src/routes/llms-small.txt/+server.ts b/apps/svelte.dev/src/routes/llms-small.txt/+server.ts
index cc613ce008..63eb51f77e 100644
--- a/apps/svelte.dev/src/routes/llms-small.txt/+server.ts
+++ b/apps/svelte.dev/src/routes/llms-small.txt/+server.ts
@@ -1,7 +1,8 @@
-import { generate_llm_content } from '$lib/server/llms';
+import { generate_llm_content, sections } from '$lib/server/llms';
export function GET() {
const main_content = generate_llm_content({
+ sections,
ignore: [
// Svelte ignores
'docs/svelte/legacy/**/*',
diff --git a/apps/svelte.dev/src/routes/llms.txt/+server.ts b/apps/svelte.dev/src/routes/llms.txt/+server.ts
index 4969c4f765..a67010735b 100644
--- a/apps/svelte.dev/src/routes/llms.txt/+server.ts
+++ b/apps/svelte.dev/src/routes/llms.txt/+server.ts
@@ -1,14 +1,14 @@
-import { get_documentation_title, packages, DOCUMENTATION_NAMES } from '$lib/server/llms';
+import { get_documentation_title, sections } from '$lib/server/llms';
const DOMAIN = `https://svelte.dev`;
export const prerender = true;
export function GET() {
- const package_docs = packages
+ const package_docs = sections
.map(
- (pkg) =>
- `- [${DOCUMENTATION_NAMES[pkg]} documentation](${DOMAIN}/docs/${pkg}/llms.txt): ${get_documentation_title(pkg)}`
+ (section) =>
+ `- [${section.title} documentation](${DOMAIN}/docs/${section.slug}/llms.txt): ${get_documentation_title(section)}`
)
.join('\n');
From e7bd8d952db2667169c7b815fe3054d4d583cbd2 Mon Sep 17 00:00:00 2001
From: Rich Harris
Date: Thu, 12 Dec 2024 19:57:14 -0500
Subject: [PATCH 44/49] unused
---
apps/svelte.dev/src/lib/server/llms.ts | 5 -----
1 file changed, 5 deletions(-)
diff --git a/apps/svelte.dev/src/lib/server/llms.ts b/apps/svelte.dev/src/lib/server/llms.ts
index 2626eeca79..9a2a9ceeb2 100644
--- a/apps/svelte.dev/src/lib/server/llms.ts
+++ b/apps/svelte.dev/src/lib/server/llms.ts
@@ -3,7 +3,6 @@ import { dev } from '$app/environment';
import { index } from './content';
interface GenerateLlmContentOptions {
- prefix?: string;
ignore?: string[];
minimize?: Partial;
sections: Section[];
@@ -35,10 +34,6 @@ const defaults: MinimizeOptions = {
export function generate_llm_content(options: GenerateLlmContentOptions): string {
let content = '';
- if (options.prefix) {
- content = `${options.prefix}\n\n`;
- }
-
for (const section of options.sections) {
if (options.sections.length > 1) {
content += `${get_documentation_start_title(section)}\n\n`;
From f5df78225bbbf60e366acb88960952d07064eedc Mon Sep 17 00:00:00 2001
From: Rich Harris
Date: Thu, 12 Dec 2024 20:02:33 -0500
Subject: [PATCH 45/49] reduce indirection
---
apps/svelte.dev/src/lib/server/llms.ts | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/apps/svelte.dev/src/lib/server/llms.ts b/apps/svelte.dev/src/lib/server/llms.ts
index 9a2a9ceeb2..c01e41944e 100644
--- a/apps/svelte.dev/src/lib/server/llms.ts
+++ b/apps/svelte.dev/src/lib/server/llms.ts
@@ -36,7 +36,7 @@ export function generate_llm_content(options: GenerateLlmContentOptions): string
for (const section of options.sections) {
if (options.sections.length > 1) {
- content += `${get_documentation_start_title(section)}\n\n`;
+ content += `# Start of ${section.title} documentation\n\n`;
}
for (const [path, document] of Object.entries(index)) {
@@ -67,10 +67,6 @@ export function get_documentation_title(section: Section): string {
return `This is the developer documentation for ${section.title}.`;
}
-export function get_documentation_start_title(section: Section): string {
- return `# Start of ${section.title} documentation`;
-}
-
function minimize_content(content: string, options?: Partial): string {
// Merge with defaults, but only for properties that are defined
const settings: MinimizeOptions = { ...defaults, ...options };
From aa3a4e6fa9ca117afb74bb554283fda570407262 Mon Sep 17 00:00:00 2001
From: Rich Harris
Date: Thu, 12 Dec 2024 20:04:34 -0500
Subject: [PATCH 46/49] more
---
apps/svelte.dev/src/lib/server/llms.ts | 15 +++++----------
1 file changed, 5 insertions(+), 10 deletions(-)
diff --git a/apps/svelte.dev/src/lib/server/llms.ts b/apps/svelte.dev/src/lib/server/llms.ts
index c01e41944e..3008cff916 100644
--- a/apps/svelte.dev/src/lib/server/llms.ts
+++ b/apps/svelte.dev/src/lib/server/llms.ts
@@ -41,7 +41,11 @@ export function generate_llm_content(options: GenerateLlmContentOptions): string
for (const [path, document] of Object.entries(index)) {
if (!path.startsWith(`docs/${section.slug}`)) continue;
- if (!should_include_file_llm_docs(path, options.ignore)) continue;
+
+ if (options.ignore?.some((pattern) => minimatch(path, pattern))) {
+ if (dev) console.log(`❌ Ignored by pattern: ${path}`);
+ continue;
+ }
const doc_content = options.minimize
? minimize_content(document.body, options.minimize)
@@ -106,15 +110,6 @@ function minimize_content(content: string, options?: Partial):
return minimized;
}
-function should_include_file_llm_docs(path: string, ignore: string[] = []): boolean {
- if (ignore.some((pattern) => minimatch(path, pattern))) {
- if (dev) console.log(`❌ Ignored by pattern: ${path}`);
- return false;
- }
-
- return true;
-}
-
function remove_quote_blocks(content: string, blockType: string): string {
return content
.split('\n')
From 84ed768b2a85afa694c4d02b685f5229a7c7277d Mon Sep 17 00:00:00 2001
From: Rich Harris
Date: Thu, 12 Dec 2024 20:09:58 -0500
Subject: [PATCH 47/49] move template into separate .md file
---
.../svelte.dev/src/routes/llms.txt/+server.ts | 31 ++++---------------
.../src/routes/llms.txt/template.md | 19 ++++++++++++
2 files changed, 25 insertions(+), 25 deletions(-)
create mode 100644 apps/svelte.dev/src/routes/llms.txt/template.md
diff --git a/apps/svelte.dev/src/routes/llms.txt/+server.ts b/apps/svelte.dev/src/routes/llms.txt/+server.ts
index a67010735b..9a961557c2 100644
--- a/apps/svelte.dev/src/routes/llms.txt/+server.ts
+++ b/apps/svelte.dev/src/routes/llms.txt/+server.ts
@@ -1,36 +1,17 @@
import { get_documentation_title, sections } from '$lib/server/llms';
+import template from './template.md?raw';
const DOMAIN = `https://svelte.dev`;
export const prerender = true;
export function GET() {
- const package_docs = sections
- .map(
- (section) =>
- `- [${section.title} documentation](${DOMAIN}/docs/${section.slug}/llms.txt): ${get_documentation_title(section)}`
- )
- .join('\n');
+ const package_docs = sections.map(
+ (section) =>
+ `- [${section.title} documentation](${DOMAIN}/docs/${section.slug}/llms.txt): ${get_documentation_title(section)}`
+ );
- const content = `# Svelte Documentation for LLMs
-
-> Svelte is a UI framework that uses a compiler to let you write breathtakingly concise components that do minimal work in the browser, using languages you already know — HTML, CSS and JavaScript.
-
-## Documentation Sets
-
-- [Abridged documentation](${DOMAIN}/llms-small.txt): A minimal version of the Svelte and SvelteKit documentation, with examples and non-essential content removed
-- [Complete documentation](${DOMAIN}/llms-full.txt): The complete Svelte and SvelteKit documentation including all examples and additional content
-
-## Individual Package Documentation
-
-${package_docs}
-
-## Notes
-
-- The abridged documentation excludes legacy compatibility notes, detailed examples, and supplementary information
-- The complete documentation includes all content from the official documentation
-- Package-specific documentation files contain only the content relevant to that package
-- The content is automatically generated from the same source as the official documentation`;
+ const content = template.replace('%PACKAGE_DOCS%', package_docs.join('\n'));
return new Response(content, {
headers: {
diff --git a/apps/svelte.dev/src/routes/llms.txt/template.md b/apps/svelte.dev/src/routes/llms.txt/template.md
new file mode 100644
index 0000000000..aa4b32e1ac
--- /dev/null
+++ b/apps/svelte.dev/src/routes/llms.txt/template.md
@@ -0,0 +1,19 @@
+# Svelte Documentation for LLMs
+
+> Svelte is a UI framework that uses a compiler to let you write breathtakingly concise components that do minimal work in the browser, using languages you already know — HTML, CSS and JavaScript.
+
+## Documentation Sets
+
+- [Abridged documentation](https://svelte.dev/llms-small.txt): A minimal version of the Svelte and SvelteKit documentation, with examples and non-essential content removed
+- [Complete documentation](https://svelte.dev/llms-full.txt): The complete Svelte and SvelteKit documentation including all examples and additional content
+
+## Individual Package Documentation
+
+%PACKAGE_DOCS%
+
+## Notes
+
+- The abridged documentation excludes legacy compatibility notes, detailed examples, and supplementary information
+- The complete documentation includes all content from the official documentation
+- Package-specific documentation files contain only the content relevant to that package
+- The content is automatically generated from the same source as the official documentation
From b2233b848d89e8f405d1ec5723e253f0a31ab863 Mon Sep 17 00:00:00 2001
From: Rich Harris
Date: Thu, 12 Dec 2024 20:33:57 -0500
Subject: [PATCH 48/49] add a section to /docs
---
apps/svelte.dev/src/routes/docs/+page.svelte | 8 ++++
.../src/routes/docs/llms/+page.svelte | 46 +++++++++++++++++++
2 files changed, 54 insertions(+)
create mode 100644 apps/svelte.dev/src/routes/docs/llms/+page.svelte
diff --git a/apps/svelte.dev/src/routes/docs/+page.svelte b/apps/svelte.dev/src/routes/docs/+page.svelte
index 06929a50e5..6691bf3986 100644
--- a/apps/svelte.dev/src/routes/docs/+page.svelte
+++ b/apps/svelte.dev/src/routes/docs/+page.svelte
@@ -90,6 +90,14 @@
+
+ I'm a Large Language Model (LLM)
+
+ If you're an artificial intelligence, or trying to teach one how to use Svelte, we offer the
+ documentation in plaintext format. Beep boop.
+
+
+
Help! I'm stuck
diff --git a/apps/svelte.dev/src/routes/docs/llms/+page.svelte b/apps/svelte.dev/src/routes/docs/llms/+page.svelte
new file mode 100644
index 0000000000..2d07e49cf2
--- /dev/null
+++ b/apps/svelte.dev/src/routes/docs/llms/+page.svelte
@@ -0,0 +1,46 @@
+
+
+
+
+ Docs for LLMs
+
+
+ We support the llms.txt convention for making documentation
+ available to large language models and the applications that make use of them.
+
+
+ Currently, we have the following root-level files...
+
+
+ - /llms.txt — a listing of the available files
+ -
+ /llms-full.txt — complete documentation for Svelte, SvelteKit and
+ the CLI
+
+ -
+ /llms-small.txt — compressed documentation for use with smaller
+ context windows
+
+
+
+ ...and package-level documentation:
+
+
+
+
+
+
From a521cc97b193645e1c45eecfa0ed997c50f9a3b3 Mon Sep 17 00:00:00 2001
From: Rich Harris
Date: Fri, 13 Dec 2024 06:22:29 -0500
Subject: [PATCH 49/49] advent of svelte
---
.../content/blog/2024-12-01-advent-of-svelte.md | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/apps/svelte.dev/content/blog/2024-12-01-advent-of-svelte.md b/apps/svelte.dev/content/blog/2024-12-01-advent-of-svelte.md
index 5a81ef26a5..f569196f7e 100644
--- a/apps/svelte.dev/content/blog/2024-12-01-advent-of-svelte.md
+++ b/apps/svelte.dev/content/blog/2024-12-01-advent-of-svelte.md
@@ -99,9 +99,13 @@ As of today, you can also return things that _aren't_ built in to the language,
- [docs](/docs/kit/hooks#Universal-hooks-transport)
- [demo](https://stackblitz.com/edit/sveltejs-kit-template-default-b5zbxomg?file=src%2Fhooks.js)
-## Day 13
+## Day 13: rise of the robots
-Coming soon!
+For those of you using LLMs to help you write code — via Cursor or Copilot or Claude or Bolt or v0 or some other interface — we now publish the documentation in a selection of robot-friendly `llms.txt` files. This is experimental and will evolve over time, but by way of example here's a [snake game](/playground/0de3c1c1a31d47bdbb7c4aa3477a6b46) built by Sonnet 3.5 with no additional prompting.
+
+Thanks to [Didier Catz](https://x.com/didiercatz) and [Stanislav Khromov](https://bsky.app/profile/khromov.se) for building this!
+
+- [docs](/docs/llms)
## Day 14