support hot reload

This commit is contained in:
Niki Wix Skaarup 2025-04-01 01:38:20 +02:00
parent 0703276134
commit 11f7aef552
Signed by: nikiskaarup
GPG key ID: FC2F1B116F6E788C
4 changed files with 39 additions and 12 deletions

View file

@ -22,7 +22,12 @@
referrerpolicy="no-referrer" referrerpolicy="no-referrer"
> >
<span class="sr-only">git.skaarup.dev/nikiskaarup/progress-tracker-v3</span> <span class="sr-only">git.skaarup.dev/nikiskaarup/progress-tracker-v3</span>
<svg class="aspect-square h-8" viewBox="0 0 98 96" xmlns="http://www.w3.org/2000/svg"> <svg
class="aspect-square h-8"
height="32"
viewBox="0 0 98 96"
xmlns="http://www.w3.org/2000/svg"
>
<path <path
fill-rule="evenodd" fill-rule="evenodd"
clip-rule="evenodd" clip-rule="evenodd"

View file

@ -15,6 +15,6 @@
<body <body
class="min-h-dvh bg-gray-950 bg-cover bg-fixed bg-center bg-no-repeat font-mono text-pretty text-gray-100" class="min-h-dvh bg-gray-950 bg-cover bg-fixed bg-center bg-no-repeat font-mono text-pretty text-gray-100"
> >
<div id="root" class="contents"></div> <div class="contents"></div>
</body> </body>
</html> </html>

View file

@ -1,6 +1,30 @@
import { mount } from 'svelte'; import { mount, unmount } from 'svelte';
import index from './index.svelte'; import index from './index.svelte';
import './index.css'; import './index.css';
const root = document.querySelector<HTMLDivElement>('#root')!; declare global {
const app = mount(index, { target: root }); var didMount: boolean | undefined;
}
let app: Record<string, any> | undefined;
// mount the application entrypoint to the DOM on first load. On subsequent hot
// updates, the app will be unmounted and re-mounted via the accept handler.
const target = document.querySelector<HTMLDivElement>('body>div')!;
if (!globalThis.didMount) {
app = mount(index, { target });
}
globalThis.didMount = true;
if (import.meta.hot) {
import.meta.hot.accept(async () => {
// avoid unmounting twice when another update gets accepted while outros are playing
if (!app) return;
const prevApp = app;
app = undefined;
await unmount(prevApp, { outro: true });
app = mount(index, { target });
});
}

View file

@ -4,26 +4,24 @@ import robotsTxt from './static/robots.txt';
import sitemapTxt from './static/sitemap.txt'; import sitemapTxt from './static/sitemap.txt';
// @ts-ignore ts2307 // @ts-ignore ts2307
import icon from './static/favicon.png' with { type: 'file' }; import icon from './static/favicon.png' with { type: 'file' };
const favicon = await Bun.file(icon).bytes(); const favicon = await Bun.file(icon).bytes();
const development = env.NODE_ENV !== 'production'; const development = env.NODE_ENV !== 'production';
Bun.serve({ Bun.serve({
routes: { routes: {
'/': homepage, '/': homepage,
'/robots.txt': new Response(robotsTxt, { '/robots.txt': new Response(robotsTxt, {
headers: { 'Content-Type': 'text/plain' } headers: { 'Content-Type': 'text/plain' },
}), }),
'/sitemap.txt': new Response(sitemapTxt, { '/sitemap.txt': new Response(sitemapTxt, {
headers: { 'Content-Type': 'text/plain' } headers: { 'Content-Type': 'text/plain' },
}), }),
'/favicon.ico': new Response(favicon, { '/favicon.ico': new Response(favicon, {
headers: { 'Content-Type': 'image/png' } headers: { 'Content-Type': 'image/png' },
}), }),
'/health': new Response('OK') '/health': new Response('OK'),
}, },
development development,
// async fetch(req, server) { // async fetch(req, server) {
// return new Response("Not found", { status: 404 }); // return new Response("Not found", { status: 404 });
// }, // },