Fix bonsai tree build and add entries index page

Fix buildBonsai split error: Astro 6 githubSlug transforms 'i.bonsai' to
'ibonsai' breaking the semtree root lookup. Added custom generateId to the
index collection and switched to doc.id directly as bonsaiText key.

Move buildBonsai from module-level await to per-component call so it runs
after the content store is ready.

Add /entries index page listing all wiki pages.
This commit is contained in:
brutsalvadi
2026-04-23 09:44:50 +02:00
parent 4ebc4c798c
commit 5786fd827f
6 changed files with 48 additions and 20 deletions
+2 -1
View File
@@ -1,10 +1,11 @@
---
import { getCollection } from 'astro:content';
import { SITE_TITLE } from '../consts';
import { bonsai } from '../wikibonsai/semtree';
import { buildBonsai } from '../wikibonsai/semtree';
const { nodes } = Astro.props;
const bonsai = await buildBonsai();
const root = bonsai ? bonsai.root : '';
const treeNodes = bonsai ? bonsai.nodes : [];
---
+2 -1
View File
@@ -1,9 +1,10 @@
---
import { SITE_TITLE } from '../consts';
import { bonsai } from '../wikibonsai/semtree';
import { buildBonsai } from '../wikibonsai/semtree';
const { current } = Astro.props;
const bonsai = await buildBonsai();
const root = bonsai ? bonsai.root : '';
const treeNodes = bonsai ? bonsai.nodes : [];
+5 -1
View File
@@ -26,7 +26,11 @@ const entries = defineCollection({
});
const index = defineCollection({
loader: glob({ pattern: '**/*.md', base: './src/content/index' }),
loader: glob({
pattern: '**/*.md',
base: './src/content/index',
generateId: ({ entry }) => entry.replace(/\.md$/, ''),
}),
schema: z.object({
title: z.string(),
}),
+33
View File
@@ -0,0 +1,33 @@
---
import Base from '../../layouts/Base.astro';
import { SITE_TITLE, SITE_DESCRIPTION } from '../../consts';
import { getCollection } from 'astro:content';
const entries = (await getCollection('entries'))
.sort((a, b) => (b.data.updatedDate ?? b.data.pubDate ?? new Date(0)).valueOf()
- (a.data.updatedDate ?? a.data.pubDate ?? new Date(0)).valueOf());
---
<Base title={`Pages — ${SITE_TITLE}`} description={SITE_DESCRIPTION}>
<div class="max-w-3xl mx-auto">
<h1 class="text-3xl font-bold mb-6" style="color: var(--text-primary)">All Pages</h1>
{entries.length === 0 && (
<p style="color: var(--text-4)">No pages yet.</p>
)}
<ul class="space-y-2">
{entries.map(entry => (
<li>
<a
href={`/entries/${entry.id}/`}
class="flex items-center gap-2 px-3 py-2 rounded-lg hover:bg-zinc-800 transition-colors group"
style="background: var(--bg-card)"
>
<span class="text-sm font-medium group-hover:text-white transition-colors" style="color: var(--text-2)">
{entry.data.title}
</span>
</a>
</li>
))}
</ul>
</div>
</Base>
+2 -1
View File
@@ -2,8 +2,9 @@
import Base from '../layouts/Base.astro';
import Branch from '../components/Branch.astro';
import { SITE_TITLE, SITE_DESCRIPTION } from '../consts';
import { bonsai } from '../wikibonsai/semtree';
import { buildBonsai } from '../wikibonsai/semtree';
const bonsai = await buildBonsai();
const root = bonsai ? bonsai.root : '';
const treeNodes = bonsai ? bonsai.nodes : [];
---
+4 -16
View File
@@ -16,8 +16,8 @@ export async function buildBonsai(): Promise<SemTree | undefined> {
const rootFilename: string = 'i.bonsai';
// build 'bonsaiText' hash
const allIndexDocs = await getCollection('index');
allIndexDocs.forEach((doc: any) => { // remove preceding/trailing newlines/whitespace
bonsaiText[path.basename(doc.id, '.md')] = doc.body.replace(/^\s+|\s+$/g, '');
allIndexDocs.forEach((doc: any) => {
bonsaiText[doc.id] = (doc.body ?? '').replace(/^\s+|\s+$/g, '');
});
let bonsai: SemTree | string = 'uninitialized bonsai';
try {
@@ -49,19 +49,6 @@ export async function buildBonsai(): Promise<SemTree | undefined> {
// node.url = '/blog/' + doc.slug;
// }
// }
console.log('bonsai: \n'
+ '\n---\n'
+ 'root: ' + bonsai.root
+ '\n---\n'
+ 'branches: ' + bonsai.branches
+ '\n---\n'
+ 'petioleMap: ' + JSON.stringify(bonsai.petioleMap)
+ '\n---\n'
+ 'orphans: ' + bonsai.orphans
+ '\n---\n'
+ 'nodes: ' + JSON.stringify(bonsai.nodes)
+ '\n---\n'
);
return bonsai;
}
} catch (e) {
@@ -69,4 +56,5 @@ export async function buildBonsai(): Promise<SemTree | undefined> {
}
}
export const bonsai: SemTree | undefined = await buildBonsai();
// Do not call buildBonsai() at module init — the content store isn't ready yet.
// Each component that needs the tree should call buildBonsai() directly.