diff --git a/bun_plugins/markdown-loader.ts b/bun_plugins/markdown-loader.ts deleted file mode 100644 index 014f47d..0000000 --- a/bun_plugins/markdown-loader.ts +++ /dev/null @@ -1,19 +0,0 @@ -import type {BunPlugin} from 'bun'; -import { marked } from 'marked'; - -const markdownLoader: BunPlugin = { - name: 'markdown-loader', - setup(build) { - // Plugin implementation - build.onLoad({filter: /\.md$/}, async args => { - const text = await Bun.file(args.path).text(); - const html = marked.parse(text); - return { - contents: `export default ${html};`, - loader: 'html', - }; - }); - }, -}; - -export default markdownLoader; diff --git a/bun_plugins/onImport-markdown-loader.ts b/bun_plugins/onImport-markdown-loader.ts new file mode 100644 index 0000000..72e933e --- /dev/null +++ b/bun_plugins/onImport-markdown-loader.ts @@ -0,0 +1,29 @@ +import { main, type BunPlugin } from 'bun'; +import { loadMetadata } from "./utils"; +import matter from 'gray-matter'; +import { marked } from 'marked'; +import { AppShell } from "../src/frontend/AppShell"; +import AppShellPage from "../src/frontend/AppShell.html" with { type: "text" }; +import { renderToString } from "react-dom/server"; + +const markdownLoader: BunPlugin = { + name: 'markdown-loader', + setup(build) { + // Plugin implementation + build.onLoad({filter: /\.md$/}, async args => { + console.log("Loading markdown file:", args.path); + const {data, content } = matter(await Bun.file(args.path).text()); + loadMetadata(args.path, data); + const html = marked.parse(content); + + // JSX Approach + console.log(renderToString(AppShell({ post: html }))) + return { + contents: renderToString(AppShell({ post: html })), + loader: 'html', + }; + }); + }, +}; + +export default markdownLoader; diff --git a/bun_plugins/onStartup-post-importer.ts b/bun_plugins/onStartup-post-importer.ts new file mode 100644 index 0000000..4a792f2 --- /dev/null +++ b/bun_plugins/onStartup-post-importer.ts @@ -0,0 +1,16 @@ +import matter from 'gray-matter'; +import { loadMetadata } from "./utils"; + +// When the server starts, import all the blog post metadata into the database +// Executed on startup because it's included in ./bunfig.toml + +(async () => { + const glob = new Bun.Glob("**/*.md"); + for await (const file of glob.scan("./content")) { + const {data, content } = matter(await Bun.file(`./content/${file}`).text()); + const route = `/${file.replace(/\.md$/, "")}`; + loadMetadata(route, data); + } + + console.log('Posts have been imported into db'); +})(); diff --git a/bun_plugins/utils.ts b/bun_plugins/utils.ts new file mode 100644 index 0000000..9051362 --- /dev/null +++ b/bun_plugins/utils.ts @@ -0,0 +1,72 @@ +import { Database } from 'bun:sqlite'; +import path from 'path'; + +// Initialize the database if it doesn't exist +const dbPath = path.join(process.cwd(), 'blog_metadata.sqlite'); +const db = new Database(dbPath); + +// Create the posts table if it doesn't exist +db.run(` + CREATE TABLE IF NOT EXISTS posts ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + path TEXT UNIQUE NOT NULL, + title TEXT, + date TEXT, + author TEXT, + tags TEXT, + published INTEGER, + summary TEXT, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME DEFAULT CURRENT_TIMESTAMP + ) +`); + +// Load metadata from the blog post into a SQLite database +// This allows us to index and make queries against the metadata +// to support functions like search, filtering, and sorting +export function loadMetadata(filePath: string, data: { [key: string]: any }) { + if (!data) return; + + try { + // Extract common fields + const { title, date, author, tags, published, summary } = data; + + // Log the values for debugging + // console.log('Metadata values:', { + // filePath: typeof filePath, + // title: typeof title, + // date: typeof date, + // author: typeof author, + // tags: typeof tags, + // published: typeof published, + // summary: typeof summary + // }); + + // Convert all values to strings or null explicitly + const values = [ + filePath ? String(filePath) : null, + title ? String(title) : null, + date ? String(date) : null, + author ? String(author) : null, + tags ? JSON.stringify(tags) : null, + published !== undefined ? (published ? 1 : 0) : null, + summary ? String(summary) : null + ]; + + // Log the prepared values + // console.log('Prepared values:', values); + + // Query to insert or replace metadata + const query = db.query(` + INSERT OR REPLACE INTO posts + (path, title, date, author, tags, published, summary, updated_at) + VALUES (?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP) + `); + + query.run(...values); + + // console.log(`Stored metadata for: ${filePath}`); + } catch (error) { + // console.error(`Failed to store metadata for ${filePath}:`, error); + } +} diff --git a/bunfig.toml b/bunfig.toml index 99eed22..4563137 100644 --- a/bunfig.toml +++ b/bunfig.toml @@ -1,2 +1,4 @@ +preload = ["./bun_plugins/onStartup-post-importer.ts"] + [serve.static] -plugins = ["./bun_plugins/markdown-loader.ts"] \ No newline at end of file +plugins = ["./bun_plugins/onImport-markdown-loader.ts"]