# 🎯 Design-Entscheidungen
Dieses Dokument dokumentiert wichtige technische Entscheidungen und deren BegrĂĽndungen.
## 1. Parser-Technologie: unified/remark
**Entscheidung:** unified + remark als Core-Parser
**Datum:** 2025-10-01
### Kontext
Es wurden mehrere Markdown-Parser fĂĽr die Verarbeitung von Bildungsressourcen mit YAML Front Matter evaluiert.
### Alternativen
| Parser | Vorteile | Nachteile | Score |
|--------|----------|-----------|-------|
| **marked** | Sehr populär (30k+ GitHub Stars)
Einfache API
Gute Performance | Fokus auf HTML-Output
Kein AST-Zugriff
Begrenzte Erweiterbarkeit | 6/10 |
| **markdown-it** | Erweiterbar durch Plugins
Sehr schnell
CommonMark-konform | Komplexe API
HTML-fokussiert
Keine Browser-Isomorphie | 7/10 |
| **unified/remark** | AST-basiert (MDAST)
Isomorph (Node + Browser)
Riesiges Plugin-Ă–kosystem
De-facto Standard | Steilere Lernkurve
Mehr Setup-Code | **9/10** |
| **gray-matter + marked** | Sehr einfach
Schneller Einstieg | Weniger strukturiert
Begrenzte Flexibilität | 5/10 |
### Entscheidungskriterien
1. **AST-Zugriff** (Gewichtung: 30%)
- ✅ unified: Voller MDAST-Zugriff für präzise Manipulation
- ❌ marked: Kein AST, nur Token-Stream
2. **Isomorphie** (Gewichtung: 25%)
- âś… unified: Funktioniert identisch in Node.js und Browser
- ⚠️ markdown-it: Primär Node.js-fokussiert
3. **Erweiterbarkeit** (Gewichtung: 20%)
- âś… unified: 200+ Plugins im Ă–kosystem
- ⚠️ marked: Begrenzte Extension-API
4. **Standards** (Gewichtung: 15%)
- âś… unified: MDAST ist De-facto-Standard
- âś… markdown-it: CommonMark-konform
5. **Community & Wartung** (Gewichtung: 10%)
- âś… unified: Sehr aktiv, Teil von unifiedjs
- âś… marked: Aktiv maintained
### Konsequenzen
**Positiv:**
- Maximale Flexibilität für zukünftige Features
- AST-Transformationen fĂĽr WordPress/Nostr
- Browser-Support ohne Code-Änderungen
- Plugin-System fĂĽr Custom-Syntax
**Negativ:**
- Mehr initialer Setup-Code erforderlich
- Höhere Komplexität für einfache Use-Cases
- Größere Learning-Curve für Contributors
### Code-Beispiel
```javascript
import { unified } from 'unified'
import remarkParse from 'remark-parse'
import remarkFrontmatter from 'remark-frontmatter'
import remarkGfm from 'remark-gfm'
const processor = unified()
.use(remarkParse)
.use(remarkFrontmatter, ['yaml'])
.use(remarkGfm)
const ast = processor.parse(markdown)
```
---
## 2. YAML-Parser: `yaml` library
**Entscheidung:** `yaml` (v2.x) statt `js-yaml`
**Datum:** 2025-10-01
### Kontext
YAML Front Matter muss zuverlässig geparst werden, inkl. komplexer Strukturen (Arrays, nested Objects).
### Alternativen
| Library | Bundle Size | Spec-Konformität | Performance | Score |
|---------|-------------|------------------|-------------|-------|
| **yaml** | 42 KB | YAML 1.2 | Sehr gut | **9/10** |
| **js-yaml** | 68 KB | YAML 1.2 | Gut | 7/10 |
| JSON.parse | 0 KB (native) | N/A (nur JSON) | Exzellent | 3/10 |
### Entscheidung: `yaml`
**GrĂĽnde:**
1. âś… **Kleinere Bundle-Size** (42 KB vs. 68 KB)
2. âś… **Moderne API** (ESM-first, TypeScript-Typen)
3. âś… **Spec-compliant** (YAML 1.2)
4. âś… **Aktive Entwicklung**
5. âś… **Bessere Error-Messages**
### Konsequenzen
- Zuverlässiges Parsing komplexer YAML-Strukturen
- Gute Performance auch bei groĂźen Dateien
- Kleinere Bundle-Size fĂĽr Browser-Builds
---
## 3. HTTP-Client: Native `fetch`
**Entscheidung:** Native `fetch` API statt axios/node-fetch
**Datum:** 2025-10-01
### Kontext
HTTP-Requests fĂĽr Forgejo API und URL-basierte Markdown-Dateien.
### Alternativen
| Option | Vorteile | Nachteile | Score |
|--------|----------|-----------|-------|
| **native fetch** | In Node 18+ integriert
Identisch im Browser
Keine Dependencies | Erfordert Node.js 18+ | **10/10** |
| **axios** | Feature-reich
Interceptors
Auto-Transform | Zusätzliche Dependency
25 KB Bundle | 6/10 |
| **node-fetch** | Populär | Zusätzliche Dependency
Nicht identisch mit Browser | 5/10 |
### Entscheidung: Native `fetch`
**GrĂĽnde:**
1. âś… **Zero Dependencies**
2. âś… **Isomorphie** - Identische API in Node.js 18+ und Browser
3. âś… **Standard** - Web API Standard
4. âś… **Async/await** - Moderne Syntax
**Requirement:** Node.js >= 18.0.0
### Konsequenzen
- Keine zusätzlichen Dependencies
- Code funktioniert ohne Änderungen im Browser
- Einfachere Maintenance
---
## 4. Module-System: ESM (ES Modules)
**Entscheidung:** Pure ESM, kein CommonJS
**Datum:** 2025-10-01
### Kontext
Wahl des Module-Systems fĂĽr das Projekt.
### Entscheidung: ESM
```json
{
"type": "module"
}
```
**GrĂĽnde:**
1. âś… **Standard** - ESM ist der JavaScript-Standard
2. ✅ **Browser-kompatibel** - Direkt in Browsern lauffähig
3. âś… **Tree-Shaking** - Bessere Bundle-Optimierung
4. âś… **Zukunftssicher** - CommonJS ist Legacy
**Import-Syntax:**
```javascript
import { parseMarkdownFile } from './parser.js'
// statt:
// const { parseMarkdownFile } = require('./parser.js')
```
### Konsequenzen
**Positiv:**
- Moderne, zukunftssichere Codebasis
- Bessere Bundle-Optimierung
- Browser-Kompatibilität
**Negativ:**
- Keine Kompatibilität mit alten CommonJS-only Tools
- Erfordert `.js` Extension bei relativen Imports
---
## 5. Datenquelle-Priorität: API-First
**Entscheidung:** Primärer Fokus auf Forgejo API
**Datum:** 2025-10-01
### Kontext
Verschiedene Datenquellen mĂĽssen unterstĂĽtzt werden.
### Priorisierung
1. **Forgejo/Gitea API** (Priorität 1)
- Primäre Datenquelle
- Direkter API-Zugriff
- No Git-Clone nötig
2. **HTTP/HTTPS URLs** (Priorität 2)
- Einfacher Fallback
- Für öffentliche Dateien
3. **Lokale Dateien** (Priorität 3)
- FĂĽr Entwicklung und Tests
- Node.js-only
### Implementation
```javascript
// src/index.js
export async function parseMarkdown(source, options = {}) {
if (isForgejoURL(source)) {
return parseFromForgejo(source, options)
} else if (isHTTPURL(source)) {
return parseFromURL(source, options)
} else {
return parseFromFile(source, options)
}
}
```
---
## 6. Error-Handling: Graceful Degradation
**Entscheidung:** Fehlertolerante Metadaten-Extraktion
**Datum:** 2025-10-01
### Prinzip
Fehlende oder ungĂĽltige Metadaten fĂĽhren nicht zu Fehler, sondern zu Warnings.
```javascript
{
metadata: {
name: "Unbekannt", // Fallback
_warnings: [
"Fehlendes Feld: commonMetadata.name"
]
}
}
```
**GrĂĽnde:**
1. ✅ Robustheit gegenüber unvollständigen Daten
2. âś… Bessere User Experience
3. ✅ Ermöglicht partielle Verarbeitung
---
## 7. Browser-Build: Phase 2
**Entscheidung:** Browser-Build wird in Phase 2 implementiert
**Datum:** 2025-10-01
### Kontext
Browser-UnterstĂĽtzung ist wichtig, aber nicht im ersten Release.
### Phasen-Plan
**Phase 1 (jetzt):**
- Node.js-kompatibel
- Isomorpher Code (aber kein Build)
- Tests in Node.js
**Phase 2:**
- ESM Browser-Build
- Bundling mit Rollup/esbuild
- Browser-Tests
**Grund:**
- Fokus auf Core-Funktionalität
- Vermeidung von Over-Engineering
- Schnelleres Initial-Release
---
## 8. Testing: Node.js Native Test Runner
**Entscheidung:** Node.js `--test` statt Jest/Mocha
**Datum:** 2025-10-01
### Alternativen
| Test-Framework | Vorteile | Nachteile | Score |
|----------------|----------|-----------|-------|
| **Node.js native** | Keine Dependencies
Schnell
ESM-Support | Weniger Features | **8/10** |
| **Jest** | Feature-reich
Snapshots | Langsam
ESM-Probleme | 6/10 |
| **Vitest** | Schnell
ESM-first | Weitere Dependency | 7/10 |
### Entscheidung: Node.js Native
```javascript
// test/parser.test.js
import { test } from 'node:test'
import assert from 'node:assert'
test('parses markdown with YAML', async () => {
const result = await parseMarkdownFile('./fixtures/test.md')
assert.ok(result.yaml)
})
```
**GrĂĽnde:**
- âś… Zero Dependencies fĂĽr Tests
- âś… Schnelle AusfĂĽhrung
- âś… Native ESM-Support
- âś… Ausreichend fĂĽr unsere Zwecke
---
## Zusammenfassung: Technologie-Stack
| Kategorie | Technologie | BegrĂĽndung |
|-----------|-------------|------------|
| **Parser** | unified + remark | AST-basiert, isomorph, erweiterbar |
| **YAML** | yaml (v2.x) | Klein, modern, spec-compliant |
| **HTTP** | native fetch | Zero deps, isomorph |
| **Modules** | ESM | Standard, zukunftssicher |
| **Testing** | Node.js native | Zero deps, schnell |
| **Code Style** | Prettier + ESLint | Standard, automatisierbar |
---
## Änderungshistorie
| Datum | Entscheidung | Autor |
|-------|--------------|-------|
| 2025-10-01 | Initial: unified/remark | Jörg Lohrer |
| 2025-10-01 | YAML library | Jörg Lohrer |
| 2025-10-01 | Native fetch | Jörg Lohrer |
| 2025-10-01 | ESM-only | Jörg Lohrer |
---
**Fragen oder Vorschläge?** → [Issue erstellen](https://git.rpi-virtuell.de/Comenius-Institut/mdparser/issues)