Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion source.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export const docs = defineDocs({
docs: {
async: isDevelopment,
postprocess: {
includeProcessedMarkdown: !isDevelopment,
includeProcessedMarkdown: true,
},
},
});
Expand Down
90 changes: 90 additions & 0 deletions src/lib/llms.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
export const llmsSectionConfigs = {
dashboard: {
label: "Dashboard",
urlPrefix: "/docs/dashboard",
},
ios: {
label: "iOS",
urlPrefix: "/docs/ios",
},
android: {
label: "Android",
urlPrefix: "/docs/android",
},
flutter: {
label: "Flutter",
urlPrefix: "/docs/flutter",
},
expo: {
label: "Expo",
urlPrefix: "/docs/expo",
},
"react-native": {
label: "React Native",
urlPrefix: "/docs/react-native",
},
integrations: {
label: "Integrations",
urlPrefix: "/docs/integrations",
},
"web-checkout": {
label: "Web Checkout",
urlPrefix: "/docs/web-checkout",
},
} as const;

export type LLMSection = keyof typeof llmsSectionConfigs;
export type LLMPageLike = {
url: string;
data: {
title: string;
description?: string;
};
};

export function getLLMSectionConfig(section?: string) {
if (!section) return undefined;
return llmsSectionConfigs[section as LLMSection];
}

export function getPagesForLLMSection(pages: LLMPageLike[], section?: string) {
const config = getLLMSectionConfig(section);
if (!config) return pages;

return pages.filter(
(page) => page.url === config.urlPrefix || page.url.startsWith(`${config.urlPrefix}/`),
);
}

export function buildLLMSummaryTextFromPages(pages: LLMPageLike[], section?: string) {
const config = getLLMSectionConfig(section);
const title = config ? `${config.label} Documentation` : "Documentation";
const lines: string[] = [`# ${title}`, ""];

for (const page of getPagesForLLMSection(pages, section)) {
const description = page.data.description ? `: ${page.data.description}` : "";
lines.push(`- [${page.data.title}](${page.url})${description}`);
}

return lines.join("\n");
}

export async function buildLLMSummaryText(section?: string) {
const { source } = await import("@/lib/source");
return buildLLMSummaryTextFromPages(source.getPages(), section);
}

export async function buildLLMFullText(section?: string) {
const { source, getLLMText } = await import("@/lib/source");
const scanned = await Promise.all(getPagesForLLMSection(source.getPages(), section).map(getLLMText));
return scanned.join("\n\n");
}

export function buildLLMResponse(body: string) {
return new Response(body, {
headers: {
"Access-Control-Allow-Origin": "*",
"Content-Type": "text/plain; charset=utf-8",
},
});
}
12 changes: 8 additions & 4 deletions src/lib/source.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,11 +134,15 @@ export const source = loader({
},
});

export async function getPageMarkdownText(
page: InferPageType<typeof source>,
_type: "raw" | "processed" = "processed",
) {
return page.data.getText("processed");
}

