@bleedingdev/modern-js-app-tools 3.9.0-ultramodern.5 → 3.9.0-ultramodern.6

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.
@@ -46,7 +46,7 @@ export interface BffGeneratedModule {
46
46
  export interface BffGeneratedEntries {
47
47
  readonly generation: BffGeneration;
48
48
  plugin: BffGeneratedModule;
49
- runtime: BffGeneratedModule;
49
+ runtime: BffGeneratedModule | null;
50
50
  /** Direct dependencies required by the emitted SDK modules. */
51
51
  packageDependencies: Record<string, string>;
52
52
  }
@@ -183,7 +183,6 @@ export default defineConfig({
183
183
  endpoint: '/_data/batch',
184
184
  maxBatchSize: 16,
185
185
  maxBatchBytes: 64 * 1024,
186
- flushIntervalMs: 8,
187
186
  maxConcurrency: 4,
188
187
  requestTimeoutMs: 10000,
189
188
  allowedMethods: ['GET'],
@@ -217,9 +216,9 @@ export default defineConfig({
217
216
  });
218
217
  ```
219
218
 
220
- `batch.flushIntervalMs` controls the client-side micro-batch window in the generated Effect client. `maxConcurrency` and `requestTimeoutMs` are applied by the server batch gateway when dispatching items.
219
+ `maxConcurrency` and `requestTimeoutMs` control the server batch gateway. Native `HttpApiClient` calls send individual requests; they do not automatically batch requests.
221
220
 
222
- The generated `api.client.*` API only exists for loader-materialized `@api/index` imports. Directly importing the server entry (`api/index`) exposes the Effect BFF definition; its `client` property is a placeholder that fails on operation access.
221
+ Import a shared `HttpApi` contract and pass it to `HttpApiClient.make` or `makeEffectHttpApiClient`. The client is fully type-inferred; `defineEffectBff` exposes server handlers and does not contain a client.
223
222
 
224
223
  ## Effect cohort
225
224
 
@@ -113,15 +113,20 @@ const layer = HttpApiBuilder.layer(bffApi).pipe(
113
113
  export default defineEffectBff({ api: bffApi, layer });
114
114
  ```
115
115
 
116
- Call Effect endpoints from browser code via `@api/index`:
116
+ Create a native, fully inferred client from the shared contract:
117
117
 
118
118
  ```ts title="src/routes/page.tsx"
119
- import api from '@api/index';
119
+ import { Effect, makeEffectHttpApiClient } from '@modern-js/bff-effect/effect-client';
120
+ import { bffApi } from '../../shared/api';
120
121
 
121
- const response = await api.client.hello.ping({});
122
+ const response = await Effect.runPromise(
123
+ makeEffectHttpApiClient(bffApi, { baseUrl: '/api' }).pipe(
124
+ Effect.flatMap(client => client.hello.ping({})),
125
+ ),
126
+ );
122
127
  ```
123
128
 
124
- The `api.client.*` surface is materialized by the BFF loader for `@api/index` imports. Do not import `api/index` directly and expect `client` to run in server code, scripts, or tests; direct entry imports expose the server runtime definition, and `client` is only a typed placeholder there.
129
+ Requests, responses, and declared errors are inferred from `bffApi`. No client generation or server-entry import is needed.
125
130
 
126
131
  For UltraModern, Effect `HttpApi` plus Effect BFF is the single blessed authored HTTP path. Use `HttpApi` endpoints with `query`, `params`, `payload`, `success`, and declared errors such as `HttpApiSchema.status(...)`; implement them with `HttpApiBuilder.group(...).handle(...)` and `HttpApiBuilder.layer(...).pipe(Layer.provide(...))`, then default-export the entry as `defineEffectBff({ api, layer })`. See `packages/server/bff-effect/tests/effect-edge-runtime.test.ts` for the live runtime shape.
127
132
 
@@ -15,17 +15,9 @@ UltraModern.js 3.0 is our SuperApp framework forked from Modern.js. It keeps the
15
15
  - Add platform-level contracts only where they improve cross-team reliability.
16
16
  - Keep escape hatches explicit and outside the generated HTTP API path.
17
17
 
18
- ## Compatibility Contract
18
+ ## Current Workspace Contract
19
19
 
20
- UltraModern.js 3.0 keeps:
21
-
22
- - Modern.js app/config/plugin mental model.
23
- - Existing project structure and command flow.
24
- - Progressive adoption path (apps can stay mostly unchanged).
25
-
26
- UltraModern.js additions are designed as the default product surface for new SuperApps. The framework direction is Effect + TanStack + SSR + Micro Verticals, and generated HTTP API work uses that direction by default instead of preserving parallel raw-handler layouts.
27
- Existing Modern.js apps can migrate gradually; once an API surface is generated
28
- or migrated as UltraModern HTTP API, it must use the strict Effect HttpApi path.
20
+ UltraModern.js uses Effect HttpApi, TanStack Router, SSR, and independently deployable Micro Verticals. Generated workspaces use `api/index.ts`, `shared/api.ts`, and `src/api/*` with concrete Effect schemas. The CLI creates, adds to, and validates workspaces against the current contract.
29
21
 
30
22
  ## Intentional Differences (v3 line)
31
23
 
@@ -53,21 +45,9 @@ or migrated as UltraModern HTTP API, it must use the strict Effect HttpApi path.
53
45
  - Generated UltraModern API work uses the Effect runtime only; raw Hono/function handlers are not part of the generated API architecture.
54
46
  - We make incompatible scaffold changes when they remove architecture drift.
55
47
 
56
- ## Migration Guide
57
-
58
- For teams already on Modern.js 3.0 or an older BleedingDev UltraModern scaffold, the adoption path is to move API work onto the strict Effect HttpApi surface instead of preserving older raw handler layouts.
59
-
60
- 1. Keep existing Modern.js apps running as-is while they are outside the generated UltraModern surface. TanStack Router is the preferred path for new scaffolds and incremental route adoption, but route migration can happen on the team's schedule.
61
- 2. Use `bff.runtimeFramework: 'effect'` with `bff.effect.strictEffectApproach: true` for API work. Entries live at `api/index.ts`, contracts live at `shared/api.ts`, clients live under `src/api/*`, and request/response/error shapes come from Effect `Schema` plus `HttpApi`.
62
- 3. Treat raw handlers, `api/lambda/**`, manual `Response` construction, and manual request parsing as migration defects in generated or migrated UltraModern workspaces.
63
- 4. The public preset now ships with explicit release and certification gates. Generated workspaces include `.github/workflows/ultramodern-workspace-gates.yml`, so `pnpm check` and `pnpm build` stay part of the local adoption contract from day one while CI runs the primitive gates as parallel matrix jobs.
64
-
65
- For an older generated workspace, migrate by treating the published cohort as
66
- the source of truth:
48
+ ## Create and Validate a Workspace
67
49
 
68
50
  ```bash
69
- pnpm dlx @bleedingdev/modern-js-ultramodern-create@latest --help
70
- pnpm dlx @bleedingdev/modern-js-ultramodern-create@latest catalog --vertical --dry-run
71
51
  pnpm dlx @bleedingdev/modern-js-ultramodern-create@latest catalog --vertical
72
52
  mise install
73
53
  mise exec -- pnpm install
@@ -75,73 +55,12 @@ mise exec -- pnpm check
75
55
  mise exec -- pnpm build
76
56
  ```
77
57
 
78
- ### Migrating localized Cloudflare SSR workspaces
79
-
80
- Current cohorts localize Cloudflare SSR workspaces.
81
- The framework moves bare locale-root redirects into the framework-owned
82
- Cloudflare Worker entry and the i18n server runtime. A request for `/` is
83
- redirected server-side with `302` to the negotiated locale path, for example
84
- `/cs` for `Accept-Language: cs-CZ` or `/en` for English and fallback traffic.
85
-
86
- Existing generated workspaces should upgrade the whole BleedingDev Modern
87
- package cohort together. Resolve the current cohort version first, then run
88
- the matching migration:
89
-
90
- ```bash
91
- COHORT="$(npm view @bleedingdev/modern-js-ultramodern-create version)"
92
- pnpm dlx "@bleedingdev/modern-js-ultramodern-create@$COHORT" ultramodern \
93
- migrate-strict-effect --version "$COHORT"
94
- pnpm install
95
- pnpm check
96
- pnpm build
97
- pnpm cloudflare:build
98
- ```
99
-
100
- For deployed Cloudflare Workers, redeploy after the cohort update and verify
101
- the root response before accepting the migration:
58
+ Localized Cloudflare SSR workspaces redirect `/` on the server to the negotiated locale. For example, `Accept-Language: cs-CZ` returns `302` with `Location: /cs`, `Cache-Control: private, no-store`, and `Vary` covering locale detection headers. Validate the deployed Worker with:
102
59
 
103
60
  ```bash
104
61
  curl -I -H 'Accept-Language: cs-CZ,cs;q=0.9,en;q=0.1' https://<worker-host>/
105
62
  ```
106
63
 
107
- The expected response is `302` with `Location: /cs` or the matching locale,
108
- `Cache-Control: private, no-store`, and `Vary` covering the locale detection
109
- headers. Following the redirect should return the SSR locale page with the
110
- matching document language and i18n SSR data.
111
-
112
- Do not fix older root `404` responses by adding app-owned root route files,
113
- client-side redirects, custom navigation wrappers, Cloudflare Worker
114
- postprocessing, generated output edits, or local redirect shims. If `/` still
115
- returns `404` after upgrading, confirm the production build log shows
116
- `Modern.js Framework v<cohort-version>` for the cohort you migrated to and
117
- redeploy the Worker.
118
-
119
- Strict generated API migration is part of every current cohort: the direct
120
- `api/index.ts` generator, generated `.mts` checks, the strict Oxlint boundary
121
- rule set, Effect cohort overrides, and the strict Effect migration command.
122
- Agents that cannot install the BleedingDev cohort yet should use the local
123
- Modern.js workspace for migration validation; otherwise pin the target cohort
124
- with `--ultramodern-package-version`.
125
-
126
- Before hand-editing package aliases or generated metadata, run the framework
127
- migration command from the target workspace:
128
-
129
- ```bash
130
- COHORT="$(npm view @bleedingdev/modern-js-ultramodern-create version)"
131
- pnpm dlx "@bleedingdev/modern-js-ultramodern-create@$COHORT" ultramodern \
132
- migrate-strict-effect --version "$COHORT"
133
- pnpm api:check
134
- pnpm contract:check
135
- ```
136
-
137
- The command updates `.modernjs/ultramodern.json`, root
138
- `modernjs.packageSource`, generated Modern package aliases, framework-owned
139
- toolchain pins, direct topology API metadata, strict Effect pnpm
140
- overrides/trust policy, and the pnpm lockfile. Remaining failures are source
141
- migration work: move code to `shared/api.ts`, `api/index.ts`, and
142
- `src/api/*-client.ts`, then delete `api/effect`, `api/lambda`, `shared/effect`,
143
- and `src/effect`.
144
-
145
64
  Generated strict Effect workspaces pin the compatible Effect cohort with pnpm
146
65
  overrides: `effect@4.0.0-rc.112`, `@effect/opentelemetry@4.0.0-rc.112`,
147
66
  and `@effect/vitest@4.0.0-rc.112`. Do not add app-local direct Effect
package/package.json CHANGED
@@ -17,7 +17,7 @@
17
17
  "modern",
18
18
  "modern.js"
19
19
  ],
20
- "version": "3.9.0-ultramodern.5",
20
+ "version": "3.9.0-ultramodern.6",
21
21
  "types": "./dist/types/index.d.ts",
22
22
  "main": "./dist/cjs/index.js",
23
23
  "exports": {
@@ -119,18 +119,18 @@
119
119
  "@babel/traverse": "^8.0.4",
120
120
  "@babel/types": "^8.0.4",
121
121
  "@loadable/component": "5.16.7",
122
- "@modern-js/app-tools-extensions": "npm:@bleedingdev/modern-js-app-tools-extensions@3.9.0-ultramodern.5",
123
- "@modern-js/builder": "npm:@bleedingdev/modern-js-builder@3.9.0-ultramodern.5",
124
- "@modern-js/i18n-utils": "npm:@bleedingdev/modern-js-i18n-utils@3.9.0-ultramodern.5",
125
- "@modern-js/plugin": "npm:@bleedingdev/modern-js-plugin@3.9.0-ultramodern.5",
126
- "@modern-js/plugin-data-loader": "npm:@bleedingdev/modern-js-plugin-data-loader@3.9.0-ultramodern.5",
127
- "@modern-js/prod-server": "npm:@bleedingdev/modern-js-prod-server@3.9.0-ultramodern.5",
128
- "@modern-js/server": "npm:@bleedingdev/modern-js-server@3.9.0-ultramodern.5",
129
- "@modern-js/server-core": "npm:@bleedingdev/modern-js-server-core@3.9.0-ultramodern.5",
130
- "@modern-js/server-runtime-extensions": "npm:@bleedingdev/modern-js-server-runtime-extensions@3.9.0-ultramodern.5",
131
- "@modern-js/server-utils": "npm:@bleedingdev/modern-js-server-utils@3.9.0-ultramodern.5",
132
- "@modern-js/types": "npm:@bleedingdev/modern-js-types@3.9.0-ultramodern.5",
133
- "@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.9.0-ultramodern.5",
122
+ "@modern-js/app-tools-extensions": "npm:@bleedingdev/modern-js-app-tools-extensions@3.9.0-ultramodern.6",
123
+ "@modern-js/builder": "npm:@bleedingdev/modern-js-builder@3.9.0-ultramodern.6",
124
+ "@modern-js/i18n-utils": "npm:@bleedingdev/modern-js-i18n-utils@3.9.0-ultramodern.6",
125
+ "@modern-js/plugin": "npm:@bleedingdev/modern-js-plugin@3.9.0-ultramodern.6",
126
+ "@modern-js/plugin-data-loader": "npm:@bleedingdev/modern-js-plugin-data-loader@3.9.0-ultramodern.6",
127
+ "@modern-js/prod-server": "npm:@bleedingdev/modern-js-prod-server@3.9.0-ultramodern.6",
128
+ "@modern-js/server": "npm:@bleedingdev/modern-js-server@3.9.0-ultramodern.6",
129
+ "@modern-js/server-core": "npm:@bleedingdev/modern-js-server-core@3.9.0-ultramodern.6",
130
+ "@modern-js/server-runtime-extensions": "npm:@bleedingdev/modern-js-server-runtime-extensions@3.9.0-ultramodern.6",
131
+ "@modern-js/server-utils": "npm:@bleedingdev/modern-js-server-utils@3.9.0-ultramodern.6",
132
+ "@modern-js/types": "npm:@bleedingdev/modern-js-types@3.9.0-ultramodern.6",
133
+ "@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.9.0-ultramodern.6",
134
134
  "@rsbuild/core": "2.2.3",
135
135
  "@swc/core": "1.16.2",
136
136
  "@swc/helpers": "^0.5.23",