Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions bunfig.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
[serve.static]
plugins = ["bun-plugin-svelte"]
# plugins = ["./src/dashboard/svelte.ts"]

[test]
coverageThreshold = 0.90
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@
},
"devDependencies": {
"@types/bun": "^1.2.22",
"bun-plugin-svelte": "^0.0.6",
"dotenv": "^17.2.2",
"drizzle-arktype": "^0.1.3",
"drizzle-kit": "^0.31.4",
"drizzle-orm": "^0.44.5",
Expand Down
6 changes: 6 additions & 0 deletions src/cors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,10 @@ export class CorsedResponse extends Response {
response.headers.set('Access-Control-Allow-Origin', Bun.env.ALLOWED_ORIGINS || '*');
return response;
}

static html(body: string, init?: ResponseInit) {
const response = new CorsedResponse(body, init);
response.headers.set('Content-Type', 'text/html; charset=utf-8');
return response;
}
}
12 changes: 12 additions & 0 deletions src/dashboard/app.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Dashboard</title>
<script type="module" src="./frontend.ts"></script>
</head>
<body>
<div id="root"></div>
</body>
</html>
6 changes: 6 additions & 0 deletions src/dashboard/backend.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { BunPlugin } from 'bun';

export const backend: BunPlugin = {
name: 'Dashboard backend',
setup({}) {}
};
28 changes: 28 additions & 0 deletions src/dashboard/frontend.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { mount, unmount } from 'svelte';
import App from './home.svelte';

declare global {
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 root = document.getElementById('root')!;
if (!globalThis.didMount) {
app = mount(App, { target: root });
}
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(App, { target: root });
});
}
13 changes: 13 additions & 0 deletions src/dashboard/home.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<script>
const { hello } = $props()
let count = $state(0)
</script>

<h1>hellowo {hello}</h1>
<button onclick={() => {count++}}>{count}</button>

<style>
button {
color: red;
}
</style>
33 changes: 33 additions & 0 deletions src/dashboard/svelte.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { plugin } from 'bun';

import * as svelte from 'svelte/compiler';

plugin({
name: 'Svelte',
setup(build) {
build.onLoad({ filter: /\.svelte(\?.*)?$/ }, async (args) => {
const searchParams = new URLSearchParams(args.path.split('?')[1]);
const dom = searchParams.has('dom');
const path = args.path.replace(/\?.*$/, '');

const file = await Bun.file(path).text();
const { js, warnings } = svelte.compile(file, {
filename: path,
generate: dom ? 'client' : 'server',
css: 'injected',
hmr: !process.env.PROD
});

for (const warning of warnings) {
console.warn(`[svelte] ${warning.message}`);
}

return dom
? {
loader: 'object',
exports: { default: js.code }
}
: { contents: js.code, loader: 'js' };
});
}
});
4 changes: 4 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,17 @@ import {
SendCorrectionsRequest
} from './tables.js';
import { omit, uniqueBy } from './utils.js';
import dashboard from './dashboard/app.html';
import DashboardHome from './dashboard/home.svelte';
import { render } from 'svelte/server';

const port = process.argv[2] ? parseInt(process.argv[2]) : 3000;

Bun.serve({
port,
development: !Bun.env.PROD,
routes: {
'/dashboard': dashboard,
'/corrections': {
async POST(req: Request) {
const body = await req.json().then(SendCorrectionsRequest.assert);
Expand Down