@madojs/mado 0.10.1 → 0.11.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 +24 -26
- package/CHANGELOG.md +68 -0
- package/README.md +18 -45
- package/TODO.md +52 -48
- package/dist/src/component.d.ts +2 -1
- package/dist/src/component.js +5 -2
- package/dist/src/component.js.map +1 -1
- package/dist/src/each.d.ts +1 -1
- package/dist/src/each.js +1 -1
- package/dist/src/each.js.map +1 -1
- package/dist/src/index.d.ts +11 -6
- package/dist/src/index.js +5 -3
- package/dist/src/index.js.map +1 -1
- package/dist/src/lazy.d.ts +1 -1
- package/dist/src/lazy.js +1 -1
- package/dist/src/lazy.js.map +1 -1
- package/dist/src/page.d.ts +17 -21
- package/dist/src/page.js +7 -12
- package/dist/src/page.js.map +1 -1
- package/dist/src/router/manifest.d.ts +1 -1
- package/dist/src/router/manifest.js +21 -13
- package/dist/src/router/manifest.js.map +1 -1
- package/dist/src/router/match.d.ts +2 -2
- package/dist/src/router/match.js +3 -3
- package/dist/src/router/match.js.map +1 -1
- package/dist/src/router/navigation.js +1 -1
- package/dist/src/router/navigation.js.map +1 -1
- package/dist/src/vite/index.d.ts +10 -0
- package/dist/src/vite/index.js +33 -0
- package/dist/src/vite/index.js.map +1 -0
- package/docs/en/00-the-mado-way.md +25 -12
- package/docs/en/01-routing.md +90 -142
- package/docs/en/02-project-layout.md +59 -53
- package/docs/en/03-static-bake.md +5 -6
- package/docs/en/05-why-mado.md +6 -6
- package/docs/en/06-for-backenders.md +18 -22
- package/docs/en/08-llm-zero-history-test.md +9 -14
- package/docs/en/09-shadow-vs-light-dom.md +28 -36
- package/docs/en/10-app-architecture.md +158 -96
- package/docs/en/11-layouts.md +22 -24
- package/docs/en/12-auth-and-api.md +89 -182
- package/docs/en/13-deployment.md +18 -22
- package/docs/en/14-testing.md +4 -4
- package/docs/en/16-bake-cookbook.md +11 -12
- package/docs/en/18-api-freeze-map.md +6 -4
- package/docs/en/20-v1-stability.md +1 -1
- package/docs/fr/00-the-mado-way.md +55 -90
- package/docs/fr/01-routing.md +70 -152
- package/docs/fr/02-project-layout.md +61 -42
- package/docs/fr/03-static-bake.md +1 -1
- package/docs/fr/05-why-mado.md +6 -6
- package/docs/fr/06-for-backenders.md +7 -7
- package/docs/fr/08-llm-zero-history-test.md +21 -48
- package/docs/fr/09-shadow-vs-light-dom.md +43 -162
- package/docs/fr/10-app-architecture.md +110 -33
- package/docs/fr/11-layouts.md +24 -12
- package/docs/fr/12-auth-and-api.md +63 -22
- package/docs/fr/13-deployment.md +7 -10
- package/docs/fr/14-testing.md +1 -1
- package/docs/fr/16-bake-cookbook.md +2 -2
- package/docs/fr/18-api-freeze-map.md +1 -1
- package/docs/fr/20-v1-stability.md +1 -1
- package/docs/recipes/nginx/README.md +13 -0
- package/docs/ru/00-the-mado-way.md +53 -75
- package/docs/ru/01-routing.md +68 -143
- package/docs/ru/02-project-layout.md +61 -41
- package/docs/ru/03-static-bake.md +2 -2
- package/docs/ru/05-why-mado.md +6 -6
- package/docs/ru/06-for-backenders.md +7 -7
- package/docs/ru/08-llm-zero-history-test.md +9 -14
- package/docs/ru/09-shadow-vs-light-dom.md +43 -178
- package/docs/ru/10-app-architecture.md +115 -63
- package/docs/ru/11-layouts.md +24 -24
- package/docs/ru/12-auth-and-api.md +57 -35
- package/docs/ru/13-deployment.md +7 -11
- package/docs/ru/14-testing.md +1 -1
- package/docs/ru/16-bake-cookbook.md +12 -6
- package/docs/ru/18-api-freeze-map.md +5 -3
- package/docs/ru/20-v1-stability.md +1 -1
- package/docs/uk/00-the-mado-way.md +70 -44
- package/docs/uk/01-routing.md +41 -47
- package/docs/uk/02-project-layout.md +68 -41
- package/docs/uk/03-static-bake.md +1 -2
- package/docs/uk/06-for-backenders.md +3 -3
- package/docs/uk/08-llm-zero-history-test.md +22 -24
- package/docs/uk/09-shadow-vs-light-dom.md +37 -86
- package/docs/uk/10-app-architecture.md +72 -31
- package/docs/uk/11-layouts.md +25 -12
- package/docs/uk/12-auth-and-api.md +58 -22
- package/docs/uk/13-deployment.md +4 -3
- package/docs/uk/14-testing.md +1 -1
- package/docs/uk/18-api-freeze-map.md +1 -1
- package/docs/uk/20-v1-stability.md +1 -1
- package/llms.txt +14 -15
- package/package.json +18 -11
- package/scripts/_config.mjs +15 -161
- package/scripts/bake.mjs +67 -57
- package/scripts/cli/generate.mjs +348 -0
- package/scripts/cli/help.mjs +27 -0
- package/scripts/cli/index.mjs +79 -0
- package/scripts/cli/init.mjs +153 -0
- package/scripts/cli/release.mjs +152 -0
- package/scripts/cli/run.mjs +96 -0
- package/scripts/cli.mjs +2 -621
- package/scripts/package-smoke.mjs +4 -1
- package/scripts/preview.mjs +13 -37
- package/scripts/size-budget.mjs +5 -2
- package/scripts/vite.default.mjs +11 -0
- package/starters/default/.editorconfig +12 -0
- package/starters/default/README.md +74 -0
- package/starters/default/eslint.config.mjs +256 -0
- package/starters/default/index.html +13 -0
- package/starters/default/package.json +30 -0
- package/starters/default/public/favicon.svg +4 -0
- package/starters/default/src/app.routes.ts +39 -0
- package/starters/default/src/layouts/app-shell.layout.ts +35 -0
- package/starters/default/src/layouts/auth-shell.layout.ts +17 -0
- package/starters/default/src/main.ts +16 -0
- package/starters/default/src/modules/auth/_contracts/auth-api.types.ts +17 -0
- package/starters/default/src/modules/auth/auth.connector.ts +45 -0
- package/starters/default/src/modules/auth/auth.guard.ts +22 -0
- package/starters/default/src/modules/auth/auth.public.ts +9 -0
- package/starters/default/src/modules/auth/auth.routes.ts +8 -0
- package/starters/default/src/modules/auth/auth.service.ts +71 -0
- package/starters/default/src/modules/auth/auth.types.ts +15 -0
- package/starters/default/src/modules/auth/login.page.ts +62 -0
- package/starters/default/src/modules/billing/_contracts/stripe.types.ts +17 -0
- package/starters/default/src/modules/billing/api/stripe.connector.ts +71 -0
- package/starters/default/src/modules/billing/billing.public.ts +5 -0
- package/starters/default/src/modules/billing/billing.routes.ts +9 -0
- package/starters/default/src/modules/billing/billing.types.ts +15 -0
- package/starters/default/src/modules/billing/components/invoice-status-badge.component.ts +43 -0
- package/starters/default/src/modules/billing/data/invoices.resource.ts +35 -0
- package/starters/default/src/modules/billing/pages/invoice-detail.page.ts +70 -0
- package/starters/default/src/modules/billing/pages/invoices-list.page.ts +73 -0
- package/starters/default/src/modules/home/home.page.ts +34 -0
- package/starters/default/src/modules/home/not-found.page.ts +11 -0
- package/starters/default/src/shared/http/http-client.ts +86 -0
- package/starters/default/src/shared/http/http-error.ts +37 -0
- package/starters/default/src/shared/http/interceptors.ts +59 -0
- package/starters/default/src/shared/lib/format-date.ts +19 -0
- package/starters/default/src/shared/styles/content.css +70 -0
- package/starters/default/src/shared/styles/reset.css +32 -0
- package/starters/default/src/shared/styles/shell.css +57 -0
- package/starters/default/src/shared/styles/tokens.css +44 -0
- package/starters/default/src/shared/ui/x-button.component.ts +49 -0
- package/starters/default/src/shared/ui/x-spinner.component.ts +22 -0
- package/starters/default/src/styles.d.ts +1 -0
- package/starters/default/src/vite-env.d.ts +1 -0
- package/starters/default/tsconfig.json +24 -0
- package/starters/default/vite.config.ts +9 -0
- package/MADO_V1_PLAN.md +0 -179
- package/ROADMAP.md +0 -178
- package/dist/src/html.d.ts +0 -18
- package/dist/src/html.js +0 -17
- package/dist/src/html.js.map +0 -1
- package/dist/src/router.d.ts +0 -13
- package/dist/src/router.js +0 -13
- package/dist/src/router.js.map +0 -1
- package/scripts/bundle.mjs +0 -212
- package/scripts/llm-zero-history-smoke.mjs +0 -93
- package/scripts/new.mjs +0 -80
- package/scripts/showcase-regression.mjs +0 -392
- package/server/serve.mjs +0 -455
- package/starters/admin/README.md +0 -63
- package/starters/admin/index.html +0 -28
- package/starters/admin/mado.config.json +0 -22
- package/starters/admin/package.json +0 -24
- package/starters/admin/public/favicon.svg +0 -4
- package/starters/admin/src/components/x-button.ts +0 -82
- package/starters/admin/src/components/x-input.ts +0 -105
- package/starters/admin/src/layouts/app.ts +0 -101
- package/starters/admin/src/layouts/auth.ts +0 -41
- package/starters/admin/src/lib/api.ts +0 -184
- package/starters/admin/src/lib/auth.ts +0 -83
- package/starters/admin/src/main.ts +0 -15
- package/starters/admin/src/pages/admin/dashboard.ts +0 -48
- package/starters/admin/src/pages/admin/order-detail.ts +0 -80
- package/starters/admin/src/pages/admin/orders.ts +0 -117
- package/starters/admin/src/pages/home.ts +0 -34
- package/starters/admin/src/pages/login.ts +0 -70
- package/starters/admin/src/pages/not-found.ts +0 -12
- package/starters/admin/src/routes.ts +0 -40
- package/starters/admin/src/styles/global.ts +0 -86
- package/starters/admin/tsconfig.json +0 -15
- package/starters/crud/README.md +0 -33
- package/starters/crud/index.html +0 -28
- package/starters/crud/mado.config.json +0 -20
- package/starters/crud/package.json +0 -24
- package/starters/crud/src/components/app-shell.ts +0 -56
- package/starters/crud/src/components/ticket-detail.ts +0 -33
- package/starters/crud/src/components/ticket-form.ts +0 -69
- package/starters/crud/src/components/ticket-list.ts +0 -66
- package/starters/crud/src/lib/api.ts +0 -76
- package/starters/crud/src/main.ts +0 -9
- package/starters/crud/src/pages/home.ts +0 -34
- package/starters/crud/src/pages/not-found.ts +0 -12
- package/starters/crud/src/pages/ticket-detail.ts +0 -7
- package/starters/crud/src/pages/ticket-new.ts +0 -7
- package/starters/crud/src/pages/tickets.ts +0 -7
- package/starters/crud/src/routes.ts +0 -11
- package/starters/crud/src/styles/global.ts +0 -155
- package/starters/crud/tsconfig.json +0 -15
- package/starters/minimal/README.md +0 -21
- package/starters/minimal/index.html +0 -28
- package/starters/minimal/mado.config.json +0 -20
- package/starters/minimal/package.json +0 -24
- package/starters/minimal/src/components/app-counter.ts +0 -31
- package/starters/minimal/src/main.ts +0 -9
- package/starters/minimal/src/pages/home.ts +0 -35
- package/starters/minimal/src/pages/not-found.ts +0 -14
- package/starters/minimal/src/routes.ts +0 -8
- package/starters/minimal/src/styles/global.ts +0 -60
- package/starters/minimal/tsconfig.json +0 -15
- package/templates/page-detail.ts +0 -63
- package/templates/page-form.ts +0 -94
- package/templates/page-list.ts +0 -79
|
@@ -3,118 +3,83 @@
|
|
|
3
3
|
> Une seule bonne façon. Des contrats stricts. Pas de magie.
|
|
4
4
|
|
|
5
5
|
Mado est un framework pour les équipes qui construisent des panneaux d'admin,
|
|
6
|
-
des outils internes et des SPA métier
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
200 écrans et 5 développeurs. Si vous les enfreignez — les types et le linter
|
|
10
|
-
vous le diront immédiatement.
|
|
6
|
+
des outils internes et des SPA métier. Ces apps doivent être simples à créer
|
|
7
|
+
et ennuyeuses à maintenir. Mado préfère donc des conventions claires à cinq
|
|
8
|
+
styles équivalents.
|
|
11
9
|
|
|
12
10
|
## Principes
|
|
13
11
|
|
|
14
|
-
1. **Une seule voie.**
|
|
15
|
-
|
|
16
|
-
2. **L'explicite plutôt que la magie.** Pas de scanners
|
|
17
|
-
implicites
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
peut pas être typé — c'est un signal que l'API est mauvaise.
|
|
24
|
-
5. **Pas de dépendances runtime.** Chaque dépendance est un engagement sur des années ;
|
|
25
|
-
l'écosystème Web Components n'en a pas besoin.
|
|
12
|
+
1. **Une seule voie.** Si vous écrivez quelque chose d'inhabituel, vérifiez
|
|
13
|
+
d'abord s'il existe déjà un helper/API canonique.
|
|
14
|
+
2. **L'explicite plutôt que la magie.** Pas de file-system scanners, globals
|
|
15
|
+
implicites ou side effects cachés.
|
|
16
|
+
3. **La plateforme d'abord.** Web Components, History API, `<form>`, `fetch` et
|
|
17
|
+
Shadow DOM restent visibles.
|
|
18
|
+
4. **Types stricts.** `tsc --strict --noUncheckedIndexedAccess` toujours.
|
|
19
|
+
5. **Pas de dépendances runtime.** Le tooling dev/build est acceptable ; le
|
|
20
|
+
runtime Mado reste natif.
|
|
26
21
|
|
|
27
|
-
##
|
|
22
|
+
## Structure du projet
|
|
28
23
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
```
|
|
24
|
+
```txt
|
|
32
25
|
src/
|
|
33
|
-
├──
|
|
34
|
-
├──
|
|
35
|
-
├──
|
|
36
|
-
├──
|
|
37
|
-
|
|
38
|
-
└──
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
```ts
|
|
47
|
-
// src/components/user-card.ts
|
|
48
|
-
import { component, html, css } from "@madojs/mado";
|
|
49
|
-
|
|
50
|
-
component(
|
|
51
|
-
"x-user-card",
|
|
52
|
-
() => {
|
|
53
|
-
return () => html`<div class="card"><slot /></div>`;
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
styles: css`
|
|
57
|
-
.card {
|
|
58
|
-
padding: 1rem;
|
|
59
|
-
}
|
|
60
|
-
`,
|
|
61
|
-
},
|
|
62
|
-
);
|
|
26
|
+
├── main.ts ← boot: global CSS/providers + render router
|
|
27
|
+
├── app.routes.ts ← readable app map, exports `manifest` + default routes()
|
|
28
|
+
├── layouts/ ← app-zone wrappers (`page({ view: ({ child }) => ... })`)
|
|
29
|
+
├── shared/ ← UI bricks, http client, pure lib, global CSS
|
|
30
|
+
└── modules/ ← bounded contexts
|
|
31
|
+
└── billing/
|
|
32
|
+
├── billing.routes.ts
|
|
33
|
+
├── billing.public.ts
|
|
34
|
+
├── billing.types.ts
|
|
35
|
+
├── pages/
|
|
36
|
+
├── data/
|
|
37
|
+
├── api/
|
|
38
|
+
└── _contracts/
|
|
63
39
|
```
|
|
64
40
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
### Une seule façon de charger les données
|
|
41
|
+
Le starter par défaut est la version canonique de cette forme. Si d'anciens
|
|
42
|
+
exemples divergent, le starter et `docs/10-app-architecture.md` gagnent.
|
|
69
43
|
|
|
70
|
-
|
|
44
|
+
## Un composant = un fichier
|
|
71
45
|
|
|
72
46
|
```ts
|
|
73
|
-
|
|
74
|
-
const user = resource(() => `/api/users/${id()}`, jsonFetcher());
|
|
47
|
+
import { component, css, html } from "@madojs/mado";
|
|
75
48
|
|
|
76
|
-
|
|
77
|
-
|
|
49
|
+
component("x-user-card", () => () => html`<div class="card"><slot></slot></div>`, {
|
|
50
|
+
styles: css`
|
|
51
|
+
.card { padding: 1rem; }
|
|
52
|
+
`,
|
|
53
|
+
});
|
|
78
54
|
```
|
|
79
55
|
|
|
80
|
-
|
|
56
|
+
Importer le fichier du composant enregistre l'élément. Importez-le là où le tag
|
|
57
|
+
est utilisé.
|
|
81
58
|
|
|
82
|
-
|
|
59
|
+
## Une seule façon de décrire une page
|
|
83
60
|
|
|
84
61
|
```ts
|
|
85
|
-
|
|
86
|
-
import { page, html, resource, jsonFetcher } from "@madojs/mado";
|
|
62
|
+
import { html, page, resource, jsonFetcher } from "@madojs/mado";
|
|
87
63
|
|
|
88
64
|
export default page({
|
|
89
|
-
title: ({ id }) => `
|
|
90
|
-
view: ({ params }) =>
|
|
65
|
+
title: ({ id }) => `User #${id}`,
|
|
66
|
+
view: ({ params }) => {
|
|
67
|
+
const user = resource(() => `/api/users/${params.id}`, jsonFetcher());
|
|
68
|
+
return html`...`;
|
|
69
|
+
},
|
|
91
70
|
});
|
|
92
71
|
```
|
|
93
72
|
|
|
94
|
-
|
|
95
|
-
un
|
|
96
|
-
|
|
97
|
-
### Une seule façon de déclarer les routes
|
|
98
|
-
|
|
99
|
-
Voir [`01-routing.md`](./01-routing.md).
|
|
100
|
-
|
|
101
|
-
## Ce que nous NE faisons PAS
|
|
102
|
-
|
|
103
|
-
- ❌ N'écrivez pas de composants sans trait d'union. C'est la règle du navigateur pour
|
|
104
|
-
les custom elements : `user-card` est correct, `usercard` ne l'est pas.
|
|
105
|
-
- `x-*` n'est qu'une convention pour les exemples et les tests Mado, pas un standard de marque.
|
|
106
|
-
En production, utilisez un préfixe de domaine : `app-*`, `crm-*`, `ticket-*`, `admin-*`.
|
|
107
|
-
- ❌ N'utilisez pas `innerHTML` directement. Uniquement via `html\`\``.
|
|
108
|
-
- ❌ N'appelez pas `setTimeout`/`setInterval` sans nettoyage. Uniquement à l'intérieur de `effect()`.
|
|
109
|
-
- ❌ Ne stockez pas d'état mutable global. Utilisez les signals et `context`.
|
|
110
|
-
- ❌ N'ajoutez pas de packages sans discussion. Chaque dépendance est un engagement.
|
|
111
|
-
|
|
112
|
-
## En cas de doute
|
|
73
|
+
Les signals, resources et forms locaux à une page vivent dans `view()`. L'état
|
|
74
|
+
partagé par un module vit dans `*.service.ts`.
|
|
113
75
|
|
|
114
|
-
|
|
76
|
+
## Ce que nous ne faisons pas
|
|
115
77
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
78
|
+
- Pas de JSX/Vue/Svelte syntax.
|
|
79
|
+
- Pas de custom elements sans trait d'union.
|
|
80
|
+
- Pas de lecture de signal via `.value`; un signal est une fonction.
|
|
81
|
+
- Pas de `innerHTML` direct.
|
|
82
|
+
- Pas de runtime packages sans discussion.
|
|
119
83
|
|
|
120
|
-
|
|
84
|
+
En cas de doute, documentez une recette claire plutôt que d'ajouter un nouveau
|
|
85
|
+
primitive au core.
|
package/docs/fr/01-routing.md
CHANGED
|
@@ -1,202 +1,120 @@
|
|
|
1
1
|
# Routage
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> Une seule app map. Pas de folder scanners. Pas de syntaxe magique.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Mado ne déduit pas les routes depuis les fichiers. La composition doit rester
|
|
6
|
+
lisible dans un seul endroit.
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
fichiers. Cela a des avantages (la structure d'URL visible dans `pages/`), mais en production
|
|
9
|
-
cela signifie :
|
|
8
|
+
## App Manifest
|
|
10
9
|
|
|
11
|
-
|
|
12
|
-
- Des caractères spéciaux dans les chemins : `[id]`, `(group)`, `_layout`, `+page.svelte`, `...slug`.
|
|
13
|
-
- Les routes serveur et les routes client se mélangent.
|
|
14
|
-
- Tester le routage est pénible : vous avez besoin d'un émulateur de build-tool.
|
|
15
|
-
|
|
16
|
-
Mado considère cela comme **trop de magie**. Nous procédons différemment.
|
|
17
|
-
|
|
18
|
-
## Manifeste
|
|
19
|
-
|
|
20
|
-
Un seul fichier — `src/routes.ts`. Un seul objet. Lu de haut en bas.
|
|
10
|
+
Utilisez `src/app.routes.ts` comme carte de l'application :
|
|
21
11
|
|
|
22
12
|
```ts
|
|
23
|
-
|
|
24
|
-
import {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
13
|
+
import { layout, routes } from "@madojs/mado";
|
|
14
|
+
import { requireAuth } from "./modules/auth/auth.public";
|
|
15
|
+
import { authRoutes } from "./modules/auth/auth.routes";
|
|
16
|
+
import { billingRoutes } from "./modules/billing/billing.routes";
|
|
17
|
+
|
|
18
|
+
export const manifest = {
|
|
19
|
+
"/": () => import("./modules/home/home.page.js"),
|
|
20
|
+
"/login": layout({
|
|
21
|
+
layout: () => import("./layouts/auth-shell.layout.js"),
|
|
22
|
+
routes: authRoutes,
|
|
23
|
+
}),
|
|
24
|
+
"/billing": layout({
|
|
25
|
+
layout: () => import("./layouts/app-shell.layout.js"),
|
|
26
|
+
guard: requireAuth,
|
|
27
|
+
routes: billingRoutes,
|
|
28
|
+
}),
|
|
29
|
+
"*": () => import("./modules/home/not-found.page.js"),
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export default routes(manifest);
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
Ouvrez `app.routes.ts` pour voir les zones de l'app : pages publiques, auth,
|
|
36
|
+
zones protégées, guards et shells.
|
|
36
37
|
|
|
37
|
-
|
|
38
|
+
Exportez `manifest` pour `mado bake`.
|
|
38
39
|
|
|
39
|
-
|
|
40
|
+
## Module Routes
|
|
40
41
|
|
|
41
|
-
|
|
42
|
+
Les modules exportent de simples route maps. Ils n'appellent pas `layout()` et
|
|
43
|
+
ne décident pas quel shell les enveloppe.
|
|
42
44
|
|
|
43
45
|
```ts
|
|
44
|
-
|
|
46
|
+
export const billingRoutes = {
|
|
47
|
+
"/invoices": () => import("./pages/invoices-list.page.js"),
|
|
48
|
+
"/invoices/:id": () => import("./pages/invoice-detail.page.js"),
|
|
49
|
+
};
|
|
45
50
|
```
|
|
46
51
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
- Les navigations suivantes utilisent le résultat mis en cache.
|
|
52
|
+
Le prefix est appliqué par `src/app.routes.ts` quand le module est monté sous
|
|
53
|
+
`"/billing"`.
|
|
50
54
|
|
|
51
|
-
|
|
55
|
+
## Layout Group
|
|
52
56
|
|
|
53
57
|
```ts
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
58
|
+
"/admin": layout({
|
|
59
|
+
layout: () => import("./layouts/app-shell.layout.js"),
|
|
60
|
+
guard: requireAuth,
|
|
61
|
+
routes: adminRoutes,
|
|
62
|
+
}),
|
|
57
63
|
```
|
|
58
64
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
### 3. Imbriqué avec layout
|
|
65
|
+
Un layout est un fichier `page({...})` ordinaire :
|
|
62
66
|
|
|
63
67
|
```ts
|
|
64
|
-
import {
|
|
65
|
-
|
|
66
|
-
export default routes({
|
|
67
|
-
'/': () => import('./pages/home.js'),
|
|
68
|
-
|
|
69
|
-
'/admin/*': nested({
|
|
70
|
-
layout: () => import('./layouts/admin.js'),
|
|
71
|
-
routes: {
|
|
72
|
-
'': () => import('./pages/admin/dashboard.js'),
|
|
73
|
-
'users': () => import('./pages/admin/users.js'),
|
|
74
|
-
'logs': () => import('./pages/admin/logs.js'),
|
|
75
|
-
},
|
|
76
|
-
}),
|
|
77
|
-
});
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
Un layout est juste une `page({...})` ordinaire qui rend `ctx.child` où elle le souhaite :
|
|
81
|
-
|
|
82
|
-
```ts
|
|
83
|
-
// src/layouts/admin.ts
|
|
84
|
-
import { page, html, css, component } from '@madojs/mado';
|
|
68
|
+
import { html, page } from "@madojs/mado";
|
|
85
69
|
|
|
86
70
|
export default page({
|
|
87
71
|
view: ({ child }) => html`
|
|
88
|
-
<div class="
|
|
89
|
-
<
|
|
90
|
-
<main>${child}</main>
|
|
72
|
+
<div class="layout layout--app">
|
|
73
|
+
<main class="app-main">${child}</main>
|
|
91
74
|
</div>
|
|
92
75
|
`,
|
|
93
76
|
});
|
|
94
77
|
```
|
|
95
78
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
```ts
|
|
99
|
-
import { page, html, resource, jsonFetcher } from '@madojs/mado';
|
|
100
|
-
|
|
101
|
-
export default page({
|
|
102
|
-
title: ({ id }) => `Utilisateur #${id}`, // string | (params) => string
|
|
103
|
-
load: ({ id }) => resource(...), // optionnel, retourne Resource ou data
|
|
104
|
-
view: ({ params, data, path, child }) => html`...`, // OBLIGATOIRE
|
|
105
|
-
});
|
|
106
|
-
```
|
|
79
|
+
Gardez les layout views stateless. Les signals, resources et forms spécifiques
|
|
80
|
+
à une page vivent dans les pages/components/resources.
|
|
107
81
|
|
|
108
|
-
|
|
109
|
-
fonction par exemple — `routes()` génère une erreur claire :
|
|
110
|
-
|
|
111
|
-
```
|
|
112
|
-
[Mado] La route lazy n'a pas retourné page({...}) comme export par défaut.
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
## Paramètres d'URL
|
|
82
|
+
## Page Contract
|
|
116
83
|
|
|
117
84
|
```ts
|
|
118
|
-
|
|
119
|
-
```
|
|
85
|
+
import { html, page } from "@madojs/mado";
|
|
120
86
|
|
|
121
|
-
```ts
|
|
122
87
|
export default page<{ id: string }>({
|
|
123
|
-
title: ({ id }) => `
|
|
124
|
-
view:
|
|
88
|
+
title: ({ id }) => `User ${id}`,
|
|
89
|
+
view: ({ params }) => html`<h1>${params.id}</h1>`,
|
|
125
90
|
});
|
|
126
91
|
```
|
|
127
92
|
|
|
128
|
-
|
|
129
|
-
`params.foo` qui n'existe pas dans la route.
|
|
130
|
-
|
|
131
|
-
## Options globales
|
|
132
|
-
|
|
133
|
-
```ts
|
|
134
|
-
export default routes(
|
|
135
|
-
{ '/': home, '/about': about, '*': nf },
|
|
136
|
-
{
|
|
137
|
-
titleSuffix: ' · MonApp', // → "Accueil · MonApp"
|
|
138
|
-
loading: () => html`<x-spinner/>`, // pendant le chargement du module
|
|
139
|
-
error: (err) => html`<x-fatal-error .err=${err}/>`,
|
|
140
|
-
},
|
|
141
|
-
);
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
## Navigation programmatique
|
|
93
|
+
## Navigation
|
|
145
94
|
|
|
146
95
|
```ts
|
|
147
|
-
import
|
|
96
|
+
import appRoutes from "./app.routes.js";
|
|
148
97
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
98
|
+
appRoutes.navigate("/billing/invoices");
|
|
99
|
+
appRoutes.navigate("/billing/invoices?page=2");
|
|
100
|
+
appRoutes.navigate("/login", { replace: true });
|
|
152
101
|
```
|
|
153
102
|
|
|
154
|
-
|
|
155
|
-
le navigateur effectue un rechargement complet, comme prévu pour les liens externes).
|
|
156
|
-
|
|
157
|
-
## Paramètres de requête
|
|
103
|
+
## Query Parameters
|
|
158
104
|
|
|
159
105
|
```ts
|
|
160
|
-
import { queryParam } from
|
|
106
|
+
import { queryParam } from "@madojs/mado";
|
|
161
107
|
|
|
162
|
-
const page = queryParam(
|
|
163
|
-
page();
|
|
164
|
-
page.set(
|
|
165
|
-
page.set(null);
|
|
166
|
-
page.set(
|
|
108
|
+
const page = queryParam("page", "1");
|
|
109
|
+
page();
|
|
110
|
+
page.set("2");
|
|
111
|
+
page.set(null);
|
|
112
|
+
page.set("3", { push: true });
|
|
167
113
|
```
|
|
168
114
|
|
|
169
|
-
|
|
170
|
-
les computed.
|
|
171
|
-
|
|
172
|
-
## Ce qui est intentionnellement absent
|
|
173
|
-
|
|
174
|
-
- ❌ Auto-scan de `pages/`. **Un seul fichier manifeste explicite**.
|
|
175
|
-
- ❌ Caractères spéciaux dans les chemins (`[id]`, `(group)`, `_layout`). **Les paramètres sont
|
|
176
|
-
uniquement `:name`, rien d'autre**.
|
|
177
|
-
- ❌ Routage côté serveur dans le même manifeste. Mado est un framework côté client.
|
|
178
|
-
- ❌ Auto-préchargement au survol. Si vous en avez vraiment besoin — faites-le manuellement :
|
|
179
|
-
`link.addEventListener('mouseenter', loader)`. Généralement inutile.
|
|
180
|
-
|
|
181
|
-
## FAQ
|
|
182
|
-
|
|
183
|
-
**Et si j'ai 100 routes ? Le fichier ne deviendra-t-il pas énorme ?**
|
|
184
|
-
Il atteindra ~150 lignes. C'est toujours **une seule source de vérité** contre une centaine
|
|
185
|
-
de fichiers dans `pages/` avec des noms magiques. En pratique, même les grands projets (1000+
|
|
186
|
-
pages) peuvent se diviser en manifestes de fonctionnalités :
|
|
187
|
-
|
|
188
|
-
```ts
|
|
189
|
-
import { routes } from '@madojs/mado';
|
|
190
|
-
import adminRoutes from './features/admin/routes.js';
|
|
191
|
-
import billingRoutes from './features/billing/routes.js';
|
|
192
|
-
|
|
193
|
-
export default routes({
|
|
194
|
-
...adminRoutes,
|
|
195
|
-
...billingRoutes,
|
|
196
|
-
'*': () => import('./pages/not-found.js'),
|
|
197
|
-
});
|
|
198
|
-
```
|
|
115
|
+
## Ce qui est absent volontairement
|
|
199
116
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
117
|
+
- Pas d'auto-scan des dossiers de pages.
|
|
118
|
+
- Pas de syntaxe filesystem comme `[id]`, `(group)`, `_layout`.
|
|
119
|
+
- Pas de server routes dans le manifest client.
|
|
120
|
+
- Pas de découverte cachée des layouts.
|
|
@@ -1,65 +1,84 @@
|
|
|
1
1
|
# Structure du projet
|
|
2
2
|
|
|
3
|
-
Chaque
|
|
3
|
+
Chaque application Mado utilise la même forme canonique. Cette convention
|
|
4
|
+
permet aux humains et aux assistants IA de savoir où placer le code.
|
|
4
5
|
|
|
5
|
-
```
|
|
6
|
+
```txt
|
|
6
7
|
my-app/
|
|
7
8
|
├── package.json # runtime dep: @madojs/mado
|
|
8
9
|
├── tsconfig.json # strict TS, ES2022, Bundler resolution
|
|
9
|
-
├──
|
|
10
|
-
├── index.html #
|
|
11
|
-
├── public/ # assets statiques
|
|
10
|
+
├── vite.config.ts # mado() from @madojs/mado/vite
|
|
11
|
+
├── index.html # entrée Vite + shell SPA
|
|
12
|
+
├── public/ # assets statiques: favicon, images, robots.txt
|
|
12
13
|
└── src/
|
|
13
|
-
├── main.ts #
|
|
14
|
-
├── routes.ts
|
|
15
|
-
├──
|
|
16
|
-
├──
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
14
|
+
├── main.ts # importe le CSS et monte le router dans #app
|
|
15
|
+
├── app.routes.ts # app map: manifest + default routes(...)
|
|
16
|
+
├── layouts/ # layouts de zones d'application
|
|
17
|
+
├── shared/ # ui, http, lib, styles
|
|
18
|
+
└── modules/ # bounded contexts
|
|
19
|
+
└── billing/
|
|
20
|
+
├── billing.routes.ts
|
|
21
|
+
├── billing.public.ts
|
|
22
|
+
├── billing.types.ts
|
|
23
|
+
├── pages/
|
|
24
|
+
├── data/
|
|
25
|
+
├── api/
|
|
26
|
+
└── _contracts/
|
|
23
27
|
```
|
|
24
28
|
|
|
25
29
|
## États Des Artefacts
|
|
26
30
|
|
|
27
31
|
| Dossier | Ce que c'est | Écrit par | Déployer ? |
|
|
28
|
-
|
|
32
|
+
| --- | --- | --- | --- |
|
|
29
33
|
| `src/` | sources TypeScript | vous | non |
|
|
30
|
-
| `
|
|
31
|
-
| `
|
|
32
|
-
|
|
34
|
+
| `public/` | assets statiques copiés tels quels | vous | via `out/` |
|
|
35
|
+
| `out/` | artefact déployable: shell SPA + assets + HTML baked | `mado release` | oui |
|
|
36
|
+
|
|
37
|
+
`mado release` = `typecheck` + build Vite (`out/index.html`, `out/assets/`,
|
|
38
|
+
`public/*`) + `bake` directement dans les chemins de routes + `sitemap.xml` +
|
|
39
|
+
precompression.
|
|
33
40
|
|
|
34
|
-
`
|
|
35
|
-
|
|
36
|
-
`sitemap.xml` dans les chemins déployables de `out/` + copie de `public/*`.
|
|
41
|
+
`index.html` reste à la racine car Vite le traite comme entry template. Mettez
|
|
42
|
+
dans `public/` uniquement les fichiers à copier tels quels.
|
|
37
43
|
|
|
38
44
|
## Où mettre un nouveau fichier ?
|
|
39
45
|
|
|
40
46
|
| Quoi | Où |
|
|
41
|
-
|
|
42
|
-
| Page pour une nouvelle URL | `src/pages
|
|
43
|
-
|
|
|
44
|
-
|
|
|
45
|
-
|
|
|
46
|
-
|
|
|
47
|
+
| --- | --- |
|
|
48
|
+
| Page pour une nouvelle URL | `src/modules/<module>/pages/<name>.page.ts` + module routes |
|
|
49
|
+
| Route map de module | `src/modules/<module>/<module>.routes.ts` |
|
|
50
|
+
| App shell/layout | `src/layouts/<zone>.layout.ts` |
|
|
51
|
+
| Widget UI partagé | `src/shared/ui/<x-name>.component.ts` |
|
|
52
|
+
| Widget UI propre à un module | `src/modules/<module>/components/<name>.component.ts` |
|
|
53
|
+
| API connector | `src/modules/<module>/api/<provider>.connector.ts` |
|
|
54
|
+
| Data resource/mutation | `src/modules/<module>/data/<name>.resource.ts` |
|
|
55
|
+
| Auth/session | `src/modules/auth/` |
|
|
56
|
+
| Surface publique de module | `src/modules/<module>/<module>.public.ts` |
|
|
57
|
+
| Fonction pure sans UI | `src/shared/lib/<name>.ts` |
|
|
58
|
+
| Image statique / favicon | `public/<file>` |
|
|
59
|
+
| CSS de shell | `src/shared/styles/shell.css` |
|
|
60
|
+
| CSS de contenu page | `src/shared/styles/content.css` |
|
|
47
61
|
|
|
48
|
-
|
|
49
|
-
Consultez l'équipe, **consignez** la réponse dans `docs/`.
|
|
62
|
+
## Vite Config
|
|
50
63
|
|
|
51
|
-
|
|
64
|
+
```ts
|
|
65
|
+
import { defineConfig } from "vite";
|
|
66
|
+
import { mado } from "@madojs/mado/vite";
|
|
67
|
+
|
|
68
|
+
export default defineConfig({
|
|
69
|
+
plugins: [mado()],
|
|
70
|
+
css: {
|
|
71
|
+
transformer: "lightningcss",
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
```
|
|
52
75
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
| Fichier | kebab-case | `user-profile.ts` |
|
|
56
|
-
| Tag de composant | `x-` + kebab | `<x-user-profile>` |
|
|
57
|
-
| Context | PascalCase + `Ctx` | `ThemeCtx`, `AuthCtx` |
|
|
58
|
-
| Signal | camelCase | `userId`, `isLoggedIn` |
|
|
59
|
-
| Fonction de page (composant interne) | `x-<route>-page` | `<x-posts-page>` |
|
|
76
|
+
Le starter active le transformer Lightning CSS de Vite. Mado ne possède pas le
|
|
77
|
+
prefixing, le lowering CSS ou la minification.
|
|
60
78
|
|
|
61
|
-
## Ce qui ne va PAS dans src
|
|
79
|
+
## Ce qui ne va PAS dans `src/`
|
|
62
80
|
|
|
63
|
-
-
|
|
64
|
-
-
|
|
65
|
-
|
|
81
|
+
- Configs de build-tool supplémentaires — utilisez `vite.config.ts`.
|
|
82
|
+
- Fichiers `.env` — lisez l'env dans `src/shared/lib/config.ts` puis importez
|
|
83
|
+
ce module.
|
|
84
|
+
- Tests mélangés au code — gardez-les dans `test/`.
|
package/docs/fr/05-why-mado.md
CHANGED
|
@@ -31,11 +31,11 @@ Si votre cas ne tombe pas dans le dernier point — Mado n'est probablement pas
|
|
|
31
31
|
| Taille | ~6 Ko | ~16 Ko |
|
|
32
32
|
| Âge / support | ~10 ans, Google | 6 mois, auteur unique |
|
|
33
33
|
| Réactivité | décorateurs `@property` + `requestUpdate` manuel | signals (`signal`/`computed`/`effect`) intégrés |
|
|
34
|
-
| Router | aucun, vous devez en trouver un (`@lit-labs/router`, etc.) | inclus : `routes()` +
|
|
34
|
+
| Router | aucun, vous devez en trouver un (`@lit-labs/router`, etc.) | inclus : `routes()` + layout groups + prefetch |
|
|
35
35
|
| Chargement de données | aucun, vous devez l'assembler | `resource()` + `mutation()` + invalidation glob |
|
|
36
36
|
| Forms | aucun | `useForm()` avec contraintes proches du HTML |
|
|
37
37
|
| SEO / statique | complexe (`@lit-labs/ssr`) | `bake` (linkedom) + edge-prerender |
|
|
38
|
-
| Build | nécessite
|
|
38
|
+
| Build | nécessite des plugins spécifiques au framework | Vite transport + runtime natif |
|
|
39
39
|
| Style de code | classes + décorateurs | fonctions + tagged templates |
|
|
40
40
|
| Écosystème | réel (Shoelace, Material Web, etc.) | aucun |
|
|
41
41
|
| Quand choisir | écrire un design system / bibliothèque Web Components pour l'intégration | écrire une application complète, vouloir tout dans une boîte |
|
|
@@ -55,14 +55,14 @@ Si votre cas ne tombe pas dans le dernier point — Mado n'est probablement pas
|
|
|
55
55
|
| Réactivité | signals (même classe d'idées) | signals |
|
|
56
56
|
| Templates | JSX (compilé en expressions réactives) | tagged template `html\`\`` |
|
|
57
57
|
| Modèle de composant | fonctions, nœuds virtuels Solid | Web Components |
|
|
58
|
-
| Build | Vite + babel-plugin-solid requis |
|
|
58
|
+
| Build | Vite + babel-plugin-solid requis | Vite pour dev/build, aucune dépendance runtime |
|
|
59
59
|
| Router | `@solidjs/router` | inclus |
|
|
60
60
|
| Données | `createResource` | `resource()` |
|
|
61
61
|
| SSR | sérieusement supporté (SolidStart) | intentionnellement absent |
|
|
62
62
|
| Écosystème | en croissance, ~50 packages | aucun |
|
|
63
|
-
| Quand choisir | besoin de top performance + JSX + prêt à configurer le build | vouloir
|
|
63
|
+
| Quand choisir | besoin de top performance + JSX + prêt à configurer le build | vouloir un runtime browser-native avec tooling simple |
|
|
64
64
|
|
|
65
|
-
**Pitch honnête :** *"Solid est techniquement plus rapide et plus mature.
|
|
65
|
+
**Pitch honnête :** *"Solid est techniquement plus rapide et plus mature. Mado est plus simple dans son idée : runtime browser-native, Web Components, tagged templates, et Vite fait le travail dev/build ennuyeux. Si vous voulez JSX et un écosystème plus large, allez avec Solid."*
|
|
66
66
|
|
|
67
67
|
---
|
|
68
68
|
|
|
@@ -153,7 +153,7 @@ Je ne vais pas m'étendre là-dessus longtemps, car React est dans une **catégo
|
|
|
153
153
|
|
|
154
154
|
Pas la taille, pas la performance, pas les signals — tout a de meilleurs concurrents.
|
|
155
155
|
|
|
156
|
-
> **"Ouvrez le source et lisez-le en une soirée. ~3500 lignes,
|
|
156
|
+
> **"Ouvrez le source et lisez-le en une soirée. ~3500 lignes, petits modules. Si quelque chose casse — vous n'allez pas sur une issue avec 3000 commentaires. Vous allez dans `src/router/` et lisez le code."**
|
|
157
157
|
|
|
158
158
|
C'est ce qu'on appelle la **propriété** — vous possédez le code, plutôt que de dépendre de celui de quelqu'un d'autre.
|
|
159
159
|
|