every-plugin 2.10.1 → 3.0.0-rc.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 (480) hide show
  1. package/bin/every-plugin-serve.mjs +12 -0
  2. package/bin/every-plugin.mjs +59 -0
  3. package/dist/_virtual/_rolldown/runtime.cjs +1 -2
  4. package/dist/build/artifact-names.cjs +119 -0
  5. package/dist/build/artifact-names.cjs.map +1 -0
  6. package/dist/build/artifact-names.d.cts +68 -0
  7. package/dist/build/artifact-names.d.cts.map +1 -0
  8. package/dist/build/artifact-names.d.mts +68 -0
  9. package/dist/build/artifact-names.d.mts.map +1 -0
  10. package/dist/build/artifact-names.mjs +102 -0
  11. package/dist/build/artifact-names.mjs.map +1 -0
  12. package/dist/build/contract-types.cjs +89 -0
  13. package/dist/build/contract-types.cjs.map +1 -0
  14. package/dist/build/contract-types.mjs +81 -0
  15. package/dist/build/contract-types.mjs.map +1 -0
  16. package/dist/build/rspack/build-report-plugin.cjs +37 -0
  17. package/dist/build/rspack/build-report-plugin.cjs.map +1 -0
  18. package/dist/build/rspack/build-report-plugin.d.cts +18 -0
  19. package/dist/build/rspack/build-report-plugin.d.cts.map +1 -0
  20. package/dist/build/rspack/build-report-plugin.d.mts +18 -0
  21. package/dist/build/rspack/build-report-plugin.d.mts.map +1 -0
  22. package/dist/build/rspack/build-report-plugin.mjs +37 -0
  23. package/dist/build/rspack/build-report-plugin.mjs.map +1 -0
  24. package/dist/build/rspack/chunk-completeness-plugin.cjs +59 -0
  25. package/dist/build/rspack/chunk-completeness-plugin.cjs.map +1 -0
  26. package/dist/build/rspack/chunk-completeness-plugin.mjs +59 -0
  27. package/dist/build/rspack/chunk-completeness-plugin.mjs.map +1 -0
  28. package/dist/build/rspack/compose.cjs +69 -0
  29. package/dist/build/rspack/compose.cjs.map +1 -0
  30. package/dist/build/rspack/compose.d.cts +20 -0
  31. package/dist/build/rspack/compose.d.cts.map +1 -0
  32. package/dist/build/rspack/compose.d.mts +20 -0
  33. package/dist/build/rspack/compose.d.mts.map +1 -0
  34. package/dist/build/rspack/compose.mjs +65 -0
  35. package/dist/build/rspack/compose.mjs.map +1 -0
  36. package/dist/build/rspack/fix-mf-data-uri-plugin.cjs +11 -11
  37. package/dist/build/rspack/fix-mf-data-uri-plugin.cjs.map +1 -1
  38. package/dist/build/rspack/fix-mf-data-uri-plugin.d.cts +2 -0
  39. package/dist/build/rspack/fix-mf-data-uri-plugin.d.cts.map +1 -1
  40. package/dist/build/rspack/fix-mf-data-uri-plugin.d.mts +2 -0
  41. package/dist/build/rspack/fix-mf-data-uri-plugin.d.mts.map +1 -1
  42. package/dist/build/rspack/fix-mf-data-uri-plugin.mjs +11 -10
  43. package/dist/build/rspack/fix-mf-data-uri-plugin.mjs.map +1 -1
  44. package/dist/build/rspack/generated-config.cjs +35 -0
  45. package/dist/build/rspack/generated-config.cjs.map +1 -0
  46. package/dist/build/rspack/generated-config.mjs +32 -0
  47. package/dist/build/rspack/generated-config.mjs.map +1 -0
  48. package/dist/build/rspack/index.cjs +8 -5
  49. package/dist/build/rspack/index.d.cts +5 -3
  50. package/dist/build/rspack/index.d.mts +5 -3
  51. package/dist/build/rspack/index.mjs +5 -3
  52. package/dist/build/rspack/module-federation.cjs +2 -2
  53. package/dist/build/rspack/module-federation.cjs.map +1 -1
  54. package/dist/build/rspack/module-federation.mjs +1 -1
  55. package/dist/build/rspack/module-federation.mjs.map +1 -1
  56. package/dist/build/rspack/plugin.cjs +44 -69
  57. package/dist/build/rspack/plugin.cjs.map +1 -1
  58. package/dist/build/rspack/plugin.d.cts +4 -13
  59. package/dist/build/rspack/plugin.d.cts.map +1 -1
  60. package/dist/build/rspack/plugin.d.mts +4 -13
  61. package/dist/build/rspack/plugin.d.mts.map +1 -1
  62. package/dist/build/rspack/plugin.mjs +44 -69
  63. package/dist/build/rspack/plugin.mjs.map +1 -1
  64. package/dist/build/rspack/utils.cjs +7 -5
  65. package/dist/build/rspack/utils.cjs.map +1 -1
  66. package/dist/build/rspack/utils.mjs +7 -6
  67. package/dist/build/rspack/utils.mjs.map +1 -1
  68. package/dist/build/ui/factory.cjs +88 -0
  69. package/dist/build/ui/factory.cjs.map +1 -0
  70. package/dist/build/ui/factory.d.cts +11 -0
  71. package/dist/build/ui/factory.d.cts.map +1 -0
  72. package/dist/build/ui/factory.d.mts +11 -0
  73. package/dist/build/ui/factory.d.mts.map +1 -0
  74. package/dist/build/ui/factory.mjs +80 -0
  75. package/dist/build/ui/factory.mjs.map +1 -0
  76. package/dist/build/ui/generated-config.cjs +122 -0
  77. package/dist/build/ui/generated-config.cjs.map +1 -0
  78. package/dist/build/ui/generated-config.d.cts +33 -0
  79. package/dist/build/ui/generated-config.d.cts.map +1 -0
  80. package/dist/build/ui/generated-config.d.mts +33 -0
  81. package/dist/build/ui/generated-config.d.mts.map +1 -0
  82. package/dist/build/ui/generated-config.mjs +114 -0
  83. package/dist/build/ui/generated-config.mjs.map +1 -0
  84. package/dist/build/ui/hash-artifacts-plugin.cjs +61 -0
  85. package/dist/build/ui/hash-artifacts-plugin.cjs.map +1 -0
  86. package/dist/build/ui/hash-artifacts-plugin.d.cts +20 -0
  87. package/dist/build/ui/hash-artifacts-plugin.d.cts.map +1 -0
  88. package/dist/build/ui/hash-artifacts-plugin.d.mts +20 -0
  89. package/dist/build/ui/hash-artifacts-plugin.d.mts.map +1 -0
  90. package/dist/build/ui/hash-artifacts-plugin.mjs +58 -0
  91. package/dist/build/ui/hash-artifacts-plugin.mjs.map +1 -0
  92. package/dist/build/ui/index.cjs +90 -0
  93. package/dist/build/ui/index.cjs.map +1 -0
  94. package/dist/build/ui/index.d.cts +29 -0
  95. package/dist/build/ui/index.d.cts.map +1 -0
  96. package/dist/build/ui/index.d.mts +29 -0
  97. package/dist/build/ui/index.d.mts.map +1 -0
  98. package/dist/build/ui/index.mjs +68 -0
  99. package/dist/build/ui/index.mjs.map +1 -0
  100. package/dist/build/ui/manifest-plugin.cjs +37 -0
  101. package/dist/build/ui/manifest-plugin.cjs.map +1 -0
  102. package/dist/build/ui/manifest-plugin.d.cts +19 -0
  103. package/dist/build/ui/manifest-plugin.d.cts.map +1 -0
  104. package/dist/build/ui/manifest-plugin.d.mts +19 -0
  105. package/dist/build/ui/manifest-plugin.d.mts.map +1 -0
  106. package/dist/build/ui/manifest-plugin.mjs +37 -0
  107. package/dist/build/ui/manifest-plugin.mjs.map +1 -0
  108. package/dist/build/ui/rsbuild-config.cjs +203 -0
  109. package/dist/build/ui/rsbuild-config.cjs.map +1 -0
  110. package/dist/build/ui/rsbuild-config.d.cts +45 -0
  111. package/dist/build/ui/rsbuild-config.d.cts.map +1 -0
  112. package/dist/build/ui/rsbuild-config.d.mts +45 -0
  113. package/dist/build/ui/rsbuild-config.d.mts.map +1 -0
  114. package/dist/build/ui/rsbuild-config.mjs +200 -0
  115. package/dist/build/ui/rsbuild-config.mjs.map +1 -0
  116. package/dist/build/ui/stubs.cjs +107 -0
  117. package/dist/build/ui/stubs.cjs.map +1 -0
  118. package/dist/build/ui/stubs.d.cts +25 -0
  119. package/dist/build/ui/stubs.d.cts.map +1 -0
  120. package/dist/build/ui/stubs.d.mts +25 -0
  121. package/dist/build/ui/stubs.d.mts.map +1 -0
  122. package/dist/build/ui/stubs.mjs +106 -0
  123. package/dist/build/ui/stubs.mjs.map +1 -0
  124. package/dist/cli.cjs +83 -0
  125. package/dist/cli.cjs.map +1 -0
  126. package/dist/cli.d.cts +6 -0
  127. package/dist/cli.d.cts.map +1 -0
  128. package/dist/cli.d.mts +6 -0
  129. package/dist/cli.d.mts.map +1 -0
  130. package/dist/cli.mjs +82 -0
  131. package/dist/cli.mjs.map +1 -0
  132. package/dist/client.cjs +69 -0
  133. package/dist/client.cjs.map +1 -0
  134. package/dist/client.d.cts +15 -0
  135. package/dist/client.d.cts.map +1 -0
  136. package/dist/client.d.mts +15 -0
  137. package/dist/client.d.mts.map +1 -0
  138. package/dist/client.mjs +68 -0
  139. package/dist/client.mjs.map +1 -0
  140. package/dist/dev/host.cjs +149 -0
  141. package/dist/dev/host.cjs.map +1 -0
  142. package/dist/dev/host.d.cts +32 -0
  143. package/dist/dev/host.d.cts.map +1 -0
  144. package/dist/dev/host.d.mts +32 -0
  145. package/dist/dev/host.d.mts.map +1 -0
  146. package/dist/dev/host.mjs +148 -0
  147. package/dist/dev/host.mjs.map +1 -0
  148. package/dist/dev/serve.cjs +295 -0
  149. package/dist/dev/serve.cjs.map +1 -0
  150. package/dist/dev/serve.d.cts +23 -0
  151. package/dist/dev/serve.d.cts.map +1 -0
  152. package/dist/dev/serve.d.mts +23 -0
  153. package/dist/dev/serve.d.mts.map +1 -0
  154. package/dist/dev/serve.mjs +289 -0
  155. package/dist/dev/serve.mjs.map +1 -0
  156. package/dist/dev/watch-kill.cjs +39 -0
  157. package/dist/dev/watch-kill.cjs.map +1 -0
  158. package/dist/dev/watch-kill.mjs +38 -0
  159. package/dist/dev/watch-kill.mjs.map +1 -0
  160. package/dist/effect-helpers.cjs +23 -0
  161. package/dist/effect-helpers.cjs.map +1 -0
  162. package/dist/effect-helpers.d.cts +20 -0
  163. package/dist/effect-helpers.d.cts.map +1 -0
  164. package/dist/effect-helpers.d.mts +20 -0
  165. package/dist/effect-helpers.d.mts.map +1 -0
  166. package/dist/effect-helpers.mjs +22 -0
  167. package/dist/effect-helpers.mjs.map +1 -0
  168. package/dist/errors.cjs +50 -69
  169. package/dist/errors.cjs.map +1 -1
  170. package/dist/errors.d.cts +13 -96
  171. package/dist/errors.d.cts.map +1 -1
  172. package/dist/errors.d.mts +13 -96
  173. package/dist/errors.d.mts.map +1 -1
  174. package/dist/errors.mjs +16 -34
  175. package/dist/errors.mjs.map +1 -1
  176. package/dist/identity.cjs +19 -0
  177. package/dist/identity.cjs.map +1 -0
  178. package/dist/identity.d.cts +33 -0
  179. package/dist/identity.d.cts.map +1 -0
  180. package/dist/identity.d.mts +33 -0
  181. package/dist/identity.d.mts.map +1 -0
  182. package/dist/identity.mjs +16 -0
  183. package/dist/identity.mjs.map +1 -0
  184. package/dist/index.cjs +11 -5
  185. package/dist/index.d.cts +9 -6
  186. package/dist/index.d.mts +9 -6
  187. package/dist/index.mjs +7 -4
  188. package/dist/plugin.cjs +13 -26
  189. package/dist/plugin.cjs.map +1 -1
  190. package/dist/plugin.d.cts +64 -25
  191. package/dist/plugin.d.cts.map +1 -1
  192. package/dist/plugin.d.mts +64 -25
  193. package/dist/plugin.d.mts.map +1 -1
  194. package/dist/plugin.mjs +16 -29
  195. package/dist/plugin.mjs.map +1 -1
  196. package/dist/remote-entry.cjs +102 -0
  197. package/dist/remote-entry.cjs.map +1 -0
  198. package/dist/remote-entry.d.cts +52 -0
  199. package/dist/remote-entry.d.cts.map +1 -0
  200. package/dist/remote-entry.d.mts +52 -0
  201. package/dist/remote-entry.d.mts.map +1 -0
  202. package/dist/remote-entry.mjs +98 -0
  203. package/dist/remote-entry.mjs.map +1 -0
  204. package/dist/runtime/errors.cjs +159 -33
  205. package/dist/runtime/errors.cjs.map +1 -1
  206. package/dist/runtime/errors.d.cts +64 -7
  207. package/dist/runtime/errors.d.cts.map +1 -1
  208. package/dist/runtime/errors.d.mts +64 -7
  209. package/dist/runtime/errors.d.mts.map +1 -1
  210. package/dist/runtime/errors.mjs +154 -30
  211. package/dist/runtime/errors.mjs.map +1 -1
  212. package/dist/runtime/index.cjs +95 -23
  213. package/dist/runtime/index.cjs.map +1 -1
  214. package/dist/runtime/index.d.cts +16 -0
  215. package/dist/runtime/index.d.cts.map +1 -1
  216. package/dist/runtime/index.d.mts +16 -0
  217. package/dist/runtime/index.d.mts.map +1 -1
  218. package/dist/runtime/index.mjs +98 -26
  219. package/dist/runtime/index.mjs.map +1 -1
  220. package/dist/runtime/mf-config.cjs +3 -78
  221. package/dist/runtime/mf-config.cjs.map +1 -1
  222. package/dist/runtime/mf-config.d.cts +3 -49
  223. package/dist/runtime/mf-config.d.cts.map +1 -1
  224. package/dist/runtime/mf-config.d.mts +3 -49
  225. package/dist/runtime/mf-config.d.mts.map +1 -1
  226. package/dist/runtime/mf-config.mjs +5 -78
  227. package/dist/runtime/mf-config.mjs.map +1 -1
  228. package/dist/runtime/services/module-federation.service.cjs +57 -12
  229. package/dist/runtime/services/module-federation.service.cjs.map +1 -1
  230. package/dist/runtime/services/module-federation.service.d.cts +4 -13
  231. package/dist/runtime/services/module-federation.service.d.mts +4 -13
  232. package/dist/runtime/services/module-federation.service.mjs +57 -14
  233. package/dist/runtime/services/module-federation.service.mjs.map +1 -1
  234. package/dist/runtime/services/normalize.cjs +2 -22
  235. package/dist/runtime/services/normalize.d.cts +2 -21
  236. package/dist/runtime/services/normalize.d.mts +2 -21
  237. package/dist/runtime/services/normalize.mjs +2 -21
  238. package/dist/runtime/services/plugin-lifecycle.service.cjs +9 -11
  239. package/dist/runtime/services/plugin-lifecycle.service.cjs.map +1 -1
  240. package/dist/runtime/services/plugin-lifecycle.service.d.cts +3 -16
  241. package/dist/runtime/services/plugin-lifecycle.service.d.mts +3 -16
  242. package/dist/runtime/services/plugin-lifecycle.service.mjs +10 -13
  243. package/dist/runtime/services/plugin-lifecycle.service.mjs.map +1 -1
  244. package/dist/runtime/services/plugin-loader.service.cjs +59 -30
  245. package/dist/runtime/services/plugin-loader.service.cjs.map +1 -1
  246. package/dist/runtime/services/plugin-loader.service.d.cts +6 -53
  247. package/dist/runtime/services/plugin-loader.service.d.mts +6 -53
  248. package/dist/runtime/services/plugin-loader.service.mjs +58 -31
  249. package/dist/runtime/services/plugin-loader.service.mjs.map +1 -1
  250. package/dist/runtime/services/plugin.service.cjs +10 -12
  251. package/dist/runtime/services/plugin.service.cjs.map +1 -1
  252. package/dist/runtime/services/plugin.service.d.cts +14 -36
  253. package/dist/runtime/services/plugin.service.d.cts.map +1 -1
  254. package/dist/runtime/services/plugin.service.d.mts +14 -36
  255. package/dist/runtime/services/plugin.service.d.mts.map +1 -1
  256. package/dist/runtime/services/plugin.service.mjs +14 -18
  257. package/dist/runtime/services/plugin.service.mjs.map +1 -1
  258. package/dist/runtime/services/secrets.service.cjs +12 -12
  259. package/dist/runtime/services/secrets.service.cjs.map +1 -1
  260. package/dist/runtime/services/secrets.service.d.cts +3 -15
  261. package/dist/runtime/services/secrets.service.d.mts +3 -15
  262. package/dist/runtime/services/secrets.service.mjs +12 -13
  263. package/dist/runtime/services/secrets.service.mjs.map +1 -1
  264. package/dist/runtime/services/shared-identity.cjs +40 -0
  265. package/dist/runtime/services/shared-identity.cjs.map +1 -0
  266. package/dist/runtime/services/shared-identity.mjs +38 -0
  267. package/dist/runtime/services/shared-identity.mjs.map +1 -0
  268. package/dist/runtime/validation.cjs +2 -2
  269. package/dist/runtime/validation.cjs.map +1 -1
  270. package/dist/runtime/validation.mjs +2 -2
  271. package/dist/runtime/validation.mjs.map +1 -1
  272. package/dist/shared-deps-spec.cjs +384 -0
  273. package/dist/shared-deps-spec.cjs.map +1 -0
  274. package/dist/shared-deps-spec.d.cts +182 -0
  275. package/dist/shared-deps-spec.d.cts.map +1 -0
  276. package/dist/shared-deps-spec.d.mts +182 -0
  277. package/dist/shared-deps-spec.d.mts.map +1 -0
  278. package/dist/shared-deps-spec.mjs +368 -0
  279. package/dist/shared-deps-spec.mjs.map +1 -0
  280. package/dist/types.d.cts +47 -41
  281. package/dist/types.d.cts.map +1 -1
  282. package/dist/types.d.mts +47 -41
  283. package/dist/types.d.mts.map +1 -1
  284. package/dist/ui/manifest/construct.cjs +319 -0
  285. package/dist/ui/manifest/construct.cjs.map +1 -0
  286. package/dist/ui/manifest/construct.d.cts +48 -0
  287. package/dist/ui/manifest/construct.d.cts.map +1 -0
  288. package/dist/ui/manifest/construct.d.mts +48 -0
  289. package/dist/ui/manifest/construct.d.mts.map +1 -0
  290. package/dist/ui/manifest/construct.mjs +319 -0
  291. package/dist/ui/manifest/construct.mjs.map +1 -0
  292. package/dist/ui/manifest/contract.cjs +34 -0
  293. package/dist/ui/manifest/contract.cjs.map +1 -0
  294. package/dist/ui/manifest/contract.d.cts +26 -0
  295. package/dist/ui/manifest/contract.d.cts.map +1 -0
  296. package/dist/ui/manifest/contract.d.mts +26 -0
  297. package/dist/ui/manifest/contract.d.mts.map +1 -0
  298. package/dist/ui/manifest/contract.mjs +26 -0
  299. package/dist/ui/manifest/contract.mjs.map +1 -0
  300. package/dist/ui/manifest/descriptor.cjs +64 -0
  301. package/dist/ui/manifest/descriptor.cjs.map +1 -0
  302. package/dist/ui/manifest/descriptor.d.cts +60 -0
  303. package/dist/ui/manifest/descriptor.d.cts.map +1 -0
  304. package/dist/ui/manifest/descriptor.d.mts +60 -0
  305. package/dist/ui/manifest/descriptor.d.mts.map +1 -0
  306. package/dist/ui/manifest/descriptor.mjs +61 -0
  307. package/dist/ui/manifest/descriptor.mjs.map +1 -0
  308. package/dist/ui/manifest/generator.cjs +128 -0
  309. package/dist/ui/manifest/generator.cjs.map +1 -0
  310. package/dist/ui/manifest/generator.d.cts +41 -0
  311. package/dist/ui/manifest/generator.d.cts.map +1 -0
  312. package/dist/ui/manifest/generator.d.mts +41 -0
  313. package/dist/ui/manifest/generator.d.mts.map +1 -0
  314. package/dist/ui/manifest/generator.mjs +125 -0
  315. package/dist/ui/manifest/generator.mjs.map +1 -0
  316. package/dist/ui/manifest/index.cjs +35 -0
  317. package/dist/ui/manifest/index.d.cts +9 -0
  318. package/dist/ui/manifest/index.d.mts +9 -0
  319. package/dist/ui/manifest/index.mjs +9 -0
  320. package/dist/ui/manifest/manifest-schema.cjs +97 -0
  321. package/dist/ui/manifest/manifest-schema.cjs.map +1 -0
  322. package/dist/ui/manifest/manifest-schema.d.cts +132 -0
  323. package/dist/ui/manifest/manifest-schema.d.cts.map +1 -0
  324. package/dist/ui/manifest/manifest-schema.d.mts +132 -0
  325. package/dist/ui/manifest/manifest-schema.d.mts.map +1 -0
  326. package/dist/ui/manifest/manifest-schema.mjs +90 -0
  327. package/dist/ui/manifest/manifest-schema.mjs.map +1 -0
  328. package/dist/ui/manifest/mount-registry.cjs +52 -0
  329. package/dist/ui/manifest/mount-registry.cjs.map +1 -0
  330. package/dist/ui/manifest/mount-registry.d.cts +61 -0
  331. package/dist/ui/manifest/mount-registry.d.cts.map +1 -0
  332. package/dist/ui/manifest/mount-registry.d.mts +61 -0
  333. package/dist/ui/manifest/mount-registry.d.mts.map +1 -0
  334. package/dist/ui/manifest/mount-registry.mjs +48 -0
  335. package/dist/ui/manifest/mount-registry.mjs.map +1 -0
  336. package/dist/ui/manifest/nav.cjs +13 -0
  337. package/dist/ui/manifest/nav.cjs.map +1 -0
  338. package/dist/ui/manifest/nav.d.cts +34 -0
  339. package/dist/ui/manifest/nav.d.cts.map +1 -0
  340. package/dist/ui/manifest/nav.d.mts +34 -0
  341. package/dist/ui/manifest/nav.d.mts.map +1 -0
  342. package/dist/ui/manifest/nav.mjs +13 -0
  343. package/dist/ui/manifest/nav.mjs.map +1 -0
  344. package/dist/ui/manifest/route-config.cjs +33 -0
  345. package/dist/ui/manifest/route-config.cjs.map +1 -0
  346. package/dist/ui/manifest/route-config.d.cts +40 -0
  347. package/dist/ui/manifest/route-config.d.cts.map +1 -0
  348. package/dist/ui/manifest/route-config.d.mts +40 -0
  349. package/dist/ui/manifest/route-config.d.mts.map +1 -0
  350. package/dist/ui/manifest/route-config.mjs +33 -0
  351. package/dist/ui/manifest/route-config.mjs.map +1 -0
  352. package/dist/version-manifest.cjs +77 -0
  353. package/dist/version-manifest.cjs.map +1 -0
  354. package/dist/version-manifest.d.cts +62 -0
  355. package/dist/version-manifest.d.cts.map +1 -0
  356. package/dist/version-manifest.d.mts +62 -0
  357. package/dist/version-manifest.d.mts.map +1 -0
  358. package/dist/version-manifest.mjs +75 -0
  359. package/dist/version-manifest.mjs.map +1 -0
  360. package/package.json +182 -68
  361. package/skills/plugin-client/SKILL.md +34 -9
  362. package/skills/plugin-development/SKILL.md +79 -47
  363. package/skills/plugin-testing/SKILL.md +42 -12
  364. package/src/build/artifact-names.ts +117 -0
  365. package/src/build/contract-types.ts +101 -0
  366. package/src/build/rspack/build-report-plugin.ts +34 -0
  367. package/src/build/rspack/chunk-completeness-plugin.ts +66 -0
  368. package/src/build/rspack/compose.ts +87 -0
  369. package/src/build/rspack/fix-mf-data-uri-plugin.ts +23 -12
  370. package/src/build/rspack/generated-config.ts +35 -0
  371. package/src/build/rspack/index.ts +10 -5
  372. package/src/build/rspack/module-federation.ts +1 -1
  373. package/src/build/rspack/plugin.ts +103 -105
  374. package/src/build/rspack/utils.ts +8 -2
  375. package/src/build/ui/factory.ts +96 -0
  376. package/src/build/ui/generated-config.ts +137 -0
  377. package/src/build/ui/hash-artifacts-plugin.ts +79 -0
  378. package/src/build/ui/index.ts +98 -0
  379. package/src/build/ui/manifest-plugin.ts +54 -0
  380. package/src/build/ui/rsbuild-config.ts +256 -0
  381. package/src/build/ui/stubs.ts +103 -0
  382. package/src/cli.ts +100 -0
  383. package/src/client.ts +111 -0
  384. package/src/dev/host.ts +235 -0
  385. package/src/dev/serve.ts +359 -0
  386. package/src/dev/watch-kill.ts +58 -0
  387. package/src/effect-helpers.ts +25 -0
  388. package/src/errors.ts +17 -18
  389. package/src/identity.ts +36 -0
  390. package/src/index.ts +13 -0
  391. package/src/plugin.ts +94 -91
  392. package/src/remote-entry.ts +170 -0
  393. package/src/runtime/errors.ts +229 -26
  394. package/src/runtime/index.ts +132 -43
  395. package/src/runtime/mf-config.ts +12 -107
  396. package/src/runtime/services/module-federation.service.ts +218 -117
  397. package/src/runtime/services/normalize.ts +1 -18
  398. package/src/runtime/services/plugin-lifecycle.service.ts +66 -75
  399. package/src/runtime/services/plugin-loader.service.ts +280 -209
  400. package/src/runtime/services/plugin.service.ts +61 -43
  401. package/src/runtime/services/secrets.service.ts +20 -15
  402. package/src/runtime/services/shared-identity.ts +68 -0
  403. package/src/runtime/validation.ts +5 -7
  404. package/src/shared-deps-spec.ts +478 -0
  405. package/src/types.ts +62 -50
  406. package/src/ui/manifest/construct.ts +456 -0
  407. package/src/ui/manifest/contract.ts +33 -0
  408. package/src/ui/manifest/descriptor.ts +96 -0
  409. package/src/ui/manifest/generator.ts +238 -0
  410. package/src/ui/manifest/index.ts +55 -0
  411. package/src/ui/manifest/manifest-schema.ts +107 -0
  412. package/src/ui/manifest/mount-registry.ts +50 -0
  413. package/src/ui/manifest/nav.ts +43 -0
  414. package/src/ui/manifest/route-config.ts +82 -0
  415. package/src/version-manifest.ts +106 -0
  416. package/dist/build/rspack/dev-server-middleware.cjs +0 -248
  417. package/dist/build/rspack/dev-server-middleware.cjs.map +0 -1
  418. package/dist/build/rspack/dev-server-middleware.mjs +0 -247
  419. package/dist/build/rspack/dev-server-middleware.mjs.map +0 -1
  420. package/dist/build/shared-deps.cjs +0 -83
  421. package/dist/build/shared-deps.cjs.map +0 -1
  422. package/dist/build/shared-deps.d.cts +0 -67
  423. package/dist/build/shared-deps.d.cts.map +0 -1
  424. package/dist/build/shared-deps.d.mts +0 -67
  425. package/dist/build/shared-deps.d.mts.map +0 -1
  426. package/dist/build/shared-deps.mjs +0 -79
  427. package/dist/build/shared-deps.mjs.map +0 -1
  428. package/dist/effect.cjs +0 -9
  429. package/dist/effect.d.cts +0 -1
  430. package/dist/effect.d.mts +0 -1
  431. package/dist/effect.mjs +0 -3
  432. package/dist/orpc-openapi.cjs +0 -17
  433. package/dist/orpc-openapi.d.cts +0 -2
  434. package/dist/orpc-openapi.d.mts +0 -2
  435. package/dist/orpc-openapi.mjs +0 -5
  436. package/dist/orpc.cjs +0 -46
  437. package/dist/orpc.d.cts +0 -7
  438. package/dist/orpc.d.mts +0 -7
  439. package/dist/orpc.mjs +0 -11
  440. package/dist/package.cjs +0 -23
  441. package/dist/package.cjs.map +0 -1
  442. package/dist/package.mjs +0 -17
  443. package/dist/package.mjs.map +0 -1
  444. package/dist/runtime/services/module-federation.service.d.cts.map +0 -1
  445. package/dist/runtime/services/module-federation.service.d.mts.map +0 -1
  446. package/dist/runtime/services/normalize.cjs.map +0 -1
  447. package/dist/runtime/services/normalize.d.cts.map +0 -1
  448. package/dist/runtime/services/normalize.d.mts.map +0 -1
  449. package/dist/runtime/services/normalize.mjs.map +0 -1
  450. package/dist/runtime/services/plugin-lifecycle.service.d.cts.map +0 -1
  451. package/dist/runtime/services/plugin-lifecycle.service.d.mts.map +0 -1
  452. package/dist/runtime/services/plugin-loader.service.d.cts.map +0 -1
  453. package/dist/runtime/services/plugin-loader.service.d.mts.map +0 -1
  454. package/dist/runtime/services/secrets.service.d.cts.map +0 -1
  455. package/dist/runtime/services/secrets.service.d.mts.map +0 -1
  456. package/dist/testing/index.cjs +0 -57
  457. package/dist/testing/index.cjs.map +0 -1
  458. package/dist/testing/index.d.cts +0 -54
  459. package/dist/testing/index.d.cts.map +0 -1
  460. package/dist/testing/index.d.mts +0 -54
  461. package/dist/testing/index.d.mts.map +0 -1
  462. package/dist/testing/index.mjs +0 -55
  463. package/dist/testing/index.mjs.map +0 -1
  464. package/dist/zod-core.cjs +0 -9
  465. package/dist/zod-core.d.cts +0 -1
  466. package/dist/zod-core.d.mts +0 -1
  467. package/dist/zod-core.mjs +0 -3
  468. package/dist/zod.cjs +0 -11
  469. package/dist/zod.d.cts +0 -2
  470. package/dist/zod.d.mts +0 -2
  471. package/dist/zod.mjs +0 -3
  472. package/src/build/rspack/dev-server-middleware.ts +0 -324
  473. package/src/build/shared-deps.ts +0 -102
  474. package/src/effect.ts +0 -1
  475. package/src/orpc-openapi.ts +0 -2
  476. package/src/orpc.ts +0 -9
  477. package/src/testing/index.ts +0 -87
  478. package/src/testing/mocks/module-federation.service.ts +0 -41
  479. package/src/zod-core.ts +0 -1
  480. package/src/zod.ts +0 -3
