@bleedingdev/modern-js-app-tools-extensions 3.9.0-ultramodern.9 → 3.9.3-ultramodern.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (275) hide show
  1. package/README.md +23 -0
  2. package/dist/cjs/backend-federation-build/codegen.js +29 -18
  3. package/dist/cjs/backend-federation-build/config.js +84 -45
  4. package/dist/cjs/backend-federation-build/emit.js +63 -22
  5. package/dist/cjs/build-config/build-environment.js +30 -165
  6. package/dist/cjs/build-config/internal-effect-discovery.js +231 -0
  7. package/dist/cjs/build-config/public.js +2 -5
  8. package/dist/cjs/build-config/remote-address.js +58 -0
  9. package/dist/cjs/cloudflare/artifacts.js +8 -19
  10. package/dist/cjs/cloudflare/delivery-unit.js +125 -43
  11. package/dist/cjs/cloudflare/index.js +14 -4
  12. package/dist/cjs/cloudflare/native-renderer.js +100 -0
  13. package/dist/cjs/cloudflare/renderer-identity.js +106 -0
  14. package/dist/cjs/cloudflare/worker-manifest.js +54 -13
  15. package/dist/cjs/cloudflare/worker-options.js +48 -0
  16. package/dist/cjs/cloudflare/wrangler-config.js +210 -13
  17. package/dist/cjs/cloudflare-builder.js +307 -89
  18. package/dist/cjs/cloudflare-output-contract.js +36 -4
  19. package/dist/cjs/cloudflare-output-verifier/identity.js +112 -23
  20. package/dist/cjs/cloudflare-output-verifier/index.js +10 -0
  21. package/dist/cjs/cloudflare-output-verifier/manifest.js +46 -0
  22. package/dist/cjs/cloudflare-output-verifier/mutation-policy.js +7 -1
  23. package/dist/cjs/cloudflare-output-verifier/worker-bundles.js +10 -5
  24. package/dist/cjs/config.js +10 -5
  25. package/dist/cjs/deploy-output/npmAliases.js +92 -6
  26. package/dist/cjs/deploy-output/plugin.js +27 -6
  27. package/dist/cjs/deploy-output/public-assets.js +146 -0
  28. package/dist/cjs/deploy-output/target.js +57 -1
  29. package/dist/cjs/deploy-output/trace-files.js +99 -0
  30. package/dist/cjs/module-federation-config/exposes.js +70 -0
  31. package/dist/cjs/module-federation-config/index.js +73 -0
  32. package/dist/cjs/module-federation-config/inspect.js +103 -0
  33. package/dist/cjs/module-federation-config/object-literal.js +87 -0
  34. package/dist/cjs/module-federation-config/syntax.js +151 -0
  35. package/dist/cjs/module-federation-config/types.js +18 -0
  36. package/dist/cjs/native-type-checker.js +180 -17
  37. package/dist/cjs/policy-defaults.js +38 -29
  38. package/dist/cjs/release-envelope/canonical.js +2 -9
  39. package/dist/cjs/release-envelope/contract.js +68 -0
  40. package/dist/cjs/release-envelope/framework-output.js +296 -105
  41. package/dist/cjs/release-envelope/index.js +150 -36
  42. package/dist/cjs/release-envelope/plugin.js +24 -15
  43. package/dist/cjs/release-envelope/renderer-output-stamp.js +170 -0
  44. package/dist/cjs/release-envelope/types.js +10 -8
  45. package/dist/cjs/release-identity.js +9 -6
  46. package/dist/cjs/renderer-build-identity.js +144 -0
  47. package/dist/cjs/templates/cloudflare-entry.001-bootstrap-security.mjs +14 -6
  48. package/dist/cjs/templates/cloudflare-entry.002-assets-routes.mjs +10 -2
  49. package/dist/cjs/templates/cloudflare-entry.004-rendering-css.mjs +403 -96
  50. package/dist/cjs/templates/cloudflare-entry.005-worker-dispatch.mjs +547 -103
  51. package/dist/cjs/templates/cloudflare-entry.006-fetch-handler.mjs +26 -7
  52. package/dist/cjs/templates/cloudflare-worker-route-data.mjs +1069 -0
  53. package/dist/cjs/workspace-topology.js +84 -0
  54. package/dist/esm/backend-federation-build/codegen.mjs +29 -18
  55. package/dist/esm/backend-federation-build/config.mjs +74 -38
  56. package/dist/esm/backend-federation-build/emit.mjs +64 -23
  57. package/dist/esm/build-config/build-environment.mjs +31 -163
  58. package/dist/esm/build-config/internal-effect-discovery.mjs +187 -0
  59. package/dist/esm/build-config/public.mjs +1 -1
  60. package/dist/esm/build-config/remote-address.mjs +20 -0
  61. package/dist/esm/cloudflare/artifacts.mjs +8 -19
  62. package/dist/esm/cloudflare/delivery-unit.mjs +124 -45
  63. package/dist/esm/cloudflare/index.mjs +15 -5
  64. package/dist/esm/cloudflare/native-renderer.mjs +48 -0
  65. package/dist/esm/cloudflare/renderer-identity.mjs +57 -0
  66. package/dist/esm/cloudflare/worker-manifest.mjs +55 -14
  67. package/dist/esm/cloudflare/worker-options.mjs +10 -0
  68. package/dist/esm/cloudflare/wrangler-config.mjs +203 -12
  69. package/dist/esm/cloudflare-builder.mjs +301 -89
  70. package/dist/esm/cloudflare-output-contract.mjs +29 -3
  71. package/dist/esm/cloudflare-output-verifier/identity.mjs +113 -24
  72. package/dist/esm/cloudflare-output-verifier/index.mjs +10 -0
  73. package/dist/esm/cloudflare-output-verifier/manifest.mjs +46 -0
  74. package/dist/esm/cloudflare-output-verifier/mutation-policy.mjs +7 -1
  75. package/dist/esm/cloudflare-output-verifier/worker-bundles.mjs +11 -6
  76. package/dist/esm/config.mjs +3 -1
  77. package/dist/esm/deploy-output/npmAliases.mjs +92 -6
  78. package/dist/esm/deploy-output/plugin.mjs +24 -6
  79. package/dist/esm/deploy-output/public-assets.mjs +82 -0
  80. package/dist/esm/deploy-output/target.mjs +50 -3
  81. package/dist/esm/deploy-output/trace-files.mjs +47 -0
  82. package/dist/esm/module-federation-config/exposes.mjs +18 -0
  83. package/dist/esm/module-federation-config/index.mjs +4 -0
  84. package/dist/esm/module-federation-config/inspect.mjs +65 -0
  85. package/dist/esm/module-federation-config/object-literal.mjs +43 -0
  86. package/dist/esm/module-federation-config/syntax.mjs +101 -0
  87. package/dist/esm/module-federation-config/types.mjs +0 -0
  88. package/dist/esm/native-type-checker.mjs +175 -18
  89. package/dist/esm/policy-defaults.mjs +36 -30
  90. package/dist/esm/release-envelope/canonical.mjs +2 -9
  91. package/dist/esm/release-envelope/contract.mjs +21 -0
  92. package/dist/esm/release-envelope/framework-output.mjs +297 -106
  93. package/dist/esm/release-envelope/index.mjs +149 -38
  94. package/dist/esm/release-envelope/plugin.mjs +24 -15
  95. package/dist/esm/release-envelope/renderer-output-stamp.mjs +112 -0
  96. package/dist/esm/release-envelope/types.mjs +2 -3
  97. package/dist/esm/release-identity.mjs +9 -6
  98. package/dist/esm/renderer-build-identity.mjs +92 -0
  99. package/dist/esm/templates/cloudflare-entry.001-bootstrap-security.mjs +14 -6
  100. package/dist/esm/templates/cloudflare-entry.002-assets-routes.mjs +10 -2
  101. package/dist/esm/templates/cloudflare-entry.004-rendering-css.mjs +403 -96
  102. package/dist/esm/templates/cloudflare-entry.005-worker-dispatch.mjs +547 -103
  103. package/dist/esm/templates/cloudflare-entry.006-fetch-handler.mjs +26 -7
  104. package/dist/esm/templates/cloudflare-worker-route-data.mjs +1069 -0
  105. package/dist/esm/workspace-topology.mjs +21 -0
  106. package/dist/esm-node/backend-federation-build/codegen.mjs +29 -18
  107. package/dist/esm-node/backend-federation-build/config.mjs +74 -38
  108. package/dist/esm-node/backend-federation-build/emit.mjs +64 -23
  109. package/dist/esm-node/build-config/build-environment.mjs +31 -163
  110. package/dist/esm-node/build-config/internal-effect-discovery.mjs +188 -0
  111. package/dist/esm-node/build-config/public.mjs +1 -1
  112. package/dist/esm-node/build-config/remote-address.mjs +21 -0
  113. package/dist/esm-node/cloudflare/artifacts.mjs +8 -19
  114. package/dist/esm-node/cloudflare/delivery-unit.mjs +124 -45
  115. package/dist/esm-node/cloudflare/index.mjs +15 -5
  116. package/dist/esm-node/cloudflare/native-renderer.mjs +49 -0
  117. package/dist/esm-node/cloudflare/renderer-identity.mjs +58 -0
  118. package/dist/esm-node/cloudflare/worker-manifest.mjs +55 -14
  119. package/dist/esm-node/cloudflare/worker-options.mjs +11 -0
  120. package/dist/esm-node/cloudflare/wrangler-config.mjs +203 -12
  121. package/dist/esm-node/cloudflare-builder.mjs +301 -89
  122. package/dist/esm-node/cloudflare-output-contract.mjs +29 -3
  123. package/dist/esm-node/cloudflare-output-verifier/identity.mjs +113 -24
  124. package/dist/esm-node/cloudflare-output-verifier/index.mjs +10 -0
  125. package/dist/esm-node/cloudflare-output-verifier/manifest.mjs +46 -0
  126. package/dist/esm-node/cloudflare-output-verifier/mutation-policy.mjs +7 -1
  127. package/dist/esm-node/cloudflare-output-verifier/worker-bundles.mjs +11 -6
  128. package/dist/esm-node/config.mjs +3 -1
  129. package/dist/esm-node/deploy-output/npmAliases.mjs +92 -6
  130. package/dist/esm-node/deploy-output/plugin.mjs +24 -6
  131. package/dist/esm-node/deploy-output/public-assets.mjs +83 -0
  132. package/dist/esm-node/deploy-output/target.mjs +50 -3
  133. package/dist/esm-node/deploy-output/trace-files.mjs +48 -0
  134. package/dist/esm-node/module-federation-config/exposes.mjs +19 -0
  135. package/dist/esm-node/module-federation-config/index.mjs +5 -0
  136. package/dist/esm-node/module-federation-config/inspect.mjs +66 -0
  137. package/dist/esm-node/module-federation-config/object-literal.mjs +44 -0
  138. package/dist/esm-node/module-federation-config/syntax.mjs +102 -0
  139. package/dist/esm-node/module-federation-config/types.mjs +1 -0
  140. package/dist/esm-node/native-type-checker.mjs +175 -18
  141. package/dist/esm-node/policy-defaults.mjs +36 -30
  142. package/dist/esm-node/release-envelope/canonical.mjs +2 -9
  143. package/dist/esm-node/release-envelope/contract.mjs +22 -0
  144. package/dist/esm-node/release-envelope/framework-output.mjs +297 -106
  145. package/dist/esm-node/release-envelope/index.mjs +149 -38
  146. package/dist/esm-node/release-envelope/plugin.mjs +24 -15
  147. package/dist/esm-node/release-envelope/renderer-output-stamp.mjs +113 -0
  148. package/dist/esm-node/release-envelope/types.mjs +2 -3
  149. package/dist/esm-node/release-identity.mjs +9 -6
  150. package/dist/esm-node/renderer-build-identity.mjs +93 -0
  151. package/dist/esm-node/templates/cloudflare-entry.001-bootstrap-security.mjs +14 -6
  152. package/dist/esm-node/templates/cloudflare-entry.002-assets-routes.mjs +10 -2
  153. package/dist/esm-node/templates/cloudflare-entry.004-rendering-css.mjs +403 -96
  154. package/dist/esm-node/templates/cloudflare-entry.005-worker-dispatch.mjs +547 -103
  155. package/dist/esm-node/templates/cloudflare-entry.006-fetch-handler.mjs +26 -7
  156. package/dist/esm-node/templates/cloudflare-worker-route-data.mjs +1069 -0
  157. package/dist/esm-node/workspace-topology.mjs +22 -0
  158. package/dist/types/backend-federation-build/codegen.d.ts +30 -0
  159. package/dist/types/backend-federation-build/config.d.ts +10 -57
  160. package/dist/types/backend-federation-build/emit.d.ts +12 -2
  161. package/dist/types/backend-federation-build/index.d.ts +1 -1
  162. package/dist/types/build-config/build-environment.d.ts +4 -10
  163. package/dist/types/build-config/internal-effect-discovery.d.ts +6 -0
  164. package/dist/types/build-config/public.d.ts +1 -1
  165. package/dist/types/build-config/remote-address.d.ts +3 -0
  166. package/dist/types/cloudflare/artifacts.d.ts +7 -6
  167. package/dist/types/cloudflare/constants.d.ts +1 -1
  168. package/dist/types/cloudflare/delivery-unit.d.ts +38 -7
  169. package/dist/types/cloudflare/native-renderer.d.ts +30 -0
  170. package/dist/types/cloudflare/renderer-identity.d.ts +25 -0
  171. package/dist/types/cloudflare/worker-manifest.d.ts +20 -4
  172. package/dist/types/cloudflare/worker-options.d.ts +20 -0
  173. package/dist/types/cloudflare/wrangler-config.d.ts +55 -2
  174. package/dist/types/cloudflare-builder.d.ts +51 -8
  175. package/dist/types/cloudflare-output-contract.d.ts +5 -3
  176. package/dist/types/cloudflare-output-verifier/identity.d.ts +7 -3
  177. package/dist/types/cloudflare-output-verifier/worker-bundles.d.ts +2 -2
  178. package/dist/types/config.d.ts +102 -13
  179. package/dist/types/deploy-output/plugin.d.ts +29 -9
  180. package/dist/types/deploy-output/public-assets.d.ts +51 -0
  181. package/dist/types/deploy-output/target.d.ts +28 -5
  182. package/dist/types/deploy-output/trace-files.d.ts +17 -0
  183. package/dist/types/module-federation-config/exposes.d.ts +11 -0
  184. package/dist/types/module-federation-config/index.d.ts +5 -0
  185. package/dist/types/module-federation-config/inspect.d.ts +2 -0
  186. package/dist/types/module-federation-config/object-literal.d.ts +4 -0
  187. package/dist/types/module-federation-config/syntax.d.ts +7 -0
  188. package/dist/types/module-federation-config/types.d.ts +20 -0
  189. package/dist/types/native-type-checker.d.ts +28 -3
  190. package/dist/types/policy-defaults.d.ts +12 -2
  191. package/dist/types/release-envelope/canonical.d.ts +5 -5
  192. package/dist/types/release-envelope/contract.d.mts +8 -0
  193. package/dist/types/release-envelope/framework-output.d.ts +23 -13
  194. package/dist/types/release-envelope/index.d.ts +17 -5
  195. package/dist/types/release-envelope/plugin.d.ts +10 -6
  196. package/dist/types/release-envelope/renderer-output-stamp.d.ts +34 -0
  197. package/dist/types/release-envelope/types.d.ts +42 -4
  198. package/dist/types/release-identity.d.ts +13 -2
  199. package/dist/types/renderer-build-identity.d.ts +41 -0
  200. package/dist/types/templates/cloudflare-worker-route-data.d.mts +14 -0
  201. package/dist/types/workspace-topology.d.ts +91 -0
  202. package/package.json +87 -27
  203. package/src/backend-federation-build/codegen.ts +28 -19
  204. package/src/backend-federation-build/config.ts +189 -123
  205. package/src/backend-federation-build/emit.ts +119 -38
  206. package/src/backend-federation-build/index.ts +4 -1
  207. package/src/build-config/build-environment.ts +69 -293
  208. package/src/build-config/internal-effect-discovery.ts +458 -0
  209. package/src/build-config/public.ts +0 -1
  210. package/src/build-config/remote-address.ts +33 -0
  211. package/src/cloudflare/artifacts.ts +22 -43
  212. package/src/cloudflare/delivery-unit.ts +283 -60
  213. package/src/cloudflare/index.ts +35 -19
  214. package/src/cloudflare/native-renderer.ts +117 -0
  215. package/src/cloudflare/renderer-identity.ts +171 -0
  216. package/src/cloudflare/worker-manifest.ts +115 -13
  217. package/src/cloudflare/worker-options.ts +60 -0
  218. package/src/cloudflare/wrangler-config.ts +390 -14
  219. package/src/cloudflare-builder.ts +543 -170
  220. package/src/cloudflare-output-contract.ts +45 -2
  221. package/src/cloudflare-output-verifier/identity.ts +138 -7
  222. package/src/cloudflare-output-verifier/index.ts +20 -0
  223. package/src/cloudflare-output-verifier/manifest.ts +77 -0
  224. package/src/cloudflare-output-verifier/mutation-policy.ts +11 -1
  225. package/src/cloudflare-output-verifier/worker-bundles.ts +27 -11
  226. package/src/config.ts +105 -19
  227. package/src/deploy-output/npmAliases.ts +141 -4
  228. package/src/deploy-output/plugin.ts +55 -18
  229. package/src/deploy-output/public-assets.ts +224 -0
  230. package/src/deploy-output/target.ts +97 -14
  231. package/src/deploy-output/trace-files.ts +80 -0
  232. package/src/module-federation-config/exposes.ts +46 -0
  233. package/src/module-federation-config/index.ts +22 -0
  234. package/src/module-federation-config/inspect.ts +157 -0
  235. package/src/module-federation-config/object-literal.ts +76 -0
  236. package/src/module-federation-config/syntax.ts +212 -0
  237. package/src/module-federation-config/types.ts +22 -0
  238. package/src/native-type-checker.ts +284 -27
  239. package/src/policy-defaults.ts +47 -17
  240. package/src/release-envelope/canonical.ts +6 -18
  241. package/src/release-envelope/contract.mjs +28 -0
  242. package/src/release-envelope/framework-output.ts +681 -156
  243. package/src/release-envelope/index.ts +315 -60
  244. package/src/release-envelope/plugin.ts +54 -38
  245. package/src/release-envelope/renderer-output-stamp.ts +210 -0
  246. package/src/release-envelope/types.ts +75 -6
  247. package/src/release-identity.ts +30 -4
  248. package/src/renderer-build-identity.ts +208 -0
  249. package/src/templates/cloudflare-entry.001-bootstrap-security.mjs +14 -6
  250. package/src/templates/cloudflare-entry.002-assets-routes.mjs +10 -2
  251. package/src/templates/cloudflare-entry.004-rendering-css.mjs +403 -96
  252. package/src/templates/cloudflare-entry.005-worker-dispatch.mjs +547 -103
  253. package/src/templates/cloudflare-entry.006-fetch-handler.mjs +26 -7
  254. package/src/templates/cloudflare-worker-route-data.mjs +1069 -0
  255. package/src/workspace-topology.ts +125 -0
  256. package/dist/cjs/templates/cloudflare-worker-fs-promises.mjs +0 -11
  257. package/dist/cjs/templates/cloudflare-worker-loadable-server.mjs +0 -281
  258. package/dist/cjs/templates/cloudflare-worker-mf-ssr-runtime-plugin.mjs +0 -14
  259. package/dist/cjs/templates/cloudflare-worker-path.mjs +0 -98
  260. package/dist/esm/templates/cloudflare-worker-fs-promises.mjs +0 -11
  261. package/dist/esm/templates/cloudflare-worker-loadable-server.mjs +0 -281
  262. package/dist/esm/templates/cloudflare-worker-mf-ssr-runtime-plugin.mjs +0 -14
  263. package/dist/esm/templates/cloudflare-worker-path.mjs +0 -98
  264. package/dist/esm-node/templates/cloudflare-worker-fs-promises.mjs +0 -11
  265. package/dist/esm-node/templates/cloudflare-worker-loadable-server.mjs +0 -281
  266. package/dist/esm-node/templates/cloudflare-worker-mf-ssr-runtime-plugin.mjs +0 -14
  267. package/dist/esm-node/templates/cloudflare-worker-path.mjs +0 -98
  268. package/dist/types/templates/cloudflare-worker-fs-promises.d.mts +0 -5
  269. package/dist/types/templates/cloudflare-worker-loadable-server.d.mts +0 -48
  270. package/dist/types/templates/cloudflare-worker-mf-ssr-runtime-plugin.d.mts +0 -13
  271. package/dist/types/templates/cloudflare-worker-path.d.mts +0 -21
  272. package/src/templates/cloudflare-worker-fs-promises.mjs +0 -11
  273. package/src/templates/cloudflare-worker-loadable-server.mjs +0 -281
  274. package/src/templates/cloudflare-worker-mf-ssr-runtime-plugin.mjs +0 -14
  275. package/src/templates/cloudflare-worker-path.mjs +0 -98
