From 11f7aef552faa5571950a5838f8a691f5f7a6ed2 Mon Sep 17 00:00:00 2001 From: Niki Wix Skaarup Date: Tue, 1 Apr 2025 01:38:20 +0200 Subject: [PATCH] support hot reload --- src/components/header.svelte | 7 ++++++- src/index.html | 2 +- src/index.ts | 30 +++++++++++++++++++++++++++--- src/server.ts | 12 +++++------- 4 files changed, 39 insertions(+), 12 deletions(-) diff --git a/src/components/header.svelte b/src/components/header.svelte index 8b18c11..c33a25a 100644 --- a/src/components/header.svelte +++ b/src/components/header.svelte @@ -22,7 +22,12 @@ referrerpolicy="no-referrer" > git.skaarup.dev/nikiskaarup/progress-tracker-v3 - + -
+
diff --git a/src/index.ts b/src/index.ts index 8195c29..3a852b5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,30 @@ -import { mount } from 'svelte'; +import { mount, unmount } from 'svelte'; import index from './index.svelte'; import './index.css'; -const root = document.querySelector('#root')!; -const app = mount(index, { target: root }); +declare global { + var didMount: boolean | undefined; +} + +let app: Record | 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('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 }); + }); +} diff --git a/src/server.ts b/src/server.ts index 230906c..5e78869 100644 --- a/src/server.ts +++ b/src/server.ts @@ -4,26 +4,24 @@ import robotsTxt from './static/robots.txt'; import sitemapTxt from './static/sitemap.txt'; // @ts-ignore ts2307 import icon from './static/favicon.png' with { type: 'file' }; - const favicon = await Bun.file(icon).bytes(); - const development = env.NODE_ENV !== 'production'; Bun.serve({ routes: { '/': homepage, '/robots.txt': new Response(robotsTxt, { - headers: { 'Content-Type': 'text/plain' } + headers: { 'Content-Type': 'text/plain' }, }), '/sitemap.txt': new Response(sitemapTxt, { - headers: { 'Content-Type': 'text/plain' } + headers: { 'Content-Type': 'text/plain' }, }), '/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) { // return new Response("Not found", { status: 404 }); // },