@@ -0,0 +1,319 @@
1
+ import { CORE_UI_PLUGIN_KEY } from "./contract.mjs";
2
+ import { MOUNT_REGISTRY, resolveMountSegment } from "./mount-registry.mjs";
3
+ import { digestOf } from "./descriptor.mjs";
4
+ import { compareNavItems } from "./nav.mjs";
5
+ import { ROUTE_OPTION_KEYS } from "./route-config.mjs";
6
+ import { Outlet, createRootRoute, createRoute, redirect } from "@tanstack/react-router";
7
+
8
+ //#region src/ui/manifest/construct.ts
9
+ /**
10
+ * Host-side route-graph construction (ADR 0008 §1): manifests + route
11
+ * configs in → host-built tree out. The host constructs ITS OWN Route
12
+ * objects from validated manifest data via public `createRoute` APIs; no
13
+ * foreign route object is ever mutated. Gates are attached HOST-side from
14
+ * the mount registry — plugins cannot ship a route that escapes its
15
+ * mount's gate because plugins never construct route objects.
16
+ *
17
+ * Mounts are the ONLY cross-source parenting points: a root-level
18
+ * pathless layout file (`_public.tsx`) declares the mount for the whole
19
+ * composition (exactly one declaring source per mount); every other
20
+ * source's routes live under the same `_mount/` directory prefix and
21
+ * parent onto the shared mount route. This module executes inside the
22
+ * core ui's module graph (production MF expose `./compose`, dev source
23
+ * import) so constructed routes are minted by the same react/router
24
+ * instance that renders them.
25
+ */
26
+ /**
27
+ * TanStack's Route generics are intentionally invariant — routes built from
28
+ * manifest data can't satisfy them structurally. One named boundary for
29
+ * handing a constructed route to the tree-building APIs.
30
+ */
31
+ function toAnyRoute(route) {
32
+ return route;
33
+ }
34
+ /**
35
+ * Gate redirects are absolute: gates attach to root-level mount routes, and
36
+ * relatives would silently shift if a mount ever moved deeper in the tree.
37
+ * The login surface is plugin-owned, never core-known.
38
+ */
39
+ const LOGIN_TO = "/login";
40
+ const HOME_TO = "/";
41
+ /**
42
+ * Gate implementations by mount gate kind. Only `session` and `admin` are
43
+ * implemented (ADR 0008 §3); unimplemented mounts are rejected during mount
44
+ * declaration before any gate lookup, and gates are optional by type — a
45
+ * mount without an entry (or `none`) renders ungated.
46
+ */
47
+ const GATES = {
48
+ session: ({ context, location }) => {
49
+ if (!userOf(context)) throw redirect({
50
+ to: LOGIN_TO,
51
+ search: { redirect: location.pathname + location.searchStr }
52
+ });
53
+ },
54
+ admin: ({ context }) => {
55
+ const user = userOf(context);
56
+ if (!user) throw redirect({ to: LOGIN_TO });
57
+ if (user.role !== "admin") throw redirect({ to: HOME_TO });
58
+ }
59
+ };
60
+ const userOf = (context) => context?.user ?? context?.session?.user;
61
+ function joinPath(a, b) {
62
+ const left = a && a !== "/" ? a.replace(/\/+$/, "") : "";
63
+ const right = b && b !== "/" ? b.replace(/^\/+/, "") : "";
64
+ if (!left) return right ? `/${right}` : "/";
65
+ if (!right) return left;
66
+ return `${left}/${right}`;
67
+ }
68
+ const navOf = (options) => {
69
+ const nav = options.staticData?.nav;
70
+ if (nav && typeof nav === "object" && typeof nav.label === "string") return nav;
71
+ };
72
+ /** Layout routes (mount or pathless) pass their authored options through,
73
+ * like every other route kind. On mount routes the registry gate composes
74
+ * BEFORE the declaration's own beforeLoad so a source can never escape its
75
+ * mount's gate (ADR 0008 §3), while the declaration's return value still
76
+ * flows to children as route context. */
77
+ function layoutBeforeLoad(gate, declared) {
78
+ if (!gate) return declared;
79
+ return (args) => {
80
+ gate(args);
81
+ return declared?.(args);
82
+ };
83
+ }
84
+ const AUTHORED_OPTION_KEYS = ROUTE_OPTION_KEYS.filter((key) => key !== "beforeLoad" && key !== "component");
85
+ function authoredOptions(options) {
86
+ const authored = {};
87
+ for (const key of AUTHORED_OPTION_KEYS) if (options[key] !== void 0) authored[key] = options[key];
88
+ return authored;
89
+ }
90
+ function rootAuthoredOptions(options) {
91
+ const { params: _params, ...authored } = authoredOptions(options);
92
+ return authored;
93
+ }
94
+ async function constructTree(input) {
95
+ const refs = [...input.plugins].sort((a, b) => a.key.localeCompare(b.key));
96
+ const resolved = [];
97
+ for (const ref of refs) resolved.push(await input.resolve(ref));
98
+ const ordered = [...resolved.filter((plugin) => plugin.key === "ui"), ...resolved.filter((plugin) => plugin.key !== "ui")];
99
+ const optionsByPlugin = /* @__PURE__ */ new Map();
100
+ const skippedByPlugin = /* @__PURE__ */ new Map();
101
+ for (const plugin of resolved) {
102
+ if (!plugin.manifest?.routes) continue;
103
+ const optionsById = /* @__PURE__ */ new Map();
104
+ const skipped = /* @__PURE__ */ new Set();
105
+ await Promise.all(plugin.manifest.routes.map(async (record) => {
106
+ const loader = plugin.routeConfig.routeConfigLoaders[record.id];
107
+ if (!loader) {
108
+ console.log(`[Compose] skipping route "${record.id}" in "${plugin.key}" — no routeConfig loader`);
109
+ skipped.add(record.id);
110
+ return;
111
+ }
112
+ optionsById.set(record.id, await loader());
113
+ }));
114
+ let changed = true;
115
+ while (changed) {
116
+ changed = false;
117
+ for (const record of plugin.manifest.routes) {
118
+ if (skipped.has(record.id)) continue;
119
+ if (record.parentId && skipped.has(record.parentId)) {
120
+ skipped.add(record.id);
121
+ changed = true;
122
+ }
123
+ }
124
+ }
125
+ optionsByPlugin.set(plugin.key, optionsById);
126
+ skippedByPlugin.set(plugin.key, skipped);
127
+ }
128
+ const declarations = /* @__PURE__ */ new Map();
129
+ const mountByLayoutId = /* @__PURE__ */ new Map();
130
+ for (const plugin of ordered) {
131
+ if (!plugin.manifest?.routes) continue;
132
+ for (const record of plugin.manifest.routes) {
133
+ if (!record.mount) continue;
134
+ const mountId = record.mount;
135
+ if (!MOUNT_REGISTRY[mountId].implemented) throw new Error(`mount "${record.mount}" is declared vocabulary but unimplemented (ADR 0008 §3) — declared by "${plugin.key}"`);
136
+ const existing = declarations.get(mountId);
137
+ if (existing) {
138
+ if (existing.key === "ui" && plugin.key !== "ui") {
139
+ console.log(`[Compose] mount declaration "${existing.key}:${existing.record.id}" (${mountId}) shadows "${plugin.key}:${record.id}" — core ui wins; shadowed declaration skipped`);
140
+ mountByLayoutId.set(record.id, mountId);
141
+ continue;
142
+ }
143
+ throw new Error(`mount "${mountId}" declared by multiple sources: "${existing.key}" (${existing.record.file}) and "${plugin.key}" (${record.file})`);
144
+ }
145
+ if (skippedByPlugin.get(plugin.key).has(record.id)) continue;
146
+ declarations.set(mountId, {
147
+ key: plugin.key,
148
+ record,
149
+ options: optionsByPlugin.get(plugin.key).get(record.id)
150
+ });
151
+ mountByLayoutId.set(record.id, mountId);
152
+ }
153
+ }
154
+ const rootRoute = toAnyRoute(createRootRoute({
155
+ ...input.rootOptions ? rootAuthoredOptions(input.rootOptions) : {},
156
+ component: input.rootOptions?.component ?? Outlet,
157
+ ...input.rootOptions?.beforeLoad ? { beforeLoad: input.rootOptions.beforeLoad } : {}
158
+ }));
159
+ const mountRoutes = /* @__PURE__ */ new Map();
160
+ for (const mountId of Object.keys(MOUNT_REGISTRY)) {
161
+ const declaration = declarations.get(mountId);
162
+ if (!declaration) continue;
163
+ const def = MOUNT_REGISTRY[mountId];
164
+ const gate = GATES[def.gate];
165
+ const options = declaration.options;
166
+ const route = createRoute({
167
+ id: `__mount_${mountId}`,
168
+ getParentRoute: () => rootRoute,
169
+ ...gate || options.beforeLoad ? { beforeLoad: layoutBeforeLoad(gate, options.beforeLoad) } : {},
170
+ ...authoredOptions(options),
171
+ component: options.component ?? Outlet
172
+ });
173
+ mountRoutes.set(mountId, toAnyRoute(route));
174
+ }
175
+ const nav = [];
176
+ const mountCounts = {};
177
+ const childrenByParent = /* @__PURE__ */ new Map();
178
+ /** cross-plugin path-collision guard: claimed paths per parent route */
179
+ const claimedPathsByParent = /* @__PURE__ */ new Map();
180
+ const attach = (parent, child) => {
181
+ const list = childrenByParent.get(parent) ?? [];
182
+ list.push(child);
183
+ childrenByParent.set(parent, list);
184
+ };
185
+ for (const plugin of ordered) {
186
+ if (!plugin.manifest?.routes) continue;
187
+ const optionsById = optionsByPlugin.get(plugin.key);
188
+ const fullPathById = /* @__PURE__ */ new Map();
189
+ const mountById = /* @__PURE__ */ new Map();
190
+ const byId = /* @__PURE__ */ new Map();
191
+ const parentFor = (record) => {
192
+ if (record.parentId) {
193
+ const local = byId.get(record.parentId);
194
+ if (local) return {
195
+ route: local.route,
196
+ fullPath: fullPathById.get(record.parentId),
197
+ mount: mountById.get(record.parentId)
198
+ };
199
+ const mount = mountByLayoutId.get(record.parentId);
200
+ if (mount) return {
201
+ route: mountRoutes.get(mount),
202
+ fullPath: "",
203
+ mount
204
+ };
205
+ throw new Error(`unresolvable parent "${record.parentId}" for "${record.id}" in "${plugin.key}" — mounts are the only cross-source parenting points`);
206
+ }
207
+ const firstSegment = record.id.split("/")[0] ?? "";
208
+ if (firstSegment.startsWith("_")) {
209
+ const mount = resolveMountSegment(firstSegment.slice(1));
210
+ if (mount && mountRoutes.has(mount)) return {
211
+ route: mountRoutes.get(mount),
212
+ fullPath: "",
213
+ mount
214
+ };
215
+ if (mount) throw new Error(`mount "${mount}" is not declared by any source (route "${record.id}" in "${plugin.key}")`);
216
+ throw new Error(`unknown mount "_${firstSegment.slice(1)}" (route "${record.id}" in "${plugin.key}")`);
217
+ }
218
+ throw new Error(`route "${record.id}" in "${plugin.key}" must live under a mount`);
219
+ };
220
+ const pending = plugin.manifest.routes.filter((record) => !record.mount && !skippedByPlugin.get(plugin.key).has(record.id));
221
+ const shadowedIds = /* @__PURE__ */ new Set();
222
+ let progressed = true;
223
+ while (pending.length > 0 && progressed) {
224
+ progressed = false;
225
+ for (let i = 0; i < pending.length; i += 1) {
226
+ const record = pending[i];
227
+ const parentId = record.parentId;
228
+ if (parentId) {
229
+ if (shadowedIds.has(parentId)) {
230
+ shadowedIds.add(record.id);
231
+ pending.splice(i, 1);
232
+ i -= 1;
233
+ progressed = true;
234
+ continue;
235
+ }
236
+ if (!byId.has(parentId) && !mountByLayoutId.has(parentId)) continue;
237
+ }
238
+ pending.splice(i, 1);
239
+ progressed = true;
240
+ const options = optionsById.get(record.id);
241
+ const parent = parentFor(record);
242
+ const routePath = record.path;
243
+ const isLayoutRoute = record.type === "layout" || routePath === void 0;
244
+ if (!isLayoutRoute) {
245
+ const siblings = claimedPathsByParent.get(parent.route) ?? /* @__PURE__ */ new Map();
246
+ const claimant = siblings.get(routePath);
247
+ if (claimant) {
248
+ if (plugin.key !== "ui" && claimant.startsWith(`${"ui"}:`)) {
249
+ console.log(`[Compose] route claim "${claimant}" (${routePath}) shadows "${plugin.key}:${record.id}" — core ui wins; shadowed route skipped`);
250
+ shadowedIds.add(record.id);
251
+ break;
252
+ }
253
+ throw new Error(`path collision: "${plugin.key}" route "${record.id}" declares "${routePath}" which is already claimed by "${claimant}" under the same parent`);
254
+ }
255
+ siblings.set(routePath, `${plugin.key}:${record.id}`);
256
+ claimedPathsByParent.set(parent.route, siblings);
257
+ }
258
+ const fullPath = joinPath(parent.fullPath, routePath);
259
+ let route;
260
+ if (isLayoutRoute) route = createRoute({
261
+ id: `${plugin.key}__${record.id}`,
262
+ getParentRoute: () => parent.route,
263
+ ...authoredOptions(options),
264
+ ...options.beforeLoad ? { beforeLoad: options.beforeLoad } : {},
265
+ component: options.component ?? Outlet
266
+ });
267
+ else route = createRoute({
268
+ path: routePath,
269
+ getParentRoute: () => parent.route,
270
+ ...authoredOptions(options),
271
+ ...options.beforeLoad ? { beforeLoad: options.beforeLoad } : {},
272
+ component: options.component ?? Outlet
273
+ });
274
+ byId.set(record.id, {
275
+ record,
276
+ route: toAnyRoute(route)
277
+ });
278
+ fullPathById.set(record.id, fullPath);
279
+ mountById.set(record.id, parent.mount);
280
+ attach(parent.route, toAnyRoute(route));
281
+ mountCounts[parent.mount] = (mountCounts[parent.mount] ?? 0) + 1;
282
+ const navDeclaration = navOf(options);
283
+ if (navDeclaration && navDeclaration.hidden !== true) nav.push({
284
+ id: `${plugin.key}:${record.id}`,
285
+ label: navDeclaration.label,
286
+ ...typeof navDeclaration.icon === "string" ? { icon: navDeclaration.icon } : {},
287
+ ...typeof navDeclaration.group === "string" ? { group: navDeclaration.group } : {},
288
+ ...typeof navDeclaration.order === "number" ? { order: navDeclaration.order } : {},
289
+ to: navDeclaration.to ?? fullPath,
290
+ plugin: plugin.key,
291
+ mount: parent.mount
292
+ });
293
+ break;
294
+ }
295
+ }
296
+ if (pending.length > 0) throw new Error(`unresolvable parentage in "${plugin.key}": ${pending.map((record) => record.id).join(", ")}`);
297
+ }
298
+ for (const [parent, children] of childrenByParent) parent.addChildren(children);
299
+ rootRoute.addChildren([...mountRoutes.values()]);
300
+ nav.sort(compareNavItems);
301
+ return {
302
+ rootRoute,
303
+ routeTree: rootRoute,
304
+ digest: await digestOf({
305
+ plugins: refs.map((ref) => ({
306
+ key: ref.key,
307
+ mfName: ref.mfName
308
+ })),
309
+ manifests: resolved.map((plugin) => plugin.manifest)
310
+ }),
311
+ manifests: resolved.map((plugin) => plugin.manifest),
312
+ nav: { items: nav },
313
+ mountCounts
314
+ };
315
+ }
316
+
317
+ //#endregion
318
+ export { constructTree };
319
+ //# sourceMappingURL=construct.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"construct.mjs","names":[],"sources":["../../../src/ui/manifest/construct.ts"],"sourcesContent":["import type { AnyRoute } from \"@tanstack/react-router\";\nimport { createRootRoute, createRoute, Outlet, redirect } from \"@tanstack/react-router\";\nimport { CORE_UI_PLUGIN_KEY } from \"./contract\";\nimport { digestOf } from \"./descriptor\";\nimport type { PluginManifest, RouteRecord } from \"./manifest-schema\";\nimport { MOUNT_REGISTRY, type MountDef, type MountId, resolveMountSegment } from \"./mount-registry\";\nimport { compareNavItems, type NavDeclaration, type NavItem, type NavManifest } from \"./nav\";\nimport { ROUTE_OPTION_KEYS, type RouteConfigModule, type RouteOptionsBundle } from \"./route-config\";\n\n/**\n * Host-side route-graph construction (ADR 0008 §1): manifests + route\n * configs in → host-built tree out. The host constructs ITS OWN Route\n * objects from validated manifest data via public `createRoute` APIs; no\n * foreign route object is ever mutated. Gates are attached HOST-side from\n * the mount registry — plugins cannot ship a route that escapes its\n * mount's gate because plugins never construct route objects.\n *\n * Mounts are the ONLY cross-source parenting points: a root-level\n * pathless layout file (`_public.tsx`) declares the mount for the whole\n * composition (exactly one declaring source per mount); every other\n * source's routes live under the same `_mount/` directory prefix and\n * parent onto the shared mount route. This module executes inside the\n * core ui's module graph (production MF expose `./compose`, dev source\n * import) so constructed routes are minted by the same react/router\n * instance that renders them.\n */\n\n/**\n * TanStack's Route generics are intentionally invariant — routes built from\n * manifest data can't satisfy them structurally. One named boundary for\n * handing a constructed route to the tree-building APIs.\n */\nfunction toAnyRoute(route: unknown): AnyRoute {\n return route as AnyRoute;\n}\n\nexport interface GateUser {\n id: string;\n name?: string;\n /** Better Auth user role — \"admin\" gates the admin mount. */\n role?: string;\n}\n\nexport interface HostContext {\n user?: GateUser;\n session?: { user?: GateUser };\n}\n\ntype GateFn = (args: {\n context: HostContext;\n location: { pathname: string; searchStr: string };\n}) => void;\n\n/**\n * Gate redirects are absolute: gates attach to root-level mount routes, and\n * relatives would silently shift if a mount ever moved deeper in the tree.\n * The login surface is plugin-owned, never core-known.\n */\nconst LOGIN_TO: string = \"/login\";\nconst HOME_TO: string = \"/\";\n\n/**\n * Gate implementations by mount gate kind. Only `session` and `admin` are\n * implemented (ADR 0008 §3); unimplemented mounts are rejected during mount\n * declaration before any gate lookup, and gates are optional by type — a\n * mount without an entry (or `none`) renders ungated.\n */\nconst GATES: Partial<Record<MountDef[\"gate\"], GateFn>> = {\n session: ({ context, location }) => {\n const user = userOf(context);\n if (!user) {\n throw redirect({\n to: LOGIN_TO,\n search: { redirect: location.pathname + location.searchStr } as never,\n });\n }\n },\n admin: ({ context }) => {\n const user = userOf(context);\n if (!user) throw redirect({ to: LOGIN_TO });\n if (user.role !== \"admin\") throw redirect({ to: HOME_TO });\n },\n};\n\nconst userOf = (context: HostContext | undefined): GateUser | undefined =>\n context?.user ?? context?.session?.user;\n\nexport interface ConstructPluginRef {\n /** composition identity — plugin key; participates in the digest */\n key: string;\n /** deployment identity — the MF container name loadRemote targets */\n mfName: string;\n}\n\nexport interface ResolvedPlugin {\n key: string;\n manifest: PluginManifest;\n routeConfig: RouteConfigModule;\n}\n\nexport interface ConstructInput {\n name: string;\n plugins: ReadonlyArray<ConstructPluginRef>;\n resolve: (ref: ConstructPluginRef) => Promise<ResolvedPlugin>;\n /** core ui `__root` options — component/error/notFound + head baseline */\n rootOptions?: RouteOptionsBundle;\n}\n\nexport interface ConstructedTree {\n rootRoute: AnyRoute;\n routeTree: AnyRoute;\n digest: string;\n manifests: PluginManifest[];\n nav: NavManifest;\n /** constructed route count per mount id */\n mountCounts: Record<string, number>;\n}\n\ninterface MountDeclaration {\n key: string;\n record: RouteRecord;\n options: RouteOptionsBundle;\n}\n\nfunction joinPath(a: string | undefined, b: string | undefined): string {\n const left = a && a !== \"/\" ? a.replace(/\\/+$/, \"\") : \"\";\n const right = b && b !== \"/\" ? b.replace(/^\\/+/, \"\") : \"\";\n if (!left) return right ? `/${right}` : \"/\";\n if (!right) return left;\n return `${left}/${right}`;\n}\n\nconst navOf = (options: RouteOptionsBundle): NavDeclaration | undefined => {\n const nav = options.staticData?.nav;\n if (nav && typeof nav === \"object\" && typeof (nav as NavDeclaration).label === \"string\") {\n return nav as NavDeclaration;\n }\n return undefined;\n};\n\n/** Layout routes (mount or pathless) pass their authored options through,\n * like every other route kind. On mount routes the registry gate composes\n * BEFORE the declaration's own beforeLoad so a source can never escape its\n * mount's gate (ADR 0008 §3), while the declaration's return value still\n * flows to children as route context. */\nfunction layoutBeforeLoad(\n gate: GateFn | undefined,\n declared: RouteOptionsBundle[\"beforeLoad\"],\n): RouteOptionsBundle[\"beforeLoad\"] {\n if (!gate) return declared;\n return (args) => {\n gate(args);\n return declared?.(args);\n };\n}\n\nconst AUTHORED_OPTION_KEYS = ROUTE_OPTION_KEYS.filter(\n (key) => key !== \"beforeLoad\" && key !== \"component\",\n);\n\nfunction authoredOptions(options: RouteOptionsBundle): Partial<RouteOptionsBundle> {\n const authored: Partial<Record<keyof RouteOptionsBundle, unknown>> = {};\n for (const key of AUTHORED_OPTION_KEYS) {\n if (options[key] !== undefined) authored[key] = options[key];\n }\n return authored as Partial<RouteOptionsBundle>;\n}\n\nfunction rootAuthoredOptions(options: RouteOptionsBundle): Partial<RouteOptionsBundle> {\n const { params: _params, ...authored } = authoredOptions(options);\n return authored;\n}\n\nexport async function constructTree(input: ConstructInput): Promise<ConstructedTree> {\n const refs = [...input.plugins].sort((a, b) => a.key.localeCompare(b.key));\n const resolved: ResolvedPlugin[] = [];\n for (const ref of refs) {\n resolved.push(await input.resolve(ref));\n }\n\n const ordered = [\n ...resolved.filter((plugin) => plugin.key === CORE_UI_PLUGIN_KEY),\n ...resolved.filter((plugin) => plugin.key !== CORE_UI_PLUGIN_KEY),\n ];\n\n const optionsByPlugin = new Map<string, Map<string, RouteOptionsBundle>>();\n const skippedByPlugin = new Map<string, Set<string>>();\n for (const plugin of resolved) {\n // A plugin with no manifest at all contributes no routes — skip it rather\n // than crashing SSR composition (same contract as the missing-loader skip\n // below).\n if (!plugin.manifest?.routes) continue;\n const optionsById = new Map<string, RouteOptionsBundle>();\n const skipped = new Set<string>();\n await Promise.all(\n plugin.manifest.routes.map(async (record) => {\n const loader = plugin.routeConfig.routeConfigLoaders[record.id];\n if (!loader) {\n console.log(\n `[Compose] skipping route \"${record.id}\" in \"${plugin.key}\" — no routeConfig loader`,\n );\n skipped.add(record.id);\n return;\n }\n optionsById.set(record.id, await loader());\n }),\n );\n // cascade: any route whose parent is skipped is also skipped\n let changed = true;\n while (changed) {\n changed = false;\n for (const record of plugin.manifest.routes) {\n if (skipped.has(record.id)) continue;\n if (record.parentId && skipped.has(record.parentId)) {\n skipped.add(record.id);\n changed = true;\n }\n }\n }\n optionsByPlugin.set(plugin.key, optionsById);\n skippedByPlugin.set(plugin.key, skipped);\n }\n\n const declarations = new Map<MountId, MountDeclaration>();\n const mountByLayoutId = new Map<string, MountId>();\n for (const plugin of ordered) {\n if (!plugin.manifest?.routes) continue;\n for (const record of plugin.manifest.routes) {\n if (!record.mount) continue;\n const mountId = record.mount as MountId;\n const def = MOUNT_REGISTRY[mountId];\n if (!def.implemented) {\n throw new Error(\n `mount \"${record.mount}\" is declared vocabulary but unimplemented (ADR 0008 §3) — declared by \"${plugin.key}\"`,\n );\n }\n const existing = declarations.get(mountId);\n if (existing) {\n if (existing.key === CORE_UI_PLUGIN_KEY && plugin.key !== CORE_UI_PLUGIN_KEY) {\n console.log(\n `[Compose] mount declaration \"${existing.key}:${existing.record.id}\" (${mountId}) shadows \"${plugin.key}:${record.id}\" — core ui wins; shadowed declaration skipped`,\n );\n mountByLayoutId.set(record.id, mountId);\n continue;\n }\n throw new Error(\n `mount \"${mountId}\" declared by multiple sources: \"${existing.key}\" (${existing.record.file}) and \"${plugin.key}\" (${record.file})`,\n );\n }\n if (skippedByPlugin.get(plugin.key)!.has(record.id)) continue;\n declarations.set(mountId, {\n key: plugin.key,\n record,\n options: optionsByPlugin.get(plugin.key)!.get(record.id)!,\n });\n mountByLayoutId.set(record.id, mountId);\n }\n }\n\n const rootRoute = toAnyRoute(\n createRootRoute({\n ...(input.rootOptions ? rootAuthoredOptions(input.rootOptions) : {}),\n component: input.rootOptions?.component ?? Outlet,\n ...(input.rootOptions?.beforeLoad ? { beforeLoad: input.rootOptions.beforeLoad } : {}),\n }),\n );\n\n const mountRoutes = new Map<MountId, AnyRoute>();\n for (const mountId of Object.keys(MOUNT_REGISTRY) as MountId[]) {\n const declaration = declarations.get(mountId);\n if (!declaration) continue;\n const def = MOUNT_REGISTRY[mountId]!;\n const gate = GATES[def.gate];\n const options = declaration.options;\n const route = createRoute({\n id: `__mount_${mountId}`,\n getParentRoute: () => rootRoute,\n ...(gate || options.beforeLoad\n ? { beforeLoad: layoutBeforeLoad(gate, options.beforeLoad) }\n : {}),\n ...authoredOptions(options),\n component: options.component ?? Outlet,\n });\n mountRoutes.set(mountId, toAnyRoute(route));\n }\n\n const nav: NavItem[] = [];\n const mountCounts: Record<string, number> = {};\n const childrenByParent = new Map<AnyRoute, AnyRoute[]>();\n /** cross-plugin path-collision guard: claimed paths per parent route */\n const claimedPathsByParent = new Map<AnyRoute, Map<string, string>>();\n const attach = (parent: AnyRoute, child: AnyRoute) => {\n const list = childrenByParent.get(parent) ?? [];\n list.push(child);\n childrenByParent.set(parent, list);\n };\n\n for (const plugin of ordered) {\n if (!plugin.manifest?.routes) continue;\n const optionsById = optionsByPlugin.get(plugin.key)!;\n const fullPathById = new Map<string, string>();\n const mountById = new Map<string, MountId>();\n const byId = new Map<string, { record: RouteRecord; route: AnyRoute }>();\n\n const parentFor = (\n record: RouteRecord,\n ): { route: AnyRoute; fullPath: string; mount: MountId } => {\n if (record.parentId) {\n const local = byId.get(record.parentId);\n if (local) {\n return {\n route: local.route,\n fullPath: fullPathById.get(record.parentId)!,\n mount: mountById.get(record.parentId)!,\n };\n }\n const mount = mountByLayoutId.get(record.parentId);\n if (mount) return { route: mountRoutes.get(mount)!, fullPath: \"\", mount };\n throw new Error(\n `unresolvable parent \"${record.parentId}\" for \"${record.id}\" in \"${plugin.key}\" — mounts are the only cross-source parenting points`,\n );\n }\n const firstSegment = record.id.split(\"/\")[0] ?? \"\";\n if (firstSegment.startsWith(\"_\")) {\n const mount = resolveMountSegment(firstSegment.slice(1));\n if (mount && mountRoutes.has(mount))\n return { route: mountRoutes.get(mount)!, fullPath: \"\", mount };\n if (mount) {\n throw new Error(\n `mount \"${mount}\" is not declared by any source (route \"${record.id}\" in \"${plugin.key}\")`,\n );\n }\n throw new Error(\n `unknown mount \"_${firstSegment.slice(1)}\" (route \"${record.id}\" in \"${plugin.key}\")`,\n );\n }\n throw new Error(`route \"${record.id}\" in \"${plugin.key}\" must live under a mount`);\n };\n\n const pending = plugin.manifest.routes.filter(\n (record) => !record.mount && !skippedByPlugin.get(plugin.key)!.has(record.id),\n );\n const shadowedIds = new Set<string>();\n let progressed = true;\n while (pending.length > 0 && progressed) {\n progressed = false;\n for (let i = 0; i < pending.length; i += 1) {\n const record = pending[i]!;\n const parentId = record.parentId;\n if (parentId) {\n if (shadowedIds.has(parentId)) {\n shadowedIds.add(record.id);\n pending.splice(i, 1);\n i -= 1;\n progressed = true;\n continue;\n }\n if (!byId.has(parentId) && !mountByLayoutId.has(parentId)) continue;\n }\n pending.splice(i, 1);\n progressed = true;\n\n const options = optionsById.get(record.id)!;\n const parent = parentFor(record);\n const routePath = record.path;\n const isLayoutRoute = record.type === \"layout\" || routePath === undefined;\n if (!isLayoutRoute) {\n const siblings = claimedPathsByParent.get(parent.route) ?? new Map<string, string>();\n const claimant = siblings.get(routePath);\n if (claimant) {\n if (\n plugin.key !== CORE_UI_PLUGIN_KEY &&\n claimant.startsWith(`${CORE_UI_PLUGIN_KEY}:`)\n ) {\n console.log(\n `[Compose] route claim \"${claimant}\" (${routePath}) shadows \"${plugin.key}:${record.id}\" — core ui wins; shadowed route skipped`,\n );\n shadowedIds.add(record.id);\n break;\n }\n throw new Error(\n `path collision: \"${plugin.key}\" route \"${record.id}\" declares \"${routePath}\" which is already claimed by \"${claimant}\" under the same parent`,\n );\n }\n siblings.set(routePath, `${plugin.key}:${record.id}`);\n claimedPathsByParent.set(parent.route, siblings);\n }\n const fullPath = joinPath(parent.fullPath, routePath);\n let route: AnyRoute;\n if (isLayoutRoute) {\n route = createRoute({\n id: `${plugin.key}__${record.id}`,\n getParentRoute: () => parent.route,\n ...authoredOptions(options),\n ...(options.beforeLoad ? { beforeLoad: options.beforeLoad } : {}),\n component: options.component ?? Outlet,\n });\n } else {\n route = createRoute({\n path: routePath,\n getParentRoute: () => parent.route,\n ...authoredOptions(options),\n ...(options.beforeLoad ? { beforeLoad: options.beforeLoad } : {}),\n component: options.component ?? Outlet,\n });\n }\n\n byId.set(record.id, { record, route: toAnyRoute(route) });\n fullPathById.set(record.id, fullPath);\n mountById.set(record.id, parent.mount);\n attach(parent.route, toAnyRoute(route));\n mountCounts[parent.mount] = (mountCounts[parent.mount] ?? 0) + 1;\n\n const navDeclaration = navOf(options);\n if (navDeclaration && navDeclaration.hidden !== true) {\n nav.push({\n id: `${plugin.key}:${record.id}`,\n label: navDeclaration.label,\n ...(typeof navDeclaration.icon === \"string\" ? { icon: navDeclaration.icon } : {}),\n ...(typeof navDeclaration.group === \"string\" ? { group: navDeclaration.group } : {}),\n ...(typeof navDeclaration.order === \"number\" ? { order: navDeclaration.order } : {}),\n to: navDeclaration.to ?? fullPath,\n plugin: plugin.key,\n mount: parent.mount,\n });\n }\n break;\n }\n }\n if (pending.length > 0) {\n throw new Error(\n `unresolvable parentage in \"${plugin.key}\": ${pending.map((record) => record.id).join(\", \")}`,\n );\n }\n }\n\n for (const [parent, children] of childrenByParent) {\n (parent as { addChildren: (children: AnyRoute[]) => void }).addChildren(children);\n }\n rootRoute.addChildren([...mountRoutes.values()] as AnyRoute[]);\n nav.sort(compareNavItems);\n\n const digest = await digestOf({\n plugins: refs.map((ref) => ({ key: ref.key, mfName: ref.mfName })),\n manifests: resolved.map((plugin) => plugin.manifest),\n });\n\n return {\n rootRoute,\n routeTree: rootRoute,\n digest,\n manifests: resolved.map((plugin) => plugin.manifest),\n nav: { items: nav },\n mountCounts,\n };\n}\n"],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+ const require_identity = require('../../identity.cjs');
3
+
4
+ //#region src/ui/manifest/contract.ts
5
+ /**
6
+ * Cross-workspace composition contract: file names, MF expose names, and the
7
+ * core's identity — the literals every consumer of the composed tree must
8
+ * agree on. Browser-safe, node-safe, zero imports.
9
+ */
10
+ /** The core ui's composition key — `bos.config.json`'s `app.ui` identity. */
11
+ const CORE_UI_PLUGIN_KEY = "ui";
12
+ const UI_REMOTE_ENTRY_FILENAME = "remoteEntry.js";
13
+ const UI_REMOTE_SERVER_ENTRY_FILENAME = "remoteEntry.server.js";
14
+ const MANIFEST_FILENAME = "manifest.gen.json";
15
+ const ROUTE_CONFIG_FILENAME = "routeConfig.gen.ts";
16
+ /** Canonical MF exposes every manifest-composed ui source ships. */
17
+ const UI_EXPOSES = {
18
+ routeConfig: "./routeConfig",
19
+ compose: "./compose",
20
+ router: "./Router"
21
+ };
22
+ /** Exposes a PLUGIN ui source ships (the core additionally exposes compose/Router). */
23
+ const PLUGIN_UI_SHARED_EXPOSES = { routeConfig: UI_EXPOSES.routeConfig };
24
+
25
+ //#endregion
26
+ exports.CORE_UI_PLUGIN_KEY = CORE_UI_PLUGIN_KEY;
27
+ exports.MANIFEST_FILENAME = MANIFEST_FILENAME;
28
+ exports.PLUGIN_UI_SHARED_EXPOSES = PLUGIN_UI_SHARED_EXPOSES;
29
+ exports.ROUTE_CONFIG_FILENAME = ROUTE_CONFIG_FILENAME;
30
+ exports.UI_EXPOSES = UI_EXPOSES;
31
+ exports.UI_REMOTE_ENTRY_FILENAME = UI_REMOTE_ENTRY_FILENAME;
32
+ exports.UI_REMOTE_SERVER_ENTRY_FILENAME = UI_REMOTE_SERVER_ENTRY_FILENAME;
33
+ exports.sanitizeContainerName = require_identity.containerName;
34
+ //# sourceMappingURL=contract.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.cjs","names":[],"sources":["../../../src/ui/manifest/contract.ts"],"sourcesContent":["/**\n * Cross-workspace composition contract: file names, MF expose names, and the\n * core's identity — the literals every consumer of the composed tree must\n * agree on. Browser-safe, node-safe, zero imports.\n */\n\n/** The core ui's composition key — `bos.config.json`'s `app.ui` identity. */\nexport const CORE_UI_PLUGIN_KEY = \"ui\";\n\nexport const UI_REMOTE_ENTRY_FILENAME = \"remoteEntry.js\";\nexport const UI_REMOTE_SERVER_ENTRY_FILENAME = \"remoteEntry.server.js\";\nexport const MANIFEST_FILENAME = \"manifest.gen.json\";\nexport const ROUTE_CONFIG_FILENAME = \"routeConfig.gen.ts\";\n\n/** Canonical MF exposes every manifest-composed ui source ships. */\nexport const UI_EXPOSES = {\n routeConfig: \"./routeConfig\",\n compose: \"./compose\",\n router: \"./Router\",\n} as const;\n\n/** Exposes a PLUGIN ui source ships (the core additionally exposes compose/Router). */\nexport const PLUGIN_UI_SHARED_EXPOSES = {\n routeConfig: UI_EXPOSES.routeConfig,\n} as const;\n\n/**\n * MF container naming rule shared by the build (rsbuild config) and runtime\n * config resolution — the host must register remotes under exactly the name\n * the built container declares. Delegates to the canonical identity module\n * (`every-plugin/identity`), which owns the derivation.\n */\nexport { containerName as sanitizeContainerName } from \"../../identity\";\n"],"mappings":";;;;;;;;;;AAOA,MAAa,qBAAqB;AAElC,MAAa,2BAA2B;AACxC,MAAa,kCAAkC;AAC/C,MAAa,oBAAoB;AACjC,MAAa,wBAAwB;;AAGrC,MAAa,aAAa;CACxB,aAAa;CACb,SAAS;CACT,QAAQ;AACV;;AAGA,MAAa,2BAA2B,EACtC,aAAa,WAAW,YAC1B"}
@@ -0,0 +1,26 @@
1
+ import { containerName } from "../../identity.cjs";
2
+ //#region src/ui/manifest/contract.d.ts
3
+ /**
4
+ * Cross-workspace composition contract: file names, MF expose names, and the
5
+ * core's identity — the literals every consumer of the composed tree must
6
+ * agree on. Browser-safe, node-safe, zero imports.
7
+ */
8
+ /** The core ui's composition key — `bos.config.json`'s `app.ui` identity. */
9
+ declare const CORE_UI_PLUGIN_KEY = "ui";
10
+ declare const UI_REMOTE_ENTRY_FILENAME = "remoteEntry.js";
11
+ declare const UI_REMOTE_SERVER_ENTRY_FILENAME = "remoteEntry.server.js";
12
+ declare const MANIFEST_FILENAME = "manifest.gen.json";
13
+ declare const ROUTE_CONFIG_FILENAME = "routeConfig.gen.ts";
14
+ /** Canonical MF exposes every manifest-composed ui source ships. */
15
+ declare const UI_EXPOSES: {
16
+ readonly routeConfig: "./routeConfig";
17
+ readonly compose: "./compose";
18
+ readonly router: "./Router";
19
+ };
20
+ /** Exposes a PLUGIN ui source ships (the core additionally exposes compose/Router). */
21
+ declare const PLUGIN_UI_SHARED_EXPOSES: {
22
+ readonly routeConfig: "./routeConfig";
23
+ };
24
+ //#endregion
25
+ export { CORE_UI_PLUGIN_KEY, MANIFEST_FILENAME, PLUGIN_UI_SHARED_EXPOSES, ROUTE_CONFIG_FILENAME, UI_EXPOSES, UI_REMOTE_ENTRY_FILENAME, UI_REMOTE_SERVER_ENTRY_FILENAME, containerName as sanitizeContainerName };
26
+ //# sourceMappingURL=contract.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.d.cts","names":[],"sources":["../../../src/ui/manifest/contract.ts"],"mappings":";;;;;;;;cAOa;cAEA;cACA;cACA;cACA;;cAGA;WACX;WACA;WACA;;;cAIW;WACX"}
@@ -0,0 +1,26 @@
1
+ import { containerName } from "../../identity.mjs";
2
+ //#region src/ui/manifest/contract.d.ts
3
+ /**
4
+ * Cross-workspace composition contract: file names, MF expose names, and the
5
+ * core's identity — the literals every consumer of the composed tree must
6
+ * agree on. Browser-safe, node-safe, zero imports.
7
+ */
8
+ /** The core ui's composition key — `bos.config.json`'s `app.ui` identity. */
9
+ declare const CORE_UI_PLUGIN_KEY = "ui";
10
+ declare const UI_REMOTE_ENTRY_FILENAME = "remoteEntry.js";
11
+ declare const UI_REMOTE_SERVER_ENTRY_FILENAME = "remoteEntry.server.js";
12
+ declare const MANIFEST_FILENAME = "manifest.gen.json";
13
+ declare const ROUTE_CONFIG_FILENAME = "routeConfig.gen.ts";
14
+ /** Canonical MF exposes every manifest-composed ui source ships. */
15
+ declare const UI_EXPOSES: {
16
+ readonly routeConfig: "./routeConfig";
17
+ readonly compose: "./compose";
18
+ readonly router: "./Router";
19
+ };
20
+ /** Exposes a PLUGIN ui source ships (the core additionally exposes compose/Router). */
21
+ declare const PLUGIN_UI_SHARED_EXPOSES: {
22
+ readonly routeConfig: "./routeConfig";
23
+ };
24
+ //#endregion
25
+ export { CORE_UI_PLUGIN_KEY, MANIFEST_FILENAME, PLUGIN_UI_SHARED_EXPOSES, ROUTE_CONFIG_FILENAME, UI_EXPOSES, UI_REMOTE_ENTRY_FILENAME, UI_REMOTE_SERVER_ENTRY_FILENAME, containerName as sanitizeContainerName };
26
+ //# sourceMappingURL=contract.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.d.mts","names":[],"sources":["../../../src/ui/manifest/contract.ts"],"mappings":";;;;;;;;cAOa;cAEA;cACA;cACA;cACA;;cAGA;WACX;WACA;WACA;;;cAIW;WACX"}
@@ -0,0 +1,26 @@
1
+ import { containerName } from "../../identity.mjs";
2
+
3
+ //#region src/ui/manifest/contract.ts
4
+ /**
5
+ * Cross-workspace composition contract: file names, MF expose names, and the
6
+ * core's identity — the literals every consumer of the composed tree must
7
+ * agree on. Browser-safe, node-safe, zero imports.
8
+ */
9
+ /** The core ui's composition key — `bos.config.json`'s `app.ui` identity. */
10
+ const CORE_UI_PLUGIN_KEY = "ui";
11
+ const UI_REMOTE_ENTRY_FILENAME = "remoteEntry.js";
12
+ const UI_REMOTE_SERVER_ENTRY_FILENAME = "remoteEntry.server.js";
13
+ const MANIFEST_FILENAME = "manifest.gen.json";
14
+ const ROUTE_CONFIG_FILENAME = "routeConfig.gen.ts";
15
+ /** Canonical MF exposes every manifest-composed ui source ships. */
16
+ const UI_EXPOSES = {
17
+ routeConfig: "./routeConfig",
18
+ compose: "./compose",
19
+ router: "./Router"
20
+ };
21
+ /** Exposes a PLUGIN ui source ships (the core additionally exposes compose/Router). */
22
+ const PLUGIN_UI_SHARED_EXPOSES = { routeConfig: UI_EXPOSES.routeConfig };
23
+
24
+ //#endregion
25
+ export { CORE_UI_PLUGIN_KEY, MANIFEST_FILENAME, PLUGIN_UI_SHARED_EXPOSES, ROUTE_CONFIG_FILENAME, UI_EXPOSES, UI_REMOTE_ENTRY_FILENAME, UI_REMOTE_SERVER_ENTRY_FILENAME, containerName as sanitizeContainerName };
26
+ //# sourceMappingURL=contract.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.mjs","names":[],"sources":["../../../src/ui/manifest/contract.ts"],"sourcesContent":["/**\n * Cross-workspace composition contract: file names, MF expose names, and the\n * core's identity — the literals every consumer of the composed tree must\n * agree on. Browser-safe, node-safe, zero imports.\n */\n\n/** The core ui's composition key — `bos.config.json`'s `app.ui` identity. */\nexport const CORE_UI_PLUGIN_KEY = \"ui\";\n\nexport const UI_REMOTE_ENTRY_FILENAME = \"remoteEntry.js\";\nexport const UI_REMOTE_SERVER_ENTRY_FILENAME = \"remoteEntry.server.js\";\nexport const MANIFEST_FILENAME = \"manifest.gen.json\";\nexport const ROUTE_CONFIG_FILENAME = \"routeConfig.gen.ts\";\n\n/** Canonical MF exposes every manifest-composed ui source ships. */\nexport const UI_EXPOSES = {\n routeConfig: \"./routeConfig\",\n compose: \"./compose\",\n router: \"./Router\",\n} as const;\n\n/** Exposes a PLUGIN ui source ships (the core additionally exposes compose/Router). */\nexport const PLUGIN_UI_SHARED_EXPOSES = {\n routeConfig: UI_EXPOSES.routeConfig,\n} as const;\n\n/**\n * MF container naming rule shared by the build (rsbuild config) and runtime\n * config resolution — the host must register remotes under exactly the name\n * the built container declares. Delegates to the canonical identity module\n * (`every-plugin/identity`), which owns the derivation.\n */\nexport { containerName as sanitizeContainerName } from \"../../identity\";\n"],"mappings":";;;;;;;;;AAOA,MAAa,qBAAqB;AAElC,MAAa,2BAA2B;AACxC,MAAa,kCAAkC;AAC/C,MAAa,oBAAoB;AACjC,MAAa,wBAAwB;;AAGrC,MAAa,aAAa;CACxB,aAAa;CACb,SAAS;CACT,QAAQ;AACV;;AAGA,MAAa,2BAA2B,EACtC,aAAa,WAAW,YAC1B"}
@@ -0,0 +1,64 @@
1
+ const require_mount_registry = require('./mount-registry.cjs');
2
+
3
+ //#region src/ui/manifest/descriptor.ts
4
+ function App(input) {
5
+ return input;
6
+ }
7
+ function Plugin(name) {
8
+ return {
9
+ local: (path) => ({
10
+ name,
11
+ source: {
12
+ kind: "local",
13
+ path
14
+ }
15
+ }),
16
+ remote: (mfName, url) => ({
17
+ name,
18
+ source: {
19
+ kind: "remote",
20
+ mfName,
21
+ url
22
+ }
23
+ })
24
+ };
25
+ }
26
+ /** Flatten an app against the registry of apps: `extends` inherits the base's plugins, child wins. */
27
+ function resolveApp(input, apps) {
28
+ const base = input.extends ? apps[input.extends] : void 0;
29
+ if (input.extends && !base) throw new Error(`extends target "${input.extends}" not found`);
30
+ const plugins = {};
31
+ for (const [key, ref] of Object.entries(base?.plugins ?? {})) plugins[key] = {
32
+ key,
33
+ ...ref
34
+ };
35
+ for (const [key, ref] of Object.entries(input.plugins)) plugins[key] = {
36
+ key,
37
+ ...ref
38
+ };
39
+ return {
40
+ name: input.name,
41
+ plugins
42
+ };
43
+ }
44
+ /**
45
+ * Composition digest — sha256 (WebCrypto) over everything that determines
46
+ * the tree: app name, plugin keys, MF names, manifests, and the imported
47
+ * `MOUNT_REGISTRY_VERSION`. Deployment URLs are deliberately excluded so
48
+ * disk and prod paths digest identically (hydration parity).
49
+ */
50
+ async function digestOf(input) {
51
+ const bytes = new TextEncoder().encode(JSON.stringify({
52
+ ...input,
53
+ mountRegistryVersion: 5
54
+ }));
55
+ const hash = await crypto.subtle.digest("SHA-256", bytes);
56
+ return Array.from(new Uint8Array(hash)).map((b) => b.toString(16).padStart(2, "0")).join("").slice(0, 16);
57
+ }
58
+
59
+ //#endregion
60
+ exports.App = App;
61
+ exports.Plugin = Plugin;
62
+ exports.digestOf = digestOf;
63
+ exports.resolveApp = resolveApp;
64
+ //# sourceMappingURL=descriptor.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"descriptor.cjs","names":[],"sources":["../../../src/ui/manifest/descriptor.ts"],"sourcesContent":["import { MOUNT_REGISTRY_VERSION } from \"./mount-registry\";\n\n/**\n * Shape-of-028 descriptor slice (ADR 0005 / plan 028) — composition-resolver\n * surface only. Pure data: `App({...})` returns a typed object. `extends`\n * resolves child-wins over the base app's plugins (publish-time flattening\n * model of wayfinder ticket 08). Plan 028 will declaration-merge\n * `KnownPlugins` from generated types; until then the interface is empty and\n * `Plugin(\"bogus\")` does not compile.\n */\n\nexport interface RemoteSource {\n kind: \"local\" | \"remote\";\n path?: string;\n mfName?: string;\n url?: string;\n}\n\nexport interface PluginRef {\n key: string;\n source: RemoteSource;\n}\n\nexport interface ResolvedApp {\n name: string;\n plugins: Record<string, PluginRef>;\n}\n\nexport interface PluginRefInput {\n name: string;\n source: RemoteSource;\n}\n\nexport interface AppInput {\n name: string;\n extends?: string;\n plugins: Record<string, PluginRefInput>;\n}\n\n/** Declaration-merged from generated types by plan 028 — must stay an interface (types cannot merge). */\n// biome-ignore lint/suspicious/noEmptyInterface: declaration-merge surface\nexport interface KnownPlugins {}\n\nexport function App(input: AppInput): AppInput {\n return input;\n}\n\nexport function Plugin<K extends Extract<keyof KnownPlugins, string>>(\n name: K,\n): {\n local: (path: string) => PluginRefInput;\n remote: (mfName: string, url: string) => PluginRefInput;\n} {\n return {\n local: (path) => ({ name, source: { kind: \"local\", path } }),\n remote: (mfName, url) => ({ name, source: { kind: \"remote\", mfName, url } }),\n };\n}\n\n/** Flatten an app against the registry of apps: `extends` inherits the base's plugins, child wins. */\nexport function resolveApp(input: AppInput, apps: Record<string, AppInput>): ResolvedApp {\n const base = input.extends ? apps[input.extends] : undefined;\n if (input.extends && !base) throw new Error(`extends target \"${input.extends}\" not found`);\n const plugins: Record<string, PluginRef> = {};\n for (const [key, ref] of Object.entries(base?.plugins ?? {})) {\n plugins[key] = { key, ...ref };\n }\n for (const [key, ref] of Object.entries(input.plugins)) {\n plugins[key] = { key, ...ref };\n }\n return { name: input.name, plugins };\n}\n\nexport interface CompositionDigestInput {\n /** optional app label — deliberately NOT a tree-identity input; omit for server/client parity */\n appName?: string;\n plugins: Array<{ key: string; mfName: string }>;\n manifests: Array<unknown>;\n}\n\n/**\n * Composition digest — sha256 (WebCrypto) over everything that determines\n * the tree: app name, plugin keys, MF names, manifests, and the imported\n * `MOUNT_REGISTRY_VERSION`. Deployment URLs are deliberately excluded so\n * disk and prod paths digest identically (hydration parity).\n */\nexport async function digestOf(input: CompositionDigestInput): Promise<string> {\n const bytes = new TextEncoder().encode(\n JSON.stringify({ ...input, mountRegistryVersion: MOUNT_REGISTRY_VERSION }),\n );\n const hash = await crypto.subtle.digest(\"SHA-256\", bytes);\n return Array.from(new Uint8Array(hash))\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\")\n .slice(0, 16);\n}\n"],"mappings":";;;AA2CA,SAAgB,IAAI,OAA2B;CAC7C,OAAO;AACT;AAEA,SAAgB,OACd,MAIA;CACA,OAAO;EACL,QAAQ,UAAU;GAAE;GAAM,QAAQ;IAAE,MAAM;IAAS;GAAK;EAAE;EAC1D,SAAS,QAAQ,SAAS;GAAE;GAAM,QAAQ;IAAE,MAAM;IAAU;IAAQ;GAAI;EAAE;CAC5E;AACF;;AAGA,SAAgB,WAAW,OAAiB,MAA6C;CACvF,MAAM,OAAO,MAAM,UAAU,KAAK,MAAM,WAAW;CACnD,IAAI,MAAM,WAAW,CAAC,MAAM,MAAM,IAAI,MAAM,mBAAmB,MAAM,QAAQ,YAAY;CACzF,MAAM,UAAqC,CAAC;CAC5C,KAAK,MAAM,CAAC,KAAK,QAAQ,OAAO,QAAQ,MAAM,WAAW,CAAC,CAAC,GACzD,QAAQ,OAAO;EAAE;EAAK,GAAG;CAAI;CAE/B,KAAK,MAAM,CAAC,KAAK,QAAQ,OAAO,QAAQ,MAAM,OAAO,GACnD,QAAQ,OAAO;EAAE;EAAK,GAAG;CAAI;CAE/B,OAAO;EAAE,MAAM,MAAM;EAAM;CAAQ;AACrC;;;;;;;AAeA,eAAsB,SAAS,OAAgD;CAC7E,MAAM,QAAQ,IAAI,YAAY,CAAC,CAAC,OAC9B,KAAK,UAAU;EAAE,GAAG;EAAO;CAA6C,CAAC,CAC3E;CACA,MAAM,OAAO,MAAM,OAAO,OAAO,OAAO,WAAW,KAAK;CACxD,OAAO,MAAM,KAAK,IAAI,WAAW,IAAI,CAAC,CAAC,CACpC,KAAK,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,GAAG,GAAG,CAAC,CAAC,CAC3C,KAAK,EAAE,CAAC,CACR,MAAM,GAAG,EAAE;AAChB"}
@@ -0,0 +1,60 @@
1
+ //#region src/ui/manifest/descriptor.d.ts
2
+ /**
3
+ * Shape-of-028 descriptor slice (ADR 0005 / plan 028) — composition-resolver
4
+ * surface only. Pure data: `App({...})` returns a typed object. `extends`
5
+ * resolves child-wins over the base app's plugins (publish-time flattening
6
+ * model of wayfinder ticket 08). Plan 028 will declaration-merge
7
+ * `KnownPlugins` from generated types; until then the interface is empty and
8
+ * `Plugin("bogus")` does not compile.
9
+ */
10
+ interface RemoteSource {
11
+ kind: "local" | "remote";
12
+ path?: string;
13
+ mfName?: string;
14
+ url?: string;
15
+ }
16
+ interface PluginRef {
17
+ key: string;
18
+ source: RemoteSource;
19
+ }
20
+ interface ResolvedApp {
21
+ name: string;
22
+ plugins: Record<string, PluginRef>;
23
+ }
24
+ interface PluginRefInput {
25
+ name: string;
26
+ source: RemoteSource;
27
+ }
28
+ interface AppInput {
29
+ name: string;
30
+ extends?: string;
31
+ plugins: Record<string, PluginRefInput>;
32
+ }
33
+ /** Declaration-merged from generated types by plan 028 — must stay an interface (types cannot merge). */
34
+ interface KnownPlugins {}
35
+ declare function App(input: AppInput): AppInput;
36
+ declare function Plugin<K extends Extract<keyof KnownPlugins, string>>(name: K): {
37
+ local: (path: string) => PluginRefInput;
38
+ remote: (mfName: string, url: string) => PluginRefInput;
39
+ };
40
+ /** Flatten an app against the registry of apps: `extends` inherits the base's plugins, child wins. */
41
+ declare function resolveApp(input: AppInput, apps: Record<string, AppInput>): ResolvedApp;
42
+ interface CompositionDigestInput {
43
+ /** optional app label — deliberately NOT a tree-identity input; omit for server/client parity */
44
+ appName?: string;
45
+ plugins: Array<{
46
+ key: string;
47
+ mfName: string;
48
+ }>;
49
+ manifests: Array<unknown>;
50
+ }
51
+ /**
52
+ * Composition digest — sha256 (WebCrypto) over everything that determines
53
+ * the tree: app name, plugin keys, MF names, manifests, and the imported
54
+ * `MOUNT_REGISTRY_VERSION`. Deployment URLs are deliberately excluded so
55
+ * disk and prod paths digest identically (hydration parity).
56
+ */
57
+ declare function digestOf(input: CompositionDigestInput): Promise<string>;
58
+ //#endregion
59
+ export { App, AppInput, CompositionDigestInput, KnownPlugins, Plugin, PluginRef, PluginRefInput, RemoteSource, ResolvedApp, digestOf, resolveApp };
60
+ //# sourceMappingURL=descriptor.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"descriptor.d.cts","names":[],"sources":["../../../src/ui/manifest/descriptor.ts"],"mappings":";;;;;;;;;UAWiB;EACf;EACA;EACA;EACA;;UAGe;EACf;EACA,QAAQ;;UAGO;EACf;EACA,SAAS,eAAe;;UAGT;EACf;EACA,QAAQ;;UAGO;EACf;EACA;EACA,SAAS,eAAe;;;UAKT;iBAED,IAAI,OAAO,WAAW;iBAItB,OAAO,UAAU,cAAc,uBAC7C,MAAM;EAEN,QAAQ,iBAAiB;EACzB,SAAS,gBAAgB,gBAAgB;;;iBAS3B,WAAW,OAAO,UAAU,MAAM,eAAe,YAAY;UAa5D;;EAEf;EACA,SAAS;IAAQ;IAAa;;EAC9B,WAAW;;;;;;;;iBASS,SAAS,OAAO,yBAAyB"}