package/README.md CHANGED
@@ -3,3 +3,26 @@
3
3
  Fork-owned UltraModern.js app tooling for Cloudflare Worker delivery, output verification, and release-envelope identity enforcement.
4
4
 
5
5
  The package is composed into upstream app-tools through existing deploy/plugin extension seams. It must not depend on `@modern-js/app-tools`.
6
+
7
+ ## Private origins and module-scope bindings
8
+
9
+ Private origins behind a Cloudflare Tunnel are first-class on
10
+ `deploy.worker.vpcServices` (`{ binding, serviceId, prefix? }`). Modern.js
11
+ writes them to `wrangler.json` as `vpc_services` (top level and every
12
+ `wrangler.env.<name>`, because Wrangler bindings are not inherited), and a
13
+ binding with `prefix`
14
+ is dispatched with `env[binding].fetch(request)` like a prefixed
15
+ `deploy.worker.services` entry. A VPC binding name may not reuse any other
16
+ Worker binding: any `binding` field or array-entry `name` in the Wrangler
17
+ config (`ASSETS`, services, D1, KV, Hyperdrive, queue producers, Durable
18
+ Objects, `send_email`, rate limits, …), including each `wrangler.env.<name>`'s
19
+ own bindings, or a `vars` key. A VPC prefix must be a decoded path starting with `/` that URL parsing keeps unchanged (no query, fragment,
20
+ `.` or `..` segments), and may not overlap, even as a percent-encoded alias, the
21
+ Effect BFF prefix or any other routed prefix (the worker decodes the request
22
+ path, dispatches the BFF first, matches path segments and takes the first
23
+ match),
24
+ and the typed option excludes a raw `wrangler.vpc_services`.
25
+
26
+ Code that needs a binding outside the request handler, such as a Hyperdrive
27
+ connection string or a VPC fetcher, imports `env` from `cloudflare:workers`,
28
+ which worker bundles externalize like `cloudflare:sockets`.
@@ -88,28 +88,34 @@ const createBackendRemoteEntrySource = async (workspaceRoot, app, effectApiPath,
88
88
  } : {}
