6 changed files with 432 additions and 17 deletions
@ -0,0 +1,20 @@
@@ -0,0 +1,20 @@
|
||||
/** |
||||
* Server-side loader for NIP-34 specification reference |
||||
*/ |
||||
|
||||
import { readFile } from 'fs/promises'; |
||||
import { join } from 'path'; |
||||
import type { PageServerLoad } from './$types'; |
||||
import logger from '$lib/services/logger.js'; |
||||
|
||||
export const load: PageServerLoad = async () => { |
||||
try { |
||||
// Read NIP-34 specification from docs/34.md
|
||||
const filePath = join(process.cwd(), 'docs', '34.md'); |
||||
const content = await readFile(filePath, 'utf-8'); |
||||
return { content }; |
||||
} catch (error) { |
||||
logger.error({ error }, 'Error loading NIP-34 specification'); |
||||
return { content: null, error: 'Failed to load NIP-34 specification' }; |
||||
} |
||||
}; |
||||
@ -0,0 +1,169 @@
@@ -0,0 +1,169 @@
|
||||
<script lang="ts"> |
||||
import { page } from '$app/stores'; |
||||
import { onMount } from 'svelte'; |
||||
|
||||
let content = $state(''); |
||||
let loading = $state(true); |
||||
let error = $state<string | null>(null); |
||||
|
||||
onMount(async () => { |
||||
try { |
||||
const docContent = $page.data.content; |
||||
if (docContent) { |
||||
const MarkdownIt = (await import('markdown-it')).default; |
||||
const hljsModule = await import('highlight.js'); |
||||
const hljs = hljsModule.default || hljsModule; |
||||
|
||||
const md: any = new MarkdownIt({ |
||||
highlight: function (str: string, lang: string): string { |
||||
if (lang && hljs.getLanguage(lang)) { |
||||
try { |
||||
return '<pre class="hljs"><code>' + |
||||
hljs.highlight(str, { language: lang }).value + |
||||
'</code></pre>'; |
||||
} catch (__) {} |
||||
} |
||||
return '<pre class="hljs"><code>' + md.utils.escapeHtml(str) + '</code></pre>'; |
||||
} |
||||
}); |
||||
|
||||
content = md.render(docContent); |
||||
} else { |
||||
error = $page.data.error || 'Failed to load NIP-34 specification'; |
||||
} |
||||
} catch (err) { |
||||
error = err instanceof Error ? err.message : 'Failed to load specification'; |
||||
console.error('Error parsing NIP-34 specification:', err); |
||||
} finally { |
||||
loading = false; |
||||
} |
||||
}); |
||||
</script> |
||||
|
||||
<div class="container"> |
||||
<header> |
||||
<h1>NIP-34 Specification</h1> |
||||
<p class="subtitle">Nostr Improvement Proposal for Git Collaboration</p> |
||||
</header> |
||||
|
||||
<main class="docs-content"> |
||||
{#if loading} |
||||
<div class="loading">Loading specification...</div> |
||||
{:else if error} |
||||
<div class="error">{error}</div> |
||||
{:else} |
||||
<div class="markdown-content"> |
||||
{@html content} |
||||
</div> |
||||
{/if} |
||||
</main> |
||||
</div> |
||||
|
||||
<style> |
||||
.subtitle { |
||||
color: var(--text-muted); |
||||
margin: 0; |
||||
} |
||||
|
||||
.docs-content { |
||||
background: var(--card-bg); |
||||
padding: 2rem; |
||||
border-radius: 0.5rem; |
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); |
||||
border: 1px solid var(--border-color); |
||||
} |
||||
|
||||
:global(.markdown-content) { |
||||
line-height: 1.6; |
||||
} |
||||
|
||||
:global(.markdown-content h1) { |
||||
font-size: 2rem; |
||||
margin-top: 2rem; |
||||
margin-bottom: 1rem; |
||||
border-bottom: 2px solid var(--border-color); |
||||
padding-bottom: 0.5rem; |
||||
color: var(--text-primary); |
||||
} |
||||
|
||||
:global(.markdown-content h2) { |
||||
font-size: 1.5rem; |
||||
margin-top: 1.5rem; |
||||
margin-bottom: 0.75rem; |
||||
color: var(--text-primary); |
||||
} |
||||
|
||||
:global(.markdown-content h3) { |
||||
font-size: 1.25rem; |
||||
margin-top: 1.25rem; |
||||
margin-bottom: 0.5rem; |
||||
color: var(--text-primary); |
||||
} |
||||
|
||||
:global(.markdown-content code) { |
||||
background: var(--bg-secondary); |
||||
padding: 0.125rem 0.25rem; |
||||
border-radius: 0.25rem; |
||||
font-family: 'IBM Plex Mono', monospace; |
||||
font-size: 0.875em; |
||||
color: var(--text-primary); |
||||
} |
||||
|
||||
:global(.markdown-content pre) { |
||||
background: var(--bg-tertiary); |
||||
color: var(--text-primary); |
||||
padding: 1rem; |
||||
border-radius: 0.5rem; |
||||
overflow-x: auto; |
||||
margin: 1rem 0; |
||||
border: 1px solid var(--border-color); |
||||
} |
||||
|
||||
:global(.markdown-content pre code) { |
||||
background: transparent; |
||||
padding: 0; |
||||
color: inherit; |
||||
} |
||||
|
||||
:global(.markdown-content p) { |
||||
margin: 1rem 0; |
||||
} |
||||
|
||||
:global(.markdown-content ul, .markdown-content ol) { |
||||
margin: 1rem 0; |
||||
padding-left: 2rem; |
||||
} |
||||
|
||||
:global(.markdown-content li) { |
||||
margin: 0.5rem 0; |
||||
} |
||||
|
||||
:global(.markdown-content blockquote) { |
||||
border-left: 4px solid var(--accent); |
||||
padding-left: 1rem; |
||||
margin: 1rem 0; |
||||
color: var(--text-secondary); |
||||
} |
||||
|
||||
:global(.markdown-content table) { |
||||
width: 100%; |
||||
border-collapse: collapse; |
||||
margin: 1rem 0; |
||||
} |
||||
|
||||
:global(.markdown-content th, .markdown-content td) { |
||||
border: 1px solid var(--border-color); |
||||
padding: 0.5rem; |
||||
text-align: left; |
||||
} |
||||
|
||||
:global(.markdown-content th) { |
||||
background: var(--bg-secondary); |
||||
font-weight: 600; |
||||
color: var(--text-primary); |
||||
} |
||||
|
||||
:global(.markdown-content td) { |
||||
color: var(--text-primary); |
||||
} |
||||
</style> |
||||
Loading…
Reference in new issue