@madojs/mado 0.11.1 → 0.13.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/AGENTS.md +116 -32
- package/CHANGELOG.md +216 -1
- package/README.md +158 -173
- package/dist/src/component.d.ts +6 -3
- package/dist/src/component.d.ts.map +1 -0
- package/dist/src/component.js +163 -36
- package/dist/src/component.js.map +1 -1
- package/dist/src/context.d.ts +13 -32
- package/dist/src/context.d.ts.map +1 -0
- package/dist/src/context.js +73 -48
- package/dist/src/context.js.map +1 -1
- package/dist/src/css.d.ts +1 -0
- package/dist/src/css.d.ts.map +1 -0
- package/dist/src/css.js +34 -5
- package/dist/src/css.js.map +1 -1
- package/dist/src/devtools-hook.d.ts +14 -0
- package/dist/src/devtools-hook.d.ts.map +1 -0
- package/dist/src/devtools-hook.js +27 -0
- package/dist/src/devtools-hook.js.map +1 -0
- package/dist/src/devtools.d.ts +24 -22
- package/dist/src/devtools.d.ts.map +1 -0
- package/dist/src/devtools.js +230 -58
- package/dist/src/devtools.js.map +1 -1
- package/dist/src/diagnostics.d.ts +12 -0
- package/dist/src/diagnostics.d.ts.map +1 -0
- package/dist/src/diagnostics.js +68 -8
- package/dist/src/diagnostics.js.map +1 -1
- package/dist/src/each.d.ts +1 -5
- package/dist/src/each.d.ts.map +1 -0
- package/dist/src/each.js +0 -8
- package/dist/src/each.js.map +1 -1
- package/dist/src/forms.d.ts +27 -96
- package/dist/src/forms.d.ts.map +1 -0
- package/dist/src/forms.js +184 -394
- package/dist/src/forms.js.map +1 -1
- package/dist/src/head.d.ts +7 -6
- package/dist/src/head.d.ts.map +1 -0
- package/dist/src/head.js +8 -7
- package/dist/src/head.js.map +1 -1
- package/dist/src/html/bindings.d.ts +1 -0
- package/dist/src/html/bindings.d.ts.map +1 -0
- package/dist/src/html/bindings.js.map +1 -1
- package/dist/src/html/parser.d.ts +4 -5
- package/dist/src/html/parser.d.ts.map +1 -0
- package/dist/src/html/parser.js +64 -15
- package/dist/src/html/parser.js.map +1 -1
- package/dist/src/html/template-types.d.ts +1 -0
- package/dist/src/html/template-types.d.ts.map +1 -0
- package/dist/src/html/template-types.js.map +1 -1
- package/dist/src/html/template.d.ts +5 -1
- package/dist/src/html/template.d.ts.map +1 -0
- package/dist/src/html/template.js +102 -13
- package/dist/src/html/template.js.map +1 -1
- package/dist/src/index.d.ts +15 -12
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +18 -10
- package/dist/src/index.js.map +1 -1
- package/dist/src/json.d.ts +3 -0
- package/dist/src/json.d.ts.map +1 -0
- package/dist/src/json.js +14 -0
- package/dist/src/json.js.map +1 -0
- package/dist/src/lifecycle.d.ts +1 -0
- package/dist/src/lifecycle.d.ts.map +1 -0
- package/dist/src/lifecycle.js +3 -2
- package/dist/src/lifecycle.js.map +1 -1
- package/dist/src/page.d.ts +63 -28
- package/dist/src/page.d.ts.map +1 -0
- package/dist/src/page.js +5 -0
- package/dist/src/page.js.map +1 -1
- package/dist/src/persisted.d.ts +6 -1
- package/dist/src/persisted.d.ts.map +1 -0
- package/dist/src/persisted.js +17 -11
- package/dist/src/persisted.js.map +1 -1
- package/dist/src/resource.d.ts +2 -1
- package/dist/src/resource.d.ts.map +1 -0
- package/dist/src/resource.js +128 -50
- package/dist/src/resource.js.map +1 -1
- package/dist/src/router/base.d.ts +66 -0
- package/dist/src/router/base.d.ts.map +1 -0
- package/dist/src/router/base.js +168 -0
- package/dist/src/router/base.js.map +1 -0
- package/dist/src/router/manifest.d.ts +1 -0
- package/dist/src/router/manifest.d.ts.map +1 -0
- package/dist/src/router/manifest.js +156 -171
- package/dist/src/router/manifest.js.map +1 -1
- package/dist/src/router/match.d.ts +17 -2
- package/dist/src/router/match.d.ts.map +1 -0
- package/dist/src/router/match.js +60 -6
- package/dist/src/router/match.js.map +1 -1
- package/dist/src/router/navigation.d.ts +1 -0
- package/dist/src/router/navigation.d.ts.map +1 -0
- package/dist/src/router/navigation.js +58 -9
- package/dist/src/router/navigation.js.map +1 -1
- package/dist/src/signal.d.ts +1 -0
- package/dist/src/signal.d.ts.map +1 -0
- package/dist/src/signal.js +46 -17
- package/dist/src/signal.js.map +1 -1
- package/dist/src/static-runtime.d.ts +82 -0
- package/dist/src/static-runtime.d.ts.map +1 -0
- package/dist/src/static-runtime.js +209 -0
- package/dist/src/static-runtime.js.map +1 -0
- package/dist/src/vite/index.d.ts +32 -3
- package/dist/src/vite/index.d.ts.map +1 -0
- package/dist/src/vite/index.js +49 -17
- package/dist/src/vite/index.js.map +1 -1
- package/docs/README.md +5 -8
- package/docs/architecture/adr/0001-browser-static-snapshots.md +132 -0
- package/docs/architecture/v1-roadmap.md +19 -0
- package/docs/en/00-the-mado-way.md +1 -1
- package/docs/en/01-quickstart.md +183 -0
- package/docs/en/10-pages-and-components.md +279 -0
- package/docs/en/11-templates-and-signals.md +211 -0
- package/docs/en/12-routing.md +229 -0
- package/docs/en/13-data.md +227 -0
- package/docs/en/14-forms.md +91 -0
- package/docs/en/15-static-snapshots.md +181 -0
- package/docs/en/{10-app-architecture.md → 16-app-architecture.md} +56 -4
- package/docs/en/{13-deployment.md → 20-deployment.md} +79 -17
- package/docs/en/{15-error-handling.md → 21-error-handling.md} +9 -6
- package/docs/en/{14-testing.md → 22-testing.md} +6 -5
- package/docs/en/23-cookbook.md +292 -0
- package/docs/en/24-devtools-and-diagnostics.md +45 -0
- package/docs/en/{18-api-freeze-map.md → 30-api-freeze-map.md} +17 -9
- package/docs/en/{20-v1-stability.md → 32-v1-stability.md} +5 -5
- package/docs/en/33-migration-0.12-0.13.md +56 -0
- package/docs/en/40-llm-guide.md +774 -0
- package/docs/en/{06-for-backenders.md → 41-for-backenders.md} +28 -25
- package/docs/en/{05-why-mado.md → 42-why-mado.md} +3 -3
- package/docs/en/README.md +99 -27
- package/docs/recipes/nginx/Containerfile +26 -0
- package/docs/recipes/nginx/nginx.conf +42 -0
- package/llms.txt +263 -210
- package/package.json +51 -23
- package/scripts/clean.mjs +8 -0
- package/scripts/cli/generate.mjs +57 -10
- package/scripts/cli/help.mjs +13 -5
- package/scripts/cli/index.mjs +31 -7
- package/scripts/cli/init.mjs +19 -19
- package/scripts/cli/release.mjs +38 -83
- package/scripts/cli/run.mjs +5 -3
- package/scripts/logger.mjs +117 -0
- package/scripts/output-guard.mjs +128 -0
- package/scripts/preview.mjs +105 -24
- package/scripts/static/browser.mjs +695 -0
- package/scripts/static/discover.mjs +284 -0
- package/scripts/static/output.mjs +141 -0
- package/scripts/static/serialize.mjs +212 -0
- package/scripts/static/server.mjs +167 -0
- package/scripts/static.mjs +205 -0
- package/starters/default/README.md +57 -55
- package/starters/default/package.json +6 -12
- package/starters/default/src/app.routes.ts +20 -33
- package/starters/default/src/components/feature-card.component.ts +40 -0
- package/starters/default/src/components/live-counter.component.ts +57 -0
- package/starters/default/src/content/guides.ts +55 -0
- package/starters/default/src/main.ts +9 -13
- package/starters/default/src/pages/app.page.ts +41 -0
- package/starters/default/src/pages/guide.page.ts +40 -0
- package/starters/default/src/pages/home.page.ts +49 -0
- package/starters/default/src/pages/not-found.page.ts +18 -0
- package/starters/default/src/styles/document.css +39 -0
- package/starters/default/src/styles/reset.css +37 -0
- package/starters/default/src/styles/tokens.css +30 -0
- package/starters/default/src/styles.d.ts +3 -1
- package/starters/default/src/vite-env.d.ts +1 -1
- package/starters/default/tsconfig.node.json +13 -0
- package/starters/default/vite.config.ts +14 -4
- package/starters/modular/README.md +142 -0
- package/starters/modular/index.html +13 -0
- package/starters/modular/package.json +30 -0
- package/starters/modular/src/app.routes.ts +39 -0
- package/starters/{default → modular}/src/layouts/app-shell.layout.ts +9 -7
- package/starters/{default → modular}/src/layouts/auth-shell.layout.ts +3 -3
- package/starters/modular/src/main.ts +16 -0
- package/starters/{default → modular}/src/modules/auth/login.page.ts +5 -12
- package/starters/{default → modular}/src/modules/billing/pages/invoice-detail.page.ts +3 -4
- package/starters/{default → modular}/src/modules/billing/pages/invoices-list.page.ts +4 -4
- package/starters/{default → modular}/src/modules/home/home.page.ts +5 -7
- package/starters/modular/src/modules/home/not-found.page.ts +14 -0
- package/starters/{default → modular}/src/shared/styles/reset.css +21 -1
- package/starters/modular/src/styles.d.ts +1 -0
- package/starters/modular/src/vite-env.d.ts +1 -0
- package/starters/modular/tsconfig.json +33 -0
- package/starters/modular/tsconfig.node.json +13 -0
- package/starters/modular/vite.config.ts +132 -0
- package/TODO.md +0 -79
- package/dist/src/lazy.d.ts +0 -38
- package/dist/src/lazy.js +0 -73
- package/dist/src/lazy.js.map +0 -1
- package/docs/en/01-routing.md +0 -152
- package/docs/en/02-project-layout.md +0 -124
- package/docs/en/03-static-bake.md +0 -249
- package/docs/en/04-ide-setup.md +0 -162
- package/docs/en/07-llm-pitfalls.md +0 -724
- package/docs/en/08-llm-zero-history-test.md +0 -56
- package/docs/en/09-shadow-vs-light-dom.md +0 -174
- package/docs/en/11-layouts.md +0 -113
- package/docs/en/12-auth-and-api.md +0 -124
- package/docs/en/16-bake-cookbook.md +0 -100
- package/docs/en/17-shadow-dom-forms.md +0 -192
- package/docs/fr/00-the-mado-way.md +0 -85
- package/docs/fr/01-routing.md +0 -120
- package/docs/fr/02-project-layout.md +0 -84
- package/docs/fr/03-static-bake.md +0 -289
- package/docs/fr/04-ide-setup.md +0 -162
- package/docs/fr/05-why-mado.md +0 -193
- package/docs/fr/06-for-backenders.md +0 -438
- package/docs/fr/07-llm-pitfalls.md +0 -625
- package/docs/fr/08-llm-zero-history-test.md +0 -38
- package/docs/fr/09-shadow-vs-light-dom.md +0 -65
- package/docs/fr/10-app-architecture.md +0 -138
- package/docs/fr/11-layouts.md +0 -47
- package/docs/fr/12-auth-and-api.md +0 -76
- package/docs/fr/13-deployment.md +0 -57
- package/docs/fr/14-testing.md +0 -41
- package/docs/fr/15-error-handling.md +0 -50
- package/docs/fr/16-bake-cookbook.md +0 -88
- package/docs/fr/17-shadow-dom-forms.md +0 -196
- package/docs/fr/18-api-freeze-map.md +0 -63
- package/docs/fr/19-reactivity-ordering.md +0 -97
- package/docs/fr/20-v1-stability.md +0 -88
- package/docs/fr/README.md +0 -27
- package/docs/ru/00-the-mado-way.md +0 -84
- package/docs/ru/01-routing.md +0 -119
- package/docs/ru/02-project-layout.md +0 -84
- package/docs/ru/03-static-bake.md +0 -250
- package/docs/ru/04-ide-setup.md +0 -144
- package/docs/ru/05-why-mado.md +0 -193
- package/docs/ru/06-for-backenders.md +0 -428
- package/docs/ru/07-llm-pitfalls.md +0 -624
- package/docs/ru/08-llm-zero-history-test.md +0 -57
- package/docs/ru/09-shadow-vs-light-dom.md +0 -63
- package/docs/ru/10-app-architecture.md +0 -152
- package/docs/ru/11-layouts.md +0 -47
- package/docs/ru/12-auth-and-api.md +0 -75
- package/docs/ru/13-deployment.md +0 -66
- package/docs/ru/14-testing.md +0 -50
- package/docs/ru/15-error-handling.md +0 -56
- package/docs/ru/16-bake-cookbook.md +0 -95
- package/docs/ru/17-shadow-dom-forms.md +0 -193
- package/docs/ru/18-api-freeze-map.md +0 -64
- package/docs/ru/19-reactivity-ordering.md +0 -95
- package/docs/ru/20-v1-stability.md +0 -82
- package/docs/ru/README.md +0 -25
- package/docs/uk/00-the-mado-way.md +0 -82
- package/docs/uk/01-routing.md +0 -76
- package/docs/uk/02-project-layout.md +0 -73
- package/docs/uk/03-static-bake.md +0 -48
- package/docs/uk/04-ide-setup.md +0 -26
- package/docs/uk/05-why-mado.md +0 -34
- package/docs/uk/06-for-backenders.md +0 -55
- package/docs/uk/07-llm-pitfalls.md +0 -145
- package/docs/uk/08-llm-zero-history-test.md +0 -34
- package/docs/uk/09-shadow-vs-light-dom.md +0 -58
- package/docs/uk/10-app-architecture.md +0 -97
- package/docs/uk/11-layouts.md +0 -47
- package/docs/uk/12-auth-and-api.md +0 -70
- package/docs/uk/13-deployment.md +0 -40
- package/docs/uk/14-testing.md +0 -34
- package/docs/uk/15-error-handling.md +0 -32
- package/docs/uk/16-bake-cookbook.md +0 -36
- package/docs/uk/17-shadow-dom-forms.md +0 -193
- package/docs/uk/18-api-freeze-map.md +0 -61
- package/docs/uk/19-reactivity-ordering.md +0 -95
- package/docs/uk/20-v1-stability.md +0 -83
- package/docs/uk/README.md +0 -27
- package/scripts/bake.mjs +0 -570
- package/scripts/package-smoke.mjs +0 -77
- package/scripts/release-notes.mjs +0 -66
- package/scripts/size-budget.mjs +0 -91
- package/starters/default/src/modules/home/not-found.page.ts +0 -11
- package/starters/default/src/shared/ui/x-button.component.ts +0 -49
- /package/docs/en/{19-reactivity-ordering.md → 31-reactivity-ordering.md} +0 -0
- /package/starters/{default → modular}/.editorconfig +0 -0
- /package/starters/{default → modular}/eslint.config.mjs +0 -0
- /package/starters/{default → modular}/public/favicon.svg +0 -0
- /package/starters/{default → modular}/src/modules/auth/_contracts/auth-api.types.ts +0 -0
- /package/starters/{default → modular}/src/modules/auth/auth.connector.ts +0 -0
- /package/starters/{default → modular}/src/modules/auth/auth.guard.ts +0 -0
- /package/starters/{default → modular}/src/modules/auth/auth.public.ts +0 -0
- /package/starters/{default → modular}/src/modules/auth/auth.routes.ts +0 -0
- /package/starters/{default → modular}/src/modules/auth/auth.service.ts +0 -0
- /package/starters/{default → modular}/src/modules/auth/auth.types.ts +0 -0
- /package/starters/{default → modular}/src/modules/billing/_contracts/stripe.types.ts +0 -0
- /package/starters/{default → modular}/src/modules/billing/api/stripe.connector.ts +0 -0
- /package/starters/{default → modular}/src/modules/billing/billing.public.ts +0 -0
- /package/starters/{default → modular}/src/modules/billing/billing.routes.ts +0 -0
- /package/starters/{default → modular}/src/modules/billing/billing.types.ts +0 -0
- /package/starters/{default → modular}/src/modules/billing/components/invoice-status-badge.component.ts +0 -0
- /package/starters/{default → modular}/src/modules/billing/data/invoices.resource.ts +0 -0
- /package/starters/{default → modular}/src/shared/http/http-client.ts +0 -0
- /package/starters/{default → modular}/src/shared/http/http-error.ts +0 -0
- /package/starters/{default → modular}/src/shared/http/interceptors.ts +0 -0
- /package/starters/{default → modular}/src/shared/lib/format-date.ts +0 -0
- /package/starters/{default → modular}/src/shared/styles/content.css +0 -0
- /package/starters/{default → modular}/src/shared/styles/shell.css +0 -0
- /package/starters/{default → modular}/src/shared/styles/tokens.css +0 -0
- /package/starters/{default → modular}/src/shared/ui/x-spinner.component.ts +0 -0
package/README.md
CHANGED
|
@@ -6,126 +6,85 @@
|
|
|
6
6
|
/>
|
|
7
7
|
|
|
8
8
|
<p>
|
|
9
|
-
<strong>
|
|
9
|
+
<strong>A calm native-first web framework for sites and apps.</strong>
|
|
10
10
|
</p>
|
|
11
11
|
|
|
12
12
|
<p>
|
|
13
|
-
|
|
13
|
+
Web Components · Signals · Browser-rendered static snapshots · Zero runtime dependencies
|
|
14
14
|
</p>
|
|
15
15
|
</div>
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
# Mado
|
|
19
19
|
|
|
20
|
-
> A calm
|
|
20
|
+
> A calm native-first web framework for sites and apps.
|
|
21
21
|
|
|
22
22
|
[](https://www.npmjs.com/package/@madojs/mado)
|
|
23
23
|
[](https://github.com/madojs/mado/actions/workflows/ci.yml)
|
|
24
|
-
[](https://github.com/madojs/mado/actions/workflows/browser.yml)
|
|
25
24
|
[](./LICENSE)
|
|
26
25
|
[](https://www.paypal.com/paypalme/tsekhmister)
|
|
27
26
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
Build with real Web Components, signals, routing, data and forms.
|
|
28
|
+
Ship live SPAs and browser-rendered static documents from one
|
|
29
|
+
component model.
|
|
31
30
|
|
|
32
|
-
|
|
33
|
-
Vite required, no hidden build pipeline. The entire runtime is readable in an
|
|
34
|
-
evening. When something breaks, you can read the source and fix it.
|
|
31
|
+
**One component model. One page model. One release command.**
|
|
35
32
|
|
|
36
|
-
Mado (`窓`) means
|
|
37
|
-
dragging a whole frontend factory into the room.
|
|
38
|
-
|
|
39
|
-
## When to use Mado
|
|
40
|
-
|
|
41
|
-
- **Admin panels and dashboards** — forms, tables, filters, auth, role guards.
|
|
42
|
-
- **Internal tools and backoffice** — CRUD workflows, settings, billing UI.
|
|
43
|
-
- **Small SaaS frontends** — where long-term maintainability matters more than
|
|
44
|
-
ecosystem size.
|
|
45
|
-
- **Embedded widgets** — where small footprint and independence from host
|
|
46
|
-
frameworks matter.
|
|
47
|
-
|
|
48
|
-
The common thread: apps where **the frontend should not become its own
|
|
49
|
-
infrastructure problem**.
|
|
50
|
-
|
|
51
|
-
## When not to use Mado
|
|
52
|
-
|
|
53
|
-
- **SEO-heavy public sites** that need SSR with hydration.
|
|
54
|
-
- **Large teams optimizing for hiring compatibility** — React/Vue have bigger
|
|
55
|
-
talent pools.
|
|
56
|
-
- **Projects that need a mature UI-kit ecosystem** comparable to React today.
|
|
57
|
-
- **Beginners learning frontend** — React, Vue and Svelte have far larger
|
|
58
|
-
learning resources.
|
|
59
|
-
- **Teams uncomfortable with a pre-v1 framework** — Mado is honest about its
|
|
60
|
-
stage.
|
|
61
|
-
|
|
62
|
-
## What Mado will not build
|
|
63
|
-
|
|
64
|
-
Mado stays useful by saying no. These are intentionally out of scope:
|
|
65
|
-
|
|
66
|
-
- SSR with hydration. Use `bake` or edge prerender for SEO-oriented static
|
|
67
|
-
output.
|
|
68
|
-
- A template compiler, JSX transform, or VDOM compatibility layer.
|
|
69
|
-
- A separate store library. Use `signal()`, `computed()` and `resource()`.
|
|
70
|
-
- Suspense primitives or a router plugin system.
|
|
71
|
-
- Built-in i18n, animation, or virtual-scroll primitives.
|
|
72
|
-
- Non-evergreen browser support. The baseline is modern evergreen browsers with
|
|
73
|
-
Baseline 2023 platform features.
|
|
74
|
-
|
|
75
|
-
## Why teams pick Mado
|
|
76
|
-
|
|
77
|
-
| What matters to you | Best choice |
|
|
78
|
-
|---|---|
|
|
79
|
-
| Largest ecosystem, most hires available | React or Vue |
|
|
80
|
-
| Reusable design-system components across host frameworks | Lit |
|
|
81
|
-
| Maximum rendering performance, JSX workflow | Solid or Svelte 5 |
|
|
82
|
-
| Progressive enhancement of server-rendered pages | htmx + your backend |
|
|
83
|
-
| Full app stack with minimal infrastructure and calm maintenance | **Mado** |
|
|
84
|
-
|
|
85
|
-
**Honest tradeoffs:**
|
|
86
|
-
|
|
87
|
-
- **vs Lit** — Lit is better for design systems. Mado is for whole apps:
|
|
88
|
-
router, data, forms and prerender in one package, no assembly required.
|
|
89
|
-
- **vs Solid** — Solid is faster and more mature. Mado keeps a smaller runtime
|
|
90
|
-
and uses Vite only as the development/build transport layer.
|
|
91
|
-
- **vs htmx** — htmx is excellent when your backend owns HTML. Mado is for
|
|
92
|
-
cases where you want a real SPA: local state, optimistic updates, cached
|
|
93
|
-
resources, lazy modules and persisted UI state.
|
|
33
|
+
Mado (`窓`) means *window* in Japanese: a calm window into your app,
|
|
34
|
+
without dragging a whole frontend factory into the room.
|
|
94
35
|
|
|
95
36
|
## What you get
|
|
96
37
|
|
|
97
|
-
Routing, forms, state, data fetching and prerendering — without ecosystem tax:
|
|
98
|
-
|
|
99
|
-
- No runtime dependencies to audit, update or break
|
|
100
|
-
- Vite-powered dev/build without a framework-specific bundler to maintain
|
|
101
|
-
- Fewer Mado-specific moving parts to debug
|
|
102
|
-
- Compact API surface you can learn in a day
|
|
103
|
-
- Lower long-term cognitive load
|
|
104
|
-
|
|
105
38
|
```txt
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
39
|
+
Mado component = Custom Element + open Shadow DOM
|
|
40
|
+
Mado page = route + load + head + view + optional static declaration
|
|
41
|
+
Mado release = Vite build
|
|
42
|
+
+ browser-rendered static documents
|
|
43
|
+
+ Declarative Shadow DOM
|
|
44
|
+
+ SPA fallback
|
|
45
|
+
+ deployment artifact
|
|
46
|
+
|
|
47
|
+
Client activation = atomic takeover
|
|
48
|
+
≠ hydration
|
|
49
|
+
≠ SSR reconciliation
|
|
110
50
|
```
|
|
111
51
|
|
|
112
|
-
|
|
52
|
+
Browser-native source, with Vite as the development and delivery
|
|
53
|
+
transport. No framework-specific compiler and zero runtime
|
|
54
|
+
dependencies.
|
|
55
|
+
|
|
56
|
+
## Use cases
|
|
113
57
|
|
|
114
|
-
|
|
58
|
+
- Public landing pages
|
|
59
|
+
- Documentation sites
|
|
60
|
+
- Product / catalog pages
|
|
61
|
+
- SaaS applications
|
|
62
|
+
- Business applications
|
|
63
|
+
- Admin panels and internal tools
|
|
64
|
+
- Dashboards
|
|
65
|
+
- Embedded widgets
|
|
66
|
+
|
|
67
|
+
## Quick start
|
|
115
68
|
|
|
116
69
|
```bash
|
|
117
|
-
npm exec --package @madojs/mado
|
|
70
|
+
npm exec --package @madojs/mado -- mado init my-app
|
|
118
71
|
cd my-app
|
|
119
72
|
npm install
|
|
120
73
|
npm run dev
|
|
121
74
|
```
|
|
122
75
|
|
|
123
|
-
The default starter is the
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
76
|
+
The default starter is the universal starter: ~15 source files,
|
|
77
|
+
runnable without a backend, demonstrating one Shadow Component shared
|
|
78
|
+
between a static landing page and a live SPA route.
|
|
79
|
+
|
|
80
|
+
Need the modular reference architecture (auth shell, guarded zones,
|
|
81
|
+
billing module, HTTP client, module boundaries)?
|
|
127
82
|
|
|
128
|
-
|
|
83
|
+
```bash
|
|
84
|
+
mado init my-app --starter modular
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## The Mado way
|
|
129
88
|
|
|
130
89
|
### Signals — reactive state
|
|
131
90
|
|
|
@@ -139,9 +98,6 @@ effect(() => console.log(count()));
|
|
|
139
98
|
count.set(1);
|
|
140
99
|
```
|
|
141
100
|
|
|
142
|
-
Signals are getter functions: read with `count()`, write with `count.set(v)`
|
|
143
|
-
or `count.update(fn)`.
|
|
144
|
-
|
|
145
101
|
### Templates — tagged template html
|
|
146
102
|
|
|
147
103
|
```ts
|
|
@@ -155,7 +111,7 @@ html`<button @click=${fn} ?disabled=${loading} class=${cls}>${label}</button>`;
|
|
|
155
111
|
- `?attr=${flag}` — boolean attribute
|
|
156
112
|
- Functions and signals are tracked reactively
|
|
157
113
|
|
|
158
|
-
### Components — Web Components
|
|
114
|
+
### Components — real Web Components
|
|
159
115
|
|
|
160
116
|
```ts
|
|
161
117
|
import { component, css, html } from "@madojs/mado";
|
|
@@ -169,25 +125,47 @@ component(
|
|
|
169
125
|
);
|
|
170
126
|
```
|
|
171
127
|
|
|
172
|
-
|
|
128
|
+
Open shadow root, scoped styles, slots, attribute reactivity, a real
|
|
129
|
+
custom element under the hood. The same component renders inside the
|
|
130
|
+
static snapshot via Declarative Shadow DOM and inside the live SPA via
|
|
131
|
+
direct DOM attachment.
|
|
132
|
+
|
|
133
|
+
### Pages — `route + load + head + view`
|
|
173
134
|
|
|
174
135
|
```ts
|
|
175
|
-
import {
|
|
136
|
+
import { html, page } from "@madojs/mado";
|
|
137
|
+
|
|
138
|
+
export default page({
|
|
139
|
+
static: true, // capture as HTML at release
|
|
140
|
+
title: "Mado Keyboard",
|
|
141
|
+
head: () => ({ description: "A canonical product page." }),
|
|
142
|
+
view: () => html`<h1>Welcome</h1>`,
|
|
143
|
+
});
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Routing — explicit, code-split
|
|
147
|
+
|
|
148
|
+
```ts
|
|
149
|
+
import { routes, routeUrl } from "@madojs/mado";
|
|
176
150
|
|
|
177
151
|
export default routes({
|
|
178
|
-
"/":
|
|
179
|
-
"/users/:id":
|
|
180
|
-
"*":
|
|
152
|
+
"/": () => import("./pages/home.page"),
|
|
153
|
+
"/users/:id": () => import("./pages/user.page"),
|
|
154
|
+
"*": () => import("./pages/not-found.page"),
|
|
181
155
|
});
|
|
156
|
+
|
|
157
|
+
// Internal links must be base-aware.
|
|
158
|
+
html`<a data-link href=${routeUrl("/users/42")}>User</a>`;
|
|
182
159
|
```
|
|
183
160
|
|
|
184
|
-
Lazy loading, layout groups, query params, guards, hover prefetch,
|
|
185
|
-
restoration, error boundary, View Transitions
|
|
161
|
+
Lazy loading, layout groups, query params, guards, hover prefetch,
|
|
162
|
+
scroll restoration, error boundary, View Transitions, base-path
|
|
163
|
+
awareness (Vite `base` → runtime `import.meta.env.BASE_URL`).
|
|
186
164
|
|
|
187
165
|
### Data — resource + mutation
|
|
188
166
|
|
|
189
167
|
```ts
|
|
190
|
-
import { resource, mutation,
|
|
168
|
+
import { resource, mutation, jsonFetcher } from "@madojs/mado";
|
|
191
169
|
|
|
192
170
|
const user = resource(
|
|
193
171
|
() => `/api/users/${userId()}`,
|
|
@@ -203,104 +181,110 @@ const save = mutation(api.saveUser, {
|
|
|
203
181
|
Cache, loading/error state, abort, refresh, optimistic `mutate()`,
|
|
204
182
|
glob-based invalidation. Lifecycle-aware inside components.
|
|
205
183
|
|
|
206
|
-
|
|
207
|
-
and data shape; two resources with the same key share cached data and in-flight
|
|
208
|
-
requests.
|
|
209
|
-
|
|
210
|
-
### Forms — schema-based validation
|
|
184
|
+
### Forms — browser constraint validation
|
|
211
185
|
|
|
212
186
|
```ts
|
|
213
187
|
import { useForm, html } from "@madojs/mado";
|
|
214
188
|
|
|
215
189
|
const form = useForm({
|
|
216
|
-
|
|
217
|
-
age: { type: "number", min: 18 },
|
|
190
|
+
initial: { email: "", age: "" as number | "" },
|
|
218
191
|
});
|
|
219
192
|
|
|
220
|
-
html
|
|
221
|
-
<
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
`;
|
|
193
|
+
html`<form @submit=${form.onSubmit(save)}>
|
|
194
|
+
<input name="email" type="email" required @input=${form.onInput} />
|
|
195
|
+
<input name="age" type="number" min="18" @input=${form.onInput} />
|
|
196
|
+
<button type="submit">Save</button>
|
|
197
|
+
</form>`;
|
|
226
198
|
```
|
|
227
199
|
|
|
228
|
-
HTML
|
|
229
|
-
|
|
200
|
+
HTML owns constraints and keyboard/form semantics; Mado supplies typed values,
|
|
201
|
+
errors, touched/dirty state and abortable async validation.
|
|
230
202
|
|
|
231
|
-
###
|
|
232
|
-
|
|
233
|
-
```ts
|
|
234
|
-
import { each } from "@madojs/mado";
|
|
235
|
-
|
|
236
|
-
html`<ul>${() => each(items(), (item) => item.id, (item) => html`<li>${item.name}</li>`)}</ul>`;
|
|
237
|
-
```
|
|
238
|
-
|
|
239
|
-
### Static prerender — SEO without SSR
|
|
203
|
+
### Static snapshots — SEO without SSR
|
|
240
204
|
|
|
241
205
|
```bash
|
|
242
206
|
mado release
|
|
243
207
|
```
|
|
244
208
|
|
|
245
|
-
|
|
246
|
-
|
|
209
|
+
`mado release` runs your app in a real Chromium and freezes the
|
|
210
|
+
rendered HTML — including the Shadow DOM via Declarative Shadow DOM —
|
|
211
|
+
into one file per route. On first paint Mado atomically replaces the
|
|
212
|
+
static tree with the live tree: no hydration protocol, no node
|
|
213
|
+
reconciliation, no per-attribute diffing.
|
|
247
214
|
|
|
248
|
-
|
|
215
|
+
- Real search engines see a fully rendered document.
|
|
216
|
+
- Social preview bots see the canonical / og tags inside the raw HTML.
|
|
217
|
+
- JS-disabled browsers see meaningful content.
|
|
218
|
+
- The live app boots from the same snapshot without re-fetching seeded
|
|
219
|
+
data.
|
|
220
|
+
|
|
221
|
+
## CLI
|
|
249
222
|
|
|
250
223
|
```bash
|
|
251
|
-
mado
|
|
252
|
-
mado
|
|
224
|
+
mado init my-app # scaffold universal starter
|
|
225
|
+
mado init my-app --starter modular # scaffold modular reference architecture
|
|
226
|
+
mado dev # Vite dev server
|
|
227
|
+
mado build # Vite production SPA build
|
|
228
|
+
mado typecheck # tsc --noEmit
|
|
229
|
+
mado static [--base-url …] # low-level snapshot only
|
|
230
|
+
mado release # vite build + snapshots + deployment files
|
|
231
|
+
mado preview # serve out/ like a real static host
|
|
232
|
+
mado new <kind> <path> # scaffold canonical files
|
|
253
233
|
```
|
|
254
234
|
|
|
255
|
-
|
|
256
|
-
|
|
235
|
+
All CLI records share `level`, `scope`, `code`, `message`, `data` and a
|
|
236
|
+
timestamp. Use `--log-level`, `--log-format=pretty|plain|json`,
|
|
237
|
+
`MADO_LOG_LEVEL`, `MADO_LOG_FORMAT` or `NO_COLOR` for automation.
|
|
257
238
|
|
|
258
|
-
##
|
|
239
|
+
## Devtools
|
|
259
240
|
|
|
260
|
-
```
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
mado build # tsc compile (framework/package work)
|
|
264
|
-
mado typecheck # type check without emit
|
|
265
|
-
mado test # run test suite
|
|
266
|
-
mado new module billing # scaffold canonical app files
|
|
267
|
-
mado release # full production build
|
|
268
|
-
mado preview # serve production build locally
|
|
241
|
+
```ts
|
|
242
|
+
import { devtools } from "@madojs/mado/devtools.js";
|
|
243
|
+
devtools.open();
|
|
269
244
|
```
|
|
270
245
|
|
|
271
|
-
|
|
246
|
+
The development-only Shadow DOM overlay is toggled with `Alt+Shift+M` and
|
|
247
|
+
inspects reactivity, components, routing, data and structured diagnostics.
|
|
272
248
|
|
|
273
|
-
|
|
274
|
-
- [Routing](./docs/en/01-routing.md)
|
|
275
|
-
- [Project layout](./docs/en/02-project-layout.md)
|
|
276
|
-
- [Static bake & SEO](./docs/en/03-static-bake.md)
|
|
277
|
-
- [App architecture](./docs/en/10-app-architecture.md)
|
|
278
|
-
- [Layouts](./docs/en/11-layouts.md)
|
|
279
|
-
- [Auth and API](./docs/en/12-auth-and-api.md)
|
|
280
|
-
- [Deployment](./docs/en/13-deployment.md)
|
|
281
|
-
- [Testing](./docs/en/14-testing.md)
|
|
282
|
-
- [Error handling](./docs/en/15-error-handling.md)
|
|
283
|
-
- [For backend developers](./docs/en/06-for-backenders.md)
|
|
284
|
-
- [Why Mado (detailed comparison)](./docs/en/05-why-mado.md)
|
|
285
|
-
|
|
286
|
-
Localized docs: [French](./docs/fr/README.md) · [Ukrainian](./docs/uk/README.md) · [Russian](./docs/ru/README.md)
|
|
249
|
+
## Honest boundaries
|
|
287
250
|
|
|
288
|
-
|
|
251
|
+
- No server renderer.
|
|
252
|
+
- No hydration protocol.
|
|
253
|
+
- No framework compiler.
|
|
254
|
+
- No runtime dependencies.
|
|
255
|
+
- No built-in backend.
|
|
256
|
+
- No UI-kit marketplace.
|
|
257
|
+
- Modern evergreen browsers only.
|
|
258
|
+
- A compatible Chromium is required at release time for static routes.
|
|
259
|
+
- Static `paths()` and `initialData()` callbacks must be browser-safe
|
|
260
|
+
and secret-free (they run during discovery AND ship in the client
|
|
261
|
+
bundle).
|
|
289
262
|
|
|
290
|
-
##
|
|
263
|
+
## Why teams pick Mado
|
|
291
264
|
|
|
292
|
-
|
|
293
|
-
|
|
265
|
+
| What matters to you | Best choice |
|
|
266
|
+
|---|---|
|
|
267
|
+
| Largest ecosystem, most hires available | React or Vue |
|
|
268
|
+
| Reusable design-system components across host frameworks | Lit |
|
|
269
|
+
| Maximum rendering performance, JSX workflow | Solid or Svelte 5 |
|
|
270
|
+
| Progressive enhancement of server-rendered pages | htmx + your backend |
|
|
271
|
+
| One component model for sites and apps with calm maintenance | **Mado** |
|
|
294
272
|
|
|
295
|
-
##
|
|
273
|
+
## Production
|
|
296
274
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
275
|
+
```bash
|
|
276
|
+
mado release # typecheck + vite build + static snapshots + deployment files
|
|
277
|
+
mado preview # serve out/ like a real static host
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
One command, one artifact (`out/`). Upload anywhere: VPS, Cloudflare
|
|
281
|
+
Pages, GitHub Pages (with base), any static CDN.
|
|
282
|
+
|
|
283
|
+
## Documentation
|
|
284
|
+
|
|
285
|
+
Canonical docs (English) live in [`docs/en/`](./docs/en/README.md).
|
|
286
|
+
|
|
287
|
+
AI-agent entrypoints: [AGENTS.md](./AGENTS.md) · [llms.txt](./llms.txt)
|
|
304
288
|
|
|
305
289
|
## Tests
|
|
306
290
|
|
|
@@ -312,15 +296,16 @@ npm run size
|
|
|
312
296
|
npm run package:smoke
|
|
313
297
|
```
|
|
314
298
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
299
|
+
The full snapshot + takeover round-trip and the base-path contract
|
|
300
|
+
are required CI gates (`.github/workflows/ci.yml → static-snapshot`),
|
|
301
|
+
run under a pinned Playwright-managed Chromium with
|
|
302
|
+
`MADO_REQUIRE_BROWSER=1` so they never silently skip on PRs.
|
|
318
303
|
|
|
319
304
|
## Contributing
|
|
320
305
|
|
|
321
306
|
Read [CONTRIBUTING.md](./CONTRIBUTING.md). Bug fixes with tests, docs
|
|
322
|
-
improvements, examples and carefully discussed core changes are
|
|
323
|
-
Runtime dependencies are not.
|
|
307
|
+
improvements, examples and carefully discussed core changes are
|
|
308
|
+
welcome. Runtime dependencies are not.
|
|
324
309
|
|
|
325
310
|
## License
|
|
326
311
|
|
package/dist/src/component.d.ts
CHANGED
|
@@ -12,8 +12,9 @@
|
|
|
12
12
|
* The returned render function is called via an effect, so any signals
|
|
13
13
|
* read inside it automatically re-render the template.
|
|
14
14
|
*
|
|
15
|
-
* Shadow DOM (open) is used by default. It can be disabled
|
|
16
|
-
* styles will be scoped via @scope
|
|
15
|
+
* Shadow DOM (open, serializable) is used by default. It can be disabled for
|
|
16
|
+
* advanced integration cases, and styles will be scoped via @scope
|
|
17
|
+
* (or a tag-prefix fallback).
|
|
17
18
|
*/
|
|
18
19
|
import { type Signal, type Disposer } from "./signal.js";
|
|
19
20
|
import { html } from "./html/template.js";
|
|
@@ -33,7 +34,8 @@ export interface ComponentContext {
|
|
|
33
34
|
* No MutationObserver boilerplate needed. The signal updates via a
|
|
34
35
|
* per-instance MutationObserver registered during setup().
|
|
35
36
|
*/
|
|
36
|
-
attr(name: string
|
|
37
|
+
attr(name: string): Signal<string | null>;
|
|
38
|
+
attr(name: string, defaultValue: string): Signal<string>;
|
|
37
39
|
}
|
|
38
40
|
export type SetupFn = (ctx: ComponentContext) => () => TemplateResult;
|
|
39
41
|
export type StyleInput = string | CSSResult | Array<string | CSSResult>;
|
|
@@ -50,3 +52,4 @@ export interface ComponentOptions {
|
|
|
50
52
|
}
|
|
51
53
|
export declare function component(tagName: string, setup: SetupFn, options?: ComponentOptions): void;
|
|
52
54
|
export { html };
|
|
55
|
+
//# sourceMappingURL=component.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../../src/component.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAkB,KAAK,MAAM,EAAE,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAC;AACzE,OAAO,EAAE,IAAI,EAAmB,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAIL,KAAK,SAAS,EACf,MAAM,UAAU,CAAC;AAyFlB,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,WAAW,CAAC;IAClB,iDAAiD;IACjD,SAAS,CAAC,EAAE,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC9B;;;;;;;;;OASG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC1C,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;CAC1D;AAED,MAAM,MAAM,OAAO,GAAG,CAAC,GAAG,EAAE,gBAAgB,KAAK,MAAM,cAAc,CAAC;AAEtE,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,SAAS,GAAG,KAAK,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;AAExE,MAAM,WAAW,gBAAgB;IAC/B,yCAAyC;IACzC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB;AAED,wBAAgB,SAAS,CACvB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,OAAO,EACd,OAAO,GAAE,gBAAqB,GAC7B,IAAI,CAmMN;AA8CD,OAAO,EAAE,IAAI,EAAE,CAAC"}
|