export async function getLLMText(page: InferPageType<typeof source>) {
// Dev disables processed markdown generation to avoid paying that extra MDX
// postprocess cost on the first docs request, so fall back to raw text there.
const textType = process.env.NODE_ENV === "development" ? "raw" : "processed";
const processed = await page.data.getText(textType);
const processed = await getPageMarkdownText(page);

return `# ${page.data.title}

Expand Down
45 changes: 45 additions & 0 deletions src/routeTree.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ import { Route as rootRouteImport } from './routes/__root'
import { Route as SitemapDotxmlRouteImport } from './routes/sitemap[.]xml'
import { Route as RobotsDottxtRouteImport } from './routes/robots[.]txt'
import { Route as LlmsDottxtRouteImport } from './routes/llms[.]txt'
import { Route as LlmsChar123sectionChar125DottxtRouteImport } from './routes/llms-{$section}[.]txt'
import { Route as LlmsFullDottxtRouteImport } from './routes/llms-full[.]txt'
import { Route as LlmsFullChar123sectionChar125DottxtRouteImport } from './routes/llms-full-{$section}[.]txt'
import { Route as SplatRouteImport } from './routes/$'
import { Route as IndexRouteImport } from './routes/index'
import { Route as ApiSearchRouteImport } from './routes/api/search'
Expand All @@ -36,11 +38,23 @@ const LlmsDottxtRoute = LlmsDottxtRouteImport.update({
path: '/llms.txt',
getParentRoute: () => rootRouteImport,
} as any)
const LlmsChar123sectionChar125DottxtRoute =
LlmsChar123sectionChar125DottxtRouteImport.update({
id: '/llms-{$section}.txt',
path: '/llms-{$section}.txt',
getParentRoute: () => rootRouteImport,
} as any)
const LlmsFullDottxtRoute = LlmsFullDottxtRouteImport.update({
id: '/llms-full.txt',
path: '/llms-full.txt',
getParentRoute: () => rootRouteImport,
} as any)
const LlmsFullChar123sectionChar125DottxtRoute =
LlmsFullChar123sectionChar125DottxtRouteImport.update({
id: '/llms-full-{$section}.txt',
path: '/llms-full-{$section}.txt',
getParentRoute: () => rootRouteImport,
} as any)
const SplatRoute = SplatRouteImport.update({
id: '/$',
path: '/$',
Expand Down Expand Up @@ -80,7 +94,9 @@ const ApiRawSplatRoute = ApiRawSplatRouteImport.update({
export interface FileRoutesByFullPath {
'/': typeof IndexRoute
'/$': typeof SplatRoute
'/llms-full-{$section}.txt': typeof LlmsFullChar123sectionChar125DottxtRoute
'/llms-full.txt': typeof LlmsFullDottxtRoute
'/llms-{$section}.txt': typeof LlmsChar123sectionChar125DottxtRoute
'/llms.txt': typeof LlmsDottxtRoute
'/robots.txt': typeof RobotsDottxtRoute
'/sitemap.xml': typeof SitemapDotxmlRoute
Expand All @@ -93,7 +109,9 @@ export interface FileRoutesByFullPath {
export interface FileRoutesByTo {
'/': typeof IndexRoute
'/$': typeof SplatRoute
'/llms-full-{$section}.txt': typeof LlmsFullChar123sectionChar125DottxtRoute
'/llms-full.txt': typeof LlmsFullDottxtRoute
'/llms-{$section}.txt': typeof LlmsChar123sectionChar125DottxtRoute
'/llms.txt': typeof LlmsDottxtRoute
'/robots.txt': typeof RobotsDottxtRoute
'/sitemap.xml': typeof SitemapDotxmlRoute
Expand All @@ -107,7 +125,9 @@ export interface FileRoutesById {
__root__: typeof rootRouteImport
'/': typeof IndexRoute
'/$': typeof SplatRoute
'/llms-full-{$section}.txt': typeof LlmsFullChar123sectionChar125DottxtRoute
'/llms-full.txt': typeof LlmsFullDottxtRoute
'/llms-{$section}.txt': typeof LlmsChar123sectionChar125DottxtRoute
'/llms.txt': typeof LlmsDottxtRoute
'/robots.txt': typeof RobotsDottxtRoute
'/sitemap.xml': typeof SitemapDotxmlRoute
Expand All @@ -122,7 +142,9 @@ export interface FileRouteTypes {
fullPaths:
| '/'
| '/$'
| '/llms-full-{$section}.txt'
| '/llms-full.txt'
| '/llms-{$section}.txt'
| '/llms.txt'
| '/robots.txt'
| '/sitemap.xml'
Expand All @@ -135,7 +157,9 @@ export interface FileRouteTypes {
to:
| '/'
| '/$'
| '/llms-full-{$section}.txt'
| '/llms-full.txt'
| '/llms-{$section}.txt'
| '/llms.txt'
| '/robots.txt'
| '/sitemap.xml'
Expand All @@ -148,7 +172,9 @@ export interface FileRouteTypes {
| '__root__'
| '/'
| '/$'
| '/llms-full-{$section}.txt'
| '/llms-full.txt'
| '/llms-{$section}.txt'
| '/llms.txt'
| '/robots.txt'
| '/sitemap.xml'
Expand All @@ -162,7 +188,9 @@ export interface FileRouteTypes {
export interface RootRouteChildren {
IndexRoute: typeof IndexRoute
SplatRoute: typeof SplatRoute
LlmsFullChar123sectionChar125DottxtRoute: typeof LlmsFullChar123sectionChar125DottxtRoute
LlmsFullDottxtRoute: typeof LlmsFullDottxtRoute
LlmsChar123sectionChar125DottxtRoute: typeof LlmsChar123sectionChar125DottxtRoute
LlmsDottxtRoute: typeof LlmsDottxtRoute
RobotsDottxtRoute: typeof RobotsDottxtRoute
SitemapDotxmlRoute: typeof SitemapDotxmlRoute
Expand Down Expand Up @@ -196,13 +224,27 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof LlmsDottxtRouteImport
parentRoute: typeof rootRouteImport
}
'/llms-{$section}.txt': {
id: '/llms-{$section}.txt'
path: '/llms-{$section}.txt'
fullPath: '/llms-{$section}.txt'
preLoaderRoute: typeof LlmsChar123sectionChar125DottxtRouteImport
parentRoute: typeof rootRouteImport
}
'/llms-full.txt': {
id: '/llms-full.txt'
path: '/llms-full.txt'
fullPath: '/llms-full.txt'
preLoaderRoute: typeof LlmsFullDottxtRouteImport
parentRoute: typeof rootRouteImport
}
'/llms-full-{$section}.txt': {
id: '/llms-full-{$section}.txt'
path: '/llms-full-{$section}.txt'
fullPath: '/llms-full-{$section}.txt'
preLoaderRoute: typeof LlmsFullChar123sectionChar125DottxtRouteImport
parentRoute: typeof rootRouteImport
}
'/$': {
id: '/$'
path: '/$'
Expand Down Expand Up @@ -258,7 +300,10 @@ declare module '@tanstack/react-router' {
const rootRouteChildren: RootRouteChildren = {
IndexRoute: IndexRoute,
SplatRoute: SplatRoute,
LlmsFullChar123sectionChar125DottxtRoute:
LlmsFullChar123sectionChar125DottxtRoute,
LlmsFullDottxtRoute: LlmsFullDottxtRoute,
LlmsChar123sectionChar125DottxtRoute: LlmsChar123sectionChar125DottxtRoute,
LlmsDottxtRoute: LlmsDottxtRoute,
RobotsDottxtRoute: RobotsDottxtRoute,
SitemapDotxmlRoute: SitemapDotxmlRoute,
Expand Down
15 changes: 15 additions & 0 deletions src/routes/llms-full-{$section}[.]txt.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { buildLLMFullText, buildLLMResponse, getLLMSectionConfig } from "@/lib/llms";
import { createFileRoute } from "@tanstack/react-router";

export const Route = createFileRoute("/llms-full-{$section}.txt")({
server: {
handlers: {
GET: async ({ params }) => {
if (!getLLMSectionConfig(params.section)) {
return new Response("LLMS section not found", { status: 404 });
}
return buildLLMResponse(await buildLLMFullText(params.section));
},
},
},
});
10 changes: 2 additions & 8 deletions src/routes/llms-full[.]txt.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
import { createFileRoute } from "@tanstack/react-router";
import { source, getLLMText } from "@/lib/source";
import { buildLLMFullText, buildLLMResponse } from "@/lib/llms";

export const Route = createFileRoute("/llms-full.txt")({
server: {
handlers: {
GET: async () => {
const scan = source.getPages().map(getLLMText);
const scanned = await Promise.all(scan);
return new Response(scanned.join("\n\n"), {
headers: {
"Access-Control-Allow-Origin": "*",
},
});
return buildLLMResponse(await buildLLMFullText());
},
},
},
Expand Down
15 changes: 15 additions & 0 deletions src/routes/llms-{$section}[.]txt.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { buildLLMResponse, buildLLMSummaryText, getLLMSectionConfig } from "@/lib/llms";
import { createFileRoute } from "@tanstack/react-router";

export const Route = createFileRoute("/llms-{$section}.txt")({
server: {
handlers: {
GET: async ({ params }) => {
if (!getLLMSectionConfig(params.section)) {
return new Response("LLMS section not found", { status: 404 });
}
return buildLLMResponse(await buildLLMSummaryText(params.section));
},
},
},
});
7 changes: 2 additions & 5 deletions src/routes/llms[.]mdx.docs.$.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { createFileRoute, notFound } from "@tanstack/react-router";
import { source } from "@/lib/source";
import { getPageMarkdownText, source } from "@/lib/source";

export const Route = createFileRoute("/llms.mdx/docs/$")({
server: {
Expand All @@ -8,11 +8,8 @@ export const Route = createFileRoute("/llms.mdx/docs/$")({
const slugs = params._splat?.split("/") ?? [];
const page = source.getPage(slugs);
if (!page) throw notFound();
// Dev disables processed markdown generation to keep the first docs
// request fast, so the LLM endpoint serves raw markdown in development.
const textType = process.env.NODE_ENV === "development" ? "raw" : "processed";

return new Response(await page.data.getText(textType), {
return new Response(await getPageMarkdownText(page), {
headers: {
"Content-Type": "text/markdown",
"Access-Control-Allow-Origin": "*",
Expand Down
14 changes: 2 additions & 12 deletions src/routes/llms[.]txt.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,11 @@
import { source } from "@/lib/source";
import { buildLLMResponse, buildLLMSummaryText } from "@/lib/llms";
import { createFileRoute } from "@tanstack/react-router";

export const Route = createFileRoute("/llms.txt")({
server: {
handlers: {
GET: async () => {
const lines: string[] = [];
lines.push("# Documentation");
lines.push("");
for (const page of source.getPages()) {
lines.push(`- [${page.data.title}](${page.url}): ${page.data.description}`);
}
return new Response(lines.join("\n"), {
headers: {
"Access-Control-Allow-Origin": "*",
},
});
return buildLLMResponse(await buildLLMSummaryText());
},
},
},
Expand Down
Loading
Loading