@madojs/mado 0.6.0 → 0.6.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/CHANGELOG.md CHANGED
@@ -4,6 +4,118 @@
4
4
 
5
5
  Nothing yet.
6
6
 
7
+ ## 0.6.1
8
+
9
+ Starter & release-pipeline hardening pass. No public API breaks.
10
+ Identified from a lab pressure-test on `/admin/lab` plus a deep audit of the
11
+ starter / bundle / bake / dev-server contour. All fixes verified by
12
+ regression tests added in this release.
13
+
14
+ ### Fixed
15
+ - **Starters**: every `index.html` in `starters/{admin,crud,minimal}/` now
16
+ uses root-absolute paths in the importmap and entry `<script>` tag
17
+ (`/node_modules/@madojs/mado/...`, `/dist/main.js`). Relative paths
18
+ (`./node_modules/...`, `./dist/main.js`) broke hard-refresh of any nested
19
+ route (`/admin/orders/42` → browser fetched
20
+ `/admin/orders/dist/main.js` → 404 → blank page). Inline comments in each
21
+ file explain the trap so it does not get reverted.
22
+ - **Starters/admin**: `pages/admin/order-detail.ts` now uses `each(items,
23
+ key, render)` instead of `o.items.map(...)`, matching `llms.txt` rule #3
24
+ and the framework's own pitfalls documentation.
25
+ - **`scripts/bundle.mjs`**: cleans stale hashed assets before every build.
26
+ Previously each `mado bundle` / `mado release` left old `main-<hash>.js`
27
+ and `chunk-<hash>.js` in `out/assets/`; the rewriter then emitted
28
+ `<link rel="modulepreload">` for every leftover `.js` it found, so
29
+ production HTML shipped dead-code preloads without SRI. In app-mode the
30
+ whole assets directory is wiped; in repo-mode only recognisable hashed
31
+ files are removed so unrelated repo artifacts stay put.
32
+ - **`src/router/manifest.ts`**: opens a fresh component lifecycle scope
33
+ around every `page.view()` / layout `view()` call and disposes the
34
+ previous one on navigation (and on `router.dispose()`). `resource()`,
35
+ `effect()` and `persisted()` created inside `page.view()` now register
36
+ cleanup with that scope automatically — no more
37
+ `[mado:resource-outside-lifecycle]` warnings on the framework's own
38
+ canonical examples, and no more invalidator-subscription leaks across
39
+ route changes.
40
+ - **`src/resource.ts`**: guards against stale responses overwriting fresh
41
+ data on rapid key changes. The previous `AbortController` defence worked
42
+ only if the user-supplied fetcher honored `AbortSignal` — for fetchers
43
+ that ignore cancellation, a slow stale resolution for an old key could
44
+ win over a fast fresh one. Both then/catch branches now also check
45
+ `if (key !== lastKey) return`.
46
+ - **`server/serve.mjs`**: falls back to `./public/*` when a file is not
47
+ found at the project root, mirroring what `mado release` does to `out/`.
48
+ `favicon.svg`, `robots.txt`, `og-image.png` etc. no longer 404 in dev.
49
+ - **`server/serve.mjs`**: prints an actionable hint on `EPERM`/`EACCES`
50
+ pointing at `mado dev --host 127.0.0.1` (the default host changed from
51
+ the implicit `0.0.0.0` to `localhost`, which is friendlier in sandboxed
52
+ environments).
53
+ - **`scripts/preview.mjs`**: serves prerendered HTML from `<out>/baked/`
54
+ with priority over the SPA shell. Previously `mado preview` only looked
55
+ at `out/` and never saw bake's output, so prerendered routes returned
56
+ the empty SPA shell — looking like a "blank page" bug even when bake
57
+ had succeeded.
58
+
59
+ ### Added
60
+ - **`mado dev` / `mado serve` flag pass-through**: `cli.mjs` now splits
61
+ positional arguments from flags via `splitDevArgs()`, so calls like
62
+ `mado dev --host 127.0.0.1`, `mado dev showcase --port 6000` and
63
+ `mado dev -- --host 0.0.0.0` all work. Previously the CLI mistook the
64
+ flag for an example name and exited with `unknown example`.
65
+ - **`server/serve.mjs`**: tiny argv parser supporting `--host`, `--port`
66
+ and `--host=value` forms; HOST and PORT also fall back to environment
67
+ variables and `mado.config.json` (`dev.host`, `dev.port`).
68
+ - **`scripts/preview.mjs`**: same `--host` / `--port` flags as the dev
69
+ server, plus a startup banner showing `url:` / `out:` / `baked:` so it
70
+ is obvious which directories preview is serving from.
71
+ - **`scripts/bake.mjs`**: fails loudly when the manifest exists but no
72
+ page declares `bake: { paths, data }`. The previous behaviour produced
73
+ `0 pages + sitemap.xml` silently with exit code 0, making `mado
74
+ release` look successful while shipping only the SPA shell with no
75
+ SEO-friendly HTML. The new warning prints the skipped routes, a
76
+ worked example bake snippet, and exits non-zero. Override with
77
+ `MADO_BAKE_ALLOW_EMPTY=1` for intentional SPA-only deploys.
78
+ - **`scripts/bake.mjs`**: clearer "missing dev dep" errors — when
79
+ `linkedom` or `esbuild` is missing the message now tells the user
80
+ exactly which packages to `npm i -D`.
81
+ - **Starter landing pages**: `home.ts` in all three starters now declares
82
+ `bake: { paths: () => [{}], data: () => ({}) }` and a `head()` so
83
+ `mado release` actually prerenders the landing page out of the box.
84
+ - **Starter `devDependencies`**: `linkedom` and `esbuild` added to
85
+ `starters/{admin,crud,minimal}/package.json` so `mado release` works
86
+ immediately after `mado init <app>` + `npm install`, without manual
87
+ follow-up installs.
88
+ - **Regression tests** (`test/`):
89
+ - `starter-html-paths.test.mjs` — asserts every starter `index.html`
90
+ uses root-absolute paths in both the importmap and the entry script.
91
+ - `bundle-cleanup.test.mjs` — end-to-end: runs `mado bundle` twice on
92
+ a synthesized temp project (mutating source between runs) and
93
+ asserts there is exactly one `main-<hash>.js` in `out/assets/`
94
+ afterwards.
95
+ - `resource.test.mjs` (2 new cases) — stale-response races: a fetcher
96
+ that ignores `AbortSignal` with key=1 slower than key=2, plus a
97
+ rapid 3-way key thrash where the final key is the slowest fetch.
98
+ Both assert `data()` reflects the latest key, not the fastest
99
+ response.
100
+
101
+ ### Changed
102
+ - **`server/serve.mjs`** default host is now `localhost` (was implicitly
103
+ `0.0.0.0`). LAN exposure is opt-in via `mado dev --host 0.0.0.0` or
104
+ `HOST=0.0.0.0`. The startup banner shows both the bound host and a
105
+ click-friendly URL (`localhost` substituted when bound to `0.0.0.0`).
106
+
107
+ ### Notes
108
+ - No public API changes; no migrations required. Apps that previously
109
+ worked on a fresh-out-of-the-box `mado init` did so only because
110
+ someone manually fixed the starter's relative paths and dev deps —
111
+ this release closes those gaps so the documented "happy path" actually
112
+ is happy.
113
+ - If you intentionally deploy SPA-only (no prerendered HTML), drop
114
+ `mado bake` from your release pipeline or set
115
+ `MADO_BAKE_ALLOW_EMPTY=1`; otherwise bake will now fail your
116
+ CI with a clear pointer to the missing config.
117
+ - Test count: 137 pass, 0 fail, 3 skipped (Playwright e2e — unchanged).
118
+
7
119
  ## 0.6.0
