bosia 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bosia",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "type": "module",
5
5
  "description": "A fast, batteries-included fullstack framework — SSR · Svelte 5 Runes · Bun · ElysiaJS. File-based routing inspired by SvelteKit. No Node.js, no Vite, no adapters.",
6
6
  "keywords": [
package/src/cli/dev.ts CHANGED
@@ -1,9 +1,7 @@
1
1
  import { spawn } from "bun";
2
2
  import { resolve } from "path";
3
- import { loadEnv } from "../core/env.ts";
4
3
 
5
4
  export async function runDev() {
6
- loadEnv("development");
7
5
  const devScript = resolve(import.meta.dir, "../core/dev.ts");
8
6
  const proc = spawn(["bun", "run", devScript], {
9
7
  stdout: "inherit",
package/src/core/dev.ts CHANGED
@@ -1,6 +1,23 @@
1
1
  import { spawn, type Subprocess } from "bun";
2
2
  import { watch } from "fs";
3
3
  import { join } from "path";
4
+ import { loadEnv, resetDeclaredKeys } from "./env.ts";
5
+
6
+ // Snapshot pure shell env BEFORE any loadEnv call pollutes process.env.
7
+ // On `.env*` change we restore from this snapshot, then re-run loadEnv,
8
+ // so removed/renamed keys no longer linger in the dev process.
9
+ const SHELL_ENV_SNAPSHOT: Record<string, string | undefined> = { ...process.env };
10
+
11
+ loadEnv("development");
12
+
13
+ function reloadEnv() {
14
+ for (const k of Object.keys(process.env)) delete process.env[k];
15
+ for (const [k, v] of Object.entries(SHELL_ENV_SNAPSHOT)) {
16
+ if (v !== undefined) process.env[k] = v;
17
+ }
18
+ resetDeclaredKeys();
19
+ loadEnv("development");
20
+ }
4
21
 
5
22
  console.log("⬡ Bosia dev server starting...\n");
6
23
 
@@ -234,4 +251,18 @@ watch(join(process.cwd(), "src"), { recursive: true }, (_event, filename) => {
234
251
  scheduleBuild();
235
252
  });
236
253
 
254
+ // ─── .env Watcher ─────────────────────────────────────────
255
+ // Reset to shell-env snapshot and re-run loadEnv so removed/renamed
256
+ // keys don't linger across hot-reloads. The respawn at startAppServer
257
+ // already spreads `...process.env`, so the child picks up the fresh state.
258
+
259
+ const ENV_FILES = new Set([".env", ".env.local", ".env.development", ".env.development.local"]);
260
+
261
+ watch(process.cwd(), { recursive: false }, (_event, filename) => {
262
+ if (!filename || !ENV_FILES.has(filename)) return;
263
+ console.log(`[watch] env changed: ${filename}`);
264
+ reloadEnv();
265
+ scheduleBuild();
266
+ });
267
+
237
268
  console.log("👀 Watching src/ for changes...\n");
package/src/core/env.ts CHANGED
@@ -175,6 +175,11 @@ export function getDeclaredEnvKeys(): ReadonlySet<string> {
175
175
  return _declaredKeys;
176
176
  }
177
177
 
178
+ /** Clear the declared-keys set. Call before re-running `loadEnv` on hot-reload so removed PUBLIC_* keys stop leaking to the client. */
179
+ export function resetDeclaredKeys(): void {
180
+ _declaredKeys.clear();
181
+ }
182
+
178
183
  // ─── Classifier ──────────────────────────────────────────
179
184
 
180
185
  export interface ClassifiedEnv {
@@ -1,11 +1,7 @@
1
- <script lang="ts">
2
- const name = "{{PROJECT_NAME}}";
3
- </script>
4
-
5
1
  <main class="flex min-h-screen flex-col items-center justify-center gap-6 p-8">
6
2
  <div class="flex flex-col items-center gap-3 text-center">
7
3
  <img src="/favicon.svg" alt="" class="size-16" />
8
- <h1 class="text-4xl font-bold tracking-tight">{name}</h1>
4
+ <h1 class="text-4xl font-bold tracking-tight">Welcome to Bosia</h1>
9
5
  <p class="text-muted-foreground text-lg">
10
6
  A Bosia project — SSR + Svelte 5 + Bun + ElysiaJS
11
7
  </p>
@@ -1,5 +1,5 @@
1
1
  <svelte:head>
2
- <title>About | {{ PROJECT_NAME }}</title>
2
+ <title>About | Bosia</title>
3
3
  </svelte:head>
4
4
 
5
5
  <div>
@@ -8,7 +8,7 @@
8
8
  <header class="sticky top-0 z-10 border-b bg-background/80 backdrop-blur">
9
9
  <nav class="mx-auto flex max-w-4xl items-center gap-6 px-4 py-3">
10
10
  <a href="/" class="font-bold tracking-tight flex items-center gap-2"
11
- ><img src="/favicon.svg" alt="" class="size-5" /> {{ PROJECT_NAME }}</a
11
+ ><img src="/favicon.svg" alt="" class="size-5" /> {data.appName}</a
12
12
  >
13
13
  <a
14
14
  href="/"
@@ -37,8 +37,8 @@
37
37
  </script>
38
38
 
39
39
  <svelte:head>
40
- <title>{{ PROJECT_NAME }}</title>
41
- <meta name="description" content="{{ PROJECT_NAME }} — SSR + Svelte 5 + Bun + ElysiaJS" />
40
+ <title>Bosia Demo</title>
41
+ <meta name="description" content="Bosia Demo — SSR + Svelte 5 + Bun + ElysiaJS" />
42
42
  </svelte:head>
43
43
 
44
44
  <div class="space-y-12">
@@ -46,7 +46,7 @@
46
46
  <div class="space-y-3 pt-4">
47
47
  <h1 class="text-5xl font-bold tracking-tight flex items-center gap-3">
48
48
  <img src="/favicon.svg" alt="" class="size-10" />
49
- {{ PROJECT_NAME }}
49
+ Bosia Demo
50
50
  </h1>
51
51
  <p class="text-xl text-muted-foreground max-w-xl">
52
52
  A minimalist fullstack framework — SSR, Svelte 5 Runes, Bun, and ElysiaJS.
@@ -1,9 +1,9 @@
1
1
  <svelte:head>
2
- <title>About | {{ PROJECT_NAME }}</title>
2
+ <title>About | Bosia Demo</title>
3
3
  </svelte:head>
4
4
 
5
5
  <div class="space-y-6 max-w-2xl">
6
- <h1 class="text-4xl font-bold tracking-tight">About {{ PROJECT_NAME }}</h1>
6
+ <h1 class="text-4xl font-bold tracking-tight">About Bosia Demo</h1>
7
7
  <p class="text-muted-foreground text-lg">
8
8
  A minimalist fullstack framework built on Bun, ElysiaJS, and Svelte 5.
9
9
  </p>
@@ -4,7 +4,7 @@
4
4
  </script>
5
5
 
6
6
  <svelte:head>
7
- <title>Catch-all Demo | {{ PROJECT_NAME }}</title>
7
+ <title>Catch-all Demo | Bosia Demo</title>
8
8
  </svelte:head>
9
9
 
10
10
  <div class="flex flex-col items-center justify-center py-24 text-center space-y-6">
@@ -26,7 +26,7 @@
26
26
  </script>
27
27
 
28
28
  <svelte:head>
29
- <title>Blog | {{ PROJECT_NAME }}</title>
29
+ <title>Blog | Bosia Demo</title>
30
30
  </svelte:head>
31
31
 
32
32
  <div class="space-y-8">
@@ -8,7 +8,7 @@
8
8
  </script>
9
9
 
10
10
  <svelte:head>
11
- <title>{post ? post.title : "Post Not Found"} | {{ PROJECT_NAME }}</title>
11
+ <title>{post ? post.title : "Post Not Found"} | Bosia Demo</title>
12
12
  </svelte:head>
13
13
 
14
14
  {#if post}
@@ -4,7 +4,7 @@ import type { LoadEvent } from "bosia";
4
4
  // and to all layouts via the `data` prop.
5
5
  export async function load({ locals }: LoadEvent) {
6
6
  return {
7
- appName: "{{PROJECT_NAME}}",
7
+ appName: "Bosia Demo",
8
8
  requestTime: (locals.requestTime as number | null) ?? null,
9
9
  };
10
10
  }
@@ -2,7 +2,7 @@ import type { LoadEvent } from "bosia";
2
2
 
3
3
  export async function load({ locals }: LoadEvent) {
4
4
  return {
5
- appName: "{{PROJECT_NAME}}",
5
+ appName: "Bosia Todo",
6
6
  requestTime: (locals.requestTime as number | null) ?? null,
7
7
  };
8
8
  }