import fs from "fs"; import path from "path"; import { NextResponse } from "next/server"; let cachedFieldnotes = null; async function getFieldnotes() { if (cachedFieldnotes) return cachedFieldnotes; try { const filePath = path.join(process.cwd(), "public/consolidated_fieldnotes.json"); const data = await fs.promises.readFile(filePath, "utf8"); const parsed = JSON.parse(data); // Drop the heavy lexical JSON representation on the server to keep memory and transfer size small cachedFieldnotes = parsed.map((note) => ({ title: note.title, slug: note.slug, date: note.date, author_slug: note.author_slug, content_markdown: note.content_markdown || "", })); return cachedFieldnotes; } catch (error) { console.error("Error loading consolidated fieldnotes:", error); return []; } } export async function GET(request) { const { searchParams } = new URL(request.url); const query = searchParams.get("q") || ""; const author = searchParams.get("author") || ""; const tag = searchParams.get("tag") || ""; const notes = await getFieldnotes(); // Perform search let filtered = notes; if (author) { filtered = filtered.filter((n) => n.author_slug === author); } if (tag) { // Alchemical tags like 🜏, 🜁, etc. filtered = filtered.filter((n) => n.content_markdown.includes(tag)); } if (query) { const lowerQuery = query.toLowerCase(); filtered = filtered.filter( (n) => n.title.toLowerCase().includes(lowerQuery) || n.content_markdown.toLowerCase().includes(lowerQuery) ); } // Slice results to keep response sizes fast const results = filtered.slice(0, 15); return NextResponse.json({ total: filtered.length, results, }); }