@bleedingdev/modern-js-create 3.2.0-ultramodern.5 → 3.2.0-ultramodern.50
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/README.md +118 -15
- package/dist/index.js +4930 -454
- package/dist/types/locale/en.d.ts +2 -0
- package/dist/types/locale/zh.d.ts +2 -0
- package/dist/types/ultramodern-workspace.d.ts +13 -0
- package/package.json +8 -5
- package/template/.agents/skills-lock.json +34 -0
- package/template/.github/renovate.json +53 -0
- package/template/.github/workflows/ultramodern-gates.yml.handlebars +34 -10
- package/template/.mise.toml.handlebars +2 -0
- package/template/AGENTS.md +27 -0
- package/template/README.md +115 -14
- package/template/api/effect/index.ts.handlebars +7 -45
- package/template/config/public/locales/cs/translation.json +39 -0
- package/template/config/public/locales/en/translation.json +39 -0
- package/template/modern.config.ts.handlebars +44 -23
- package/template/oxfmt.config.ts +8 -0
- package/template/oxlint.config.ts +12 -0
- package/template/package.json.handlebars +59 -30
- package/template/pnpm-workspace.yaml +26 -0
- package/template/rstest.config.mts +7 -0
- package/template/scripts/bootstrap-agent-skills.mjs +103 -0
- package/template/scripts/check-i18n-strings.mjs +83 -0
- package/template/scripts/validate-ultramodern.mjs.handlebars +438 -16
- package/template/shared/effect/api.ts.handlebars +1 -2
- package/template/src/modern-app-env.d.ts +2 -0
- package/template/src/modern.runtime.ts.handlebars +17 -3
- package/template/src/routes/[lang]/page.tsx.handlebars +210 -0
- package/template/src/routes/index.css.handlebars +14 -3
- package/template/src/routes/layout.tsx.handlebars +2 -1
- package/template/tests/tsconfig.json +7 -0
- package/template/tests/ultramodern.contract.test.ts.handlebars +78 -0
- package/template/tsconfig.json +106 -2
- package/template-workspace/.agents/agent-reference-repos.json +24 -0
- package/template-workspace/.agents/rstackjs-agent-skills-LICENSE +21 -0
- package/template-workspace/.agents/skills/rsbuild-best-practices/SKILL.md +57 -0
- package/template-workspace/.agents/skills/rsdoctor-analysis/SKILL.md +96 -0
- package/template-workspace/.agents/skills/rsdoctor-analysis/references/command-map.md +113 -0
- package/template-workspace/.agents/skills/rsdoctor-analysis/references/common-analysis-patterns.md +190 -0
- package/template-workspace/.agents/skills/rsdoctor-analysis/references/install-rsdoctor-common.md +88 -0
- package/template-workspace/.agents/skills/rsdoctor-analysis/references/install-rsdoctor-rspack.md +138 -0
- package/template-workspace/.agents/skills/rsdoctor-analysis/references/install-rsdoctor-webpack.md +71 -0
- package/template-workspace/.agents/skills/rsdoctor-analysis/references/install-rsdoctor.md +39 -0
- package/template-workspace/.agents/skills/rsdoctor-analysis/references/rsdoctor-data-types.md +103 -0
- package/template-workspace/.agents/skills/rslib-best-practices/SKILL.md +58 -0
- package/template-workspace/.agents/skills/rslib-modern-package/SKILL.md +173 -0
- package/template-workspace/.agents/skills/rspack-best-practices/SKILL.md +70 -0
- package/template-workspace/.agents/skills/rspack-tracing/SKILL.md +75 -0
- package/template-workspace/.agents/skills/rspack-tracing/references/bottlenecks.md +47 -0
- package/template-workspace/.agents/skills/rspack-tracing/references/tracing-guide.md +38 -0
- package/template-workspace/.agents/skills/rspack-tracing/scripts/analyze_trace.js +184 -0
- package/template-workspace/.agents/skills/rstest-best-practices/SKILL.md +133 -0
- package/template-workspace/.agents/skills-lock.json +114 -0
- package/template-workspace/.github/renovate.json +29 -0
- package/template-workspace/.github/workflows/ultramodern-workspace-gates.yml.handlebars +54 -0
- package/template-workspace/.gitignore.handlebars +5 -0
- package/template-workspace/.mise.toml.handlebars +2 -0
- package/template-workspace/AGENTS.md +61 -0
- package/template-workspace/README.md.handlebars +26 -5
- package/template-workspace/oxfmt.config.ts +16 -0
- package/template-workspace/oxlint.config.ts +19 -0
- package/template-workspace/pnpm-workspace.yaml +19 -8
- package/template-workspace/scripts/assert-mf-types.mjs +44 -0
- package/template-workspace/scripts/bootstrap-agent-skills.mjs +163 -0
- package/template-workspace/scripts/setup-agent-reference-repos.mjs +364 -0
- package/template-workspace/scripts/validate-ultramodern-workspace.mjs.handlebars +743 -87
- package/template/biome.json +0 -41
- package/template/src/routes/page.tsx.handlebars +0 -119
|
@@ -35,6 +35,7 @@ export declare const EN_LOCALE: {
|
|
|
35
35
|
optionUltramodernPackageSource: string;
|
|
36
36
|
optionUltramodernPackageScope: string;
|
|
37
37
|
optionUltramodernPackageNamePrefix: string;
|
|
38
|
+
optionMicroVertical: string;
|
|
38
39
|
optionSub: string;
|
|
39
40
|
examples: string;
|
|
40
41
|
example1: string;
|
|
@@ -47,6 +48,7 @@ export declare const EN_LOCALE: {
|
|
|
47
48
|
example8: string;
|
|
48
49
|
example9: string;
|
|
49
50
|
example10: string;
|
|
51
|
+
example11: string;
|
|
50
52
|
moreInfo: string;
|
|
51
53
|
};
|
|
52
54
|
version: {
|
|
@@ -35,6 +35,7 @@ export declare const ZH_LOCALE: {
|
|
|
35
35
|
optionUltramodernPackageSource: string;
|
|
36
36
|
optionUltramodernPackageScope: string;
|
|
37
37
|
optionUltramodernPackageNamePrefix: string;
|
|
38
|
+
optionMicroVertical: string;
|
|
38
39
|
optionSub: string;
|
|
39
40
|
examples: string;
|
|
40
41
|
example1: string;
|
|
@@ -47,6 +48,7 @@ export declare const ZH_LOCALE: {
|
|
|
47
48
|
example8: string;
|
|
48
49
|
example9: string;
|
|
49
50
|
example10: string;
|
|
51
|
+
example11: string;
|
|
50
52
|
moreInfo: string;
|
|
51
53
|
};
|
|
52
54
|
version: {
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
export type MicroVerticalKind = 'remote' | 'horizontal-remote' | 'service' | 'shared';
|
|
1
2
|
type UltramodernPackageSourceStrategy = 'workspace' | 'install';
|
|
2
3
|
export type UltramodernWorkspaceOptions = {
|
|
3
4
|
targetDir: string;
|
|
4
5
|
packageName: string;
|
|
5
6
|
modernVersion: string;
|
|
7
|
+
enableTailwind?: boolean;
|
|
6
8
|
packageSource?: {
|
|
7
9
|
strategy?: UltramodernPackageSourceStrategy;
|
|
8
10
|
modernPackageVersion?: string;
|
|
@@ -11,10 +13,21 @@ export type UltramodernWorkspaceOptions = {
|
|
|
11
13
|
aliasPackageNamePrefix?: string;
|
|
12
14
|
};
|
|
13
15
|
};
|
|
16
|
+
export type AddUltramodernMicroVerticalOptions = {
|
|
17
|
+
workspaceRoot: string;
|
|
18
|
+
name: string;
|
|
19
|
+
kind: MicroVerticalKind;
|
|
20
|
+
modernVersion: string;
|
|
21
|
+
enableTailwind?: boolean;
|
|
22
|
+
packageSource?: UltramodernWorkspaceOptions['packageSource'];
|
|
23
|
+
};
|
|
14
24
|
export declare const ULTRAMODERN_WORKSPACE_FLAG = "--ultramodern-workspace";
|
|
25
|
+
export declare function addUltramodernMicroVertical(options: AddUltramodernMicroVerticalOptions): void;
|
|
15
26
|
export declare function generateUltramodernWorkspace(options: UltramodernWorkspaceOptions): void;
|
|
16
27
|
export declare const ultramodernWorkspaceVersions: {
|
|
17
28
|
tanstackRouter: string;
|
|
18
29
|
moduleFederation: string;
|
|
30
|
+
tailwind: string;
|
|
31
|
+
tailwindPostcss: string;
|
|
19
32
|
};
|
|
20
33
|
export {};
|
package/package.json
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"engines": {
|
|
22
22
|
"node": ">=20"
|
|
23
23
|
},
|
|
24
|
-
"version": "3.2.0-ultramodern.
|
|
24
|
+
"version": "3.2.0-ultramodern.50",
|
|
25
25
|
"types": "./dist/types/index.d.ts",
|
|
26
26
|
"main": "./dist/index.js",
|
|
27
27
|
"bin": {
|
|
@@ -38,10 +38,10 @@
|
|
|
38
38
|
],
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@rslib/core": "0.21.5",
|
|
41
|
-
"@types/node": "^25.
|
|
42
|
-
"@typescript/native-preview": "7.0.0-dev.
|
|
43
|
-
"tsx": "^4.22.
|
|
44
|
-
"@modern-js/i18n-utils": "npm:@bleedingdev/modern-js-i18n-utils@3.2.0-ultramodern.
|
|
41
|
+
"@types/node": "^25.9.1",
|
|
42
|
+
"@typescript/native-preview": "7.0.0-dev.20260527.2",
|
|
43
|
+
"tsx": "^4.22.3",
|
|
44
|
+
"@modern-js/i18n-utils": "npm:@bleedingdev/modern-js-i18n-utils@3.2.0-ultramodern.50"
|
|
45
45
|
},
|
|
46
46
|
"publishConfig": {
|
|
47
47
|
"registry": "https://registry.npmjs.org/",
|
|
@@ -52,5 +52,8 @@
|
|
|
52
52
|
"build": "rslib build && pnpm -w tsgo:dts \"$PWD\"",
|
|
53
53
|
"dev": "rslib build -w",
|
|
54
54
|
"start": "node ./dist/index.js"
|
|
55
|
+
},
|
|
56
|
+
"ultramodern": {
|
|
57
|
+
"frameworkVersion": "3.2.0-ultramodern.50"
|
|
55
58
|
}
|
|
56
59
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 2,
|
|
3
|
+
"installDir": ".agents/skills",
|
|
4
|
+
"sources": [
|
|
5
|
+
{
|
|
6
|
+
"id": "techsiocz-private",
|
|
7
|
+
"visibility": "private",
|
|
8
|
+
"repository": "https://github.com/TechsioCZ/skills",
|
|
9
|
+
"install": "clone-if-authorized",
|
|
10
|
+
"baseline": [
|
|
11
|
+
{
|
|
12
|
+
"name": "plan-graph",
|
|
13
|
+
"reason": "Build and validate DAGs from .plan.md files"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"name": "dag",
|
|
17
|
+
"reason": "Inspect current plan frontiers and blocked lanes"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"name": "subagent-graph",
|
|
21
|
+
"reason": "Design dependency-aware multi-agent launch graphs"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"name": "helm",
|
|
25
|
+
"reason": "Steer already-running multi-agent work"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"name": "debugger-mode",
|
|
29
|
+
"reason": "Run hypothesis-driven debugging with runtime evidence"
|
|
30
|
+
}
|
|
31
|
+
]
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
|
3
|
+
"extends": [
|
|
4
|
+
"config:recommended",
|
|
5
|
+
"helpers:pinGitHubActionDigests"
|
|
6
|
+
],
|
|
7
|
+
"dependencyDashboard": true,
|
|
8
|
+
"minimumReleaseAge": "1 day",
|
|
9
|
+
"prConcurrentLimit": 5,
|
|
10
|
+
"prHourlyLimit": 2,
|
|
11
|
+
"rangeStrategy": "bump",
|
|
12
|
+
"schedule": [
|
|
13
|
+
"before 5am on monday"
|
|
14
|
+
],
|
|
15
|
+
"timezone": "Etc/UTC",
|
|
16
|
+
"packageRules": [
|
|
17
|
+
{
|
|
18
|
+
"matchManagers": [
|
|
19
|
+
"github-actions"
|
|
20
|
+
],
|
|
21
|
+
"groupName": "github-actions",
|
|
22
|
+
"labels": [
|
|
23
|
+
"dependencies",
|
|
24
|
+
"github-actions",
|
|
25
|
+
"security"
|
|
26
|
+
]
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"matchManagers": [
|
|
30
|
+
"npm"
|
|
31
|
+
],
|
|
32
|
+
"matchUpdateTypes": [
|
|
33
|
+
"patch",
|
|
34
|
+
"minor"
|
|
35
|
+
],
|
|
36
|
+
"groupName": "npm minor and patch updates",
|
|
37
|
+
"labels": [
|
|
38
|
+
"dependencies",
|
|
39
|
+
"npm"
|
|
40
|
+
]
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"matchUpdateTypes": [
|
|
44
|
+
"major"
|
|
45
|
+
],
|
|
46
|
+
"dependencyDashboardApproval": true,
|
|
47
|
+
"labels": [
|
|
48
|
+
"dependencies",
|
|
49
|
+
"major"
|
|
50
|
+
]
|
|
51
|
+
}
|
|
52
|
+
]
|
|
53
|
+
}
|
|
@@ -4,27 +4,51 @@ on:
|
|
|
4
4
|
push:
|
|
5
5
|
pull_request:
|
|
6
6
|
|
|
7
|
+
permissions:
|
|
8
|
+
contents: read
|
|
9
|
+
|
|
10
|
+
defaults:
|
|
11
|
+
run:
|
|
12
|
+
shell: bash
|
|
13
|
+
|
|
14
|
+
env:
|
|
15
|
+
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
|
|
16
|
+
|
|
17
|
+
concurrency:
|
|
18
|
+
group: ultramodern-gates-${{ github.workflow }}-${{ github.ref }}
|
|
19
|
+
cancel-in-progress: true
|
|
20
|
+
|
|
7
21
|
jobs:
|
|
8
22
|
ultramodern-gates:
|
|
9
23
|
runs-on: ubuntu-latest
|
|
24
|
+
timeout-minutes: 20
|
|
10
25
|
steps:
|
|
11
|
-
- name:
|
|
12
|
-
uses:
|
|
26
|
+
- name: Harden Runner
|
|
27
|
+
uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2
|
|
28
|
+
with:
|
|
29
|
+
egress-policy: audit
|
|
13
30
|
|
|
14
|
-
- name:
|
|
15
|
-
uses:
|
|
31
|
+
- name: Checkout
|
|
32
|
+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
33
|
+
with:
|
|
34
|
+
fetch-depth: 1
|
|
35
|
+
persist-credentials: false
|
|
16
36
|
|
|
17
37
|
- name: Setup Node.js
|
|
18
|
-
uses: actions/setup-node@
|
|
38
|
+
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
|
19
39
|
with:
|
|
20
|
-
node-version:
|
|
21
|
-
|
|
40
|
+
node-version: 24
|
|
41
|
+
|
|
42
|
+
- name: Setup mise
|
|
43
|
+
uses: jdx/mise-action@5ac50f778e26fac95da98d50503682459e86d566 # v3.2.0
|
|
22
44
|
|
|
23
45
|
- name: Install Dependencies
|
|
24
|
-
run: pnpm install
|
|
46
|
+
run: mise exec -- pnpm install --frozen-lockfile
|
|
25
47
|
|
|
26
48
|
- name: Validate Ultramodern Contract
|
|
27
|
-
run: pnpm run ultramodern:check
|
|
49
|
+
run: mise exec -- pnpm run ultramodern:check
|
|
28
50
|
|
|
29
51
|
- name: Build
|
|
30
|
-
|
|
52
|
+
env:
|
|
53
|
+
MODERN_PUBLIC_SITE_URL: http://localhost:8080
|
|
54
|
+
run: mise exec -- pnpm run build
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# UltraModern Agent Contract
|
|
2
|
+
|
|
3
|
+
This project is generated for Codex-first UltraModern.js work.
|
|
4
|
+
|
|
5
|
+
## Quality Gates
|
|
6
|
+
|
|
7
|
+
- `pnpm lint` runs Oxlint with the Ultracite preset.
|
|
8
|
+
- `pnpm format` runs oxfmt.
|
|
9
|
+
- `pnpm typecheck` runs effect-tsgo as the TypeScript checker.
|
|
10
|
+
- `pnpm i18n:check` rejects hardcoded user-visible JSX text.
|
|
11
|
+
- `mise exec -- pnpm ultramodern:check` verifies the generated contract.
|
|
12
|
+
|
|
13
|
+
## Internationalization
|
|
14
|
+
|
|
15
|
+
Runtime i18n is enabled by default. Agents must put user-visible UI copy in `config/public/locales/<lang>/translation.json` and render it through `react-i18next` or `@modern-js/plugin-i18n/runtime`. Do not add hardcoded JSX text, `aria-label`, `title`, `alt`, or `placeholder` strings unless the value is a non-translatable technical token.
|
|
16
|
+
|
|
17
|
+
Routes are locale-prefixed by default through `localePathRedirect: true`. Keep localized pages under `src/routes/[lang]`, use links for language switching, and preserve canonical plus `hreflang` metadata. Production builds fail unless `MODERN_PUBLIC_SITE_URL` is set, so deployed canonical URLs always use the production origin.
|
|
18
|
+
|
|
19
|
+
## Private Skills
|
|
20
|
+
|
|
21
|
+
Private orchestration skills are not vendored into this template. If you are authorized for `TechsioCZ/skills`, run:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
pnpm skills:install
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
The installer clones that private repository and copies only the allowlisted skills from `.agents/skills-lock.json`.
|
package/template/README.md
CHANGED
|
@@ -1,11 +1,26 @@
|
|
|
1
1
|
# UltraModern.js 3.0 Starter
|
|
2
2
|
|
|
3
|
+
This generated workspace is the Tractor reference SuperApp. It is built around
|
|
4
|
+
one shell and three full-stack Micro Verticals:
|
|
5
|
+
|
|
6
|
+
| Package | Boundary |
|
|
7
|
+
| --- | --- |
|
|
8
|
+
| `apps/shell-super-app` | Module Federation host, route assembly, topology selection, shell fallback policy |
|
|
9
|
+
| `apps/remotes/remote-explore` | Explore routes, MF exposes, locale JSON, CSS layer, and `/explore-api/effect/explore/*` |
|
|
10
|
+
| `apps/remotes/remote-decide` | Decide routes, MF exposes, locale JSON, CSS layer, and `/decide-api/effect/decide/*` |
|
|
11
|
+
| `apps/remotes/remote-checkout` | Checkout routes, MF exposes, locale JSON, CSS layer, and `/checkout-api/effect/checkout/*` |
|
|
12
|
+
|
|
13
|
+
Each vertical is a one-package ownership boundary. Its UI, Effect BFF contract,
|
|
14
|
+
generated client, `localisedUrls`, dynamic locale JSON, CSS, MF manifest, and
|
|
15
|
+
Cloudflare Worker output must move together for version-switching proof.
|
|
16
|
+
|
|
3
17
|
## Setup
|
|
4
18
|
|
|
5
19
|
Install the dependencies:
|
|
6
20
|
|
|
7
21
|
```bash
|
|
8
|
-
|
|
22
|
+
mise install
|
|
23
|
+
mise exec -- pnpm install
|
|
9
24
|
```
|
|
10
25
|
|
|
11
26
|
## Get Started
|
|
@@ -13,19 +28,27 @@ pnpm install
|
|
|
13
28
|
Start the dev server:
|
|
14
29
|
|
|
15
30
|
```bash
|
|
16
|
-
pnpm dev
|
|
31
|
+
mise exec -- pnpm dev
|
|
17
32
|
```
|
|
18
33
|
|
|
19
34
|
Build the app for production:
|
|
20
35
|
|
|
21
36
|
```bash
|
|
22
|
-
pnpm build
|
|
37
|
+
mise exec -- pnpm build
|
|
23
38
|
```
|
|
24
39
|
|
|
25
40
|
Validate the generated Ultramodern preset contract locally:
|
|
26
41
|
|
|
27
42
|
```bash
|
|
28
|
-
pnpm run ultramodern:check
|
|
43
|
+
mise exec -- pnpm run ultramodern:check
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Run the normal local gates before treating the scaffold as adoption-ready:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
mise exec -- pnpm run check
|
|
50
|
+
mise exec -- pnpm run build
|
|
51
|
+
mise exec -- pnpm run cloudflare:build
|
|
29
52
|
```
|
|
30
53
|
|
|
31
54
|
The generated preset defaults are opt-out. Disable specific contracts via env vars:
|
|
@@ -36,20 +59,25 @@ MODERN_BASELINE_ENABLE_BFF_REQUEST_ID=false
|
|
|
36
59
|
MODERN_BASELINE_ENABLE_TELEMETRY_EXPORTERS=false
|
|
37
60
|
```
|
|
38
61
|
|
|
39
|
-
The generated starter also includes `.github/workflows/ultramodern-gates.yml
|
|
40
|
-
|
|
41
|
-
|
|
62
|
+
The generated starter also includes `.github/workflows/ultramodern-gates.yml`
|
|
63
|
+
and `.github/renovate.json`. The workflow runs
|
|
64
|
+
`mise exec -- pnpm run ultramodern:check` and `mise exec -- pnpm run build` on
|
|
65
|
+
every push and pull request with read-only permissions, commit-pinned actions,
|
|
66
|
+
frozen installs, and StepSecurity audit-mode runner hardening. Renovate is
|
|
67
|
+
configured for dependency dashboard review, one-day release age, grouped
|
|
68
|
+
updates, action digest pinning, and manual approval for major upgrades.
|
|
42
69
|
|
|
43
70
|
## Micro Vertical Workspaces
|
|
44
71
|
|
|
45
|
-
Inside a Micro Vertical workspace,
|
|
46
|
-
|
|
72
|
+
Inside a Micro Vertical workspace, add packages from the workspace root with
|
|
73
|
+
the UltraModern add flow. It derives paths, package names, ports, Module
|
|
74
|
+
Federation names, topology entries, overlays, ownership, and root dev scripts:
|
|
47
75
|
|
|
48
76
|
```bash
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
77
|
+
mise exec -- pnpm dlx @modern-js/create catalog --microvertical remote
|
|
78
|
+
mise exec -- pnpm dlx @modern-js/create design-system --microvertical horizontal-remote
|
|
79
|
+
mise exec -- pnpm dlx @modern-js/create catalog-api --microvertical service
|
|
80
|
+
mise exec -- pnpm dlx @modern-js/create catalog-contracts --microvertical shared
|
|
53
81
|
```
|
|
54
82
|
|
|
55
83
|
The canonical topology is documented in
|
|
@@ -59,6 +87,12 @@ route subtrees and degraded UI, service packages own Effect or explicit Hono
|
|
|
59
87
|
contracts, and shared packages are limited to tokens, primitives, generated
|
|
60
88
|
clients, or domain-neutral utilities.
|
|
61
89
|
|
|
90
|
+
Use a new vertical only when the feature needs its own route subtree owner,
|
|
91
|
+
independent rollout, rollback, Cloudflare/Zephyr evidence, or incident routing.
|
|
92
|
+
Keep code inside an existing vertical when it shares the same product owner,
|
|
93
|
+
fallback behavior, release train, and Effect contract. Do not use a shared
|
|
94
|
+
package for feature composites or workflow state.
|
|
95
|
+
|
|
62
96
|
If the design system needs independent deployment, keep it as a horizontal
|
|
63
97
|
Module Federation remote with the same topology, trust, SSR compatibility, and
|
|
64
98
|
fallback rules as the vertical remotes. Do not add a second preset or a
|
|
@@ -68,10 +102,77 @@ The public opinionated entrypoint is `presetUltramodern(...)`. It is the default
|
|
|
68
102
|
UltraModern.js SuperApp surface for Effect, TanStack, SSR, BFF, and Micro
|
|
69
103
|
Verticals.
|
|
70
104
|
|
|
105
|
+
## Module Federation And Effect Ownership
|
|
106
|
+
|
|
107
|
+
The shell consumes vertical UI through MF manifests and consumes vertical data
|
|
108
|
+
through generated Effect clients exported by the remote packages:
|
|
109
|
+
|
|
110
|
+
- Explore exposes header, footer, recommendations, store picker, and route UI.
|
|
111
|
+
- Decide exposes product page and route UI, and may consume Explore or Checkout
|
|
112
|
+
remotes through declared `remoteRefs`.
|
|
113
|
+
- Checkout exposes cart, checkout, thanks, mini-cart, add-to-cart, and route UI.
|
|
114
|
+
|
|
115
|
+
The shell owns orchestration and fallback policy. A vertical owns its route-local
|
|
116
|
+
loader/action behavior, degraded UI, `api/effect/index.ts`, shared Effect API
|
|
117
|
+
contract, generated client, and readiness endpoint. Hono remains a compatibility
|
|
118
|
+
lane only when explicitly scaffolded outside the default Tractor workspace.
|
|
119
|
+
|
|
120
|
+
## I18n And CSS Ownership
|
|
121
|
+
|
|
122
|
+
Route localization is owned by the package that owns the route. Each app emits
|
|
123
|
+
`src/routes/ultramodern-route-metadata` and passes
|
|
124
|
+
`ultramodernLocalisedUrls` to `@modern-js/plugin-i18n`. Dynamic JSON resources
|
|
125
|
+
are served from `/locales/{{lng}}/{{ns}}.json`; shell rewrites must not replace
|
|
126
|
+
remote-owned localized URL maps.
|
|
127
|
+
|
|
128
|
+
CSS federation is recorded in `.modernjs/ultramodern-generated-contract.json`:
|
|
129
|
+
|
|
130
|
+
- `packages/shared-design-tokens` owns `ultramodern-shared-tokens` and exports
|
|
131
|
+
`./tokens.css`.
|
|
132
|
+
- The shell owns shell base and overlay CSS under its app root marker.
|
|
133
|
+
- Each remote owns one vertical CSS layer and one remote app root marker.
|
|
134
|
+
- Tailwind CSS v4 is app-local through `@tailwindcss/postcss`.
|
|
135
|
+
- Duplicate base styles are forbidden. SSR first paint requires shared tokens
|
|
136
|
+
and Modern/Rspack-emitted app CSS.
|
|
137
|
+
|
|
138
|
+
## Cloudflare And Zephyr Evidence
|
|
139
|
+
|
|
140
|
+
Build all Cloudflare Worker artifacts:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
MODERN_PUBLIC_SITE_URL=https://shell-super-app.example.test mise exec -- pnpm run cloudflare:build
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Validate local or deployed Cloudflare output with the repo harness:
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
node scripts/ultramodern-cloudflare-ssr-validation/validate-cloudflare-ssr.js \
|
|
150
|
+
--root-dir apps/remotes/remote-checkout \
|
|
151
|
+
--bff /checkout-api/effect/checkout/readiness \
|
|
152
|
+
--expect-en "Checkout Remote" \
|
|
153
|
+
--match-build-marker \
|
|
154
|
+
--out .codex/reports/cloudflare-ssr/remote-checkout-local.json
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
After deploying public Workers, run the generated public URL proof:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
ULTRAMODERN_PUBLIC_URL_SHELL_SUPER_APP=https://shell-super-app.example.workers.dev \
|
|
161
|
+
ULTRAMODERN_PUBLIC_URL_REMOTE_EXPLORE=https://remote-explore.example.workers.dev \
|
|
162
|
+
ULTRAMODERN_PUBLIC_URL_REMOTE_DECIDE=https://remote-decide.example.workers.dev \
|
|
163
|
+
ULTRAMODERN_PUBLIC_URL_REMOTE_CHECKOUT=https://remote-checkout.example.workers.dev \
|
|
164
|
+
mise exec -- pnpm run cloudflare:proof -- --require-public-urls
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Zephyr upload and live switching proof are opt-in evidence workflows. The
|
|
168
|
+
workspace records `zephyr:dependencies` and wires `zephyr-rspack-plugin`, but
|
|
169
|
+
live proof still requires public manifest, runtime, and API URLs plus Zephyr
|
|
170
|
+
credentials. Without those values, only dry-run Zephyr evidence can be claimed.
|
|
171
|
+
|
|
71
172
|
Preview the production build locally:
|
|
72
173
|
|
|
73
174
|
```bash
|
|
74
|
-
pnpm serve
|
|
175
|
+
mise exec -- pnpm serve
|
|
75
176
|
```
|
|
76
177
|
|
|
77
178
|
For more information, see the
|
|
@@ -2,60 +2,22 @@
|
|
|
2
2
|
Effect,
|
|
3
3
|
HttpApiBuilder,
|
|
4
4
|
Layer,
|
|
5
|
-
Schema,
|
|
6
|
-
ServiceMap,
|
|
7
5
|
defineEffectBff,
|
|
8
6
|
} from '@modern-js/plugin-bff/effect-server';
|
|
9
7
|
import { bffEffectApi } from '../../shared/effect/api';
|
|
10
8
|
|
|
11
|
-
|
|
12
|
-
'GreetingUnavailableError',
|
|
13
|
-
{
|
|
14
|
-
message: Schema.String,
|
|
15
|
-
},
|
|
16
|
-
) {}
|
|
17
|
-
|
|
18
|
-
class GreetingService extends ServiceMap.Service<GreetingService>()('GreetingService', {
|
|
19
|
-
make: Effect.succeed({
|
|
20
|
-
hello: Effect.fn('GreetingService.hello')(function* () {
|
|
21
|
-
if (Date.now() < 0) {
|
|
22
|
-
return yield* Effect.fail(
|
|
23
|
-
new GreetingUnavailableError({
|
|
24
|
-
message: 'Greeting service is unavailable',
|
|
25
|
-
}),
|
|
26
|
-
);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
return {
|
|
30
|
-
message: 'Hello from Effect HttpApi',
|
|
31
|
-
runtime: 'effect' as const,
|
|
32
|
-
};
|
|
33
|
-
}),
|
|
34
|
-
}),
|
|
35
|
-
}) {
|
|
36
|
-
static readonly layer = Layer.effect(this, this.make);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const greetingsLayer = HttpApiBuilder.group(bffEffectApi, 'greetings', handlers =>
|
|
9
|
+
const greetingsLayer = HttpApiBuilder.group(bffEffectApi, 'greetings', (handlers) =>
|
|
40
10
|
handlers.handle('hello', () =>
|
|
41
|
-
|
|
42
|
-
Effect
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
runtime: 'effect' as const,
|
|
46
|
-
}),
|
|
47
|
-
),
|
|
48
|
-
),
|
|
11
|
+
Effect.succeed({
|
|
12
|
+
message: 'Hello from Effect HttpApi',
|
|
13
|
+
runtime: 'effect' as const,
|
|
14
|
+
}),
|
|
49
15
|
),
|
|
50
16
|
);
|
|
51
17
|
|
|
52
|
-
const layer = HttpApiBuilder.layer(bffEffectApi).pipe(
|
|
53
|
-
Layer.provide(greetingsLayer),
|
|
54
|
-
Layer.provide(GreetingService.layer),
|
|
55
|
-
);
|
|
18
|
+
const layer = HttpApiBuilder.layer(bffEffectApi).pipe(Layer.provide(greetingsLayer));
|
|
56
19
|
|
|
57
20
|
export default defineEffectBff({
|
|
58
21
|
api: bffEffectApi,
|
|
59
22
|
layer,
|
|
60
|
-
});
|
|
61
|
-
{{/if}}
|
|
23
|
+
});{{/if}}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"home": {
|
|
3
|
+
"bff": {
|
|
4
|
+
"response": "Odpoved Effect HttpApi:"
|
|
5
|
+
},
|
|
6
|
+
"cards": {
|
|
7
|
+
"bff": {
|
|
8
|
+
"body": "Pouzivej Effect jako hlavni BFF cestu, Hono nech jako explicitni zalozni volbu.",
|
|
9
|
+
"title": "BFF + Effect"
|
|
10
|
+
},
|
|
11
|
+
"config": {
|
|
12
|
+
"body": "Upravuj vygenerovane vychozi hodnoty v modern.config.ts.",
|
|
13
|
+
"title": "Konfigurace presetUltramodern"
|
|
14
|
+
},
|
|
15
|
+
"gates": {
|
|
16
|
+
"body": "Starter obsahuje PR workflow pro ultramodern:check a build.",
|
|
17
|
+
"title": "Ultramodern kontroly"
|
|
18
|
+
},
|
|
19
|
+
"guide": {
|
|
20
|
+
"body": "Projdi si verejny preset pripraveny pro MV, TanStack a Effect.",
|
|
21
|
+
"title": "UltraModern.js pruvodce"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"description": {
|
|
25
|
+
"afterConfig": ", udrzuj",
|
|
26
|
+
"afterPreset": "profil. Zacni v",
|
|
27
|
+
"end": "zelene a lad vygenerovany preset jen tam, kde aplikace potrebuje mekci cestu.",
|
|
28
|
+
"intro": "Tento starter prinasi verejny"
|
|
29
|
+
},
|
|
30
|
+
"language": {
|
|
31
|
+
"cs": "Cestina",
|
|
32
|
+
"en": "Anglictina",
|
|
33
|
+
"switcher": "Jazyk"
|
|
34
|
+
},
|
|
35
|
+
"logoAlt": "Logo UltraModern.js",
|
|
36
|
+
"name": "presetUltramodern",
|
|
37
|
+
"title": "UltraModern.js 3.0"
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"home": {
|
|
3
|
+
"bff": {
|
|
4
|
+
"response": "Effect HttpApi response:"
|
|
5
|
+
},
|
|
6
|
+
"cards": {
|
|
7
|
+
"bff": {
|
|
8
|
+
"body": "Keep Effect as the preferred BFF lane while Hono stays an explicit fallback.",
|
|
9
|
+
"title": "BFF + Effect"
|
|
10
|
+
},
|
|
11
|
+
"config": {
|
|
12
|
+
"body": "Tune the generated defaults in modern.config.ts.",
|
|
13
|
+
"title": "Configure presetUltramodern"
|
|
14
|
+
},
|
|
15
|
+
"gates": {
|
|
16
|
+
"body": "The starter includes a PR workflow for ultramodern:check and build.",
|
|
17
|
+
"title": "Ultramodern Gates"
|
|
18
|
+
},
|
|
19
|
+
"guide": {
|
|
20
|
+
"body": "Review the MV-first, TanStack-ready, Effect-ready public preset.",
|
|
21
|
+
"title": "UltraModern.js Guide"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"description": {
|
|
25
|
+
"afterConfig": ", keep",
|
|
26
|
+
"afterPreset": "profile. Start in",
|
|
27
|
+
"end": "green, and tune the generated preset only where your app needs a softer lane.",
|
|
28
|
+
"intro": "This starter ships the public"
|
|
29
|
+
},
|
|
30
|
+
"language": {
|
|
31
|
+
"cs": "Czech",
|
|
32
|
+
"en": "English",
|
|
33
|
+
"switcher": "Language"
|
|
34
|
+
},
|
|
35
|
+
"logoAlt": "UltraModern.js Logo",
|
|
36
|
+
"name": "presetUltramodern",
|
|
37
|
+
"title": "UltraModern.js 3.0"
|
|
38
|
+
}
|
|
39
|
+
}
|