89
89
  };
90
90
  const source = `// Generated by Modern.js backend federation build.
91
- import * as exposedNamespace from ${JSON.stringify(effectApiSpecifier)};
91
+ import { adoptEffectBffShareScope } from '@modern-js/bff-effect/effect-edge';
92
92
 
93
- const exposedModule = {
94
- ...exposedNamespace,
95
- backendFederationContract: {
96
- ...(exposedNamespace.backendFederationContract ?? {}),
97
- compatibility: {
98
- ...(exposedNamespace.backendFederationContract?.compatibility ?? {}),
99
- ...${JSON.stringify(compatibility)},
93
+ // The expose evaluates lazily so defineEffectBff registers its handler
94
+ // factories with the registry the host shares through init().
95
+ let exposedModule;
96
+ const loadExposedModule = () =>
97
+ (exposedModule ??= import(${JSON.stringify(effectApiSpecifier)}).then(exposedNamespace => ({
98
+ ...exposedNamespace,
99
+ backendFederationContract: {
100
+ ...(exposedNamespace.backendFederationContract ?? {}),
101
+ compatibility: {
102
+ ...(exposedNamespace.backendFederationContract?.compatibility ?? {}),
103
+ ...${JSON.stringify(compatibility)},
104
+ },
105
+ name: ${JSON.stringify(app.backendName)},
106
+ role: 'microvertical-server',
107
+ runtimeFramework: 'effect',
108
+ strictEffectApproach: true,
100
109
  },
101
- name: ${JSON.stringify(app.backendName)},
102
- role: 'microvertical-server',
103
- runtimeFramework: 'effect',
104
- strictEffectApproach: true,
105
- },
106
- };
110
+ })));
107
111
  const exposedModules = {
108
- ${JSON.stringify(backend_federation_contracts_namespaceObject.BACKEND_FEDERATION_EFFECT_EXPOSE)}: () => Promise.resolve(exposedModule),
112
+ ${JSON.stringify(backend_federation_contracts_namespaceObject.BACKEND_FEDERATION_EFFECT_EXPOSE)}: loadExposedModule,
109
113
  };
110
114
  const __modernjsBackendFederation = ${JSON.stringify(containerMetadata)};
111
115
 
112
- function init() {}
116
+ function init(shareScope) {
117
+ return adoptEffectBffShareScope(shareScope);
118
+ }
113
119
 
114
120
  function get(id) {
115
121
  const load = exposedModules[id];
@@ -213,8 +219,13 @@ const createBackendManifest = (workspaceRoot, distDirectory, app, entryIntegrity
213
219
  source: {
214
220
  module: sourceModule
215
221
  },
216
- readinessPath: `${app.apiPrefix}/${app.apiStem}/readiness`,
217
- openapiPath: `${app.apiPrefix}/openapi.json`,
222
+ ...'rpc' === app.apiProtocol ? {
223
+ rpcPath: app.rpcPath,
224
+ rpcSerialization: 'json'
225
+ } : {
226
+ readinessPath: `${app.apiPrefix}/${app.apiStem}/readiness`,
227
+ openapiPath: `${app.apiPrefix}/openapi.json`
228
+ },
218
229
  ...app.deliveryUnit ? {
219
230
  deliveryUnit: app.deliveryUnit
220
231
  } : {},
@@ -37,13 +37,14 @@ var __webpack_require__ = {};
37
37
  var __webpack_exports__ = {};
38
38
  __webpack_require__.r(__webpack_exports__);
39
39
  __webpack_require__.d(__webpack_exports__, {
40
- COMPACT_CONFIG_PATH: ()=>COMPACT_CONFIG_PATH,
40
+ DEVELOPMENT_OVERLAY_PATH: ()=>external_workspace_topology_js_namespaceObject.DEVELOPMENT_OVERLAY_PATH,
41
+ REFERENCE_TOPOLOGY_PATH: ()=>external_workspace_topology_js_namespaceObject.REFERENCE_TOPOLOGY_PATH,
41
42
  buildArtifactPathFor: ()=>buildArtifactPathFor,
42
- createAppFromCompactMetadata: ()=>createAppFromCompactMetadata,
43
+ createAppFromTopology: ()=>createAppFromTopology,
43
44
  createStampedDeliveryUnit: ()=>createStampedDeliveryUnit,
44
45
  findBackendFederationApp: ()=>findBackendFederationApp,
45
- findWorkspaceRoot: ()=>findWorkspaceRoot,
46
- normalizeRelativePath: ()=>normalizeRelativePath,
46
+ findWorkspaceRoot: ()=>external_workspace_topology_js_namespaceObject.findWorkspaceRoot,
47
+ normalizeRelativePath: ()=>external_workspace_topology_js_namespaceObject.normalizeRelativePath,
47
48
  readBuildIdentity: ()=>readBuildIdentity,
48
49
  resolveWorkspaceSourceRevision: ()=>resolveWorkspaceSourceRevision
49
50
  });
@@ -54,8 +55,7 @@ const external_node_path_namespaceObject = require("node:path");
54
55
  var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_namespaceObject);
55
56
  const release_identity_namespaceObject = require("@modern-js/app-tools-extensions/release-identity");
56
57
  const backend_federation_contracts_namespaceObject = require("@modern-js/backend-federation-contracts");
57
- const COMPACT_CONFIG_PATH = '.modernjs/ultramodern.json';
58
- const normalizeRelativePath = (value)=>value.replace(/\\/gu, '/').replace(/^\.\/+/u, '');
58
+ const external_workspace_topology_js_namespaceObject = require("../workspace-topology.js");
59
59
  const isRecord = (value)=>'object' == typeof value && null !== value;
60
60
  const readJsonFile = async (filePath)=>JSON.parse(await promises_default().readFile(filePath, 'utf8'));
61
61
  const buildArtifactPathFor = (appDirectory)=>external_node_path_default().join(appDirectory, backend_federation_contracts_namespaceObject.ULTRAMODERN_BUILD_ARTIFACT_PATH);
@@ -82,19 +82,20 @@ const readBuildIdentity = async (appDirectory)=>{
82
82
  const toPascalCase = (value)=>value.split(/[^a-zA-Z0-9]+/u).filter(Boolean).map((part)=>part.charAt(0).toUpperCase() + part.slice(1)).join('');
83
83
  const stringValue = (value)=>'string' == typeof value && value.length > 0 ? value : void 0;
84
84
  const createBackendName = (app, id)=>{
85
- const configuredName = stringValue(app.backendFederation?.name) ?? stringValue(app.backendFederation?.executionSurfaces?.node?.remoteName) ?? stringValue(app.serverExecution?.node?.remoteName);
85
+ const configuredName = stringValue(app.backendFederation?.name) ?? stringValue(app.backendFederation?.executionSurfaces?.node?.remoteName);
86
86
  if (configuredName) return configuredName;
87
87
  const mfName = stringValue(app.moduleFederation?.name);
88
88
  return mfName ? `${mfName}Backend` : `vertical${toPascalCase(id)}Backend`;
89
89
  };
90
- const findWorkspaceRoot = (appDirectory)=>{
91
- let current = appDirectory;
92
- while(true){
93
- if ((0, external_node_fs_namespaceObject.existsSync)(external_node_path_default().join(current, COMPACT_CONFIG_PATH))) return current;
94
- const parent = external_node_path_default().dirname(current);
95
- if (parent === current) return;
96
- current = parent;
90
+ const rebaseDefaultLocalUrl = (value, defaultPort, publicOrigin)=>{
91
+ let url;
92
+ try {
93
+ url = new URL(value);
94
+ } catch {
95
+ return value;
97
96
  }
97
+ if ('http:' !== url.protocol || 'localhost' !== url.hostname || Number(url.port) !== defaultPort || url.username || url.password) return value;
98
+ return `${publicOrigin}${url.pathname}${url.search}${url.hash}`;
98
99
  };
99
100
  const resolveWorkspaceSourceRevision = async (workspaceRoot)=>(0, release_identity_namespaceObject.resolveUltramodernSourceRevision)(workspaceRoot);
100
101
  const createStampedDeliveryUnit = (input)=>{
@@ -114,59 +115,96 @@ const createStampedDeliveryUnit = (input)=>{
114
115
  if (!validation.ok) return;
115
116
  return (0, backend_federation_contracts_namespaceObject.deliveryUnitContractBlock)(record);
116
117
  };
117
- const createAppFromCompactMetadata = (workspaceRoot, appDirectory, compactApp)=>{
118
- const id = stringValue(compactApp.id);
119
- const appPath = stringValue(compactApp.path);
120
- if (!id || 'vertical' !== compactApp.kind || !isRecord(compactApp.api)) return;
121
- const directory = appPath ? normalizeRelativePath(appPath) : `verticals/${id}`;
118
+ const createAppFromTopology = (workspaceRoot, appDirectory, topologyApp, overlay, packageManifest)=>{
119
+ const id = stringValue(topologyApp.id);
120
+ const appPath = stringValue(topologyApp.path);
121
+ if (!id || !appPath || 'vertical' !== topologyApp.kind || !isRecord(topologyApp.api) || !isRecord(topologyApp.backendFederation)) return;
122
+ const directory = (0, external_workspace_topology_js_namespaceObject.normalizeRelativePath)(appPath);
122
123
  if (external_node_path_default().resolve(workspaceRoot, directory) !== external_node_path_default().resolve(appDirectory)) return;
123
- const port = 'number' == typeof compactApp.port ? compactApp.port : void 0;
124
- if (void 0 === port) return;
125
- const apiPrefix = stringValue(compactApp.api.prefix) ?? `/${id}-api`;
126
- const apiStem = stringValue(compactApp.api.stem) ?? id;
127
- const backendName = createBackendName(compactApp, id);
128
- const manifestUrl = stringValue(compactApp.backendFederation?.executionSurfaces?.node?.manifestUrl) ?? stringValue(compactApp.serverExecution?.node?.manifestUrl) ?? `http://localhost:${port}/${backend_federation_contracts_namespaceObject.BACKEND_FEDERATION_MANIFEST_FILE}`;
129
- const containerEntry = stringValue(compactApp.backendFederation?.executionSurfaces?.node?.containerEntry) ?? stringValue(compactApp.serverExecution?.node?.containerEntry) ?? `http://localhost:${port}/${backend_federation_contracts_namespaceObject.BACKEND_FEDERATION_REMOTE_ENTRY_FILE}`;
130
- const configuredRemoteType = stringValue(compactApp.backendFederation?.executionSurfaces?.node?.remoteType) ?? stringValue(compactApp.serverExecution?.node?.remoteType);
124
+ const defaultPort = overlay.ports?.[id];
125
+ if ('number' != typeof defaultPort || !Number.isInteger(defaultPort) || defaultPort < 1 || defaultPort > 65535) throw new Error(`[backend-federation-build] Invalid development port for ${id}.`);
126
+ const portEnv = stringValue(topologyApp.portEnv) ?? `VERTICAL_${(stringValue(topologyApp.domain) ?? id).replace(/[^a-zA-Z0-9]/gu, '_').toUpperCase()}_PORT`;
127
+ const port = Number(process.env[portEnv] ?? defaultPort);
128
+ if (!Number.isInteger(port) || port < 1 || port > 65535) throw new Error(`[backend-federation-build] Invalid ${portEnv} development port for ${id}.`);
129
+ const publicUrlEnv = stringValue(topologyApp.cloudflare?.publicUrlEnv);
130
+ const configuredPublicUrl = publicUrlEnv ? process.env[publicUrlEnv]?.trim() : void 0;
131
+ let publicOrigin = `http://localhost:${port}`;
132
+ if (configuredPublicUrl) {
133
+ let url;
134
+ try {
135
+ url = new URL(configuredPublicUrl);
136
+ } catch {
137
+ throw new Error(`[backend-federation-build] Invalid ${publicUrlEnv} public URL for ${id}.`);
138
+ }
139
+ if (![
140
+ 'http:',
141
+ 'https:'
142
+ ].includes(url.protocol) || url.username || url.password) throw new Error(`[backend-federation-build] Invalid ${publicUrlEnv} public URL for ${id}.`);
143
+ publicOrigin = url.origin;
144
+ }
145
+ const apiPrefix = stringValue(topologyApp.api.bff?.prefix) ?? `/${id}-api`;
146
+ const apiProtocol = topologyApp.api.protocol ?? 'rest';
147
+ if ('rest' !== apiProtocol && 'rpc' !== apiProtocol) throw new Error(`[backend-federation-build] Unsupported API protocol for ${id}.`);
148
+ const rpcPath = 'rpc' === apiProtocol ? stringValue(topologyApp.api.rpcPath) : void 0;
149
+ if ('rpc' === apiProtocol && (!rpcPath || 'json' !== topologyApp.api.rpcSerialization)) throw new Error(`[backend-federation-build] Missing JSON RPC route metadata for ${id}.`);
150
+ const apiStem = stringValue(topologyApp.api.stem) ?? id;
151
+ const backendName = createBackendName(topologyApp, id);
152
+ const nodeOverlay = overlay.serverExecution?.[id]?.node;
153
+ if (!isRecord(nodeOverlay)) throw new Error(`[backend-federation-build] Missing declared Node server execution for ${id}.`);
154
+ const manifestUrl = rebaseDefaultLocalUrl(stringValue(nodeOverlay?.manifestUrl) ?? `http://localhost:${defaultPort}/${backend_federation_contracts_namespaceObject.BACKEND_FEDERATION_MANIFEST_FILE}`, defaultPort, publicOrigin);
155
+ const containerEntry = rebaseDefaultLocalUrl(stringValue(nodeOverlay?.containerEntry) ?? `http://localhost:${defaultPort}/${backend_federation_contracts_namespaceObject.BACKEND_FEDERATION_REMOTE_ENTRY_FILE}`, defaultPort, publicOrigin);
156
+ const configuredRemoteType = stringValue(nodeOverlay?.remoteType) ?? stringValue(topologyApp.backendFederation?.executionSurfaces?.node?.remoteType);
131
157
  if (void 0 !== configuredRemoteType && 'commonjs-module' !== configuredRemoteType) throw new Error(`[backend-federation-build] Node backend federation remoteType must be "commonjs-module"; received "${configuredRemoteType}" for ${id}.`);
