hmr-serve 0.1.0 → 0.1.4

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.
Files changed (63) hide show
  1. package/README.md +52 -19
  2. package/bin/hmr-serve.js +6 -1
  3. package/dist/cli/banner.d.ts +2 -0
  4. package/dist/cli/banner.js +60 -0
  5. package/dist/cli/banner.js.map +1 -0
  6. package/dist/cli/index.d.ts +1 -0
  7. package/dist/cli/index.js +10 -2
  8. package/dist/cli/index.js.map +1 -1
  9. package/dist/server/createServer.d.ts +5 -0
  10. package/dist/server/createServer.js +10 -1
  11. package/dist/server/createServer.js.map +1 -1
  12. package/dist/server/fs.d.ts +9 -4
  13. package/dist/server/fs.js +41 -7
  14. package/dist/server/fs.js.map +1 -1
  15. package/dist/server/index/watcher.d.ts +3 -0
  16. package/dist/server/index/watcher.js +10 -1
  17. package/dist/server/index/watcher.js.map +1 -1
  18. package/dist/server/mount.d.ts +11 -0
  19. package/dist/server/mount.js +19 -0
  20. package/dist/server/mount.js.map +1 -0
  21. package/dist/server/noNav.d.ts +22 -0
  22. package/dist/server/noNav.js +202 -0
  23. package/dist/server/noNav.js.map +1 -0
  24. package/dist/server/plugin.d.ts +6 -0
  25. package/dist/server/plugin.js +211 -20
  26. package/dist/server/plugin.js.map +1 -1
  27. package/dist/server/renderers/csv.d.ts +4 -0
  28. package/dist/server/renderers/csv.js +85 -0
  29. package/dist/server/renderers/csv.js.map +1 -0
  30. package/dist/server/renderers/html.js +1 -0
  31. package/dist/server/renderers/html.js.map +1 -1
  32. package/dist/server/renderers/markdown.js +61 -3
  33. package/dist/server/renderers/markdown.js.map +1 -1
  34. package/dist/server/renderers/media.d.ts +3 -0
  35. package/dist/server/renderers/media.js +19 -0
  36. package/dist/server/renderers/media.js.map +1 -0
  37. package/dist/server/renderers/registry.d.ts +8 -0
  38. package/dist/server/renderers/registry.js +39 -2
  39. package/dist/server/renderers/registry.js.map +1 -1
  40. package/dist/server/renderers/source.d.ts +5 -3
  41. package/dist/server/renderers/source.js +45 -15
  42. package/dist/server/renderers/source.js.map +1 -1
  43. package/dist/server/renderers/types.d.ts +3 -1
  44. package/dist/shared/types.d.ts +20 -8
  45. package/dist/shared/types.js +17 -3
  46. package/dist/shared/types.js.map +1 -1
  47. package/package.json +19 -8
  48. package/src/client/App.vue +284 -31
  49. package/src/client/api.ts +18 -1
  50. package/src/client/components/ContentPane.vue +337 -26
  51. package/src/client/components/FileIcon.vue +81 -0
  52. package/src/client/components/FileTree.vue +85 -0
  53. package/src/client/components/SettingsMenu.vue +168 -0
  54. package/src/client/components/TreeNode.vue +38 -9
  55. package/src/client/env.d.ts +6 -0
  56. package/src/client/favicon.svg +15 -0
  57. package/src/client/index.html +1 -0
  58. package/src/client/main.ts +8 -0
  59. package/src/client/router.ts +60 -0
  60. package/src/client/settings.ts +179 -0
  61. package/src/client/styles.css +570 -32
  62. package/src/client/theme.ts +51 -0
  63. package/src/shared/types.ts +38 -9
package/README.md CHANGED
@@ -1,39 +1,64 @@
1
1
  # hmr-serve
2
2
 
