68 lines
1.8 KiB
JavaScript
68 lines
1.8 KiB
JavaScript
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,
|
|
});
|
|
}
|