@madojs/mado 0.10.1 → 0.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +24 -26
- package/CHANGELOG.md +95 -0
- package/README.md +22 -47
- 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/html/bindings.js +3 -3
- package/dist/src/html/bindings.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 +74 -63
- 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
|
@@ -1,100 +1,152 @@
|
|
|
1
1
|
# Архитектура приложения
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
Официальный starter — каноничная production-форма Mado-приложения. Это не
|
|
4
|
+
framework внутри framework: только файлы, imports, Mado primitives и ESLint
|
|
5
|
+
boundaries.
|
|
6
6
|
|
|
7
7
|
## Структура
|
|
8
8
|
|
|
9
9
|
```txt
|
|
10
10
|
src/
|
|
11
11
|
├── main.ts
|
|
12
|
-
├── routes.ts
|
|
12
|
+
├── app.routes.ts
|
|
13
13
|
├── layouts/
|
|
14
|
-
│ ├── app.ts
|
|
15
|
-
│ └── auth.ts
|
|
16
|
-
├──
|
|
17
|
-
│ ├──
|
|
18
|
-
│ ├──
|
|
19
|
-
│ ├──
|
|
20
|
-
│ └──
|
|
21
|
-
|
|
22
|
-
├──
|
|
23
|
-
│ ├──
|
|
24
|
-
│
|
|
25
|
-
|
|
14
|
+
│ ├── app-shell.layout.ts
|
|
15
|
+
│ └── auth-shell.layout.ts
|
|
16
|
+
├── shared/
|
|
17
|
+
│ ├── http/
|
|
18
|
+
│ ├── lib/
|
|
19
|
+
│ ├── styles/
|
|
20
|
+
│ └── ui/
|
|
21
|
+
└── modules/
|
|
22
|
+
├── auth/
|
|
23
|
+
│ ├── auth.routes.ts
|
|
24
|
+
│ ├── auth.public.ts
|
|
25
|
+
│ ├── auth.service.ts
|
|
26
|
+
│ ├── auth.connector.ts
|
|
27
|
+
│ ├── auth.guard.ts
|
|
28
|
+
│ ├── login.page.ts
|
|
29
|
+
│ └── _contracts/
|
|
30
|
+
└── billing/
|
|
31
|
+
├── billing.routes.ts
|
|
32
|
+
├── billing.public.ts
|
|
33
|
+
├── billing.types.ts
|
|
34
|
+
├── api/
|
|
35
|
+
├── data/
|
|
36
|
+
├── pages/
|
|
37
|
+
├── components/
|
|
38
|
+
└── _contracts/
|
|
26
39
|
```
|
|
27
40
|
|
|
28
|
-
|
|
29
|
-
`components/` хранит переиспользуемые UI-теги, а `pages/` содержит один файл
|
|
30
|
-
на страницу.
|
|
41
|
+
## App Map
|
|
31
42
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
```ts
|
|
35
|
-
import { html, render } from "@madojs/mado";
|
|
36
|
-
import "./styles/global.js";
|
|
37
|
-
import "./components/x-button.js";
|
|
38
|
-
import routesApi from "./routes.js";
|
|
39
|
-
|
|
40
|
-
render(html`${routesApi.view}`, document.getElementById("app")!);
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
В `main.ts` импортируй только глобальные провайдеры, стили и маленькие общие
|
|
44
|
-
компоненты. Feature-компоненты импортирует страница, которая их рендерит.
|
|
45
|
-
|
|
46
|
-
## Routes
|
|
43
|
+
`src/app.routes.ts` — карта всего приложения. Modules экспортируют plain route
|
|
44
|
+
maps; app routes решают, какой shell и guard оборачивают каждую зону.
|
|
47
45
|
|
|
48
46
|
```ts
|
|
49
47
|
import { layout, routes } from "@madojs/mado";
|
|
50
|
-
import { requireAuth } from "./
|
|
48
|
+
import { requireAuth } from "./modules/auth/auth.public";
|
|
49
|
+
import { authRoutes } from "./modules/auth/auth.routes";
|
|
50
|
+
import { billingRoutes } from "./modules/billing/billing.routes";
|
|
51
51
|
|
|
52
52
|
export const manifest = {
|
|
53
|
-
"/": () => import("./
|
|
53
|
+
"/": () => import("./modules/home/home.page"),
|
|
54
54
|
"/login": layout({
|
|
55
|
-
layout: () => import("./layouts/auth.
|
|
56
|
-
routes:
|
|
55
|
+
layout: () => import("./layouts/auth-shell.layout"),
|
|
56
|
+
routes: authRoutes,
|
|
57
57
|
}),
|
|
58
|
-
"/
|
|
59
|
-
layout: () => import("./layouts/app.
|
|
58
|
+
"/billing": layout({
|
|
59
|
+
layout: () => import("./layouts/app-shell.layout"),
|
|
60
60
|
guard: requireAuth,
|
|
61
|
-
routes:
|
|
62
|
-
"/": () => import("./pages/admin/dashboard.js"),
|
|
63
|
-
"/orders": () => import("./pages/admin/orders.js"),
|
|
64
|
-
},
|
|
61
|
+
routes: billingRoutes,
|
|
65
62
|
}),
|
|
66
|
-
"*": () => import("./
|
|
63
|
+
"*": () => import("./modules/home/not-found.page"),
|
|
67
64
|
};
|
|
68
65
|
|
|
69
66
|
export default routes(manifest);
|
|
70
67
|
```
|
|
71
68
|
|
|
72
|
-
|
|
69
|
+
Rules:
|
|
73
70
|
|
|
74
|
-
|
|
71
|
+
- Export `manifest`, чтобы `mado bake` мог найти bakeable pages.
|
|
72
|
+
- Modules не вызывают `layout()`.
|
|
73
|
+
- Layouts описывают app zones, не домены.
|
|
74
|
+
- Router не прячется в custom element или втором shell в `main.ts`.
|
|
75
75
|
|
|
76
|
-
|
|
77
|
-
для записей `mutation(..., { invalidates })`, для форм `useForm()`.
|
|
76
|
+
## File Forms
|
|
78
77
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
78
|
+
| Suffix | Role |
|
|
79
|
+
| --- | --- |
|
|
80
|
+
| `*.page.ts` | route page, default `page({...})` |
|
|
81
|
+
| `*.layout.ts` | app-zone wrapper, default `page(...)` |
|
|
82
|
+
| `*.connector.ts` | one external API system |
|
|
83
|
+
| `*.resource.ts` | `resource()` and `mutation()` layer |
|
|
84
|
+
| `*.service.ts` | module singleton state |
|
|
85
|
+
| `*.guard.ts` | route guard |
|
|
86
|
+
| `*.routes.ts` | module-local route map |
|
|
87
|
+
| `*.public.ts` | only public module surface |
|
|
88
|
+
| `*.types.ts` | domain types |
|
|
89
|
+
| `*.component.ts` | Web Component registration |
|
|
86
90
|
|
|
87
|
-
|
|
91
|
+
Page-local signals, resources and forms live inside `view()`. Module-wide state
|
|
92
|
+
lives in `*.service.ts`.
|
|
88
93
|
|
|
89
|
-
|
|
90
|
-
|
|
94
|
+
## Data Flow
|
|
95
|
+
|
|
96
|
+
```txt
|
|
97
|
+
shared/http/http-client.ts
|
|
98
|
+
▲
|
|
99
|
+
modules/<x>/api/*.connector.ts DTO -> domain mapping
|
|
100
|
+
▲
|
|
101
|
+
modules/<x>/data/*.resource.ts cache keys + mutations
|
|
102
|
+
▲
|
|
103
|
+
modules/<x>/pages/*.page.ts UI consumes domain types
|
|
91
104
|
```
|
|
92
105
|
|
|
93
|
-
|
|
106
|
+
## Module Boundaries
|
|
107
|
+
|
|
108
|
+
Модуль opaque, кроме `<module>.public.ts`. Другие modules импортируют через этот
|
|
109
|
+
файл или никак. DTO внешних систем лежат в `_contracts/` и остаются private для
|
|
110
|
+
connector.
|
|
111
|
+
|
|
112
|
+
Default starter enforces this with ESLint:
|
|
113
|
+
|
|
114
|
+
- no barrels (`index.ts`);
|
|
115
|
+
- no `export *`;
|
|
116
|
+
- no CSS imports outside `src/main.ts`;
|
|
117
|
+
- no cross-module imports except public surfaces;
|
|
118
|
+
- no `_contracts` imports outside connectors.
|
|
119
|
+
|
|
120
|
+
## Styles
|
|
121
|
+
|
|
122
|
+
| File | Role |
|
|
123
|
+
| --- | --- |
|
|
124
|
+
| `src/shared/styles/tokens.css` | design tokens as CSS custom properties |
|
|
125
|
+
| `src/shared/styles/reset.css` | document/light DOM reset |
|
|
126
|
+
| `src/shared/styles/shell.css` | app-zone layouts from `src/layouts/` |
|
|
127
|
+
| `src/shared/styles/content.css` | page-level forms, tables, prose and states |
|
|
128
|
+
|
|
129
|
+
Reusable leaf components keep their own styles in ``css`...` `` inside
|
|
130
|
+
`component()` options and depend on tokens, not global classes.
|
|
131
|
+
|
|
132
|
+
`vite.config.ts` opts into Vite Lightning CSS transformer. Mado does not own
|
|
133
|
+
prefixing, CSS lowering or minification.
|
|
134
|
+
|
|
135
|
+
## CLI
|
|
136
|
+
|
|
137
|
+
Use `mado new` for boring file scaffolding:
|
|
94
138
|
|
|
95
139
|
```bash
|
|
96
|
-
mado
|
|
97
|
-
|
|
140
|
+
mado new module billing
|
|
141
|
+
mado new page billing/pages/invoices-list
|
|
142
|
+
mado new connector billing/api/stripe
|
|
143
|
+
mado new resource billing/data/invoices
|
|
144
|
+
mado new service billing/cart
|
|
145
|
+
mado new form billing/invoice
|
|
146
|
+
mado new component billing/components/invoice-status-badge
|
|
147
|
+
mado new guard billing/billing
|
|
148
|
+
mado new layout app-shell
|
|
98
149
|
```
|
|
99
150
|
|
|
100
|
-
|
|
151
|
+
The generator writes files only. It does not edit `app.routes.ts`, does not scan
|
|
152
|
+
the filesystem, and refuses to overwrite existing files.
|
package/docs/ru/11-layouts.md
CHANGED
|
@@ -1,47 +1,47 @@
|
|
|
1
1
|
# Layouts
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
Не
|
|
5
|
-
если
|
|
3
|
+
Blessed layout способ в Mado — route group в `src/app.routes.ts`.
|
|
4
|
+
Не заворачивайте каждую страницу вручную и не кладите общий shell в `main.ts`,
|
|
5
|
+
если есть разные зоны: public, auth, app, embed.
|
|
6
6
|
|
|
7
7
|
```ts
|
|
8
8
|
import { layout, routes } from "@madojs/mado";
|
|
9
|
-
import { requireAuth } from "./
|
|
9
|
+
import { requireAuth } from "./modules/auth/auth.public";
|
|
10
|
+
import { authRoutes } from "./modules/auth/auth.routes";
|
|
11
|
+
import { billingRoutes } from "./modules/billing/billing.routes";
|
|
10
12
|
|
|
11
13
|
export const manifest = {
|
|
12
|
-
"/": () => import("./
|
|
14
|
+
"/": () => import("./modules/home/home.page.js"),
|
|
13
15
|
"/login": layout({
|
|
14
|
-
layout: () => import("./layouts/auth.js"),
|
|
15
|
-
routes:
|
|
16
|
+
layout: () => import("./layouts/auth-shell.layout.js"),
|
|
17
|
+
routes: authRoutes,
|
|
16
18
|
}),
|
|
17
|
-
"/
|
|
18
|
-
layout: () => import("./layouts/app.js"),
|
|
19
|
+
"/billing": layout({
|
|
20
|
+
layout: () => import("./layouts/app-shell.layout.js"),
|
|
19
21
|
guard: requireAuth,
|
|
20
|
-
routes:
|
|
21
|
-
"/": () => import("./pages/admin/dashboard.js"),
|
|
22
|
-
"/orders": () => import("./pages/admin/orders.js"),
|
|
23
|
-
},
|
|
22
|
+
routes: billingRoutes,
|
|
24
23
|
}),
|
|
25
|
-
"*": () => import("./
|
|
24
|
+
"*": () => import("./modules/home/not-found.page.js"),
|
|
26
25
|
};
|
|
27
26
|
|
|
28
27
|
export default routes(manifest);
|
|
29
28
|
```
|
|
30
29
|
|
|
31
|
-
Layout —
|
|
30
|
+
Layout — обычный `page({ view })`, который рендерит `child`:
|
|
32
31
|
|
|
33
32
|
```ts
|
|
34
33
|
export default page({
|
|
35
|
-
view: ({ child }) => html
|
|
34
|
+
view: ({ child }) => html`
|
|
35
|
+
<div class="layout layout--app">
|
|
36
|
+
<main class="app-main">${child}</main>
|
|
37
|
+
</div>
|
|
38
|
+
`,
|
|
36
39
|
});
|
|
37
40
|
```
|
|
38
41
|
|
|
39
|
-
|
|
42
|
+
Rules:
|
|
40
43
|
|
|
41
|
-
-
|
|
42
|
-
-
|
|
43
|
-
- guard
|
|
44
|
-
- layout
|
|
45
|
-
|
|
46
|
-
Single-shell wrapper в `main.ts` допустим только для приложений, где абсолютно
|
|
47
|
-
все роуты живут в одной оболочке.
|
|
44
|
+
- one shell per route group, not per page;
|
|
45
|
+
- modules export plain route maps and do not call `layout()`;
|
|
46
|
+
- guard on a group protects the whole subtree;
|
|
47
|
+
- layout view stays stateless; page-local state lives in pages/components/resources.
|
|
@@ -1,53 +1,75 @@
|
|
|
1
1
|
# Auth and API
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Default starter — blessed recipe. HTTP mechanics живут в `src/shared/http/`,
|
|
4
|
+
auth state — в `src/modules/auth/`.
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
```txt
|
|
7
|
+
src/shared/http/
|
|
8
|
+
http-client.ts
|
|
9
|
+
http-error.ts
|
|
10
|
+
interceptors.ts
|
|
8
11
|
|
|
9
|
-
|
|
12
|
+
src/modules/auth/
|
|
13
|
+
auth.connector.ts
|
|
14
|
+
auth.service.ts
|
|
15
|
+
auth.guard.ts
|
|
16
|
+
auth.routes.ts
|
|
17
|
+
auth.public.ts
|
|
18
|
+
_contracts/
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Flow для business module:
|
|
22
|
+
|
|
23
|
+
```txt
|
|
24
|
+
connector -> resource/mutation -> page
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Pages не импортируют DTOs и не вызывают `fetch()` напрямую. Connectors не
|
|
28
|
+
импортируют Mado reactivity или UI.
|
|
10
29
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
- protected routes закрываются group guard.
|
|
30
|
+
## Auth Service
|
|
31
|
+
|
|
32
|
+
Auth state — ES module singleton:
|
|
15
33
|
|
|
16
34
|
```ts
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
35
|
+
const _user = signal<User | null>(null);
|
|
36
|
+
const _token = signal<string | null>(null);
|
|
37
|
+
|
|
38
|
+
export const user = () => _user();
|
|
39
|
+
export const isAuthed = computed(() => _user() !== null);
|
|
22
40
|
```
|
|
23
41
|
|
|
24
|
-
|
|
42
|
+
Expose only what other modules need through `auth.public.ts`.
|
|
43
|
+
|
|
44
|
+
## Guards
|
|
25
45
|
|
|
26
46
|
```ts
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}),
|
|
47
|
+
export function requireAuth(): boolean | string {
|
|
48
|
+
if (isAuthed()) return true;
|
|
49
|
+
return "/login";
|
|
50
|
+
}
|
|
32
51
|
```
|
|
33
52
|
|
|
34
|
-
|
|
53
|
+
Use in `src/app.routes.ts`:
|
|
35
54
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
55
|
+
```ts
|
|
56
|
+
"/billing": layout({
|
|
57
|
+
layout: () => import("./layouts/app-shell.layout"),
|
|
58
|
+
guard: requireAuth,
|
|
59
|
+
routes: billingRoutes,
|
|
60
|
+
}),
|
|
61
|
+
```
|
|
41
62
|
|
|
42
|
-
|
|
63
|
+
## Dev Proxy
|
|
43
64
|
|
|
44
|
-
```
|
|
45
|
-
{
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
65
|
+
```ts
|
|
66
|
+
export default defineConfig({
|
|
67
|
+
plugins: [mado()],
|
|
68
|
+
server: {
|
|
69
|
+
proxy: { "/api": "http://localhost:3000" },
|
|
70
|
+
},
|
|
71
|
+
});
|
|
50
72
|
```
|
|
51
73
|
|
|
52
|
-
|
|
53
|
-
|
|
74
|
+
Rule: `shared/http` knows HTTP, connectors know one external system, resources
|
|
75
|
+
know cache keys, pages know UI, `*.public.ts` is the cross-module surface.
|
package/docs/ru/13-deployment.md
CHANGED
|
@@ -10,21 +10,18 @@ mado release
|
|
|
10
10
|
|
|
11
11
|
```txt
|
|
12
12
|
out/
|
|
13
|
-
├── index.html ← SPA shell или
|
|
14
|
-
├── assets/ ← hashed
|
|
13
|
+
├── index.html ← SPA shell или baked HTML для /
|
|
14
|
+
├── assets/ ← Vite hashed assets
|
|
15
15
|
│ ├── *.gz ← precompressed gzip
|
|
16
16
|
│ └── *.br ← precompressed brotli
|
|
17
|
-
├──
|
|
18
|
-
│ ├── <route>/index.html
|
|
19
|
-
│ └── sitemap.xml
|
|
20
|
-
├── <route>/index.html ← promoted baked HTML для static hosts
|
|
17
|
+
├── <route>/index.html ← baked HTML для static hosts
|
|
21
18
|
├── sitemap.xml ← sitemap в root сайта
|
|
22
19
|
├── _redirects ← Cloudflare Pages / Netlify SPA fallback
|
|
23
20
|
└── _headers ← cache rules
|
|
24
21
|
```
|
|
25
22
|
|
|
26
23
|
`out/` можно деплоить на nginx, Cloudflare Pages, Netlify, S3/CloudFront или
|
|
27
|
-
GitHub Pages.
|
|
24
|
+
GitHub Pages. Деплоится только `out/`.
|
|
28
25
|
|
|
29
26
|
## Preview
|
|
30
27
|
|
|
@@ -35,8 +32,7 @@ mado preview
|
|
|
35
32
|
|
|
36
33
|
`mado preview` сервит финальный `out/` как обычный static host: сначала реальные
|
|
37
34
|
файлы (`/<route>/index.html`, если route был baked), потом SPA fallback в
|
|
38
|
-
`index.html`. Preview
|
|
39
|
-
`out/baked/`, поэтому он проверяет ровно то, что будет загружено на хостинг.
|
|
35
|
+
`index.html`. Preview проверяет ровно то, что будет загружено на хостинг.
|
|
40
36
|
|
|
41
37
|
## VPS + nginx
|
|
42
38
|
|
|
@@ -45,8 +41,8 @@ mado release
|
|
|
45
41
|
rsync -avz --delete out/ user@server:/var/www/myapp/
|
|
46
42
|
```
|
|
47
43
|
|
|
48
|
-
|
|
49
|
-
HTML идет с `no-cache`, deep links работают через SPA fallback.
|
|
44
|
+
Опциональный nginx-рецепт лежит в `docs/recipes/nginx/`: assets кешируются
|
|
45
|
+
immutable, HTML идет с `no-cache`, deep links работают через SPA fallback.
|
|
50
46
|
|
|
51
47
|
## Cloudflare / Netlify
|
|
52
48
|
|
package/docs/ru/14-testing.md
CHANGED
|
@@ -26,7 +26,7 @@ globalThis.document = window.document;
|
|
|
26
26
|
globalThis.Node = window.Node;
|
|
27
27
|
globalThis.HTMLElement = window.HTMLElement;
|
|
28
28
|
|
|
29
|
-
const { html, render } = await import("../dist/src/html.js");
|
|
29
|
+
const { html, render } = await import("../dist/src/html/template.js");
|
|
30
30
|
|
|
31
31
|
test("renders a value", () => {
|
|
32
32
|
const root = document.createElement("div");
|
|
@@ -55,10 +55,9 @@ export default routes(manifest);
|
|
|
55
55
|
|
|
56
56
|
## Output
|
|
57
57
|
|
|
58
|
-
Standalone `mado bake` по умолчанию пишет baked pages в `out
|
|
59
|
-
`mado release`
|
|
60
|
-
|
|
61
|
-
`out/` и копирует sitemap в `out/sitemap.xml`.
|
|
58
|
+
Standalone `mado bake` по умолчанию пишет baked pages прямо в `out/`.
|
|
59
|
+
`mado release` сначала запускает Vite build, затем bake заменяет route HTML
|
|
60
|
+
на месте и пишет sitemap в `out/sitemap.xml`.
|
|
62
61
|
|
|
63
62
|
```bash
|
|
64
63
|
mado release
|
|
@@ -67,6 +66,9 @@ tree out
|
|
|
67
66
|
|
|
68
67
|
Deployable folder — `out/`, не `dist/`.
|
|
69
68
|
|
|
69
|
+
`mado release --keep-bake-dir` оставляет дополнительную копию `out/baked/`
|
|
70
|
+
только для debugging/inspection.
|
|
71
|
+
|
|
70
72
|
## Client Boot
|
|
71
73
|
|
|
72
74
|
Baked HTML помечает `#app` атрибутом `data-mado-baked`. Это не hydration:
|
|
@@ -85,5 +87,9 @@ Bake намеренно падает громко вместо записи `[ob
|
|
|
85
87
|
|
|
86
88
|
## Canonical Links
|
|
87
89
|
|
|
88
|
-
Передай `--base-url
|
|
89
|
-
|
|
90
|
+
Передай `--base-url`, чтобы canonical links и sitemap указывали на production.
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
mado bake --base-url https://example.com
|
|
94
|
+
mado release --base-url https://example.com
|
|
95
|
+
```
|
|
@@ -9,10 +9,11 @@
|
|
|
9
9
|
import { component, html, resource, routes, signal } from "@madojs/mado";
|
|
10
10
|
```
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
Публичные subpaths — side-effect модуль devtools и Vite integration:
|
|
13
13
|
|
|
14
14
|
```ts
|
|
15
15
|
import "@madojs/mado/devtools.js";
|
|
16
|
+
import { mado } from "@madojs/mado/vite";
|
|
16
17
|
```
|
|
17
18
|
|
|
18
19
|
Все остальное под `dist/src/` — деталь реализации, даже если файл виден в
|
|
@@ -27,7 +28,7 @@ import "@madojs/mado/devtools.js";
|
|
|
27
28
|
- Templates и directives: `html`, `render`, `each`, `list`, `unsafeHTML`,
|
|
28
29
|
`ref`, `classMap`, `styleMap`.
|
|
29
30
|
- Components и CSS: `component`, `css`, `cssVars`.
|
|
30
|
-
- Routing и pages: `routes`, `router`, `page`, `layout`,
|
|
31
|
+
- Routing и pages: `routes`, `router`, `page`, `layout`,
|
|
31
32
|
`navigate`, `queryParam`, `prefetchPath`.
|
|
32
33
|
- Data: `resource`, `mutation`, `invalidate`, `jsonFetcher`, `HttpError`.
|
|
33
34
|
- Forms: `useForm`.
|
|
@@ -41,7 +42,8 @@ import "@madojs/mado/devtools.js";
|
|
|
41
42
|
|
|
42
43
|
Это не публичный API:
|
|
43
44
|
|
|
44
|
-
- Package subpaths кроме `@madojs/mado
|
|
45
|
+
- Package subpaths кроме `@madojs/mado`, `@madojs/mado/devtools.js` и
|
|
46
|
+
`@madojs/mado/vite`.
|
|
45
47
|
- Internals парсера/биндингов: `html/parser.js`, `html/bindings.js`,
|
|
46
48
|
`ChildState`, `EachEntry`.
|
|
47
49
|
- Internals роутера: `router/match.js`, `router/navigation.js`,
|
|
@@ -25,7 +25,7 @@ byte, starter copy или diagnostic string заморожены навсегд
|
|
|
25
25
|
deferred teardown для same-tick moves, cleanup через `ctx.onDispose`.
|
|
26
26
|
- Router/page/resource/form contracts, описанные в English docs.
|
|
27
27
|
- Имена CLI commands и широкий смысл команд (`build`, `dev`, `release`,
|
|
28
|
-
`bake`, `
|
|
28
|
+
`bake`, `preview`, `init`, `new`).
|
|
29
29
|
|
|
30
30
|
Ломать это можно только в major version.
|
|
31
31
|
|