Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8790a4f65a | ||
|
|
b454a0fbac |
No files matched your search
@@ -3,6 +3,12 @@ import { notFound } from "next/navigation";
|
||||
import { getDocument, listDocuments, getRelated, listRevisions } from "@mcpedia/core";
|
||||
import Markdown from "@/components/Markdown";
|
||||
|
||||
// Render at request time. The content lives in Postgres (populated by the
|
||||
// indexer/worker), which is not available at build time (CI has no DB), so we
|
||||
// opt out of static generation. At this corpus scale request-time rendering is
|
||||
// instant.
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
export default async function DocPage({
|
||||
params,
|
||||
}: {
|
||||
@@ -80,11 +86,3 @@ export default async function DocPage({
|
||||
</article>
|
||||
);
|
||||
}
|
||||
|
||||
export async function generateStaticParams() {
|
||||
const docs = await listDocuments();
|
||||
return docs.map((d) => ({
|
||||
section: d.section,
|
||||
slug: d.slug.split("/").slice(1),
|
||||
}));
|
||||
}
|
||||
@@ -2,6 +2,10 @@ import Link from "next/link";
|
||||
import { listDocuments } from "@mcpedia/core";
|
||||
import type { DocumentMeta } from "@mcpedia/core";
|
||||
|
||||
// Render at request time — content is in Postgres (not available at build in
|
||||
// CI, which has no DB). Request-time rendering is instant at this corpus scale.
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
const SECTIONS = ["docs", "writeups", "research", "notes"] as const;
|
||||
|
||||
export default async function Home() {
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import Link from "next/link";
|
||||
import { keywordSearch, hybridSearch } from "@mcpedia/core";
|
||||
|
||||
// Render at request time — queries Postgres on each request (not at build,
|
||||
// where CI has no DB).
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
type Mode = "keyword" | "hybrid";
|
||||
|
||||
export default async function SearchPage({
|
||||
|
||||
@@ -32,11 +32,11 @@ export class OpenRouterEmbeddingProvider implements EmbeddingProvider {
|
||||
this.baseUrl = (opts?.baseUrl ?? EMBED_BASE_URL).replace(/\/$/, "");
|
||||
this.apiKey = opts?.apiKey ?? EMBED_API_KEY;
|
||||
this.model = opts?.model ?? EMBED_MODEL;
|
||||
if (!this.baseUrl || !this.apiKey || !this.model) {
|
||||
throw new Error(
|
||||
"OpenRouterEmbeddingProvider: missing EMBED_BASE_URL / EMBED_API_KEY / EMBED_MODEL",
|
||||
);
|
||||
}
|
||||
// NOTE: we do NOT validate baseUrl/apiKey/model here. Throwing in the
|
||||
// constructor breaks `next build` (SSG data collection imports the search
|
||||
// package before any .env is present) and any runtime-injected env. The
|
||||
// provider is constructed lazily at first query, so an unset config
|
||||
// surfaces as a clear error from embed() at request time, not a build crash.
|
||||
}
|
||||
|
||||
get dimensions(): number {
|
||||
@@ -45,6 +45,11 @@ export class OpenRouterEmbeddingProvider implements EmbeddingProvider {
|
||||
|
||||
async embed(texts: string[]): Promise<number[][]> {
|
||||
if (texts.length === 0) return [];
|
||||
if (!this.baseUrl || !this.apiKey || !this.model) {
|
||||
throw new Error(
|
||||
"OpenRouterEmbeddingProvider: missing EMBED_BASE_URL / EMBED_API_KEY / EMBED_MODEL at request time",
|
||||
);
|
||||
}
|
||||
const res = await fetch(`${this.baseUrl}/embeddings`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
|
||||
Reference in new issue
Block a user