8
120
 
9
121
  Product-surface release: app-mode defaults, blessed admin starter, release
@@ -85,14 +85,25 @@ export function resource(keyFn, fetcher, options = {}) {
85
85
  error.set(null);
86
86
  force = false;
87
87
  fetcher(key, ac.signal).then((result) => {
88
+ // Two-layer staleness check:
89
+ // 1. ac.signal.aborted — fetcher honored the AbortSignal
90
+ // (jsonFetcher does; user fetchers may not).
91
+ // 2. key !== lastKey — defensive guard for fetchers that ignore
92
+ // the AbortSignal and resolve after a newer run() has started.
93
+ // Without this, a slow stale response can overwrite the data
94
+ // from a faster newer one when the key changes rapidly.
88
95
  if (ac.signal.aborted)
89
96
  return;
97
+ if (key !== lastKey)
98
+ return;
90
99
  cache.set(key, { data: result, timestamp: Date.now() });
91
100
  data.set(result);
92
101
  loading.set(false);
93
102
  }, (err) => {
94
103
  if (ac.signal.aborted)
95
104
  return;
105
+ if (key !== lastKey)
106
+ return;
96
107
  error.set(err instanceof Error ? err : new Error(String(err)));
97
108
  loading.set(false);
98
109
  });
@@ -1 +1 @@
1
- {"version":3,"file":"resource.js","sourceRoot":"","sources":["../../src/resource.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"resource.js","sourceRoot":"","sources":["../../src/resource.ts"],"names":[],"mappings":"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"}
@@ -15,6 +15,7 @@
15
15
  import { signal } from "../signal.js";
16
16
  import { html } from "../html/template.js";
17
17
  import { applyHead } from "../head.js";
18
+ import { createLifecycle, runInLifecycle, } from "../lifecycle.js";
18
19
  import { flatten, patternToRegex, } from "./match.js";
19
20
  import { navigate, router } from "./navigation.js";
20
21
  /**
@@ -32,6 +33,7 @@ export function routes(manifest, options = {}) {
32
33
  pathToFlat: new Map(),
33
34
  compiledForPrefetch: [],
34
35
  renderSeq: 0,
36
+ activeLifecycle: null,
35
37
  };
36
38
  activeRoutes.add(ctx);
37
39
  const flat = flatten(manifest);
@@ -53,10 +55,33 @@ export function routes(manifest, options = {}) {
53
55
  const origDispose = api.dispose;
54
56
  api.dispose = () => {
55
57
  activeRoutes.delete(ctx);
58
+ // Tear down the last page's lifecycle so its resource()/effect()
59
+ // subscriptions are released when the whole router is disposed
60
+ // (test isolation, hot reload, etc.).
61
+ ctx.activeLifecycle?.dispose();
62
+ ctx.activeLifecycle = null;
56
63
  origDispose();
57
64
  };
58
65
  return api;
59
66
  }
67
+ /**
68
+ * Open a fresh page lifecycle for the current render, disposing the
69
+ * previous page's lifecycle. Called right before any page.view() or
70
+ * layout.view() runs so that resource()/effect() created inside view
71
+ * find a `getCurrentLifecycle()` and register their cleanup with it.
72
+ *
73
+ * This is the single canonical place where page-level lifecycle is
74
+ * opened — `page.view()` is the documented place to create resources
75
+ * (see pitfalls + starter examples). Without this wrapper, calling
76
+ * `resource()` in view emits a [mado:resource-outside-lifecycle]
77
+ * warning even when used correctly.
78
+ */
79
+ function openPageLifecycle(ctx) {
80
+ ctx.activeLifecycle?.dispose();
81
+ const lc = createLifecycle();
82
+ ctx.activeLifecycle = lc;
83
+ return lc;
84
+ }
60
85
  // ---------- prefetch ----------
61
86
  /**
62
87
  * Prefetch-load modules for a path (hover, programmatic).
@@ -175,7 +200,8 @@ function renderEntry(ctx, entry, params, options, seq) {
175
200
  return html ``;
176
201
  }
177
202
  }
178
- return renderWithLayouts(sync.page, sync.layouts, params);
203
+ const lc = openPageLifecycle(ctx);
204
+ return runInLifecycle(lc, () => renderWithLayouts(sync.page, sync.layouts, params));
179
205
  }
180
206
  catch (err) {
181
207
  const e = err instanceof Error ? err : new Error(String(err));
@@ -257,7 +283,8 @@ function renderEntry(ctx, entry, params, options, seq) {
257
283
  return renderError(s.err, params, options);
258
284
  }
259
285
  try {
260
- return renderWithLayouts(s.page, s.layouts, params);
286
+ const lc = openPageLifecycle(ctx);
287
+ return runInLifecycle(lc, () => renderWithLayouts(s.page, s.layouts, params));
261
288
  }
262
289
  catch (err) {
263
290
  const e = err instanceof Error ? err : new Error(String(err));
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../../src/router/manifest.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../../src/router/manifest.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@madojs/mado",
3
- "version": "0.6.0",
3
+ "version": "0.6.1",
4
4
  "description": "Mado — a small native-web SPA framework with Web Components, signals, tagged-template html, router, resources, and forms. TypeScript-only build, zero runtime dependencies.",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/scripts/bake.mjs CHANGED
@@ -85,14 +85,26 @@ let parseHTML;
85
85
  try {
86
86
  ({ parseHTML } = await import("linkedom"));
87
87
  } catch {
88
- fatal("[bake] package 'linkedom' is required: npm i -D linkedom");
88
+ fatal(
89
+ "[bake] package 'linkedom' is required.",
90
+ "[bake] Install it as a dev dependency in this project:",
91
+ "[bake] npm i -D linkedom esbuild",
92
+ "[bake] (esbuild is also required, see next check).",
93
+ "[bake] These are not bundled into @madojs/mado on purpose: bake is an",
94
+ "[bake] optional build step and we don't want to add transitive deps to",
95
+ "[bake] every Mado install.",
96
+ );
89
97
  }
90
98
 
91
99
  let esbuild;
92
100
  try {
93
101
  esbuild = await import("esbuild");
94
102
  } catch {
95
- fatal("[bake] package 'esbuild' is required: npm i -D esbuild");
103
+ fatal(
104
+ "[bake] package 'esbuild' is required.",
105
+ "[bake] Install it as a dev dependency in this project:",
106
+ "[bake] npm i -D esbuild linkedom",
107
+ );
96
108
  }
97
109
 
98
110
  // ---------- DOM polyfills for Node ----------
@@ -183,13 +195,19 @@ const TEMPLATE_HTML = baseHtml;
183
195
  const sitemapEntries = [];
184
196
  let total = 0;
185
197
  let bakedErrors = 0;
198
+ let bakeablePages = 0;
199
+ const skippedNoBake = [];
186
200
 
187
201
  for (const [pattern, entry] of Object.entries(manifest)) {
188
202
  if (pattern === "*") continue;
189
203
 
190
204
  const pg = await resolvePage(entry);
191
205
  if (!pg) continue;
192
- if (!pg.bake) continue;
206
+ if (!pg.bake) {
207
+ skippedNoBake.push(pattern);
208
+ continue;
209
+ }
210
+ bakeablePages++;
193
211
 
194
212
  console.log(`[bake] ${pattern}`);
195
213
 
@@ -268,6 +286,36 @@ console.log(`[bake] done: ${total} pages + sitemap.xml → ${OUT_DIR}`);
268
286
  if (bakedErrors > 0) {
269
287
  fatal(`[bake] ${bakedErrors} route(s) failed; see errors above.`);
270
288
  }
289
+ // Loud diagnostic when the manifest exists but no page declares `bake`.
290
+ // Previously bake silently produced 0 pages + an empty sitemap and exited
291
+ // 0, which made `mado release` look successful while shipping no static
292
+ // HTML for crawlers. Fail loudly so the user notices.
293
+ if (bakeablePages === 0) {
294
+ error("");
295
+ error(
296
+ `[bake] WARNING: no page in ${ENTRY} declares \`bake: { paths, data }\`.`,
297
+ );
298
+ error(
299
+ `[bake] ${skippedNoBake.length} route(s) skipped: ${skippedNoBake
300
+ .slice(0, 6)
301
+ .join(", ")}${skippedNoBake.length > 6 ? ", …" : ""}`,
302
+ );
303
+ error("[bake] Add `bake` to at least one page (e.g. your landing route):");
304
+ error("[bake] export default page({");
305
+ error("[bake] view: …,");
306
+ error("[bake] bake: { paths: () => [{}], data: () => ({}) },");
307
+ error("[bake] });");
308
+ error(
309
+ "[bake] Without bake the build ships only the SPA shell — search engines",
310
+ );
311
+ error("[bake] and link previews see an empty <body>.");
312
+ // Exit non-zero so `mado release` halts and the user is forced to address
313
+ // it. If you intentionally have an SPA-only deploy, drop `mado bake` from
314
+ // the release pipeline (or set MADO_BAKE_ALLOW_EMPTY=1).
315
+ if (process.env.MADO_BAKE_ALLOW_EMPTY !== "1") {
316
+ process.exit(1);
317
+ }
318
+ }
271
319
 
272
320
  // ---------- Helpers ----------
273
321
 
@@ -25,7 +25,7 @@
25
25
  // its biggest example.
26
26
 
27
27
  import { build } from "esbuild";
28
- import { readFile, writeFile, mkdir, cp, stat, readdir } from "node:fs/promises";
28
+ import { readFile, writeFile, mkdir, cp, stat, readdir, rm } from "node:fs/promises";
29
29
  import { createHash } from "node:crypto";
30
30
  import { gzipSync, brotliCompressSync, constants as zlibConst } from "node:zlib";
31
31
  import { join, basename, resolve, dirname } from "node:path";
@@ -74,6 +74,29 @@ if (!existsSync(HTML)) {
74
74
  process.exit(1);
75
75
  }
76
76
 
77
+ // Clean stale assets from previous bundles.
78
+ //
79
+ // Without this step, hashed chunks from prior runs (main-<oldhash>.js,
80
+ // chunk-<oldhash>.js) accumulate in ASSETS_DIR. We later list ASSETS_DIR
81
+ // (via readdir below) and emit <link rel="modulepreload"> for every
82
+ // .js file we find — so stale chunks would be preloaded as if they were
83
+ // still part of the app, polluting the production HTML and shipping dead
84
+ // code over the wire. SRI is also only computed for the fresh entry, so
85
+ // stale preloads would lack integrity checks.
86
+ //
87
+ // In app-mode the entire <out>/assets/ folder is owned by the bundler,
88
+ // so wiping it is safe. In repo-mode the historical layout drops assets
89
+ // directly into <out>/ alongside non-bundle artifacts, so we only remove
90
+ // the recognisable hashed files there.
91
+ if (ASSETS_REL) {
92
+ await rm(ASSETS_DIR, { recursive: true, force: true });
93
+ } else if (existsSync(ASSETS_DIR)) {
94
+ for (const f of await readdir(ASSETS_DIR)) {
95
+ if (/^(main|chunk|asset)-[A-Z0-9]+\.(js|css)(\.map|\.gz|\.br)?$/i.test(f)) {
96
+ await rm(join(ASSETS_DIR, f), { force: true });
97
+ }
98
+ }
99
+ }
77
100
  await mkdir(ASSETS_DIR, { recursive: true });
78
101
 
79
102
  console.log(`[bundle] entry: ${ENTRY}`);
package/scripts/cli.mjs CHANGED
@@ -53,10 +53,10 @@ switch (command) {
53
53
  }
54
54
  break;
55
55
  case "serve":
56
- await runServe(args[0] ?? "");
56
+ await runServe(args);
57
57
  break;
58
58
  case "dev":
59
- await runDev(args[0] ?? "");
59
+ await runDev(args);
60
60
  break;
61
61
  case "bake":
62
62
  await runNodeScript("scripts/bake.mjs", args);
@@ -87,15 +87,25 @@ switch (command) {
87
87
  process.exit(1);
88
88
  }
89
89
 
90
- async function runServe(example) {
90
+ async function runServe(rawArgs) {
91
+ // Split args into [example?, ...flags]. The first non-flag positional is the
92
+ // example name; everything else (including `--host`, `--port`, etc.) is
93
+ // forwarded verbatim to server/serve.mjs.
94
+ const { example, forwarded } = splitDevArgs(rawArgs);
91
95
  if (!example && PROJECT_ROOT !== PACKAGE_ROOT) {
92
96
  await serveStaticProject(PROJECT_ROOT);
93
97
  return;
94
98
  }
95
99
  if (example) assertExample(example, { serveable: true });
96
- await run(process.execPath, [join(PACKAGE_ROOT, "server/serve.mjs"), example].filter(Boolean), {
97
- env: { ...process.env, EXAMPLE: example || process.env.EXAMPLE || "" },
98
- });
100
+ await run(
101
+ process.execPath,
102
+ [join(PACKAGE_ROOT, "server/serve.mjs"), example, ...forwarded].filter(
103
+ Boolean,
104
+ ),
105
+ {
106
+ env: { ...process.env, EXAMPLE: example || process.env.EXAMPLE || "" },
107
+ },
108
+ );
99
109
  }
100
110
 
101
111
  async function runInit(rawArgs) {
@@ -168,15 +178,25 @@ async function runInit(rawArgs) {
168
178
  console.log("");
169
179
  }
170
180
 
171
- async function runDev(example) {
181
+ async function runDev(rawArgs) {
182
+ // Forward unknown flags (e.g. --host, --port) to server/serve.mjs so callers
183
+ // can write `mado dev --host 127.0.0.1` without the CLI mistaking `--host`
184
+ // for an example name.
185
+ const { example, forwarded } = splitDevArgs(rawArgs);
172
186
  if (example) assertExample(example, { serveable: true });
173
187
 
174
188
  const env = { ...process.env, EXAMPLE: example || process.env.EXAMPLE || "" };
175
- const server = spawn(process.execPath, [join(PACKAGE_ROOT, "server/serve.mjs"), example].filter(Boolean), {
176
- cwd: PROJECT_ROOT,
177
- env,
178
- stdio: "inherit",
179
- });
189
+ const server = spawn(
190
+ process.execPath,
191
+ [join(PACKAGE_ROOT, "server/serve.mjs"), example, ...forwarded].filter(
192
+ Boolean,
193
+ ),
194
+ {
195
+ cwd: PROJECT_ROOT,
196
+ env,
197
+ stdio: "inherit",
198
+ },
199
+ );
180
200
  const tsc = spawn(process.execPath, [resolveBin("typescript/bin/tsc"), "-w"], {
181
201
  cwd: PROJECT_ROOT,
182
202
  stdio: "inherit",
@@ -411,6 +431,50 @@ function parseFlags(raw) {
411
431
  return { flags, positional };
412
432
  }
413
433
 
434
+ /**
435
+ * Split args for `mado dev` / `mado serve` into:
436
+ * - example: the first non-flag positional (or undefined)
437
+ * - forwarded: every remaining token (flags, their values, leftover
438
+ * positionals), preserved in order so server/serve.mjs sees them
439
+ * unchanged.
440
+ *
441
+ * This is what lets `mado dev -- --host 127.0.0.1` and
442
+ * `mado dev showcase --port 6000` both work without the CLI confusing
443
+ * `--host` for an example name.
444
+ */
445
+ function splitDevArgs(raw) {
446
+ if (!Array.isArray(raw) || raw.length === 0) {
447
+ return { example: "", forwarded: [] };
448
+ }
449
+ let example = "";
450
+ const forwarded = [];
451
+ let pickedExample = false;
452
+ for (let i = 0; i < raw.length; i++) {
453
+ const a = raw[i];
454
+ if (a === "--") {
455
+ forwarded.push(...raw.slice(i + 1));
456
+ break;
457
+ }
458
+ if (a.startsWith("-")) {
459
+ forwarded.push(a);
460
+ // Lookahead: if the next token is the flag's VALUE (does not start with
461
+ // "-"), forward it too — but only when the flag is in inline form
462
+ // (--flag value), not --flag=value.
463
+ if (!a.includes("=") && raw[i + 1] !== undefined && !raw[i + 1].startsWith("-")) {
464
+ forwarded.push(raw[++i]);
465
+ }
466
+ continue;
467
+ }
468
+ if (!pickedExample) {
469
+ example = a;
470
+ pickedExample = true;
471
+ } else {
472
+ forwarded.push(a);
473
+ }
474
+ }
475
+ return { example, forwarded };
476
+ }
477
+
414
478
  function packageNameFromDir(target) {
415
479
  return target
416
480
  .split(/[\\/]/)
@@ -24,13 +24,49 @@ import { spawnSync } from "node:child_process";
24
24
 
25
25
  import { loadConfig } from "./_config.mjs";
26
26
 
27
+ // Tiny argv parser. Supports --flag, --flag=value, --flag value.
28
+ function parsePreviewArgs(argv) {
29
+ const flags = {};
30
+ for (let i = 0; i < argv.length; i++) {
31
+ const a = argv[i];
32
+ if (a === "--") continue;
33
+ if (a.startsWith("--")) {
34
+ const eq = a.indexOf("=");
35
+ if (eq >= 0) {
36
+ flags[a.slice(2, eq)] = a.slice(eq + 1);
37
+ } else {
38
+ const name = a.slice(2);
39
+ const next = argv[i + 1];
40
+ if (next !== undefined && !next.startsWith("-")) {
41
+ flags[name] = next;
42
+ i++;
43
+ } else {
44
+ flags[name] = true;
45
+ }
46
+ }
47
+ }
48
+ }
49
+ return flags;
50
+ }
51
+
52
+ const PREVIEW_FLAGS = parsePreviewArgs(process.argv.slice(2));
53
+
27
54
  const cfg = loadConfig({});
28
55
  const ROOT = cfg.projectRoot;
29
56
  const OUT = resolve(
30
57
  ROOT,
31
58
  process.env.OUT_DIR ?? cfg.build.out ?? "out",
32
59
  );
33
- const PORT = Number(process.env.PORT ?? cfg.dev?.port ?? 4173);
60
+ // Baked HTML lives in <out>/baked/ by default (see scripts/bake.mjs and
61
+ // mado.config.json bake.outDir). Preview serves it with priority over the
62
+ // SPA shell so URLs that have a prerendered HTML page render real markup
63
+ // instead of an empty <div id="app"></div>.
64
+ const BAKED = resolve(
65
+ ROOT,
66
+ process.env.BAKED_DIR ?? cfg.bake?.outDir ?? join(cfg.build.out ?? "out", "baked"),
67
+ );
68
+ const PORT = Number(PREVIEW_FLAGS.port ?? process.env.PORT ?? cfg.dev?.port ?? 4173);
69
+ const HOST = String(PREVIEW_FLAGS.host ?? process.env.HOST ?? cfg.dev?.host ?? "localhost");
34
70
  const AUTOBUILD = process.env.PREVIEW_AUTOBUILD === "1";
35
71
  const SKIP_BUILD = process.env.SKIP_BUILD === "1" || !AUTOBUILD;
36
72
 
@@ -66,7 +102,18 @@ if (!SKIP_BUILD) {
66
102
  }
67
103
 
68
104
  if (!(await exists(OUT))) {
69
- console.error(`[preview] missing ${OUT}/ — check the steps above`);
105
+ console.error(
106
+ `[preview] missing ${OUT}/ — run \`mado release\` (or \`mado bundle\`) first.`,
107
+ );
108
+ process.exit(1);
109
+ }
110
+
111
+ const spaShell = join(OUT, "index.html");
112
+ if (!(await exists(spaShell))) {
113
+ console.error(
114
+ `[preview] missing ${spaShell} — \`mado bundle\` did not produce an HTML entry.\n` +
115
+ `[preview] Without it any non-baked route will 404 instead of falling back to the SPA.`,
116
+ );
70
117
  process.exit(1);
71
118
  }
72
119
 
@@ -114,8 +161,31 @@ const server = createServer(async (req, res) => {
114
161
  }
115
162
  });
116
163
 
117
- server.listen(PORT, () => {
118
- console.log(`\n[preview] http://localhost:${PORT}/ (Ctrl-C stop)\n`);
164
+ server.on("error", (err) => {
165
+ if (err.code === "EPERM" || err.code === "EACCES") {
166
+ console.error(
167
+ `[preview] failed to bind ${HOST}:${PORT}: ${err.message}\n` +
168
+ `[preview] tip: this sandbox may disallow binding "${HOST}".\n` +
169
+ `[preview] try: mado preview --host 127.0.0.1`,
170
+ );
171
+ } else {
172
+ console.error(
173
+ `[preview] failed to listen on ${HOST}:${PORT}: ${err.message}`,
174
+ );
175
+ }
176
+ process.exit(1);
177
+ });
178
+
179
+ server.listen(PORT, HOST, async () => {
180
+ const urlHost = HOST === "0.0.0.0" || HOST === "::" ? "localhost" : HOST;
181
+ const bakedReady = await exists(BAKED);
182
+ console.log("");
183
+ console.log("Mado preview (production-like)");
184
+ console.log(` url: http://${urlHost}:${PORT}/`);
185
+ console.log(` out: ${OUT}`);
186
+ console.log(` baked: ${bakedReady ? BAKED : "(none — SPA-only)"}`);
187
+ console.log(" (Ctrl-C to stop)");
188
+ console.log("");
119
189
  });
120
190
 
121
191
  // ---------- helpers ----------
@@ -145,14 +215,33 @@ function basenameSafe(p) {
145
215
  async function resolveTarget(pathname) {
146
216
  if (pathname === "/") pathname = "/index.html";
147
217
 
218
+ // 1) Baked HTML wins. `mado bake` writes prerendered pages into
219
+ // <out>/baked/<path>/index.html. Serve them with priority over the
220
+ // SPA shell so search engines AND human users hitting a prerendered
221
+ // URL see real content immediately. Without this branch preview
222
+ // served the empty SPA shell for every URL, which looked like a
223
+ // "blank page" bug even when bake had succeeded.
224
+ if (await exists(BAKED)) {
225
+ if (!extname(pathname) || pathname.endsWith("/index.html")) {
226
+ const bakedDir = join(BAKED, pathname.replace(/\/index\.html$/, ""));
227
+ const bakedIdx = join(bakedDir, "index.html");
228
+ if (await exists(bakedIdx)) return bakedIdx;
229
+ }
230
+ // Direct file (sitemap.xml etc.) from the baked dir.
231
+ const bakedFile = resolve(join(BAKED, pathname));
232
+ if (bakedFile.startsWith(BAKED + sep) && (await exists(bakedFile))) {
233
+ const s = await stat(bakedFile);
234
+ if (!s.isDirectory()) return bakedFile;
235
+ }
236
+ }
237
+
148
238
  const candidate = resolve(join(OUT, pathname));
149
239
  if (!candidate.startsWith(OUT + sep) && candidate !== OUT) return null;
150
240
 
151
- // 1) Exact match
241
+ // 2) Exact match inside out/.
152
242
  if (await exists(candidate)) {
153
243
  const s = await stat(candidate);
154
244
  if (s.isDirectory()) {
155
- // Baked priority: /product/foo/ → /product/foo/index.html
156
245
  const idx = join(candidate, "index.html");
157
246
  if (await exists(idx)) return idx;
158
247
  } else {
@@ -160,15 +249,20 @@ async function resolveTarget(pathname) {
160
249
  }
161
250
  }
162
251
 
163
- // 2) /foo → /foo/index.html (for baked pages without trailing slash)
252
+ // 3) /foo → /foo/index.html (for sub-folders without trailing slash).
164
253
  if (!extname(pathname)) {
165
254
  const asDir = join(OUT, pathname, "index.html");
166
255
  if (await exists(asDir)) return asDir;
167
256
  }
168
257
 
169
- // 3) SPA-fallback
170
- const spa = join(OUT, "index.html");
171
- if (await exists(spa)) return spa;
258
+ // 4) SPA-fallback: any non-asset path falls back to the SPA shell so
259
+ // client-side routing handles it. Asset-looking paths (with an
260
+ // extension) deliberately 404 instead — otherwise a 200 on
261
+ // /missing.png would mask real bugs.
262
+ if (!extname(pathname)) {
263
+ const spa = join(OUT, "index.html");
264
+ if (await exists(spa)) return spa;
265
+ }
172
266
 
173
267
  return null;
174
268
  }
package/server/serve.mjs CHANGED
@@ -35,10 +35,49 @@ const CONFIG = (() => {
35
35
  })();
36
36
  const PROXY_RULES = Object.entries(CONFIG.dev?.proxy ?? {}); // [["/api", "http://localhost:3000"], ...]
37
37
 
38
- const PORT = Number(process.env.PORT ?? CONFIG.dev?.port ?? 5173);
39
- const HMR = process.env.NO_HMR !== "1";
38
+ // Tiny argv parser. Supports --flag, --flag=value, --flag value. The first
39
+ // non-flag positional is the EXAMPLE name (legacy behavior). Anything that
40
+ // looks like a flag is consumed before we pick the positional, so calls like
41
+ // `mado dev -- --host 127.0.0.1` work as documented.
42
+ function parseArgs(argv) {
43
+ const flags = {};
44
+ const positional = [];
45
+ for (let i = 0; i < argv.length; i++) {
46
+ const a = argv[i];
47
+ if (a === "--") continue;
48
+ if (a.startsWith("--")) {
49
+ const eq = a.indexOf("=");
50
+ if (eq >= 0) {
51
+ flags[a.slice(2, eq)] = a.slice(eq + 1);
52
+ } else {
53
+ const name = a.slice(2);
54
+ const next = argv[i + 1];
55
+ if (next !== undefined && !next.startsWith("-")) {
56
+ flags[name] = next;
57
+ i++;
58
+ } else {
59
+ flags[name] = true;
60
+ }
61
+ }
62
+ } else {
63
+ positional.push(a);
64
+ }
65
+ }
66
+ return { flags, positional };
67
+ }
68
+
69
+ const { flags: CLI_FLAGS, positional: CLI_POSITIONAL } = parseArgs(
70
+ process.argv.slice(2),
71
+ );
40
72
 
41
- const EXAMPLE = process.argv[2] ?? process.env.MADO_EXAMPLE ?? process.env.EXAMPLE ?? "";
73
+ const PORT = Number(CLI_FLAGS.port ?? process.env.PORT ?? CONFIG.dev?.port ?? 5173);
74
+ // HOST is opt-in. Default to "localhost" (loopback) which is friendlier in
75
+ // sandboxes that disallow binding 0.0.0.0 (EPERM on listen). Users can opt
76
+ // into LAN exposure with `mado dev --host 0.0.0.0` or HOST=0.0.0.0.
77
+ const HOST = String(CLI_FLAGS.host ?? process.env.HOST ?? CONFIG.dev?.host ?? "localhost");
78
+ const HMR = CLI_FLAGS.hmr !== false && process.env.NO_HMR !== "1";
79
+
80
+ const EXAMPLE = CLI_POSITIONAL[0] ?? process.env.MADO_EXAMPLE ?? process.env.EXAMPLE ?? "";
42
81
  const EXAMPLE_DIR = EXAMPLE
43
82
  ? resolve(join(ROOT, "examples", EXAMPLE))
44
83
  : "";
@@ -185,7 +224,30 @@ const server = createServer(async (req, res) => {
185
224
  const s = await stat(target);
186
225
  if (s.isDirectory()) target = join(target, "index.html");
187
226
  } catch {
188
- if (!extname(pathname)) {
227
+ // Public assets: in production `mado release` copies public/* into out/.
228
+ // In dev we surface them from public/ directly so favicon.svg, robots.txt,
229
+ // og-image.png, etc. don't 404 (and so dev/prod behavior matches).
230
+ const publicCandidate = resolve(join(ROOT, "public", pathname));
231
+ if (
232
+ publicCandidate.startsWith(resolve(join(ROOT, "public")) + sep) &&
233
+ existsSync(publicCandidate)
234
+ ) {
235
+ try {
236
+ const ps = await stat(publicCandidate);
237
+ if (!ps.isDirectory()) {
238
+ target = publicCandidate;
239
+ reason = "public/";
240
+ } else if (!extname(pathname)) {
241
+ target = fallbackIndex;
242
+ } else {
243
+ reason = "file not found";
244
+ res.writeHead(404).end("not found");
245
+ return;
246
+ }
247
+ } catch {
248
+ target = fallbackIndex;
249
+ }
250
+ } else if (!extname(pathname)) {
189
251
  target = fallbackIndex;
190
252
  } else {
191
253
  reason = "file not found";
@@ -301,7 +363,15 @@ async function buildPreloadHints() {
301
363
  }
302
364
 
303
365
  server.on("error", (err) => {
304
- console.error(`[serve] failed to listen on port ${PORT}: ${err.message}`);
366
+ if (err.code === "EPERM" || err.code === "EACCES") {
367
+ console.error(
368
+ `[serve] failed to bind ${HOST}:${PORT}: ${err.message}\n` +
369
+ `[serve] tip: this sandbox may disallow binding "${HOST}".\n` +
370
+ `[serve] try: mado dev --host 127.0.0.1 (or HOST=127.0.0.1)`,
371
+ );
372
+ } else {
373
+ console.error(`[serve] failed to listen on ${HOST}:${PORT}: ${err.message}`);
374
+ }
305
375
  process.exit(1);
306
376
  });
307
377
 
@@ -351,7 +421,7 @@ async function proxyForward({ req, res, prefix, upstream, pathname, search }) {
351
421
  void prefix;
352
422
  }
353
423
 
354
- server.listen(PORT, () => {
424
+ server.listen(PORT, HOST, () => {
355
425
  const distReady = existsSync(join(ROOT, "dist/src/index.js"))
356
426
  || existsSync(join(ROOT, "dist/main.js"));
357
427
  const mount = EXAMPLE
@@ -359,9 +429,12 @@ server.listen(PORT, () => {
359
429
  : existsSync(EXAMPLES_INDEX)
360
430
  ? "examples/index.html landing"
361
431
  : "index.html app";
432
+ // Show "localhost" in the URL when bound to 0.0.0.0 — easier to click.
433
+ const urlHost = HOST === "0.0.0.0" || HOST === "::" ? "localhost" : HOST;
362
434
  console.log("");
363
435
  console.log("Mado dev server");
364
- console.log(` url: http://localhost:${PORT}/`);
436
+ console.log(` url: http://${urlHost}:${PORT}/`);
437
+ console.log(` host: ${HOST}`);
365
438
  console.log(` root: ${ROOT}`);
366
439
  console.log(` mount: ${mount}`);
367
440
  console.log(` hmr: ${HMR ? "on" : "off"}`);
@@ -5,17 +5,24 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1">
6
6
  <title>__APP_NAME__</title>
7
7
  <link rel="icon" type="image/svg+xml" href="/favicon.svg">
8
+ <!--
9
+ Paths below MUST be root-absolute (start with "/"), not "./...".
10
+ Mado is an SPA: hard-refreshing /admin/orders/42 still serves this same
11
+ index.html, and the browser resolves "./dist/main.js" against the
12
+ current URL → /admin/orders/dist/main.js → 404 → blank page.
13
+ Root-absolute paths always resolve to /dist/main.js regardless of route.
14
+ -->
8
15
  <script type="importmap">
9
16
  {
10
17
  "imports": {
11
- "@madojs/mado": "./node_modules/@madojs/mado/dist/src/index.js",
12
- "@madojs/mado/": "./node_modules/@madojs/mado/dist/src/"
18
+ "@madojs/mado": "/node_modules/@madojs/mado/dist/src/index.js",
19
+ "@madojs/mado/": "/node_modules/@madojs/mado/dist/src/"
13
20
  }
14
21
  }
15
22
  </script>
16
23
  </head>
17
24
  <body>
18
25
  <div id="app"></div>
19
- <script type="module" src="./dist/main.js"></script>
26
+ <script type="module" src="/dist/main.js"></script>
20
27
  </body>
21
28
  </html>
@@ -17,6 +17,8 @@
17
17
  "@madojs/mado": "__MADOJS_VERSION__"
18
18
  },
19
19
  "devDependencies": {
20
+ "esbuild": "^0.24.0",
21
+ "linkedom": "^0.18.0",
20
22
  "typescript": "^6.0.3"
21
23
  }
22
- }
24
+ }
@@ -1,7 +1,7 @@
1
1
  // Order detail page. Reads :id from params, fetches the order, and shows
2
2
  // inline loading/error/empty/ready states.
3
3
 
4
- import { html, jsonFetcher, page, resource } from "@madojs/mado";
4
+ import { each, html, jsonFetcher, page, resource } from "@madojs/mado";
5
5
 
6
6
  interface OrderDetail {
7
7
  id: string;
@@ -46,7 +46,9 @@ export default page<{ id: string }>({
46
46
  </tr>
47
47
  </thead>
48
48
  <tbody>
49
- ${o.items.map(
49
+ ${each(
50
+ o.items,
51
+ (it) => it.sku,
50
52
  (it) => html`
51
53
  <tr style="border-bottom:1px solid var(--border);">
52
54
  <td style="padding:8px 0;">${it.sku}</td>
@@ -1,5 +1,10 @@
1
1
  // Public landing page. Demonstrates that the marketing surface can live
2
2
  // alongside the admin app without a guard, and can be baked for SEO.
3
+ //
4
+ // `bake` is declared so that `mado bake` (and `mado release`) actually
5
+ // prerender at least one static page out of the box. Without it the
6
+ // release output ships only the SPA shell with no SEO-friendly HTML
7
+ // for crawlers landing on "/".
3
8
 
4
9
  import { html, page } from "@madojs/mado";
5
10
 
@@ -13,6 +18,10 @@ export default page({
13
18
  type: "website",
14
19
  },
15
20
  }),
21
+ bake: {
22
+ paths: () => [{}],
23
+ data: () => ({}),
24
+ },
16
25
  view: () => html`
17
26
  <main style="max-width:720px;margin:0 auto;padding:64px 24px;">
18
27
  <h1>__APP_NAME__</h1>
@@ -22,4 +31,4 @@ export default page({
22
31
  </p>
23
32
  </main>
24
33
  `,
25
- });
34
+ });
@@ -4,17 +4,25 @@
4
4
  <meta charset="utf-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1">
6
6
  <title>__APP_NAME__</title>
7
+ <link rel="icon" type="image/svg+xml" href="/favicon.svg">
8
+ <!--
9
+ Paths below MUST be root-absolute (start with "/"), not "./...".
10
+ Mado is an SPA: hard-refreshing /users/42 still serves this same
11
+ index.html, and the browser resolves "./dist/main.js" against the
12
+ current URL → /users/dist/main.js → 404 → blank page.
13
+ Root-absolute paths always resolve to /dist/main.js regardless of route.
14
+ -->
7
15
  <script type="importmap">
8
16
  {
9
17
  "imports": {
10
- "@madojs/mado": "./node_modules/@madojs/mado/dist/src/index.js",
11
- "@madojs/mado/": "./node_modules/@madojs/mado/dist/src/"
18
+ "@madojs/mado": "/node_modules/@madojs/mado/dist/src/index.js",
19
+ "@madojs/mado/": "/node_modules/@madojs/mado/dist/src/"
12
20
  }
13
21
  }
14
22
  </script>
15
23
  </head>
16
24
  <body>
17
25
  <div id="app"></div>
18
- <script type="module" src="./dist/main.js"></script>
26
+ <script type="module" src="/dist/main.js"></script>
19
27
  </body>
20
- </html>
28
+ </html>
@@ -17,6 +17,8 @@
17
17
  "@madojs/mado": "__MADOJS_VERSION__"
18
18
  },
19
19
  "devDependencies": {
20
+ "esbuild": "^0.24.0",
21
+ "linkedom": "^0.18.0",
20
22
  "typescript": "^6.0.3"
21
23
  }
22
- }
24
+ }
@@ -1,7 +1,23 @@
1
+ // Public landing page. `bake` is declared so that `mado bake` (and
2
+ // `mado release`) actually prerender at least one SEO-friendly HTML page
3
+ // out of the box. Without it the build output ships only the SPA shell.
4
+
1
5
  import { html, page } from "@madojs/mado";
2
6
 
3
7
  export default page({
4
8
  title: "__APP_NAME__",
9
+ head: () => ({
10
+ description: "A CRUD scaffold built with Mado.",
11
+ og: {
12
+ title: "__APP_NAME__",
13
+ description: "A CRUD scaffold built with Mado.",
14
+ type: "website",
15
+ },
16
+ }),
17
+ bake: {
18
+ paths: () => [{}],
19
+ data: () => ({}),
20
+ },
5
21
  view: () => html`
6
22
  <section class="page">
7
23
  <div class="hero">
@@ -4,17 +4,25 @@
4
4
  <meta charset="utf-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1">
6
6
  <title>__APP_NAME__</title>
7
+ <link rel="icon" type="image/svg+xml" href="/favicon.svg">
8
+ <!--
9
+ Paths below MUST be root-absolute (start with "/"), not "./...".
10
+ Mado is an SPA: hard-refreshing any nested route still serves this same
11
+ index.html, and the browser resolves "./dist/main.js" against the
12
+ current URL → /some/nested/dist/main.js → 404 → blank page.
13
+ Root-absolute paths always resolve to /dist/main.js regardless of route.
14
+ -->
7
15
  <script type="importmap">
8
16
  {
9
17
  "imports": {
10
- "@madojs/mado": "./node_modules/@madojs/mado/dist/src/index.js",
11
- "@madojs/mado/": "./node_modules/@madojs/mado/dist/src/"
18
+ "@madojs/mado": "/node_modules/@madojs/mado/dist/src/index.js",
19
+ "@madojs/mado/": "/node_modules/@madojs/mado/dist/src/"
12
20
  }
13
21
  }
14
22
  </script>
15
23
  </head>
16
24
  <body>
17
25
  <div id="app"></div>
18
- <script type="module" src="./dist/main.js"></script>
26
+ <script type="module" src="/dist/main.js"></script>
19
27
  </body>
20
- </html>
28
+ </html>
@@ -17,6 +17,8 @@
17
17
  "@madojs/mado": "__MADOJS_VERSION__"
18
18
  },
19
19
  "devDependencies": {
20
+ "esbuild": "^0.24.0",
21
+ "linkedom": "^0.18.0",
20
22
  "typescript": "^6.0.3"
21
23
  }
22
24
  }
@@ -1,7 +1,24 @@
1
+ // Public landing page. `bake` is declared so that `mado bake` (and
2
+ // `mado release`) actually prerender a static HTML page out of the box.
3
+ // Without it the build output ships only the SPA shell — bots that hit
4
+ // "/" see an empty <body> instead of the welcome content.
5
+
1
6
  import { html, page } from "@madojs/mado";
2
7
 
3
8
  export default page({
4
9
  title: "__APP_NAME__",
10
+ head: () => ({
11
+ description: "A minimal Mado starter app.",
12
+ og: {
13
+ title: "__APP_NAME__",
14
+ description: "A minimal Mado starter app.",
15
+ type: "website",
16
+ },
17
+ }),
18
+ bake: {
19
+ paths: () => [{}],
20
+ data: () => ({}),
21
+ },
5
22
  view: () => html`
6
23
  <main class="shell">
7
24
  <section class="panel">