@emkodev/emroute 1.6.0-beta.1 → 1.6.0

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/README.md CHANGED
@@ -28,6 +28,10 @@ bun add @emkodev/emroute
28
28
  > emroute ships TypeScript source. Your toolchain must handle `.ts` imports
29
29
  > (Bun, tsx, esbuild, etc.).
30
30
 
31
+ For markdown rendering, add [@emkodev/emkoma](doc/08c-setup-emkoma.md) (built
32
+ for emroute) or bring your own — [marked](doc/08a-setup-marked.md) and
33
+ [markdown-it](doc/08b-setup-markdown-it.md) both work.
34
+
31
35
  ## How It Works
32
36
 
33
37
  <p align="center">
@@ -144,6 +148,7 @@ See [Setup](doc/01-setup.md) and [First Route](doc/02-first-route.md).
144
148
  - [SPA modes](doc/10-spa-mode.md) — none, leaf, root, only
145
149
  - [Error handling](doc/11-error-handling.md) — widget errors, boundaries, status pages
146
150
  - [Shadow DOM](doc/12-shadow-dom.md) — unified architecture, SSR hydration
151
+ - [Hono integration](doc/13-hono.md) — using emroute with Hono
147
152
 
148
153
  ### For contributors and architects
149
154
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@emkodev/emroute",
3
- "version": "1.6.0-beta.1",
3
+ "version": "1.6.0",
4
4
  "description": "File-based router with triple rendering (SPA, SSR HTML, SSR Markdown). Zero dependencies.",
5
5
  "license": "BSD-3-Clause",
6
6
  "author": "emko.dev",
@@ -53,6 +53,8 @@ export const EMROUTE_EXTERNALS = [
53
53
  export interface RuntimeConfig {
54
54
  routesDir?: string;
55
55
  widgetsDir?: string;
56
+ /** SPA mode. When 'none', bundling is skipped entirely. */
57
+ spa?: 'none' | 'leaf' | 'root' | 'only';
56
58
  /** Consumer's SPA entry point (e.g. '/main.ts'). Skips app bundle when absent. */
57
59
  entryPoint?: string;
58
60
  bundlePaths?: {
@@ -145,6 +145,7 @@ export class BunFsRuntime extends Runtime {
145
145
  // ── Bundling ─────────────────────────────────────────────────────────
146
146
 
147
147
  override async bundle(): Promise<void> {
148
+ if (this.config.spa === 'none') return;
148
149
  const paths = this.config.bundlePaths;
149
150
  if (!paths) return;
150
151
 
@@ -101,6 +101,7 @@ export class BunSqliteRuntime extends Runtime {
101
101
  // ── Bundling ─────────────────────────────────────────────────────────
102
102
 
103
103
  override async bundle(): Promise<void> {
104
+ if (this.config.spa === 'none') return;
104
105
  const paths = this.config.bundlePaths;
105
106
  if (!paths) return;
106
107
 
@@ -215,6 +215,9 @@ export async function createEmrouteServer(
215
215
  spa = 'root',
216
216
  } = config;
217
217
 
218
+ // Let the runtime know the SPA mode so bundle() can skip when 'none'.
219
+ runtime.config.spa = spa;
220
+
218
221
  const { html: htmlBase, md: mdBase } = config.basePath ?? DEFAULT_BASE_PATH;
219
222
 
220
223
  // ── Routes manifest (read from runtime) ─────────────────────────────
@@ -364,16 +367,10 @@ export async function createEmrouteServer(
364
367
  if (lastSegment.includes('.')) {
365
368
  const fileResponse = await runtime.handle(pathname);
366
369
  if (fileResponse.status === 200) return fileResponse;
370
+ return null;
367
371
  }
368
372
 
369
- // Bare paths — in root/only mode, serve SPA shell directly (router handles
370
- // client-side nav). In none/leaf mode, redirect to /html/* for SSR.
371
- if (spa === 'root' || spa === 'only') {
372
- return new Response(shell, {
373
- status: 200,
374
- headers: { 'Content-Type': 'text/html; charset=utf-8' },
375
- });
376
- }
373
+ // Bare paths — redirect to /html/* in all modes.
377
374
  const bare = pathname === '/' ? '' : pathname.slice(1).replace(/\/$/, '');
378
375
  return Response.redirect(new URL(`${htmlBase}/${bare}`, url.origin), 302);
379
376
  }