@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
|
@@ -195,14 +195,13 @@ We register the `<x-counter>` tag in the browser — it becomes a "function" tha
|
|
|
195
195
|
|
|
196
196
|
## Forms — like `form.Validate()` on the backend
|
|
197
197
|
|
|
198
|
-
Mado uses **
|
|
198
|
+
Mado uses the browser's **constraint validation** and adds reactive state tracking.
|
|
199
199
|
|
|
200
200
|
```ts
|
|
201
201
|
import { useForm } from "@madojs/mado";
|
|
202
202
|
|
|
203
203
|
const f = useForm({
|
|
204
|
-
|
|
205
|
-
age: { required: true, type: "number", min: 18 },
|
|
204
|
+
initial: { email: "", age: "" as number | "" },
|
|
206
205
|
});
|
|
207
206
|
|
|
208
207
|
// in the template:
|
|
@@ -215,6 +214,8 @@ html`
|
|
|
215
214
|
>
|
|
216
215
|
<input
|
|
217
216
|
name="email"
|
|
217
|
+
type="email"
|
|
218
|
+
required
|
|
218
219
|
.value=${() => f.values().email ?? ""}
|
|
219
220
|
@input=${f.onInput}
|
|
220
221
|
@blur=${f.onBlur}
|
|
@@ -225,12 +226,13 @@ html`
|
|
|
225
226
|
? html`<small>${f.errors().email}</small>`
|
|
226
227
|
: null}
|
|
227
228
|
|
|
228
|
-
<
|
|
229
|
+
<input name="age" type="number" min="18" @input=${f.onInput} />
|
|
230
|
+
<button type="submit" ?disabled=${() => !f.isValid() || f.submitting()}>Save</button>
|
|
229
231
|
</form>
|
|
230
232
|
`;
|
|
231
233
|
```
|
|
232
234
|
|
|
233
|
-
Custom validation — `validate: (values) => errors | null`. No Yup schemas or dependencies.
|
|
235
|
+
Custom validation — `validate: (values, { signal }) => errors | null`. No Yup schemas or dependencies.
|
|
234
236
|
|
|
235
237
|
---
|
|
236
238
|
|
|
@@ -258,24 +260,25 @@ component("x-page", ({ host }) => {
|
|
|
258
260
|
```
|
|
259
261
|
|
|
260
262
|
This is like `context.WithValue` / `ctx.Value` in Go, but reactive.
|
|
263
|
+
The transport is the interoperable Web Components `context-request` event, so
|
|
264
|
+
providers and consumers can cross library boundaries.
|
|
261
265
|
|
|
262
266
|
---
|
|
263
267
|
|
|
264
|
-
## SEO — not SSR, but
|
|
268
|
+
## SEO — not SSR, but static snapshots (like `templ generate` in Go)
|
|
265
269
|
|
|
266
|
-
If you're used to server-side rendering for SEO, in Mado this is solved differently: **prerender at build time**.
|
|
270
|
+
If you're used to server-side rendering for SEO, in Mado this is solved differently: **browser-rendered prerender at build time**.
|
|
267
271
|
|
|
268
272
|
```ts
|
|
269
273
|
// src/modules/<module>/pages/product.ts
|
|
270
274
|
export default page({
|
|
271
|
-
|
|
272
|
-
paths: () => api.allProductSlugs(),
|
|
273
|
-
|
|
274
|
-
revalidate: 3600,
|
|
275
|
+
static: {
|
|
276
|
+
paths: () => api.allProductSlugs(), // build-time fetch
|
|
277
|
+
initialData: ({ slug }) => api.getProduct(slug),
|
|
275
278
|
},
|
|
276
|
-
head: (
|
|
279
|
+
head: (_, data) => ({
|
|
277
280
|
description: data.description,
|
|
278
|
-
canonical: `/product/${slug}`,
|
|
281
|
+
canonical: `/product/${data.slug}`,
|
|
279
282
|
og: { title: data.name, image: data.image },
|
|
280
283
|
}),
|
|
281
284
|
view: ({ params }) => html`<x-product data-slug=${params.slug} />`,
|
|
@@ -283,12 +286,12 @@ export default page({
|
|
|
283
286
|
```
|
|
284
287
|
|
|
285
288
|
```bash
|
|
286
|
-
npm run
|
|
289
|
+
npm run release # → out/product/iphone-15/index.html (+ sitemap)
|
|
287
290
|
```
|
|
288
291
|
|
|
289
292
|
The crawler sees ready-made HTML with meta tags. The user sees the same thing + interactivity after JS loads.
|
|
290
293
|
|
|
291
|
-
More details: [`
|
|
294
|
+
More details: [`15-static-snapshots.md`](./15-static-snapshots.md).
|
|
292
295
|
|
|
293
296
|
---
|
|
294
297
|
|
|
@@ -336,7 +339,7 @@ const createUser = mutation<NewUser, User>(
|
|
|
336
339
|
);
|
|
337
340
|
|
|
338
341
|
// in page.view:
|
|
339
|
-
const f = useForm({
|
|
342
|
+
const f = useForm({ initial: { name: "" } });
|
|
340
343
|
|
|
341
344
|
html`
|
|
342
345
|
<form
|
|
@@ -345,8 +348,8 @@ html`
|
|
|
345
348
|
navigate("/users");
|
|
346
349
|
})}
|
|
347
350
|
>
|
|
348
|
-
<input name="name" @input=${f.onInput} />
|
|
349
|
-
<button>Create</button>
|
|
351
|
+
<input name="name" required @input=${f.onInput} />
|
|
352
|
+
<button type="submit">Create</button>
|
|
350
353
|
</form>
|
|
351
354
|
`;
|
|
352
355
|
```
|
|
@@ -403,7 +406,8 @@ Module connectors build on this transport and map DTOs to domain types.
|
|
|
403
406
|
|
|
404
407
|
- **Hooks and hook rules.** Not in Mado. Signals are ordinary functions.
|
|
405
408
|
- **VDOM and reconciliation.** None. Signals update the DOM directly, surgically.
|
|
406
|
-
- **Webpack/
|
|
409
|
+
- **Webpack/Babel configs.** Vite is the transport; the starter ships one
|
|
410
|
+
three-line `vite.config.ts` with `mado()`.
|
|
407
411
|
- **`useEffect` dependency arrays.** `effect()` sees what you read on its own.
|
|
408
412
|
- **State management libraries** (Redux/Zustand). Signals + context.
|
|
409
413
|
- **CSS-in-JS transformations.** Shadow DOM + `css\`\`` + cssVars.
|
|
@@ -418,7 +422,7 @@ These are new concepts. Not scary, but they are additions to your React/Vue base
|
|
|
418
422
|
1. **Custom Elements / Shadow DOM.** `<x-foo>` is not a div, it is a full-fledged element with its own DOM. Slots, scoped CSS. One evening of MDN reading.
|
|
419
423
|
2. **`attribute` vs `property`.** Attribute is a string in HTML (`data-id="5"`), property is a JS property (`el.id = 5`). `?attr=${flag}` and `.prop=${value}` in templates refer to different things. Main rule: **numbers/objects/arrays — via `.prop`, flags — via `?attr`, strings — via `attr`**.
|
|
420
424
|
3. **Signals.** If it's your first time — you'll get stuck for 10 minutes, then it's easier than hooks.
|
|
421
|
-
4. **`html\`\``-templates.** It's just a JS function with highlighting via [lit-plugin](./
|
|
425
|
+
4. **`html\`\``-templates.** It's just a JS function with highlighting via [lit-plugin](./01-quickstart.md#4-ide-setup). Not magic.
|
|
422
426
|
|
|
423
427
|
Everything else — standard browser + TypeScript.
|
|
424
428
|
|
|
@@ -426,8 +430,7 @@ Everything else — standard browser + TypeScript.
|
|
|
426
430
|
|
|
427
431
|
## What's missing (honestly)
|
|
428
432
|
|
|
429
|
-
-
|
|
430
|
-
- No browser extension dev-tools. Use `localStorage.madoDebug = '1'` + console.
|
|
433
|
+
- The built-in overlay covers runtime inspection; a browser extension remains post-v1 work.
|
|
431
434
|
- No StackBlitz starters (yet).
|
|
432
435
|
- No AI assistant that knows Mado as well as React. When in doubt — read `src/`, it's not scary.
|
|
433
436
|
|
|
@@ -435,9 +438,9 @@ Everything else — standard browser + TypeScript.
|
|
|
435
438
|
|
|
436
439
|
## Further reading
|
|
437
440
|
|
|
438
|
-
- **[`
|
|
439
|
-
- **[`
|
|
440
|
-
- **[`
|
|
441
|
+
- **[`12-routing.md`](./12-routing.md)** — the router in detail.
|
|
442
|
+
- **[`16-app-architecture.md`](./16-app-architecture.md)** — project structure.
|
|
443
|
+
- **[`15-static-snapshots.md`](./15-static-snapshots.md)** — SEO without SSR.
|
|
441
444
|
- **External `madojs-examples` workspace** — full demos (landing + admin).
|
|
442
445
|
|
|
443
446
|
If something is unclear — open an issue, or just open the source. It really is readable in an evening.
|
|
@@ -39,7 +39,7 @@ If your case does not fall into the last point — Mado is most likely not the b
|
|
|
39
39
|
| Router | none, you need to find one (`@lit-labs/router`, etc) | included: `routes()` + layout groups + prefetch |
|
|
40
40
|
| Data fetching | none, you need to assemble it | `resource()` + `mutation()` + glob invalidation |
|
|
41
41
|
| Forms | none | `useForm()` with HTML-like constraints |
|
|
42
|
-
| SEO / static | complex (`@lit-labs/ssr`) | `
|
|
42
|
+
| SEO / static | complex (`@lit-labs/ssr`) | `mado static` (real Chromium snapshot + DSD) |
|
|
43
43
|
| Build | needs framework-specific build plugins | Vite transport + native runtime |
|
|
44
44
|
| Code style | classes + decorators | functions + tagged templates |
|
|
45
45
|
| Ecosystem | real (Shoelace, Material Web, etc.) | none |
|
|
@@ -138,7 +138,7 @@ I won't dwell on this for long, because React is in a **different weight class**
|
|
|
138
138
|
**Mado wins:**
|
|
139
139
|
|
|
140
140
|
- bundle size dozens of times smaller;
|
|
141
|
-
-
|
|
141
|
+
- one conventional Vite transport without a framework compiler or Babel layer;
|
|
142
142
|
- readable in an evening — if something breaks, open `src/`;
|
|
143
143
|
- signals instead of hooks (no "can't use in an if" rules, no stale-closure traps);
|
|
144
144
|
- no need to migrate between major versions.
|
|
@@ -194,7 +194,7 @@ This is sufficient for most applications. If you're building Excel in the browse
|
|
|
194
194
|
Mado is a **narrow** tool with honest positioning. It is strongest where:
|
|
195
195
|
|
|
196
196
|
1. You want to **own** the code and read it in its entirety.
|
|
197
|
-
2. **Infrastructure simplicity** is critical (no
|
|
197
|
+
2. **Infrastructure simplicity** is critical (one Vite transport, no custom compiler).
|
|
198
198
|
3. You need **batteries in one box** (router + data + forms + SEO).
|
|
199
199
|
4. You are not a junior and are not afraid of Web Components.
|
|
200
200
|
|
package/docs/en/README.md
CHANGED
|
@@ -1,27 +1,99 @@
|
|
|
1
|
-
# Mado
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
|
26
|
-
|
|
|
27
|
-
|
|
|
1
|
+
# Mado documentation
|
|
2
|
+
|
|
3
|
+
> Canonical project documentation. English-only since v0.12.
|
|
4
|
+
|
|
5
|
+
Read top-to-bottom for a complete mental model, or jump to the
|
|
6
|
+
section you need from the matrix below.
|
|
7
|
+
|
|
8
|
+
## Reading paths
|
|
9
|
+
|
|
10
|
+
- **First time here?** Start with [00 — The Mado way](./00-the-mado-way.md)
|
|
11
|
+
and then [01 — Quickstart](./01-quickstart.md).
|
|
12
|
+
- **Already shipped one Mado app?** Skim
|
|
13
|
+
[10 — Pages and components](./10-pages-and-components.md) and
|
|
14
|
+
[30 — API freeze map](./30-api-freeze-map.md).
|
|
15
|
+
- **Coming from React / Vue / Next?**
|
|
16
|
+
[42 — Why Mado](./42-why-mado.md) and
|
|
17
|
+
[40 — LLM guide](./40-llm-guide.md) cover the mental shifts.
|
|
18
|
+
- **Backend developer?** [41 — For backenders](./41-for-backenders.md)
|
|
19
|
+
is the express lane.
|
|
20
|
+
|
|
21
|
+
## Map
|
|
22
|
+
|
|
23
|
+
### Start here
|
|
24
|
+
|
|
25
|
+
| Section | File |
|
|
26
|
+
| ----------------------------- | ------------------------------------------ |
|
|
27
|
+
| The Mado way (philosophy) | [00-the-mado-way.md](./00-the-mado-way.md) |
|
|
28
|
+
| Quickstart | [01-quickstart.md](./01-quickstart.md) |
|
|
29
|
+
|
|
30
|
+
### Concepts (read once)
|
|
31
|
+
|
|
32
|
+
| Section | File |
|
|
33
|
+
| ---------------------------------- | ---------------------------------------------------------- |
|
|
34
|
+
| Pages and components | [10-pages-and-components.md](./10-pages-and-components.md) |
|
|
35
|
+
| Templates and signals | [11-templates-and-signals.md](./11-templates-and-signals.md) |
|
|
36
|
+
| Routing | [12-routing.md](./12-routing.md) |
|
|
37
|
+
| Data — `resource()` / `mutation()` | [13-data.md](./13-data.md) |
|
|
38
|
+
| Forms | [14-forms.md](./14-forms.md) |
|
|
39
|
+
| Static snapshots | [15-static-snapshots.md](./15-static-snapshots.md) |
|
|
40
|
+
| App architecture | [16-app-architecture.md](./16-app-architecture.md) |
|
|
41
|
+
|
|
42
|
+
### Production
|
|
43
|
+
|
|
44
|
+
| Section | File |
|
|
45
|
+
| ------------------ | ---------------------------------------------- |
|
|
46
|
+
| Deployment | [20-deployment.md](./20-deployment.md) |
|
|
47
|
+
| Error handling | [21-error-handling.md](./21-error-handling.md) |
|
|
48
|
+
| Testing | [22-testing.md](./22-testing.md) |
|
|
49
|
+
| Cookbook | [23-cookbook.md](./23-cookbook.md) |
|
|
50
|
+
| Devtools and diagnostics | [24-devtools-and-diagnostics.md](./24-devtools-and-diagnostics.md) |
|
|
51
|
+
|
|
52
|
+
### Reference
|
|
53
|
+
|
|
54
|
+
| Section | File |
|
|
55
|
+
| ---------------------- | ---------------------------------------------------------- |
|
|
56
|
+
| API freeze map | [30-api-freeze-map.md](./30-api-freeze-map.md) |
|
|
57
|
+
| Reactivity ordering | [31-reactivity-ordering.md](./31-reactivity-ordering.md) |
|
|
58
|
+
| v1 stability contract | [32-v1-stability.md](./32-v1-stability.md) |
|
|
59
|
+
| Migration 0.12 → 0.13 | [33-migration-0.12-0.13.md](./33-migration-0.12-0.13.md) |
|
|
60
|
+
|
|
61
|
+
### Meta
|
|
62
|
+
|
|
63
|
+
| Section | File |
|
|
64
|
+
| ------------------------------------------------------ | ------------------------------------------ |
|
|
65
|
+
| LLM guide (pitfalls + zero-history test) | [40-llm-guide.md](./40-llm-guide.md) |
|
|
66
|
+
| For backenders | [41-for-backenders.md](./41-for-backenders.md) |
|
|
67
|
+
| Why Mado vs Lit / Solid / Svelte / htmx / React | [42-why-mado.md](./42-why-mado.md) |
|
|
68
|
+
|
|
69
|
+
## Migrating from v0.11.x doc layout
|
|
70
|
+
|
|
71
|
+
The 0.12 release reorganised `docs/en/` into the groups above and
|
|
72
|
+
collapsed several overlapping files. Old → new map:
|
|
73
|
+
|
|
74
|
+
<!-- docs-lint:allow-legacy-mention -->
|
|
75
|
+
|
|
76
|
+
| Old (v0.11.x) | New (v0.12) |
|
|
77
|
+
| ----------------------------------- | ---------------------------------------------------------- |
|
|
78
|
+
| `01-routing.md` | `12-routing.md` |
|
|
79
|
+
| `02-project-layout.md` | merged into `16-app-architecture.md` |
|
|
80
|
+
| `03-static-bake.md` | `15-static-snapshots.md` |
|
|
81
|
+
| `04-ide-setup.md` | merged into `01-quickstart.md` |
|
|
82
|
+
| `05-why-mado.md` | `42-why-mado.md` |
|
|
83
|
+
| `06-for-backenders.md` | `41-for-backenders.md` |
|
|
84
|
+
| `07-llm-pitfalls.md` | merged into `40-llm-guide.md` |
|
|
85
|
+
| `08-llm-zero-history-test.md` | merged into `40-llm-guide.md` |
|
|
86
|
+
| `09-shadow-vs-light-dom.md` | replaced by `10-pages-and-components.md` |
|
|
87
|
+
| `10-app-architecture.md` | `16-app-architecture.md` |
|
|
88
|
+
| `11-layouts.md` | merged into `12-routing.md` |
|
|
89
|
+
| `12-auth-and-api.md` | merged into `13-data.md` |
|
|
90
|
+
| `13-deployment.md` | `20-deployment.md` |
|
|
91
|
+
| `14-testing.md` | `22-testing.md` |
|
|
92
|
+
| `15-error-handling.md` | `21-error-handling.md` |
|
|
93
|
+
| `16-bake-cookbook.md` | `23-cookbook.md` |
|
|
94
|
+
| `17-shadow-dom-forms.md` | merged into `14-forms.md` |
|
|
95
|
+
| `18-api-freeze-map.md` | `30-api-freeze-map.md` |
|
|
96
|
+
| `19-reactivity-ordering.md` | `31-reactivity-ordering.md` |
|
|
97
|
+
| `20-v1-stability.md` | `32-v1-stability.md` |
|
|
98
|
+
|
|
99
|
+
<!-- /docs-lint:allow-legacy-mention -->
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Optional generated-app container recipe.
|
|
2
|
+
#
|
|
3
|
+
# Usage from your app root after copying this directory to ./docker:
|
|
4
|
+
# docker build -f docker/Containerfile -t myapp .
|
|
5
|
+
|
|
6
|
+
FROM node:24-alpine AS builder
|
|
7
|
+
WORKDIR /app
|
|
8
|
+
|
|
9
|
+
COPY package.json package-lock.json* pnpm-lock.yaml* ./
|
|
10
|
+
RUN if [ -f pnpm-lock.yaml ]; then \
|
|
11
|
+
corepack enable && pnpm install --frozen-lockfile; \
|
|
12
|
+
elif [ -f package-lock.json ]; then \
|
|
13
|
+
npm ci; \
|
|
14
|
+
else \
|
|
15
|
+
npm install; \
|
|
16
|
+
fi
|
|
17
|
+
|
|
18
|
+
COPY . .
|
|
19
|
+
RUN npm run release
|
|
20
|
+
|
|
21
|
+
FROM nginx:alpine AS runtime
|
|
22
|
+
COPY docker/nginx.conf /etc/nginx/conf.d/default.conf
|
|
23
|
+
COPY --from=builder /app/out /usr/share/nginx/html
|
|
24
|
+
|
|
25
|
+
EXPOSE 80
|
|
26
|
+
HEALTHCHECK --interval=30s --timeout=3s CMD wget -qO- http://localhost/ >/dev/null || exit 1
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Static nginx config for a Mado app released with `mado release`.
|
|
2
|
+
#
|
|
3
|
+
# Serves:
|
|
4
|
+
# - Vite hashed assets from /assets/ with immutable caching;
|
|
5
|
+
# - precompressed .gz files written by `mado release`;
|
|
6
|
+
# - baked route HTML when present;
|
|
7
|
+
# - _mado/spa.html as the noindex SPA fallback for client-only routes.
|
|
8
|
+
|
|
9
|
+
server {
|
|
10
|
+
listen 80;
|
|
11
|
+
server_name _;
|
|
12
|
+
root /usr/share/nginx/html;
|
|
13
|
+
index index.html;
|
|
14
|
+
|
|
15
|
+
gzip_static on;
|
|
16
|
+
# brotli_static on; # requires ngx_brotli module
|
|
17
|
+
|
|
18
|
+
gzip on;
|
|
19
|
+
gzip_types text/plain text/css application/javascript application/json image/svg+xml;
|
|
20
|
+
gzip_min_length 1024;
|
|
21
|
+
gzip_comp_level 6;
|
|
22
|
+
|
|
23
|
+
location ^~ /assets/ {
|
|
24
|
+
add_header Cache-Control "public, max-age=31536000, immutable";
|
|
25
|
+
try_files $uri =404;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
location ~* \.html$ {
|
|
29
|
+
add_header Cache-Control "no-cache, must-revalidate";
|
|
30
|
+
try_files $uri =404;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
location ~* \.(svg|png|jpe?g|gif|ico|webp|avif|woff2?)$ {
|
|
34
|
+
add_header Cache-Control "public, max-age=86400";
|
|
35
|
+
try_files $uri =404;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
location / {
|
|
39
|
+
add_header Cache-Control "no-cache, must-revalidate";
|
|
40
|
+
try_files $uri $uri/ /_mado/spa.html;
|
|
41
|
+
}
|
|
42
|
+
}
|