Complete WIP: Architecture refactor.

Mount JSX server side templating for blog posts. Send AppShell conditionally. Maintain support for HMR via HTMLbundles using Bun's native fullstack dev server under an /hmr path. This is only mounted in development and is supported by the onImport Bun plugin. Add DB creation on startup and load pages based on those records.
This commit is contained in:
2026-01-08 05:13:48 -08:00
parent 3abd97702d
commit f46f4667a1
32 changed files with 2779 additions and 353 deletions

View File

@@ -1,11 +0,0 @@
// Client-side script that runs in <head>
// Example: TypeScript with DOM types
(() => {
const logPageInfo = (): void => {
console.log('Page loaded in <head>');
};
if (document.readyState === 'loading') {
logPageInfo();
}
})();

View File

@@ -1,43 +0,0 @@
// Client-side script that runs on page load
// Example: TypeScript with type annotations
async function loadContent(url: string) {
const response = await fetch(url, {
headers: {
'shell-loaded': 'true'
}
});
const html = await response.text();
const mainElement = document.querySelector('main');
if (mainElement) {
mainElement.outerHTML = html;
// Re-attach handlers to new links after content swap
attachLinkHandlers();
}
}
function attachLinkHandlers() {
const links: NodeListOf<HTMLAnchorElement> = document.querySelectorAll('a');
console.log('Found links:', links.length);
links.forEach(link => {
console.log('Attaching listener to:', link.href);
link.onclick = async (e) => {
console.log('clicked', link.href);
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();
window.history.pushState({}, '', link.href);
await loadContent(link.href);
}
});
}
// Listen for back/forward button clicks
window.addEventListener('popstate', async (event) => {
await loadContent(window.location.href);
});
document.addEventListener('DOMContentLoaded', () => {
attachLinkHandlers();
});

View File

@@ -1,97 +0,0 @@
body, a {
margin: 0px;
text-decoration: none;
color: black;
}
header {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
background-color: #f2f2f2;
padding: 15px;
height: 50px;
}
header span {
font-size: 30px;
font-weight: bold;
}
nav {
display: flex;
flex-direction: row;
align-items: center;
text-align: center;
gap: 10px;
}
nav a {
text-decoration: none;
color: black;
font-size: 20px;
}
hr {
margin: 0px;
opacity: 75%;
}
.post-spotlight {
display: flex;
flex-direction: column;
align-items: center;
margin: 30px;
padding: 4em;
}
article {
font-family: 'Arial Narrow Bold', sans-serif;
}
article > h2 {
font-size: 3em;
font-weight: bold;
margin: 15px;
}
article > div {
color: gray;
}
article > a {
text-decoration: none;
border: 1px solid black;
padding: 10px;
border-radius: 5px;
background-color: #f2f2f2;
color: black;
text-align: end;
}
aside {
display: flex;
flex-direction: row;
justify-content: space-evenly;
align-items: center;
margin: 15px;
}
aside h3 {
font-size: 2em;
font-weight: bold;
}
aside ul {
list-style-type: none;
padding: 0px;
}
.about ul {
display: flex;
flex-direction: row;
gap: 10px;
}