3
- <!-- Add once CI is green:
4
- [![CI](https://github.com/<owner>/hmr-serve/actions/workflows/ci.yml/badge.svg)](https://github.com/<owner>/hmr-serve/actions/workflows/ci.yml)
5
- -->
3
+ [![CI](https://github.com/floodtide/hmr-serve/actions/workflows/ci.yml/badge.svg)](https://github.com/floodtide/hmr-serve/actions/workflows/ci.yml)
4
+
5
+ <p align="center">
6
+ <img src="docs/screenshot.png" width="900" alt="hmr-serve in the browser: a VSCode-style file tree on the left and a live, rendered Markdown pane on the right" />
7
+ </p>
8
+
9
+ HMR-serve is inspired by `npm run dev` and by [`serve`](https://www.npmjs.com/package/serve). It turns any folder into a hot-loading web app, because sometimes it's nice to preview HTML, Markdown, images and other files in the browser.
6
10
 
7
11
  Point `hmr-serve` at any folder and review it live in the browser: a VSCode-style
8
- file tree on the left, a content pane on the right, and **instant updates as files
9
- change on disk** — powered by Vite's real dev server and HMR client, not a
10
- hand-rolled watcher/websocket.
12
+ file tree on the left, a content pane on the right and **instant updates as files
13
+ change on disk**, powered by Vite's real dev server and
14
+ [HMR](https://vitejs.dev/guide/features.html#hot-module-replacement) client. 🔥
15
+
16
+ **HMR** (Hot Module Replacement) is the mechanism that pushes file changes into the
17
+ browser over a WebSocket so the page updates without a full refresh. This project
18
+ uses [Vite's HMR](https://vitejs.dev/guide/features.html#hot-module-replacement)
19
+ rather than inventing its own.
11
20
 
12
- Built for reviewing AI-agent output (markdown/HTML docs) as it iterates.
21
+ > **Tip:** Helpful for reviewing AI agent output (markdown/HTML docs) as it iterates.
22
+
23
+ ## Quickstart
13
24
 
14
25
  ```bash
15
26
  npx hmr-serve ./some-folder
16
27
  # → opens http://localhost:5183 with a live tree + content pane
17
28
  ```
18
29
 
19
- ## Quickstart
30
+ Or run it like **[serve](https://www.npmjs.com/package/serve)** without the nav, which serves a directory listing or `index.html` if present, plus rendered Markdown, CSV/TSV, all with HMR:
20
31
 
21
32
  ```bash
22
- # from a clone
23
- pnpm install
24
- pnpm dev ./fixtures # serve the sample folder
33
+ npx hmr-serve ./some-folder --no-nav
34
+ ```
35
+
36
+ For a permanent setup, install globally and use the short `hmr` command:
37
+
38
+ ```bash
39
+ npm install -g hmr-serve
40
+ hmr ./some-folder
41
+ hmr ./some-folder --no-nav
25
42
  ```
26
43
 
27
44
  CLI:
28
45
 
29
46
  ```
30
- hmr-serve [dir] Folder to serve (default: current directory)
47
+ hmr [dir] Folder to serve (default: current directory)
31
48
  --port <port> Port to listen on (default: 5183)
32
49
  --open Open the browser on start
50
+ --no-nav Like serve, without the tree UI
33
51
  ```
34
52
 
35
- Supported file types at launch: `.md` (rendered), `.html` (sandboxed iframe),
36
- `.css` / `.txt` (read-only syntax-highlighted source).
53
+ **Default (nav) mode** shows a VS Code-style file tree and content pane. Supported
54
+ types: **Markdown** (rendered), **HTML** (sandboxed iframe), **code** (`.css`,
55
+ `.js`, `.ts`, `.json`, … syntax-highlighted), **text**, **CSV/TSV** (tables),
56
+ **images** and **video**. A gear menu toggles which categories show in the tree,
57
+ plus an **Other files** option. Choices are remembered per folder (localStorage).
58
+
59
+ **`--no-nav`** skips the tree UI: if the folder has `index.html` (or `index.htm`),
60
+ that is the root page; otherwise you get a directory listing. Markdown, CSV and
61
+ TSV are still rendered to HTML, and edits hot-reload via Vite.
37
62
 
38
63
  ## Architecture
39
64
 
@@ -46,16 +71,24 @@ Supported file types at launch: `.md` (rendered), `.html` (sandboxed iframe),
46
71
  server over HTTP and Vite's HMR socket. No File System Access API, no
47
72
  Chromium-only APIs — works in Safari and Firefox.
48
73
  4. **Extensible renderer registry.** `.md` → `markdown-it`; `.html` → sandboxed
49
- iframe; `.css`/`.txt` → server-side `highlight.js`. New types register in
50
- `src/server/renderers/` without touching routing.
51
- 5. **Vue 3, Options API only.** Deliberately no Composition API / `<script setup>`,
52
- and no component library — the client stays minimal.
53
- 6. **Lightweight CLI** via [`cac`](https://github.com/cacjs/cac): `<path>`, `--port`, `--open`.
74
+ iframe; `.css`/`.txt` → server-side `highlight.js`; `.csv`/`.tsv` → HTML tables
75
+ styled with GitHub markdown CSS. New types register in `src/server/renderers/`
76
+ without touching routing.
77
+ 5. **Lightweight CLI** via [`cac`](https://github.com/cacjs/cac): `<path>`, `--port`, `--open`, `--no-nav`.
54
78
 
55
79
  Live content updates ride Vite's HMR channel: the server pushes a custom
56
80
  `hmr-serve:update` event and the content pane re-fetches — so Vite's client
57
81
  handles transport and reconnection for us.
58
82
 
83
+ **Links & URLs.** Raw HTML is served at mirror paths (`/__hmrserve/raw/<file>`),
84
+ so **relative** links and assets inside a framed doc (`href="contact.html"`,
85
+ `<img src="logo.png">`) resolve against the real folder layout. The selected file
86
+ is reflected in a clean, bookmarkable URL under the served folder's name — e.g.
87
+ serving `./aurora-notes` gives `/aurora-notes/docs/intro.md`. These are real
88
+ History-API paths (no `#`): shareable, reload-safe and back/forward works.
89
+ Unknown paths 404 rather than rendering the app, so a stray absolute link can't
90
+ nest the shell inside the content pane.
91
+
59
92
  ```
60
93
  src/
61
94
  cli/ arg parsing + entry
package/bin/hmr-serve.js CHANGED
@@ -2,7 +2,12 @@
2
2
  // Published entry point. Invokes the compiled CLI directly rather than relying
3
3
  // on import-time self-execution detection, which is unreliable when launched
4
4
  // through npm's .bin symlink (argv[1] is the symlink, not this file).
5
- import { run } from '../dist/cli/index.js';
5
+ //
6
+ // Stamp startup time before importing the CLI (and Vite) so "ready in N ms"
7
+ // includes module load — same approach as Vite's own bin.
8
+ globalThis.__hmr_serve_start = performance.now();
9
+
10
+ const { run } = await import('../dist/cli/index.js');
6
11
 
7
12
  run(process.argv.slice(2)).catch((error) => {
8
13
  console.error(`\n ${error instanceof Error ? error.message : String(error)}\n`);
@@ -0,0 +1,2 @@
1
+ /** Boot banner modeled on Vite's startup output. */
2
+ export declare function printLaunchBanner(targetDir: string, url: string, readyMs: number): void;
@@ -0,0 +1,60 @@
1
+ import { createRequire } from 'node:module';
2
+ const { version } = createRequire(import.meta.url)('../../package.json');
3
+ const REPO = 'floodtide/hmr-serve';
4
+ /** Tiny ANSI helpers — no dependency. Respects NO_COLOR / FORCE_COLOR / TTY. */
5
+ function useColor() {
6
+ if (process.env.NO_COLOR != null && process.env.NO_COLOR !== '')
7
+ return false;
8
+ if (process.env.FORCE_COLOR != null && process.env.FORCE_COLOR !== '0')
9
+ return true;
10
+ return Boolean(process.stdout.isTTY);
11
+ }
12
+ const ansi = {
13
+ reset: '\x1b[0m',
14
+ bold: '\x1b[1m',
15
+ dim: '\x1b[2m',
16
+ green: '\x1b[32m',
17
+ cyan: '\x1b[36m',
18
+ };
19
+ function paint(code, text, enabled) {
20
+ return enabled ? `${code}${text}${ansi.reset}` : text;
21
+ }
22
+ /** Strip ANSI escapes so padding uses visible width. */
23
+ function visibleLength(text) {
24
+ // eslint-disable-next-line no-control-regex -- ESC (\x1b) is the ANSI escape we strip
25
+ return text.replace(/\x1b\[[0-9;]*m/g, '').length;
26
+ }
27
+ /** Vite-style URL: cyan, with the port bolded. */
28
+ function colorUrl(url, enabled) {
29
+ if (!enabled)
30
+ return url;
31
+ return (ansi.cyan + url.replace(/:(\d+)\//, `:${ansi.bold}$1${ansi.reset}${ansi.cyan}/`) + ansi.reset);
32
+ }
33
+ /** Boot banner modeled on Vite's startup output. */
34
+ export function printLaunchBanner(targetDir, url, readyMs) {
35
+ const color = useColor();
36
+ const brand = color
37
+ ? `${ansi.green}${ansi.bold}HMR-SERVE${ansi.reset}${ansi.green} v${version}${ansi.reset}`
38
+ : `HMR-SERVE v${version}`;
39
+ const repo = paint(ansi.dim, REPO, color);
40
+ const ready = color
41
+ ? `${ansi.dim}ready in ${ansi.reset}${ansi.bold}${Math.ceil(readyMs)}${ansi.reset}${ansi.dim} ms${ansi.reset}`
42
+ : `ready in ${Math.ceil(readyMs)} ms`;
43
+ const arrow = paint(ansi.green, '➜', color);
44
+ const localLabel = paint(ansi.bold, 'Local', color);
45
+ const servingLabel = paint(ansi.bold, 'Serving', color);
46
+ // Sit the repo to the right of the brand without hugging the terminal edge.
47
+ // Cap the line so it stays readable in wide windows (Vite-style).
48
+ const cols = Math.min(process.stdout.columns ?? 80, 72);
49
+ const left = ` ${brand}`;
50
+ const gap = Math.max(2, cols - visibleLength(left) - visibleLength(repo));
51
+ const titleLine = `${left}${' '.repeat(gap)}${repo}`;
52
+ console.log(`
53
+ ${titleLine}
54
+ ${ready}
55
+
56
+ ${arrow} ${localLabel}: ${colorUrl(url, color)}
57
+ ${arrow} ${servingLabel}: ${paint(ansi.dim, targetDir, color)}
58
+ `);
59
+ }
60
+ //# sourceMappingURL=banner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"banner.js","sourceRoot":"","sources":["../../src/cli/banner.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,7 @@ export interface ParsedArgs {
2
2
  targetDir: string;
3
3
  port?: number;
4
4
  open: boolean;
5
+ noNav: boolean;
5
6
  }
6
7
  /** Pure arg parsing, split out so it can be unit-tested without a live server.
7
8
  * Throws `Error` with a user-facing message on invalid input. */
package/dist/cli/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { statSync } from 'node:fs';
2
2
  import { resolve } from 'node:path';
3
3
  import { cac } from 'cac';
4
+ import { printLaunchBanner } from './banner.js';
4
5
  import { createServer } from '../server/createServer.js';
5
6
  /** Pure arg parsing, split out so it can be unit-tested without a live server.
6
7
  * Throws `Error` with a user-facing message on invalid input. */
@@ -9,7 +10,11 @@ export function parseArgs(argv) {
9
10
  cli
10
11
  .command('[dir]', 'Serve a folder with a live file tree + content pane')
11
12
  .option('--port <port>', 'Port to listen on', { default: 5183 })
12
- .option('--open', 'Open the browser on start', { default: false });
13
+ .option('--open', 'Open the browser on start', { default: false })
14
+ // cac/mri: `--no-nav` sets `nav: false` (negation of `--nav`).
15
+ .option('--nav', 'Show the file-tree UI (use --no-nav for serve-like mode)', {
16
+ default: true,
17
+ });
13
18
  cli.help();
14
19
  const parsed = cli.parse(['node', 'hmr-serve', ...argv], { run: false });
15
20
  const dir = parsed.args[0] ?? '.';
@@ -21,6 +26,7 @@ export function parseArgs(argv) {
21
26
  targetDir: resolve(process.cwd(), dir),
22
27
  port,
23
28
  open: Boolean(parsed.options.open),
29
+ noNav: parsed.options.nav === false,
24
30
  };
25
31
  }
26
32
  /** Validate the target is an existing directory. Throws on failure. */
@@ -37,16 +43,18 @@ export function assertDirectory(targetDir) {
37
43
  }
38
44
  }
39
45
  export async function run(argv) {
46
+ const started = globalThis.__hmr_serve_start ?? performance.now();
40
47
  const args = parseArgs(argv);
41
48
  assertDirectory(args.targetDir);
42
49
  const server = await createServer({
43
50
  targetDir: args.targetDir,
44
51
  port: args.port,
45
52
  open: args.open,
53
+ noNav: args.noNav,
46
54
  });
47
55
  await server.listen();
48
56
  const info = server.resolvedUrls?.local[0] ?? `http://localhost:${args.port}/`;
49
- console.log(`\n hmr-serve → serving ${args.targetDir}\n ${info}\n`);
57
+ printLaunchBanner(args.targetDir, info, performance.now() - started);
50
58
  }
51
59
  // Self-execute only when this module is the directly-run script (e.g.
52
60
  // `tsx src/cli/index.ts` in dev/e2e, or `node dist/cli/index.js`). The published
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAQzD;kEACkE;AAClE,MAAM,UAAU,SAAS,CAAC,IAAc;IACtC,MAAM,GAAG,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC;IAC7B,GAAG;SACA,OAAO,CAAC,OAAO,EAAE,qDAAqD,CAAC;SACvE,MAAM,CAAC,eAAe,EAAE,mBAAmB,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;SAC/D,MAAM,CAAC,QAAQ,EAAE,2BAA2B,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IACrE,GAAG,CAAC,IAAI,EAAE,CAAC;IAEX,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;IACzE,MAAM,GAAG,GAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAwB,IAAI,GAAG,CAAC;IAC1D,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACzC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,KAAK,EAAE,CAAC;QACxD,MAAM,IAAI,KAAK,CAAC,mBAAmB,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAC5D,CAAC;IACD,OAAO;QACL,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,GAAG,CAAC;QACtC,IAAI;QACJ,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC;KACnC,CAAC;AACJ,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,eAAe,CAAC,SAAiB;IAC/C,IAAI,IAAI,CAAC;IACT,IAAI,CAAC;QACH,IAAI,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,0BAA0B,SAAS,EAAE,CAAC,CAAC;IACzD,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,oBAAoB,SAAS,EAAE,CAAC,CAAC;IACnD,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,GAAG,CAAC,IAAc;IACtC,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAC7B,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAEhC,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC;QAChC,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,IAAI,EAAE,IAAI,CAAC,IAAI;KAChB,CAAC,CAAC;IACH,MAAM,MAAM,CAAC,MAAM,EAAE,CAAC;IAEtB,MAAM,IAAI,GAAG,MAAM,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,oBAAoB,IAAI,CAAC,IAAI,GAAG,CAAC;IAC/E,OAAO,CAAC,GAAG,CAAC,2BAA2B,IAAI,CAAC,SAAS,OAAO,IAAI,IAAI,CAAC,CAAC;AACxE,CAAC;AAED,sEAAsE;AACtE,iFAAiF;AACjF,iFAAiF;AACjF,sCAAsC;AACtC,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACpE,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,UAAU,WAAW,EAAE,EAAE,CAAC;IAChD,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;QAClD,OAAO,CAAC,KAAK,CAAC,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACjF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACvB,CAAC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AASzD;kEACkE;AAClE,MAAM,UAAU,SAAS,CAAC,IAAc;IACtC,MAAM,GAAG,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC;IAC7B,GAAG;SACA,OAAO,CAAC,OAAO,EAAE,qDAAqD,CAAC;SACvE,MAAM,CAAC,eAAe,EAAE,mBAAmB,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;SAC/D,MAAM,CAAC,QAAQ,EAAE,2BAA2B,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QAClE,+DAA+D;SAC9D,MAAM,CAAC,OAAO,EAAE,0DAA0D,EAAE;QAC3E,OAAO,EAAE,IAAI;KACd,CAAC,CAAC;IACL,GAAG,CAAC,IAAI,EAAE,CAAC;IAEX,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;IACzE,MAAM,GAAG,GAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAwB,IAAI,GAAG,CAAC;IAC1D,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACzC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,KAAK,EAAE,CAAC;QACxD,MAAM,IAAI,KAAK,CAAC,mBAAmB,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAC5D,CAAC;IACD,OAAO;QACL,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,GAAG,CAAC;QACtC,IAAI;QACJ,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC;QAClC,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,KAAK,KAAK;KACpC,CAAC;AACJ,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,eAAe,CAAC,SAAiB;IAC/C,IAAI,IAAI,CAAC;IACT,IAAI,CAAC;QACH,IAAI,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,0BAA0B,SAAS,EAAE,CAAC,CAAC;IACzD,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,oBAAoB,SAAS,EAAE,CAAC,CAAC;IACnD,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,GAAG,CAAC,IAAc;IACtC,MAAM,OAAO,GACV,UAA6C,CAAC,iBAAiB,IAAI,WAAW,CAAC,GAAG,EAAE,CAAC;IACxF,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAC7B,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAEhC,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC;QAChC,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,KAAK,EAAE,IAAI,CAAC,KAAK;KAClB,CAAC,CAAC;IACH,MAAM,MAAM,CAAC,MAAM,EAAE,CAAC;IAEtB,MAAM,IAAI,GAAG,MAAM,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,oBAAoB,IAAI,CAAC,IAAI,GAAG,CAAC;IAC/E,iBAAiB,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,WAAW,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,CAAC;AACvE,CAAC;AAED,sEAAsE;AACtE,iFAAiF;AACjF,iFAAiF;AACjF,sCAAsC;AACtC,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACpE,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,UAAU,WAAW,EAAE,EAAE,CAAC;IAChD,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;QAClD,OAAO,CAAC,KAAK,CAAC,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACjF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACvB,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -6,10 +6,15 @@ export interface CreateServerOptions {
6
6
  /** Open the browser once listening. */
7
7
  open?: boolean;
8
8
  host?: string;
9
+ /** Skip the Vue nav shell and serve files like `serve` (with HMR + MD/CSV/TSV). */
10
+ noNav?: boolean;
9
11
  }
10
12
  /**
11
13
  * Build (but do not start) a Vite dev server whose root is our app shell, with
12
14
  * the target folder mounted via {@link hmrServePlugin}. Call `.listen()` on the
13
15
  * returned server to start it.
16
+ *
17
+ * With `noNav`, the Vue shell is unused — middleware serves the folder directly
18
+ * (index file or directory listing) while Vite still provides HMR.
14
19
  */
15
20
  export declare function createServer(options: CreateServerOptions): Promise<ViteDevServer>;
@@ -17,6 +17,9 @@ function resolveClientRoot() {
17
17
  * Build (but do not start) a Vite dev server whose root is our app shell, with
18
18
  * the target folder mounted via {@link hmrServePlugin}. Call `.listen()` on the
19
19
  * returned server to start it.
20
+ *
21
+ * With `noNav`, the Vue shell is unused — middleware serves the folder directly
22
+ * (index file or directory listing) while Vite still provides HMR.
20
23
  */
21
24
  export async function createServer(options) {
22
25
  const targetDir = resolve(process.cwd(), options.targetDir);
@@ -24,10 +27,16 @@ export async function createServer(options) {
24
27
  // The package root (…/src/client → package) holds the shell, shared types and
25
28
  // node_modules; the target folder lives anywhere. Both must be fs-allowed.
26
29
  const packageRoot = resolve(clientRoot, '../..');
30
+ const noNav = Boolean(options.noNav);
27
31
  return createViteServer({
28
32
  root: clientRoot,
29
33
  configFile: false,
30
- plugins: [vue(), hmrServePlugin({ targetDir })],
34
+ // MPA (not SPA) so Vite does NOT history-fallback unknown paths to index.html.
35
+ // The shell is a single page at '/', and framed content uses its own /raw
36
+ // URLs — an unmatched path (e.g. a stray absolute link) should 404, not render
37
+ // the whole app inside the content iframe.
38
+ appType: 'mpa',
39
+ plugins: [...(noNav ? [] : [vue()]), hmrServePlugin({ targetDir, noNav })],
31
40
  server: {
32
41
  port: options.port ?? 5183,
33
42
  host: options.host,
@@ -1 +1 @@
1
- {"version":3,"file":"createServer.js","sourceRoot":"","sources":["../../src/server/createServer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,YAAY,IAAI,gBAAgB,EAAsB,MAAM,MAAM,CAAC;AAC5E,OAAO,GAAG,MAAM,oBAAoB,CAAC;AACrC,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAW7C;mFACmF;AACnF,SAAS,iBAAiB;IACxB,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACrD,0FAA0F;IAC1F,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IAC3C,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC;IACnD,OAAO,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC;AAClD,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAA4B;IAC7D,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IAC5D,MAAM,UAAU,GAAG,iBAAiB,EAAE,CAAC;IACvC,8EAA8E;IAC9E,2EAA2E;IAC3E,MAAM,WAAW,GAAG,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IAEjD,OAAO,gBAAgB,CAAC;QACtB,IAAI,EAAE,UAAU;QAChB,UAAU,EAAE,KAAK;QACjB,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,cAAc,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC;QAC/C,MAAM,EAAE;YACN,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,IAAI;YAC1B,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,KAAK;YAC3B,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,WAAW,EAAE,SAAS,CAAC,EAAE;SACxC;QACD,2EAA2E;QAC3E,OAAO,EAAE,KAAK;KACf,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"createServer.js","sourceRoot":"","sources":["../../src/server/createServer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,YAAY,IAAI,gBAAgB,EAAsB,MAAM,MAAM,CAAC;AAC5E,OAAO,GAAG,MAAM,oBAAoB,CAAC;AACrC,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAa7C;mFACmF;AACnF,SAAS,iBAAiB;IACxB,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACrD,0FAA0F;IAC1F,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IAC3C,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC;IACnD,OAAO,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC;AAClD,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAA4B;IAC7D,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IAC5D,MAAM,UAAU,GAAG,iBAAiB,EAAE,CAAC;IACvC,8EAA8E;IAC9E,2EAA2E;IAC3E,MAAM,WAAW,GAAG,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACjD,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAErC,OAAO,gBAAgB,CAAC;QACtB,IAAI,EAAE,UAAU;QAChB,UAAU,EAAE,KAAK;QACjB,+EAA+E;QAC/E,0EAA0E;QAC1E,+EAA+E;QAC/E,2CAA2C;QAC3C,OAAO,EAAE,KAAK;QACd,OAAO,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,cAAc,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;QAC1E,MAAM,EAAE;YACN,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,IAAI;YAC1B,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,KAAK;YAC3B,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,WAAW,EAAE,SAAS,CAAC,EAAE;SACxC;QACD,2EAA2E;QAC3E,OAAO,EAAE,KAAK;KACf,CAAC,CAAC;AACL,CAAC"}
@@ -5,12 +5,17 @@ export declare function extOf(name: string): string;
5
5
  /** Absolute path → root-relative, POSIX-separated path used everywhere in the API. */
6
6
  export declare function toRelPosix(root: string, abs: string): string;
7
7
  export declare function readFileText(abs: string): Promise<string>;
8
+ /** Raw bytes — used by the /raw endpoint, which must not corrupt binary assets
9
+ * (images, fonts) by decoding them as UTF-8. */
10
+ export declare function readFileBuffer(abs: string): Promise<Buffer>;
11
+ export declare function contentTypeFor(ext: string): string;
8
12
  /**
9
- * Recursively build the file tree, keeping only directories and files whose
10
- * extension the registry supports. Directories that end up empty are pruned so
11
- * the nav doesn't show dead branches. Entries are sorted dirs-first, then by name.
13
+ * Recursively build the file tree for every non-ignored file. Supported and
14
+ * unsupported files are both included so the client can filter by category /
15
+ * "Other files". Empty directories are pruned. Entries are sorted dirs-first,
16
+ * then by name.
12
17
  */
13
- export declare function buildTree(root: string, registry: RendererRegistry): Promise<FileNode[]>;
18
+ export declare function buildTree(root: string): Promise<FileNode[]>;
14
19
  /** Collect every supported file (root-relative paths) for the initial index scan. */
15
20
  export declare function listSupportedFiles(root: string, registry: RendererRegistry): Promise<string[]>;
16
21
  /** Whether `abs` resolves to a real file (used to guard endpoint reads). */
package/dist/server/fs.js CHANGED
@@ -16,12 +16,48 @@ const IGNORED_DIRS = new Set(['.git', 'node_modules', '.vite', 'dist', '.DS_Stor
16
16
  export async function readFileText(abs) {
17
17
  return readFile(abs, 'utf8');
18
18
  }
19
+ /** Raw bytes — used by the /raw endpoint, which must not corrupt binary assets
20
+ * (images, fonts) by decoding them as UTF-8. */
21
+ export async function readFileBuffer(abs) {
22
+ return readFile(abs);
23
+ }
24
+ /** Minimal extension → MIME map for raw-served content and its relative assets
25
+ * (stylesheets, scripts, images, fonts a framed HTML doc may reference).
26
+ * Unknowns fall back to octet-stream so the browser downloads rather than guesses. */
27
+ const MIME_BY_EXT = {
28
+ html: 'text/html; charset=utf-8',
29
+ htm: 'text/html; charset=utf-8',
30
+ css: 'text/css; charset=utf-8',
31
+ js: 'text/javascript; charset=utf-8',
32
+ mjs: 'text/javascript; charset=utf-8',
33
+ json: 'application/json; charset=utf-8',
34
+ txt: 'text/plain; charset=utf-8',
35
+ md: 'text/plain; charset=utf-8',
36
+ csv: 'text/csv; charset=utf-8',
37
+ tsv: 'text/tab-separated-values; charset=utf-8',
38
+ svg: 'image/svg+xml',
39
+ png: 'image/png',
40
+ jpg: 'image/jpeg',
41
+ jpeg: 'image/jpeg',
42
+ gif: 'image/gif',
43
+ webp: 'image/webp',
44
+ avif: 'image/avif',
45
+ ico: 'image/x-icon',
46
+ woff: 'font/woff',
47
+ woff2: 'font/woff2',
48
+ ttf: 'font/ttf',
49
+ otf: 'font/otf',
50
+ };
51
+ export function contentTypeFor(ext) {
52
+ return MIME_BY_EXT[ext.toLowerCase()] ?? 'application/octet-stream';
53
+ }
19
54
  /**
20
- * Recursively build the file tree, keeping only directories and files whose
21
- * extension the registry supports. Directories that end up empty are pruned so
22
- * the nav doesn't show dead branches. Entries are sorted dirs-first, then by name.
55
+ * Recursively build the file tree for every non-ignored file. Supported and
56
+ * unsupported files are both included so the client can filter by category /
57
+ * "Other files". Empty directories are pruned. Entries are sorted dirs-first,
58
+ * then by name.
23
59
  */
24
- export async function buildTree(root, registry) {
60
+ export async function buildTree(root) {
25
61
  async function walk(dir) {
26
62
  let entries;
27
63
  try {
@@ -48,9 +84,7 @@ export async function buildTree(root, registry) {
48
84
  }
49
85
  else if (entry.isFile()) {
50
86
  const ext = extOf(entry.name);
51
- if (registry.supports(ext)) {
52
- nodes.push({ path: toRelPosix(root, abs), name: entry.name, type: 'file', ext });
53
- }
87
+ nodes.push({ path: toRelPosix(root, abs), name: entry.name, type: 'file', ext });
54
88
  }
55
89
  }
56
90
  return sortNodes(nodes);
@@ -1 +1 @@
1
- {"version":3,"file":"fs.js","sourceRoot":"","sources":["../../src/server/fs.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fs.js","sourceRoot":"","sources":["../../src/server/fs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAIhD,mEAAmE;AACnE,MAAM,UAAU,KAAK,CAAC,IAAY;IAChC,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,GAAG,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IACxB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;AAC3C,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,UAAU,CAAC,IAAY,EAAE,GAAW;IAClD,OAAO,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,CAAC;AAED,uEAAuE;AACvE,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;AAErF,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,GAAW;IAC5C,OAAO,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;AAC/B,CAAC;AAED;iDACiD;AACjD,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,GAAW;IAC9C,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC;AACvB,CAAC;AAED;;uFAEuF;AACvF,MAAM,WAAW,GAA2B;IAC1C,IAAI,EAAE,0BAA0B;IAChC,GAAG,EAAE,0BAA0B;IAC/B,GAAG,EAAE,yBAAyB;IAC9B,EAAE,EAAE,gCAAgC;IACpC,GAAG,EAAE,gCAAgC;IACrC,IAAI,EAAE,iCAAiC;IACvC,GAAG,EAAE,2BAA2B;IAChC,EAAE,EAAE,2BAA2B;IAC/B,GAAG,EAAE,yBAAyB;IAC9B,GAAG,EAAE,0CAA0C;IAC/C,GAAG,EAAE,eAAe;IACpB,GAAG,EAAE,WAAW;IAChB,GAAG,EAAE,YAAY;IACjB,IAAI,EAAE,YAAY;IAClB,GAAG,EAAE,WAAW;IAChB,IAAI,EAAE,YAAY;IAClB,IAAI,EAAE,YAAY;IAClB,GAAG,EAAE,cAAc;IACnB,IAAI,EAAE,WAAW;IACjB,KAAK,EAAE,YAAY;IACnB,GAAG,EAAE,UAAU;IACf,GAAG,EAAE,UAAU;CAChB,CAAC;AAEF,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,OAAO,WAAW,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,IAAI,0BAA0B,CAAC;AACtE,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAAY;IAC1C,KAAK,UAAU,IAAI,CAAC,GAAW;QAC7B,IAAI,OAAO,CAAC;QACZ,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QACxD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,MAAM,KAAK,GAAe,EAAE,CAAC;QAC7B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC;gBAAE,SAAS;YACzE,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YAClC,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;gBACxB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC;gBACjC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACxB,KAAK,CAAC,IAAI,CAAC;wBACT,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC;wBAC3B,IAAI,EAAE,KAAK,CAAC,IAAI;wBAChB,IAAI,EAAE,WAAW;wBACjB,QAAQ;qBACT,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;iBAAM,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;gBAC1B,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC9B,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;YACnF,CAAC;QACH,CAAC;QACD,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC;AACpB,CAAC;AAED,SAAS,SAAS,CAAC,KAAiB;IAClC,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACzB,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI;YAAE,OAAO,CAAC,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9D,OAAO,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;AACL,CAAC;AAED,qFAAqF;AACrF,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,IAAY,EACZ,QAA0B;IAE1B,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,UAAU,IAAI,CAAC,GAAW;QAC7B,IAAI,OAAO,CAAC;QACZ,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QACxD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO;QACT,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC;gBAAE,SAAS;YACzE,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YAClC,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;gBACxB,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC;YAClB,CAAC;iBAAM,IAAI,KAAK,CAAC,MAAM,EAAE,IAAI,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;gBAClE,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;YAClC,CAAC;QACH,CAAC;IACH,CAAC;IACD,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC;IACjB,OAAO,GAAG,CAAC;AACb,CAAC;AAED,4EAA4E;AAC5E,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,GAAW;IACtC,IAAI,CAAC;QACH,OAAO,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IACpC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
@@ -27,5 +27,8 @@ export interface WatchHandlers {
27
27
  * with injected `readFile`/`emit`. `add`/`change` are debounced per path (an
28
28
  * editor save often fires several writes); `unlink` is applied immediately so a
29
29
  * deleted file can't linger in the index behind a pending change.
30
+ *
31
+ * Unsupported extensions are never indexed, but `add`/`unlink` still emit so the
32
+ * client can refresh the tree when "Other files" is shown.
30
33
  */
31
34
  export declare function createWatchHandler(options: WatchHandlerOptions): WatchHandlers;
@@ -3,6 +3,9 @@
3
3
  * with injected `readFile`/`emit`. `add`/`change` are debounced per path (an
4
4
  * editor save often fires several writes); `unlink` is applied immediately so a
5
5
  * deleted file can't linger in the index behind a pending change.
6
+ *
7
+ * Unsupported extensions are never indexed, but `add`/`unlink` still emit so the
8
+ * client can refresh the tree when "Other files" is shown.
6
9
  */
7
10
  export function createWatchHandler(options) {
8
11
  const { index, extOf, isSupported, readFile, emit, debounceMs = 40 } = options;
@@ -44,6 +47,10 @@ export function createWatchHandler(options) {
44
47
  }
45
48
  return {
46
49
  onAdd(path) {
50
+ if (!isSupported(extOf(path))) {
51
+ emit({ event: 'add', path });
52
+ return;
53
+ }
47
54
  schedule(path, 'add');
48
55
  },
49
56
  onChange(path) {
@@ -55,8 +62,10 @@ export function createWatchHandler(options) {
55
62
  clearTimeout(timer);
56
63
  timers.delete(path);
57
64
  pending.delete(path);
58
- if (!isSupported(extOf(path)))
65
+ if (!isSupported(extOf(path))) {
66
+ emit({ event: 'unlink', path });
59
67
  return;
68
+ }
60
69
  index.remove(path);
61
70
  emit({ event: 'unlink', path });
62
71
  },
@@ -1 +1 @@
1
- {"version":3,"file":"watcher.js","sourceRoot":"","sources":["../../../src/server/index/watcher.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"watcher.js","sourceRoot":"","sources":["../../../src/server/index/watcher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Derive the URL mount prefix from the served folder's name, e.g.
3
+ * `/Users/me/aurora-notes` → `/aurora-notes`, `My Docs` → `/my-docs`.
4
+ *
5
+ * Content lives under this prefix so its paths can never collide with the app
6
+ * shell's own root assets (`/main.ts`, `/styles.css`, `/@vite/client`) or the
7
+ * API base (`/__hmrserve`). The slug only emits [a-z0-9-], which structurally
8
+ * rules out those names (they contain `.`, `_` or `@`). Empty names fall back
9
+ * to `/files`.
10
+ */
11
+ export declare function mountPrefixFor(targetDir: string): string;
@@ -0,0 +1,19 @@
1
+ import { basename } from 'node:path';
2
+ /**
3
+ * Derive the URL mount prefix from the served folder's name, e.g.
4
+ * `/Users/me/aurora-notes` → `/aurora-notes`, `My Docs` → `/my-docs`.
5
+ *
6
+ * Content lives under this prefix so its paths can never collide with the app
7
+ * shell's own root assets (`/main.ts`, `/styles.css`, `/@vite/client`) or the
8
+ * API base (`/__hmrserve`). The slug only emits [a-z0-9-], which structurally
9
+ * rules out those names (they contain `.`, `_` or `@`). Empty names fall back
10
+ * to `/files`.
11
+ */
12
+ export function mountPrefixFor(targetDir) {
13
+ const slug = basename(targetDir)
14
+ .toLowerCase()
15
+ .replace(/[^a-z0-9]+/g, '-')
16
+ .replace(/^-+|-+$/g, '');
17
+ return `/${slug || 'files'}`;
18
+ }
19
+ //# sourceMappingURL=mount.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mount.js","sourceRoot":"","sources":["../../src/server/mount.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAErC;;;;;;;;;GASG;AACH,MAAM,UAAU,cAAc,CAAC,SAAiB;IAC9C,MAAM,IAAI,GAAG,QAAQ,CAAC,SAAS,CAAC;SAC7B,WAAW,EAAE;SACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;SAC3B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAC3B,OAAO,IAAI,IAAI,IAAI,OAAO,EAAE,CAAC;AAC/B,CAAC"}
@@ -0,0 +1,22 @@
1
+ /** Index files checked (in order) when a directory URL is requested — same idea
2
+ * as vercel/serve: an index file wins over a directory listing. */
3
+ export declare const INDEX_NAMES: readonly ["index.html", "index.htm"];
4
+ /** Extensions rendered to an HTML preview page in `--no-nav` mode (everything
5
+ * else is served as raw bytes with the appropriate MIME type). */
6
+ export declare const PREVIEW_EXTENSIONS: Set<string>;
7
+ export interface ListingEntry {
8
+ name: string;
9
+ href: string;
10
+ type: 'directory' | 'file';
11
+ }
12
+ /** Find an index file inside `dirAbs`. Returns the absolute path, or null. */
13
+ export declare function findIndexFile(dirAbs: string): Promise<string | null>;
14
+ /** Directory listing entries (dirs first, then files), with an optional `..`. */
15
+ export declare function listDirectory(dirAbs: string, urlPath: string): Promise<ListingEntry[]>;
16
+ /** Wrap rendered markdown/csv/tsv HTML in a full document with live reload. */
17
+ export declare function wrapPreviewHtml(title: string, bodyHtml: string): string;
18
+ /** Inject the Vite client into an HTML document so edits trigger a full reload. */
19
+ export declare function injectViteClient(html: string): string;
20
+ /** Serve-style directory listing page. */
21
+ export declare function renderDirectoryListing(urlPath: string, entries: ListingEntry[]): string;
22
+ export declare function isPreviewExtension(ext: string): boolean;