132
158
  if (!new URL(containerEntry).pathname.endsWith(`/${backend_federation_contracts_namespaceObject.BACKEND_FEDERATION_REMOTE_ENTRY_FILE}`)) throw new Error(`[backend-federation-build] Node backend federation containerEntry must end with "/${backend_federation_contracts_namespaceObject.BACKEND_FEDERATION_REMOTE_ENTRY_FILE}"; received "${containerEntry}" for ${id}.`);
133
159
  const remoteType = 'commonjs-module';
134
- const packageName = stringValue(compactApp.package);
135
- const uiManifestUrl = stringValue(compactApp.backendFederation?.versionBoundary?.ui?.manifestUrl) ?? stringValue(compactApp.moduleFederation?.manifestUrl);
136
- const compactDeliveryUnit = isRecord(compactApp.deliveryUnit) ? {
137
- unitId: stringValue(compactApp.deliveryUnit.unitId),
138
- buildMarker: stringValue(compactApp.deliveryUnit.buildMarker),
139
- sourceRevision: stringValue(compactApp.deliveryUnit.sourceRevision),
140
- packageName: stringValue(compactApp.deliveryUnit.packageName),
141
- version: stringValue(compactApp.deliveryUnit.version)
160
+ const packageName = stringValue(packageManifest.name);
161
+ const version = stringValue(packageManifest.version);
162
+ if (stringValue(topologyApp.package) !== packageName || !version) throw new Error(`[backend-federation-build] Topology package identity must match package.json for ${id}.`);
163
+ const declaredUiManifestUrl = stringValue(overlay.manifests?.[id]);
164
+ const uiManifestUrl = declaredUiManifestUrl ? rebaseDefaultLocalUrl(declaredUiManifestUrl, defaultPort, publicOrigin) : void 0;
165
+ const topologyDeliveryUnit = isRecord(topologyApp.deliveryUnit) ? {
166
+ unitId: stringValue(topologyApp.deliveryUnit.unitId),
167
+ buildMarker: stringValue(topologyApp.deliveryUnit.buildMarker),
168
+ sourceRevision: stringValue(topologyApp.deliveryUnit.sourceRevision),
169
+ packageName: stringValue(topologyApp.deliveryUnit.packageName),
170
+ version: stringValue(topologyApp.deliveryUnit.version)
142
171
  } : void 0;
143
172
  return {
144
173
  id,
145
174
  directory,
146
175
  packageName,
176
+ version,
147
177
  port,
148
178
  apiPrefix,
179
+ apiProtocol,
180
+ rpcPath,
149
181
  apiStem,
150
182
  backendName,
151
183
  manifestUrl,
152
184
  containerEntry,
153
185
  remoteType,
154
186
  uiManifestUrl,
155
- compactDeliveryUnit
187
+ topologyDeliveryUnit
156
188
  };
157
189
  };
