@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.
Files changed (298) hide show
  1. package/AGENTS.md +116 -32
  2. package/CHANGELOG.md +216 -1
  3. package/README.md +158 -173
  4. package/dist/src/component.d.ts +6 -3
  5. package/dist/src/component.d.ts.map +1 -0
  6. package/dist/src/component.js +163 -36
  7. package/dist/src/component.js.map +1 -1
  8. package/dist/src/context.d.ts +13 -32
  9. package/dist/src/context.d.ts.map +1 -0
  10. package/dist/src/context.js +73 -48
  11. package/dist/src/context.js.map +1 -1
  12. package/dist/src/css.d.ts +1 -0
  13. package/dist/src/css.d.ts.map +1 -0
  14. package/dist/src/css.js +34 -5
  15. package/dist/src/css.js.map +1 -1
  16. package/dist/src/devtools-hook.d.ts +14 -0
  17. package/dist/src/devtools-hook.d.ts.map +1 -0
  18. package/dist/src/devtools-hook.js +27 -0
  19. package/dist/src/devtools-hook.js.map +1 -0
  20. package/dist/src/devtools.d.ts +24 -22
  21. package/dist/src/devtools.d.ts.map +1 -0
  22. package/dist/src/devtools.js +230 -58
  23. package/dist/src/devtools.js.map +1 -1
  24. package/dist/src/diagnostics.d.ts +12 -0
  25. package/dist/src/diagnostics.d.ts.map +1 -0
  26. package/dist/src/diagnostics.js +68 -8
  27. package/dist/src/diagnostics.js.map +1 -1
  28. package/dist/src/each.d.ts +1 -5
  29. package/dist/src/each.d.ts.map +1 -0
  30. package/dist/src/each.js +0 -8
  31. package/dist/src/each.js.map +1 -1
  32. package/dist/src/forms.d.ts +27 -96
  33. package/dist/src/forms.d.ts.map +1 -0
  34. package/dist/src/forms.js +184 -394
  35. package/dist/src/forms.js.map +1 -1
  36. package/dist/src/head.d.ts +7 -6
  37. package/dist/src/head.d.ts.map +1 -0
  38. package/dist/src/head.js +8 -7
  39. package/dist/src/head.js.map +1 -1
  40. package/dist/src/html/bindings.d.ts +1 -0
  41. package/dist/src/html/bindings.d.ts.map +1 -0
  42. package/dist/src/html/bindings.js.map +1 -1
  43. package/dist/src/html/parser.d.ts +4 -5
  44. package/dist/src/html/parser.d.ts.map +1 -0
  45. package/dist/src/html/parser.js +64 -15
  46. package/dist/src/html/parser.js.map +1 -1
  47. package/dist/src/html/template-types.d.ts +1 -0
  48. package/dist/src/html/template-types.d.ts.map +1 -0
  49. package/dist/src/html/template-types.js.map +1 -1
  50. package/dist/src/html/template.d.ts +5 -1
  51. package/dist/src/html/template.d.ts.map +1 -0
  52. package/dist/src/html/template.js +102 -13
  53. package/dist/src/html/template.js.map +1 -1
  54. package/dist/src/index.d.ts +15 -12
  55. package/dist/src/index.d.ts.map +1 -0
  56. package/dist/src/index.js +18 -10
  57. package/dist/src/index.js.map +1 -1
  58. package/dist/src/json.d.ts +3 -0
  59. package/dist/src/json.d.ts.map +1 -0
  60. package/dist/src/json.js +14 -0
  61. package/dist/src/json.js.map +1 -0
  62. package/dist/src/lifecycle.d.ts +1 -0
  63. package/dist/src/lifecycle.d.ts.map +1 -0
  64. package/dist/src/lifecycle.js +3 -2
  65. package/dist/src/lifecycle.js.map +1 -1
  66. package/dist/src/page.d.ts +63 -28
  67. package/dist/src/page.d.ts.map +1 -0
  68. package/dist/src/page.js +5 -0
  69. package/dist/src/page.js.map +1 -1
  70. package/dist/src/persisted.d.ts +6 -1
  71. package/dist/src/persisted.d.ts.map +1 -0
  72. package/dist/src/persisted.js +17 -11
  73. package/dist/src/persisted.js.map +1 -1
  74. package/dist/src/resource.d.ts +2 -1
  75. package/dist/src/resource.d.ts.map +1 -0
  76. package/dist/src/resource.js +128 -50
  77. package/dist/src/resource.js.map +1 -1
  78. package/dist/src/router/base.d.ts +66 -0
  79. package/dist/src/router/base.d.ts.map +1 -0
  80. package/dist/src/router/base.js +168 -0
  81. package/dist/src/router/base.js.map +1 -0
  82. package/dist/src/router/manifest.d.ts +1 -0
  83. package/dist/src/router/manifest.d.ts.map +1 -0
  84. package/dist/src/router/manifest.js +156 -171
  85. package/dist/src/router/manifest.js.map +1 -1
  86. package/dist/src/router/match.d.ts +17 -2
  87. package/dist/src/router/match.d.ts.map +1 -0
  88. package/dist/src/router/match.js +60 -6
  89. package/dist/src/router/match.js.map +1 -1
  90. package/dist/src/router/navigation.d.ts +1 -0
  91. package/dist/src/router/navigation.d.ts.map +1 -0
  92. package/dist/src/router/navigation.js +58 -9
  93. package/dist/src/router/navigation.js.map +1 -1
  94. package/dist/src/signal.d.ts +1 -0
  95. package/dist/src/signal.d.ts.map +1 -0
  96. package/dist/src/signal.js +46 -17
  97. package/dist/src/signal.js.map +1 -1
  98. package/dist/src/static-runtime.d.ts +82 -0
  99. package/dist/src/static-runtime.d.ts.map +1 -0
  100. package/dist/src/static-runtime.js +209 -0
  101. package/dist/src/static-runtime.js.map +1 -0
  102. package/dist/src/vite/index.d.ts +32 -3
  103. package/dist/src/vite/index.d.ts.map +1 -0
  104. package/dist/src/vite/index.js +49 -17
  105. package/dist/src/vite/index.js.map +1 -1
  106. package/docs/README.md +5 -8
  107. package/docs/architecture/adr/0001-browser-static-snapshots.md +132 -0
  108. package/docs/architecture/v1-roadmap.md +19 -0
  109. package/docs/en/00-the-mado-way.md +1 -1
  110. package/docs/en/01-quickstart.md +183 -0
  111. package/docs/en/10-pages-and-components.md +279 -0
  112. package/docs/en/11-templates-and-signals.md +211 -0
  113. package/docs/en/12-routing.md +229 -0
  114. package/docs/en/13-data.md +227 -0
  115. package/docs/en/14-forms.md +91 -0
  116. package/docs/en/15-static-snapshots.md +181 -0
  117. package/docs/en/{10-app-architecture.md → 16-app-architecture.md} +56 -4
  118. package/docs/en/{13-deployment.md → 20-deployment.md} +79 -17
  119. package/docs/en/{15-error-handling.md → 21-error-handling.md} +9 -6
  120. package/docs/en/{14-testing.md → 22-testing.md} +6 -5
  121. package/docs/en/23-cookbook.md +292 -0
  122. package/docs/en/24-devtools-and-diagnostics.md +45 -0
  123. package/docs/en/{18-api-freeze-map.md → 30-api-freeze-map.md} +17 -9
  124. package/docs/en/{20-v1-stability.md → 32-v1-stability.md} +5 -5
  125. package/docs/en/33-migration-0.12-0.13.md +56 -0
  126. package/docs/en/40-llm-guide.md +774 -0
  127. package/docs/en/{06-for-backenders.md → 41-for-backenders.md} +28 -25
  128. package/docs/en/{05-why-mado.md → 42-why-mado.md} +3 -3
  129. package/docs/en/README.md +99 -27
  130. package/docs/recipes/nginx/Containerfile +26 -0
  131. package/docs/recipes/nginx/nginx.conf +42 -0
  132. package/llms.txt +263 -210
  133. package/package.json +51 -23
  134. package/scripts/clean.mjs +8 -0
  135. package/scripts/cli/generate.mjs +57 -10
  136. package/scripts/cli/help.mjs +13 -5
  137. package/scripts/cli/index.mjs +31 -7
  138. package/scripts/cli/init.mjs +19 -19
  139. package/scripts/cli/release.mjs +38 -83
  140. package/scripts/cli/run.mjs +5 -3
  141. package/scripts/logger.mjs +117 -0
  142. package/scripts/output-guard.mjs +128 -0
  143. package/scripts/preview.mjs +105 -24
  144. package/scripts/static/browser.mjs +695 -0
  145. package/scripts/static/discover.mjs +284 -0
  146. package/scripts/static/output.mjs +141 -0
  147. package/scripts/static/serialize.mjs +212 -0
  148. package/scripts/static/server.mjs +167 -0
  149. package/scripts/static.mjs +205 -0
  150. package/starters/default/README.md +57 -55
  151. package/starters/default/package.json +6 -12
  152. package/starters/default/src/app.routes.ts +20 -33
  153. package/starters/default/src/components/feature-card.component.ts +40 -0
  154. package/starters/default/src/components/live-counter.component.ts +57 -0
  155. package/starters/default/src/content/guides.ts +55 -0
  156. package/starters/default/src/main.ts +9 -13
  157. package/starters/default/src/pages/app.page.ts +41 -0
  158. package/starters/default/src/pages/guide.page.ts +40 -0
  159. package/starters/default/src/pages/home.page.ts +49 -0
  160. package/starters/default/src/pages/not-found.page.ts +18 -0
  161. package/starters/default/src/styles/document.css +39 -0
  162. package/starters/default/src/styles/reset.css +37 -0
  163. package/starters/default/src/styles/tokens.css +30 -0
  164. package/starters/default/src/styles.d.ts +3 -1
  165. package/starters/default/src/vite-env.d.ts +1 -1
  166. package/starters/default/tsconfig.node.json +13 -0
  167. package/starters/default/vite.config.ts +14 -4
  168. package/starters/modular/README.md +142 -0
  169. package/starters/modular/index.html +13 -0
  170. package/starters/modular/package.json +30 -0
  171. package/starters/modular/src/app.routes.ts +39 -0
  172. package/starters/{default → modular}/src/layouts/app-shell.layout.ts +9 -7
  173. package/starters/{default → modular}/src/layouts/auth-shell.layout.ts +3 -3
  174. package/starters/modular/src/main.ts +16 -0
  175. package/starters/{default → modular}/src/modules/auth/login.page.ts +5 -12
  176. package/starters/{default → modular}/src/modules/billing/pages/invoice-detail.page.ts +3 -4
  177. package/starters/{default → modular}/src/modules/billing/pages/invoices-list.page.ts +4 -4
  178. package/starters/{default → modular}/src/modules/home/home.page.ts +5 -7
  179. package/starters/modular/src/modules/home/not-found.page.ts +14 -0
  180. package/starters/{default → modular}/src/shared/styles/reset.css +21 -1
  181. package/starters/modular/src/styles.d.ts +1 -0
  182. package/starters/modular/src/vite-env.d.ts +1 -0
  183. package/starters/modular/tsconfig.json +33 -0
  184. package/starters/modular/tsconfig.node.json +13 -0
  185. package/starters/modular/vite.config.ts +132 -0
  186. package/TODO.md +0 -79
  187. package/dist/src/lazy.d.ts +0 -38
  188. package/dist/src/lazy.js +0 -73
  189. package/dist/src/lazy.js.map +0 -1
  190. package/docs/en/01-routing.md +0 -152
  191. package/docs/en/02-project-layout.md +0 -124
  192. package/docs/en/03-static-bake.md +0 -249
  193. package/docs/en/04-ide-setup.md +0 -162
  194. package/docs/en/07-llm-pitfalls.md +0 -724
  195. package/docs/en/08-llm-zero-history-test.md +0 -56
  196. package/docs/en/09-shadow-vs-light-dom.md +0 -174
  197. package/docs/en/11-layouts.md +0 -113
  198. package/docs/en/12-auth-and-api.md +0 -124
  199. package/docs/en/16-bake-cookbook.md +0 -100
  200. package/docs/en/17-shadow-dom-forms.md +0 -192
  201. package/docs/fr/00-the-mado-way.md +0 -85
  202. package/docs/fr/01-routing.md +0 -120
  203. package/docs/fr/02-project-layout.md +0 -84
  204. package/docs/fr/03-static-bake.md +0 -289
  205. package/docs/fr/04-ide-setup.md +0 -162
  206. package/docs/fr/05-why-mado.md +0 -193
  207. package/docs/fr/06-for-backenders.md +0 -438
  208. package/docs/fr/07-llm-pitfalls.md +0 -625
  209. package/docs/fr/08-llm-zero-history-test.md +0 -38
  210. package/docs/fr/09-shadow-vs-light-dom.md +0 -65
  211. package/docs/fr/10-app-architecture.md +0 -138
  212. package/docs/fr/11-layouts.md +0 -47
  213. package/docs/fr/12-auth-and-api.md +0 -76
  214. package/docs/fr/13-deployment.md +0 -57
  215. package/docs/fr/14-testing.md +0 -41
  216. package/docs/fr/15-error-handling.md +0 -50
  217. package/docs/fr/16-bake-cookbook.md +0 -88
  218. package/docs/fr/17-shadow-dom-forms.md +0 -196
  219. package/docs/fr/18-api-freeze-map.md +0 -63
  220. package/docs/fr/19-reactivity-ordering.md +0 -97
  221. package/docs/fr/20-v1-stability.md +0 -88
  222. package/docs/fr/README.md +0 -27
  223. package/docs/ru/00-the-mado-way.md +0 -84
  224. package/docs/ru/01-routing.md +0 -119
  225. package/docs/ru/02-project-layout.md +0 -84
  226. package/docs/ru/03-static-bake.md +0 -250
  227. package/docs/ru/04-ide-setup.md +0 -144
  228. package/docs/ru/05-why-mado.md +0 -193
  229. package/docs/ru/06-for-backenders.md +0 -428
  230. package/docs/ru/07-llm-pitfalls.md +0 -624
  231. package/docs/ru/08-llm-zero-history-test.md +0 -57
  232. package/docs/ru/09-shadow-vs-light-dom.md +0 -63
  233. package/docs/ru/10-app-architecture.md +0 -152
  234. package/docs/ru/11-layouts.md +0 -47
  235. package/docs/ru/12-auth-and-api.md +0 -75
  236. package/docs/ru/13-deployment.md +0 -66
  237. package/docs/ru/14-testing.md +0 -50
  238. package/docs/ru/15-error-handling.md +0 -56
  239. package/docs/ru/16-bake-cookbook.md +0 -95
  240. package/docs/ru/17-shadow-dom-forms.md +0 -193
  241. package/docs/ru/18-api-freeze-map.md +0 -64
  242. package/docs/ru/19-reactivity-ordering.md +0 -95
  243. package/docs/ru/20-v1-stability.md +0 -82
  244. package/docs/ru/README.md +0 -25
  245. package/docs/uk/00-the-mado-way.md +0 -82
  246. package/docs/uk/01-routing.md +0 -76
  247. package/docs/uk/02-project-layout.md +0 -73
  248. package/docs/uk/03-static-bake.md +0 -48
  249. package/docs/uk/04-ide-setup.md +0 -26
  250. package/docs/uk/05-why-mado.md +0 -34
  251. package/docs/uk/06-for-backenders.md +0 -55
  252. package/docs/uk/07-llm-pitfalls.md +0 -145
  253. package/docs/uk/08-llm-zero-history-test.md +0 -34
  254. package/docs/uk/09-shadow-vs-light-dom.md +0 -58
  255. package/docs/uk/10-app-architecture.md +0 -97
  256. package/docs/uk/11-layouts.md +0 -47
  257. package/docs/uk/12-auth-and-api.md +0 -70
  258. package/docs/uk/13-deployment.md +0 -40
  259. package/docs/uk/14-testing.md +0 -34
  260. package/docs/uk/15-error-handling.md +0 -32
  261. package/docs/uk/16-bake-cookbook.md +0 -36
  262. package/docs/uk/17-shadow-dom-forms.md +0 -193
  263. package/docs/uk/18-api-freeze-map.md +0 -61
  264. package/docs/uk/19-reactivity-ordering.md +0 -95
  265. package/docs/uk/20-v1-stability.md +0 -83
  266. package/docs/uk/README.md +0 -27
  267. package/scripts/bake.mjs +0 -570
  268. package/scripts/package-smoke.mjs +0 -77
  269. package/scripts/release-notes.mjs +0 -66
  270. package/scripts/size-budget.mjs +0 -91
  271. package/starters/default/src/modules/home/not-found.page.ts +0 -11
  272. package/starters/default/src/shared/ui/x-button.component.ts +0 -49
  273. /package/docs/en/{19-reactivity-ordering.md → 31-reactivity-ordering.md} +0 -0
  274. /package/starters/{default → modular}/.editorconfig +0 -0
  275. /package/starters/{default → modular}/eslint.config.mjs +0 -0
  276. /package/starters/{default → modular}/public/favicon.svg +0 -0
  277. /package/starters/{default → modular}/src/modules/auth/_contracts/auth-api.types.ts +0 -0
  278. /package/starters/{default → modular}/src/modules/auth/auth.connector.ts +0 -0
  279. /package/starters/{default → modular}/src/modules/auth/auth.guard.ts +0 -0
  280. /package/starters/{default → modular}/src/modules/auth/auth.public.ts +0 -0
  281. /package/starters/{default → modular}/src/modules/auth/auth.routes.ts +0 -0
  282. /package/starters/{default → modular}/src/modules/auth/auth.service.ts +0 -0
  283. /package/starters/{default → modular}/src/modules/auth/auth.types.ts +0 -0
  284. /package/starters/{default → modular}/src/modules/billing/_contracts/stripe.types.ts +0 -0
  285. /package/starters/{default → modular}/src/modules/billing/api/stripe.connector.ts +0 -0
  286. /package/starters/{default → modular}/src/modules/billing/billing.public.ts +0 -0
  287. /package/starters/{default → modular}/src/modules/billing/billing.routes.ts +0 -0
  288. /package/starters/{default → modular}/src/modules/billing/billing.types.ts +0 -0
  289. /package/starters/{default → modular}/src/modules/billing/components/invoice-status-badge.component.ts +0 -0
  290. /package/starters/{default → modular}/src/modules/billing/data/invoices.resource.ts +0 -0
  291. /package/starters/{default → modular}/src/shared/http/http-client.ts +0 -0
  292. /package/starters/{default → modular}/src/shared/http/http-error.ts +0 -0
  293. /package/starters/{default → modular}/src/shared/http/interceptors.ts +0 -0
  294. /package/starters/{default → modular}/src/shared/lib/format-date.ts +0 -0
  295. /package/starters/{default → modular}/src/shared/styles/content.css +0 -0
  296. /package/starters/{default → modular}/src/shared/styles/shell.css +0 -0
  297. /package/starters/{default → modular}/src/shared/styles/tokens.css +0 -0
  298. /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 **schema-based validation close to native HTML constraints**, plus adds state tracking.
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
- email: { required: true, type: "email" },
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
- <button ?disabled=${() => !f.isValid() || f.submitting()}>Save</button>
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 `bake` (like `templ generate` in Go)
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
- bake: {
272
- paths: () => api.allProductSlugs(), // build-time fetch
273
- data: ({ slug }) => api.getProduct(slug),
274
- revalidate: 3600,
275
+ static: {
276
+ paths: () => api.allProductSlugs(), // build-time fetch
277
+ initialData: ({ slug }) => api.getProduct(slug),
275
278
  },
276
- head: ({ slug }, data) => ({
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 bake # → out/product/iphone-15/index.html (+ sitemap)
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: [`03-static-bake.md`](./03-static-bake.md).
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({ name: { required: true } });
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/Vite configs.** No build. `tsc browser`.
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](./04-ide-setup.md). Not magic.
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
- - No hot reload, only full reload via SSE. Sufficient for most cases, but not like Vite.
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
- - **[`01-routing.md`](./01-routing.md)** — the router in detail.
439
- - **[`02-project-layout.md`](./02-project-layout.md)** — project structure.
440
- - **[`03-static-bake.md`](./03-static-bake.md)** — SEO without SSR.
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`) | `bake` (linkedom) + edge-prerender |
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
- - zero infrastructure (no Vite, no Babel, no 200 packages);
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 Vite/Webpack/Babel).
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 docs — English
2
-
3
- English documentation set.
4
-
5
- | Section | Source |
6
- | ----------------------- | ------------------------------------------------------------ |
7
- | The Mado way | [00-the-mado-way.md](./00-the-mado-way.md) |
8
- | Routing | [01-routing.md](./01-routing.md) |
9
- | Project layout | [02-project-layout.md](./02-project-layout.md) |
10
- | Static bake & SEO | [03-static-bake.md](./03-static-bake.md) |
11
- | IDE setup | [04-ide-setup.md](./04-ide-setup.md) |
12
- | Why Mado | [05-why-mado.md](./05-why-mado.md) |
13
- | For backenders | [06-for-backenders.md](./06-for-backenders.md) |
14
- | LLM pitfalls | [07-llm-pitfalls.md](./07-llm-pitfalls.md) |
15
- | LLM zero-history test | [08-llm-zero-history-test.md](./08-llm-zero-history-test.md) |
16
- | Shadow DOM vs Light DOM | [09-shadow-vs-light-dom.md](./09-shadow-vs-light-dom.md) |
17
- | App architecture | [10-app-architecture.md](./10-app-architecture.md) |
18
- | Layouts | [11-layouts.md](./11-layouts.md) |
19
- | Auth and API | [12-auth-and-api.md](./12-auth-and-api.md) |
20
- | Deployment | [13-deployment.md](./13-deployment.md) |
21
- | Testing | [14-testing.md](./14-testing.md) |
22
- | Error handling | [15-error-handling.md](./15-error-handling.md) |
23
- | Bake cookbook | [16-bake-cookbook.md](./16-bake-cookbook.md) |
24
- | Shadow DOM + Forms | [17-shadow-dom-forms.md](./17-shadow-dom-forms.md) |
25
- | API freeze map | [18-api-freeze-map.md](./18-api-freeze-map.md) |
26
- | Reactivity ordering | [19-reactivity-ordering.md](./19-reactivity-ordering.md) |
27
- | v1 stability | [20-v1-stability.md](./20-v1-stability.md) |
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
+ }