158
190
  const findBackendFederationApp = async (workspaceRoot, appDirectory)=>{
159
- const compactConfigPath = external_node_path_default().join(workspaceRoot, COMPACT_CONFIG_PATH);
160
- const compactConfig = await readJsonFile(compactConfigPath);
161
- const apps = Array.isArray(compactConfig.topology?.apps) ? compactConfig.topology.apps : [];
162
- for (const app of apps){
163
- const resolved = createAppFromCompactMetadata(workspaceRoot, appDirectory, app);
191
+ const topologyPath = external_node_path_default().join(workspaceRoot, external_workspace_topology_js_namespaceObject.REFERENCE_TOPOLOGY_PATH);
192
+ const topology = await readJsonFile(topologyPath);
193
+ if (!isRecord(topology) || !Array.isArray(topology.verticals)) throw new Error(`[backend-federation-build] Invalid declared topology at ${topologyPath}.`);
194
+ const overlayPath = external_node_path_default().join(workspaceRoot, external_workspace_topology_js_namespaceObject.DEVELOPMENT_OVERLAY_PATH);
195
+ const overlay = await readJsonFile(overlayPath);
196
+ if (!isRecord(overlay) || !isRecord(overlay.ports)) throw new Error(`[backend-federation-build] Invalid development overlay at ${overlayPath}.`);
197
+ const packageManifest = await readJsonFile(external_node_path_default().join(appDirectory, 'package.json'));
198
+ for (const app of topology.verticals){
199
+ const resolved = createAppFromTopology(workspaceRoot, appDirectory, app, overlay, packageManifest);
164
200
  if (resolved) return resolved;
165
201
  }
202
+ throw new Error(`[backend-federation-build] ${appDirectory} is missing from the declared reference topology.`);
166
203
  };
167
- exports.COMPACT_CONFIG_PATH = __webpack_exports__.COMPACT_CONFIG_PATH;
204
+ exports.DEVELOPMENT_OVERLAY_PATH = __webpack_exports__.DEVELOPMENT_OVERLAY_PATH;
205
+ exports.REFERENCE_TOPOLOGY_PATH = __webpack_exports__.REFERENCE_TOPOLOGY_PATH;
168
206
  exports.buildArtifactPathFor = __webpack_exports__.buildArtifactPathFor;
169
- exports.createAppFromCompactMetadata = __webpack_exports__.createAppFromCompactMetadata;
207
+ exports.createAppFromTopology = __webpack_exports__.createAppFromTopology;
170
208
  exports.createStampedDeliveryUnit = __webpack_exports__.createStampedDeliveryUnit;
171
209
  exports.findBackendFederationApp = __webpack_exports__.findBackendFederationApp;
172
210
  exports.findWorkspaceRoot = __webpack_exports__.findWorkspaceRoot;
@@ -174,9 +212,10 @@ exports.normalizeRelativePath = __webpack_exports__.normalizeRelativePath;
174
212
  exports.readBuildIdentity = __webpack_exports__.readBuildIdentity;
175
213
  exports.resolveWorkspaceSourceRevision = __webpack_exports__.resolveWorkspaceSourceRevision;
176
214
  for(var __rspack_i in __webpack_exports__)if (-1 === [
177
- "COMPACT_CONFIG_PATH",
215
+ "DEVELOPMENT_OVERLAY_PATH",
216
+ "REFERENCE_TOPOLOGY_PATH",
178
217
  "buildArtifactPathFor",
179
- "createAppFromCompactMetadata",
218
+ "createAppFromTopology",
180
219
  "createStampedDeliveryUnit",
181
220
  "findBackendFederationApp",
182
221
  "findWorkspaceRoot",
@@ -48,9 +48,10 @@ var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_no
48
48
  const release_identity_namespaceObject = require("@modern-js/app-tools-extensions/release-identity");
49
49
  const backend_federation_contracts_namespaceObject = require("@modern-js/backend-federation-contracts");
50
50
  const node_namespaceObject = require("@modern-js/server-runtime-extensions/backend-federation-security/node");
51
+ const renderer_output_stamp_js_namespaceObject = require("../release-envelope/renderer-output-stamp.js");
51
52
  const external_codegen_js_namespaceObject = require("./codegen.js");
52
53
  const external_config_js_namespaceObject = require("./config.js");
53
- const emitBackendFederationArtifacts = async (appDirectory, distDirectory)=>{
54
+ const emitBackendFederationArtifacts = async (appDirectory, distDirectory, options = {})=>{
54
55
  const workspaceRoot = (0, external_config_js_namespaceObject.findWorkspaceRoot)(appDirectory);
55
56
  if (!workspaceRoot) return;
56
57
  const effectApiPath = external_node_path_default().join(appDirectory, 'api/effect-api.ts');
@@ -59,35 +60,50 @@ const emitBackendFederationArtifacts = async (appDirectory, distDirectory)=>{
59
60
  const app = await (0, external_config_js_namespaceObject.findBackendFederationApp)(workspaceRoot, appDirectory);
60
61
  if (!app) return;
61
62
  const buildIdentity = await (0, external_config_js_namespaceObject.readBuildIdentity)(appDirectory);
62
- const compactDeliveryUnit = app.compactDeliveryUnit;
63
- const hasCompactDeliveryUnit = void 0 !== compactDeliveryUnit && (void 0 !== compactDeliveryUnit.unitId || void 0 !== compactDeliveryUnit.buildMarker || void 0 !== compactDeliveryUnit.packageName || void 0 !== compactDeliveryUnit.version);
63
+ const topologyDeliveryUnit = app.topologyDeliveryUnit;
64
+ const hasTopologyDeliveryUnit = void 0 !== topologyDeliveryUnit && (void 0 !== topologyDeliveryUnit.unitId || void 0 !== topologyDeliveryUnit.buildMarker || void 0 !== topologyDeliveryUnit.packageName || void 0 !== topologyDeliveryUnit.version);
64
65
  const hasBuildIdentity = void 0 !== buildIdentity.unitId || void 0 !== buildIdentity.buildVersion || void 0 !== buildIdentity.packageName || void 0 !== buildIdentity.version;
65
66
  if (hasBuildIdentity) {
66
- const compactConfigPath = external_node_path_default().join(workspaceRoot, external_config_js_namespaceObject.COMPACT_CONFIG_PATH);
67
+ const topologyPath = external_node_path_default().join(workspaceRoot, external_config_js_namespaceObject.REFERENCE_TOPOLOGY_PATH);
67
68
  const buildIdentityPath = (0, external_config_js_namespaceObject.buildArtifactPathFor)(appDirectory);
68
69
  const mismatches = [];
69
70
  const compare = (label, a, b, leftLabel = 'deliveryUnit')=>{
70
71
  if (void 0 !== a && void 0 !== b && a !== b) mismatches.push(`${label}: ${leftLabel}=${a} vs ultramodern-build=${b}`);
71
72
  };
72
73
  compare('appId', app.id, buildIdentity.appId, 'topology');
73
- if (hasCompactDeliveryUnit) {
74
- compare('unitId', compactDeliveryUnit?.unitId, buildIdentity.unitId);
75
- compare('buildMarker/build', compactDeliveryUnit?.buildMarker, buildIdentity.buildVersion);
76
- compare('packageName', compactDeliveryUnit?.packageName, buildIdentity.packageName);
77
- compare('version', compactDeliveryUnit?.version, buildIdentity.version);
74
+ if (hasTopologyDeliveryUnit) {
75
+ compare('unitId', topologyDeliveryUnit?.unitId, buildIdentity.unitId);
76
+ compare('buildMarker/build', topologyDeliveryUnit?.buildMarker, buildIdentity.buildVersion);
77
+ compare('packageName', topologyDeliveryUnit?.packageName, buildIdentity.packageName);
78
+ compare('version', topologyDeliveryUnit?.version, buildIdentity.version);
78
79
  }
79
- if (mismatches.length > 0) throw new Error(`[backend-federation-build] Delivery-unit identity drift between ${compactConfigPath} (topology) and ${buildIdentityPath}: ${mismatches.join('; ')}`);
80
+ compare('packageName', app.packageName, buildIdentity.packageName, 'package.json');
81
+ compare('packageName', topologyDeliveryUnit?.packageName, app.packageName, 'topology');
82
+ compare('version', app.version, buildIdentity.version, 'package.json');
83
+ compare('version', topologyDeliveryUnit?.version, app.version, 'topology');
84
+ if (mismatches.length > 0) throw new Error(`[backend-federation-build] Delivery-unit identity drift between ${topologyPath}, package.json and ${buildIdentityPath}: ${mismatches.join('; ')}`);
80
85
  }
81
- const unitId = compactDeliveryUnit?.unitId ?? buildIdentity.unitId;
82
- const generationBuildMarker = compactDeliveryUnit?.buildMarker ?? buildIdentity.buildVersion;
83
- const sourceRevision = await (0, external_config_js_namespaceObject.resolveWorkspaceSourceRevision)(workspaceRoot);
84
- const buildVersion = generationBuildMarker && unitId ? (0, release_identity_namespaceObject.resolveUltramodernReleaseIdentity)({
86
+ const unitId = topologyDeliveryUnit?.unitId ?? buildIdentity.unitId;
87
+ const generationBuildMarker = topologyDeliveryUnit?.buildMarker ?? buildIdentity.buildVersion;
88
+ let finalizedRendererBuild;
89
+ if (options.resolveRendererBuild && buildIdentity.artifact?.surfaces.ui) {
90
+ if (!options.entrypoints?.length) throw new Error('[backend-federation-build] Renderer output stamping requires the actual finalized application entries.');
91
+ const context = {
92
+ appDirectory,
93
+ distDirectory,
94
+ entrypoints: options.entrypoints
95
+ };
96
+ finalizedRendererBuild = await options.resolveRendererBuild(context);
97
+ (0, renderer_output_stamp_js_namespaceObject.validateFinalizedRendererBuild)(finalizedRendererBuild, context, app.id);
98
+ }
99
+ const sourceRevision = finalizedRendererBuild?.sourceRevision ?? await (0, external_config_js_namespaceObject.resolveWorkspaceSourceRevision)(workspaceRoot);
100
+ const buildVersion = finalizedRendererBuild?.buildMarker ?? (generationBuildMarker && unitId ? (0, release_identity_namespaceObject.resolveUltramodernReleaseIdentity)({
85
101
  generationBuildMarker,
86
102
  unitId,
87
103
  workspaceRoot
88
- }).buildMarker : void 0;
89
- const packageName = compactDeliveryUnit?.packageName ?? buildIdentity.packageName ?? app.packageName;
90
- const version = compactDeliveryUnit?.version ?? buildIdentity.version;
104
+ }).buildMarker : void 0);
105
+ const packageName = app.packageName;
106
+ const version = app.version;
91
107
  const deliveryUnit = (0, external_config_js_namespaceObject.createStampedDeliveryUnit)({
92
108
  appId: app.id,
93
109
  unitId,
@@ -96,10 +112,15 @@ const emitBackendFederationArtifacts = async (appDirectory, distDirectory)=>{
96
112
  version,
97
113
  sourceRevision
98
114
  });
99
- const stampedBuildArtifact = buildIdentity.artifact ? (0, backend_federation_contracts_namespaceObject.stampUltramodernBuildArtifactIdentity)(buildIdentity.artifact, {
115
+ let stampedBuildArtifact = buildIdentity.artifact ? (0, backend_federation_contracts_namespaceObject.stampUltramodernBuildArtifactIdentity)(buildIdentity.artifact, {
100
116
  buildMarker: buildVersion ?? buildIdentity.artifact.deliveryUnit.buildMarker,
101
117
  sourceRevision
102
118
  }) : void 0;
119
+ if (finalizedRendererBuild && stampedBuildArtifact?.surfaces.ui) stampedBuildArtifact = (0, renderer_output_stamp_js_namespaceObject.stampFinalizedRendererBuildArtifact)(stampedBuildArtifact, finalizedRendererBuild, {
120
+ appDirectory,
121
+ distDirectory,
122
+ entrypoints: options.entrypoints
123
+ });
103
124
  const resolvedApp = {
104
125
  ...app,
105
126
  packageName,
@@ -130,15 +151,35 @@ const emitBackendFederationArtifacts = async (appDirectory, distDirectory)=>{
130
151
  remoteType: resolvedApp.remoteType
131
152
  };
132
153
  };
133
- const emit = ()=>({
154
+ const emit = (options = {})=>{
155
+ if (options.resolveRendererBuild && !options.rendererBuildPlugin) throw new Error('[backend-federation-build] A finalized renderer resolver requires its owning metadata producer plugin.');
156
+ return {
134
157
  name: '@modern-js/backend-federation-build',
158
+ pre: options.resolveRendererBuild ? [
159
+ options.rendererBuildPlugin
160
+ ] : [],
161
+ required: options.resolveRendererBuild ? [
162
+ options.rendererBuildPlugin
163
+ ] : [],
135
164
  setup (api) {
136
165
  api.onAfterBuild(async ()=>{
137
- const { appDirectory, distDirectory } = api.getAppContext();
138
- await emitBackendFederationArtifacts(appDirectory, distDirectory);
166
+ const { appDirectory, distDirectory, entrypoints, apiOnly } = api.getAppContext();
167
+ if (options.resolveRendererBuild && !apiOnly) await (0, renderer_output_stamp_js_namespaceObject.emitRendererBuildArtifact)({
168
+ appDirectory,
169
+ distDirectory,
170
+ entrypoints: entrypoints ?? []
171
+ }, {
172
+ resolveRendererBuild: options.resolveRendererBuild,
173
+ rendererBuildPlugin: options.rendererBuildPlugin
174
+ });
175
+ await emitBackendFederationArtifacts(appDirectory, distDirectory, {
176
+ ...options,
177
+ entrypoints
178
+ });
139
179
  });
140
180
  }
141
- });
181
+ };
182
+ };
142
183
  exports["default"] = __webpack_exports__["default"];
143
184
  exports.emitBackendFederationArtifacts = __webpack_exports__.emitBackendFederationArtifacts;
144
185
  for(var __rspack_i in __webpack_exports__)if (-1 === [