every-plugin 2.10.1 → 3.0.0-rc.3

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 (462) 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 +47 -0
  25. package/dist/build/rspack/chunk-completeness-plugin.cjs.map +1 -0
  26. package/dist/build/rspack/chunk-completeness-plugin.mjs +47 -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 +118 -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 +111 -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/dev/serve.cjs +390 -0
  133. package/dist/dev/serve.cjs.map +1 -0
  134. package/dist/dev/serve.d.cts +23 -0
  135. package/dist/dev/serve.d.cts.map +1 -0
  136. package/dist/dev/serve.d.mts +23 -0
  137. package/dist/dev/serve.d.mts.map +1 -0
  138. package/dist/dev/serve.mjs +384 -0
  139. package/dist/dev/serve.mjs.map +1 -0
  140. package/dist/dev/watch-kill.cjs +39 -0
  141. package/dist/dev/watch-kill.cjs.map +1 -0
  142. package/dist/dev/watch-kill.mjs +38 -0
  143. package/dist/dev/watch-kill.mjs.map +1 -0
  144. package/dist/effect-helpers.cjs +23 -0
  145. package/dist/effect-helpers.cjs.map +1 -0
  146. package/dist/effect-helpers.d.cts +20 -0
  147. package/dist/effect-helpers.d.cts.map +1 -0
  148. package/dist/effect-helpers.d.mts +20 -0
  149. package/dist/effect-helpers.d.mts.map +1 -0
  150. package/dist/effect-helpers.mjs +22 -0
  151. package/dist/effect-helpers.mjs.map +1 -0
  152. package/dist/errors.cjs +50 -69
  153. package/dist/errors.cjs.map +1 -1
  154. package/dist/errors.d.cts +13 -96
  155. package/dist/errors.d.cts.map +1 -1
  156. package/dist/errors.d.mts +13 -96
  157. package/dist/errors.d.mts.map +1 -1
  158. package/dist/errors.mjs +16 -34
  159. package/dist/errors.mjs.map +1 -1
  160. package/dist/identity.cjs +19 -0
  161. package/dist/identity.cjs.map +1 -0
  162. package/dist/identity.d.cts +33 -0
  163. package/dist/identity.d.cts.map +1 -0
  164. package/dist/identity.d.mts +33 -0
  165. package/dist/identity.d.mts.map +1 -0
  166. package/dist/identity.mjs +16 -0
  167. package/dist/identity.mjs.map +1 -0
  168. package/dist/index.cjs +9 -5
  169. package/dist/index.d.cts +8 -6
  170. package/dist/index.d.mts +8 -6
  171. package/dist/index.mjs +6 -4
  172. package/dist/plugin.cjs +13 -26
  173. package/dist/plugin.cjs.map +1 -1
  174. package/dist/plugin.d.cts +57 -24
  175. package/dist/plugin.d.cts.map +1 -1
  176. package/dist/plugin.d.mts +58 -25
  177. package/dist/plugin.d.mts.map +1 -1
  178. package/dist/plugin.mjs +16 -29
  179. package/dist/plugin.mjs.map +1 -1
  180. package/dist/remote-entry.cjs +103 -0
  181. package/dist/remote-entry.cjs.map +1 -0
  182. package/dist/remote-entry.d.cts +53 -0
  183. package/dist/remote-entry.d.cts.map +1 -0
  184. package/dist/remote-entry.d.mts +53 -0
  185. package/dist/remote-entry.d.mts.map +1 -0
  186. package/dist/remote-entry.mjs +98 -0
  187. package/dist/remote-entry.mjs.map +1 -0
  188. package/dist/runtime/errors.cjs +159 -33
  189. package/dist/runtime/errors.cjs.map +1 -1
  190. package/dist/runtime/errors.d.cts +64 -7
  191. package/dist/runtime/errors.d.cts.map +1 -1
  192. package/dist/runtime/errors.d.mts +64 -7
  193. package/dist/runtime/errors.d.mts.map +1 -1
  194. package/dist/runtime/errors.mjs +154 -30
  195. package/dist/runtime/errors.mjs.map +1 -1
  196. package/dist/runtime/index.cjs +95 -23
  197. package/dist/runtime/index.cjs.map +1 -1
  198. package/dist/runtime/index.d.cts +16 -0
  199. package/dist/runtime/index.d.cts.map +1 -1
  200. package/dist/runtime/index.d.mts +16 -0
  201. package/dist/runtime/index.d.mts.map +1 -1
  202. package/dist/runtime/index.mjs +98 -26
  203. package/dist/runtime/index.mjs.map +1 -1
  204. package/dist/runtime/mf-config.cjs +3 -78
  205. package/dist/runtime/mf-config.cjs.map +1 -1
  206. package/dist/runtime/mf-config.d.cts +3 -49
  207. package/dist/runtime/mf-config.d.cts.map +1 -1
  208. package/dist/runtime/mf-config.d.mts +3 -49
  209. package/dist/runtime/mf-config.d.mts.map +1 -1
  210. package/dist/runtime/mf-config.mjs +5 -78
  211. package/dist/runtime/mf-config.mjs.map +1 -1
  212. package/dist/runtime/services/module-federation.service.cjs +57 -12
  213. package/dist/runtime/services/module-federation.service.cjs.map +1 -1
  214. package/dist/runtime/services/module-federation.service.d.cts +4 -13
  215. package/dist/runtime/services/module-federation.service.d.mts +4 -13
  216. package/dist/runtime/services/module-federation.service.mjs +57 -14
  217. package/dist/runtime/services/module-federation.service.mjs.map +1 -1
  218. package/dist/runtime/services/normalize.cjs +2 -22
  219. package/dist/runtime/services/normalize.d.cts +2 -21
  220. package/dist/runtime/services/normalize.d.mts +2 -21
  221. package/dist/runtime/services/normalize.mjs +2 -21
  222. package/dist/runtime/services/plugin-lifecycle.service.cjs +9 -11
  223. package/dist/runtime/services/plugin-lifecycle.service.cjs.map +1 -1
  224. package/dist/runtime/services/plugin-lifecycle.service.d.cts +3 -16
  225. package/dist/runtime/services/plugin-lifecycle.service.d.mts +3 -16
  226. package/dist/runtime/services/plugin-lifecycle.service.mjs +10 -13
  227. package/dist/runtime/services/plugin-lifecycle.service.mjs.map +1 -1
  228. package/dist/runtime/services/plugin-loader.service.cjs +56 -30
  229. package/dist/runtime/services/plugin-loader.service.cjs.map +1 -1
  230. package/dist/runtime/services/plugin-loader.service.d.cts +6 -53
  231. package/dist/runtime/services/plugin-loader.service.d.mts +6 -53
  232. package/dist/runtime/services/plugin-loader.service.mjs +55 -31
  233. package/dist/runtime/services/plugin-loader.service.mjs.map +1 -1
  234. package/dist/runtime/services/plugin.service.cjs +10 -12
  235. package/dist/runtime/services/plugin.service.cjs.map +1 -1
  236. package/dist/runtime/services/plugin.service.d.cts +14 -36
  237. package/dist/runtime/services/plugin.service.d.cts.map +1 -1
  238. package/dist/runtime/services/plugin.service.d.mts +14 -36
  239. package/dist/runtime/services/plugin.service.d.mts.map +1 -1
  240. package/dist/runtime/services/plugin.service.mjs +14 -18
  241. package/dist/runtime/services/plugin.service.mjs.map +1 -1
  242. package/dist/runtime/services/secrets.service.cjs +12 -12
  243. package/dist/runtime/services/secrets.service.cjs.map +1 -1
  244. package/dist/runtime/services/secrets.service.d.cts +3 -15
  245. package/dist/runtime/services/secrets.service.d.mts +3 -15
  246. package/dist/runtime/services/secrets.service.mjs +12 -13
  247. package/dist/runtime/services/secrets.service.mjs.map +1 -1
  248. package/dist/runtime/services/shared-identity.cjs +40 -0
  249. package/dist/runtime/services/shared-identity.cjs.map +1 -0
  250. package/dist/runtime/services/shared-identity.mjs +38 -0
  251. package/dist/runtime/services/shared-identity.mjs.map +1 -0
  252. package/dist/runtime/validation.cjs +2 -2
  253. package/dist/runtime/validation.cjs.map +1 -1
  254. package/dist/runtime/validation.mjs +2 -2
  255. package/dist/runtime/validation.mjs.map +1 -1
  256. package/dist/shared-deps-spec.cjs +384 -0
  257. package/dist/shared-deps-spec.cjs.map +1 -0
  258. package/dist/shared-deps-spec.d.cts +182 -0
  259. package/dist/shared-deps-spec.d.cts.map +1 -0
  260. package/dist/shared-deps-spec.d.mts +182 -0
  261. package/dist/shared-deps-spec.d.mts.map +1 -0
  262. package/dist/shared-deps-spec.mjs +368 -0
  263. package/dist/shared-deps-spec.mjs.map +1 -0
  264. package/dist/types.d.cts +25 -41
  265. package/dist/types.d.cts.map +1 -1
  266. package/dist/types.d.mts +25 -41
  267. package/dist/types.d.mts.map +1 -1
  268. package/dist/ui/manifest/construct.cjs +268 -0
  269. package/dist/ui/manifest/construct.cjs.map +1 -0
  270. package/dist/ui/manifest/construct.d.cts +48 -0
  271. package/dist/ui/manifest/construct.d.cts.map +1 -0
  272. package/dist/ui/manifest/construct.d.mts +48 -0
  273. package/dist/ui/manifest/construct.d.mts.map +1 -0
  274. package/dist/ui/manifest/construct.mjs +268 -0
  275. package/dist/ui/manifest/construct.mjs.map +1 -0
  276. package/dist/ui/manifest/contract.cjs +34 -0
  277. package/dist/ui/manifest/contract.cjs.map +1 -0
  278. package/dist/ui/manifest/contract.d.cts +26 -0
  279. package/dist/ui/manifest/contract.d.cts.map +1 -0
  280. package/dist/ui/manifest/contract.d.mts +26 -0
  281. package/dist/ui/manifest/contract.d.mts.map +1 -0
  282. package/dist/ui/manifest/contract.mjs +26 -0
  283. package/dist/ui/manifest/contract.mjs.map +1 -0
  284. package/dist/ui/manifest/descriptor.cjs +64 -0
  285. package/dist/ui/manifest/descriptor.cjs.map +1 -0
  286. package/dist/ui/manifest/descriptor.d.cts +60 -0
  287. package/dist/ui/manifest/descriptor.d.cts.map +1 -0
  288. package/dist/ui/manifest/descriptor.d.mts +60 -0
  289. package/dist/ui/manifest/descriptor.d.mts.map +1 -0
  290. package/dist/ui/manifest/descriptor.mjs +61 -0
  291. package/dist/ui/manifest/descriptor.mjs.map +1 -0
  292. package/dist/ui/manifest/generator.cjs +128 -0
  293. package/dist/ui/manifest/generator.cjs.map +1 -0
  294. package/dist/ui/manifest/generator.d.cts +41 -0
  295. package/dist/ui/manifest/generator.d.cts.map +1 -0
  296. package/dist/ui/manifest/generator.d.mts +41 -0
  297. package/dist/ui/manifest/generator.d.mts.map +1 -0
  298. package/dist/ui/manifest/generator.mjs +125 -0
  299. package/dist/ui/manifest/generator.mjs.map +1 -0
  300. package/dist/ui/manifest/index.cjs +35 -0
  301. package/dist/ui/manifest/index.d.cts +9 -0
  302. package/dist/ui/manifest/index.d.mts +9 -0
  303. package/dist/ui/manifest/index.mjs +9 -0
  304. package/dist/ui/manifest/manifest-schema.cjs +97 -0
  305. package/dist/ui/manifest/manifest-schema.cjs.map +1 -0
  306. package/dist/ui/manifest/manifest-schema.d.cts +132 -0
  307. package/dist/ui/manifest/manifest-schema.d.cts.map +1 -0
  308. package/dist/ui/manifest/manifest-schema.d.mts +132 -0
  309. package/dist/ui/manifest/manifest-schema.d.mts.map +1 -0
  310. package/dist/ui/manifest/manifest-schema.mjs +90 -0
  311. package/dist/ui/manifest/manifest-schema.mjs.map +1 -0
  312. package/dist/ui/manifest/mount-registry.cjs +52 -0
  313. package/dist/ui/manifest/mount-registry.cjs.map +1 -0
  314. package/dist/ui/manifest/mount-registry.d.cts +61 -0
  315. package/dist/ui/manifest/mount-registry.d.cts.map +1 -0
  316. package/dist/ui/manifest/mount-registry.d.mts +61 -0
  317. package/dist/ui/manifest/mount-registry.d.mts.map +1 -0
  318. package/dist/ui/manifest/mount-registry.mjs +48 -0
  319. package/dist/ui/manifest/mount-registry.mjs.map +1 -0
  320. package/dist/ui/manifest/nav.cjs +13 -0
  321. package/dist/ui/manifest/nav.cjs.map +1 -0
  322. package/dist/ui/manifest/nav.d.cts +34 -0
  323. package/dist/ui/manifest/nav.d.cts.map +1 -0
  324. package/dist/ui/manifest/nav.d.mts +34 -0
  325. package/dist/ui/manifest/nav.d.mts.map +1 -0
  326. package/dist/ui/manifest/nav.mjs +13 -0
  327. package/dist/ui/manifest/nav.mjs.map +1 -0
  328. package/dist/ui/manifest/route-config.cjs +33 -0
  329. package/dist/ui/manifest/route-config.cjs.map +1 -0
  330. package/dist/ui/manifest/route-config.d.cts +40 -0
  331. package/dist/ui/manifest/route-config.d.cts.map +1 -0
  332. package/dist/ui/manifest/route-config.d.mts +40 -0
  333. package/dist/ui/manifest/route-config.d.mts.map +1 -0
  334. package/dist/ui/manifest/route-config.mjs +33 -0
  335. package/dist/ui/manifest/route-config.mjs.map +1 -0
  336. package/dist/version-manifest.cjs +65 -0
  337. package/dist/version-manifest.cjs.map +1 -0
  338. package/dist/version-manifest.d.cts +52 -0
  339. package/dist/version-manifest.d.cts.map +1 -0
  340. package/dist/version-manifest.d.mts +52 -0
  341. package/dist/version-manifest.d.mts.map +1 -0
  342. package/dist/version-manifest.mjs +63 -0
  343. package/dist/version-manifest.mjs.map +1 -0
  344. package/package.json +165 -68
  345. package/skills/plugin-client/SKILL.md +24 -5
  346. package/skills/plugin-development/SKILL.md +79 -47
  347. package/skills/plugin-testing/SKILL.md +41 -12
  348. package/src/build/artifact-names.ts +117 -0
  349. package/src/build/contract-types.ts +101 -0
  350. package/src/build/rspack/build-report-plugin.ts +34 -0
  351. package/src/build/rspack/chunk-completeness-plugin.ts +57 -0
  352. package/src/build/rspack/compose.ts +87 -0
  353. package/src/build/rspack/fix-mf-data-uri-plugin.ts +23 -12
  354. package/src/build/rspack/generated-config.ts +35 -0
  355. package/src/build/rspack/index.ts +10 -5
  356. package/src/build/rspack/module-federation.ts +1 -1
  357. package/src/build/rspack/plugin.ts +103 -105
  358. package/src/build/rspack/utils.ts +8 -2
  359. package/src/build/ui/factory.ts +96 -0
  360. package/src/build/ui/generated-config.ts +133 -0
  361. package/src/build/ui/hash-artifacts-plugin.ts +79 -0
  362. package/src/build/ui/index.ts +98 -0
  363. package/src/build/ui/manifest-plugin.ts +54 -0
  364. package/src/build/ui/rsbuild-config.ts +256 -0
  365. package/src/build/ui/stubs.ts +103 -0
  366. package/src/cli.ts +100 -0
  367. package/src/dev/serve.ts +477 -0
  368. package/src/dev/watch-kill.ts +58 -0
  369. package/src/effect-helpers.ts +25 -0
  370. package/src/errors.ts +17 -18
  371. package/src/identity.ts +36 -0
  372. package/src/index.ts +4 -0
  373. package/src/plugin.ts +88 -91
  374. package/src/remote-entry.ts +171 -0
  375. package/src/runtime/errors.ts +229 -26
  376. package/src/runtime/index.ts +132 -43
  377. package/src/runtime/mf-config.ts +12 -107
  378. package/src/runtime/services/module-federation.service.ts +218 -117
  379. package/src/runtime/services/normalize.ts +1 -18
  380. package/src/runtime/services/plugin-lifecycle.service.ts +66 -75
  381. package/src/runtime/services/plugin-loader.service.ts +271 -212
  382. package/src/runtime/services/plugin.service.ts +61 -43
  383. package/src/runtime/services/secrets.service.ts +20 -15
  384. package/src/runtime/services/shared-identity.ts +68 -0
  385. package/src/runtime/validation.ts +5 -7
  386. package/src/shared-deps-spec.ts +478 -0
  387. package/src/types.ts +25 -48
  388. package/src/ui/manifest/construct.ts +403 -0
  389. package/src/ui/manifest/contract.ts +33 -0
  390. package/src/ui/manifest/descriptor.ts +96 -0
  391. package/src/ui/manifest/generator.ts +238 -0
  392. package/src/ui/manifest/index.ts +55 -0
  393. package/src/ui/manifest/manifest-schema.ts +107 -0
  394. package/src/ui/manifest/mount-registry.ts +50 -0
  395. package/src/ui/manifest/nav.ts +43 -0
  396. package/src/ui/manifest/route-config.ts +82 -0
  397. package/src/version-manifest.ts +88 -0
  398. package/dist/build/rspack/dev-server-middleware.cjs +0 -248
  399. package/dist/build/rspack/dev-server-middleware.cjs.map +0 -1
  400. package/dist/build/rspack/dev-server-middleware.mjs +0 -247
  401. package/dist/build/rspack/dev-server-middleware.mjs.map +0 -1
  402. package/dist/build/shared-deps.cjs +0 -83
  403. package/dist/build/shared-deps.cjs.map +0 -1
  404. package/dist/build/shared-deps.d.cts +0 -67
  405. package/dist/build/shared-deps.d.cts.map +0 -1
  406. package/dist/build/shared-deps.d.mts +0 -67
  407. package/dist/build/shared-deps.d.mts.map +0 -1
  408. package/dist/build/shared-deps.mjs +0 -79
  409. package/dist/build/shared-deps.mjs.map +0 -1
  410. package/dist/effect.cjs +0 -9
  411. package/dist/effect.d.cts +0 -1
  412. package/dist/effect.d.mts +0 -1
  413. package/dist/effect.mjs +0 -3
  414. package/dist/orpc-openapi.cjs +0 -17
  415. package/dist/orpc-openapi.d.cts +0 -2
  416. package/dist/orpc-openapi.d.mts +0 -2
  417. package/dist/orpc-openapi.mjs +0 -5
  418. package/dist/orpc.cjs +0 -46
  419. package/dist/orpc.d.cts +0 -7
  420. package/dist/orpc.d.mts +0 -7
  421. package/dist/orpc.mjs +0 -11
  422. package/dist/package.cjs +0 -23
  423. package/dist/package.cjs.map +0 -1
  424. package/dist/package.mjs +0 -17
  425. package/dist/package.mjs.map +0 -1
  426. package/dist/runtime/services/module-federation.service.d.cts.map +0 -1
  427. package/dist/runtime/services/module-federation.service.d.mts.map +0 -1
  428. package/dist/runtime/services/normalize.cjs.map +0 -1
  429. package/dist/runtime/services/normalize.d.cts.map +0 -1
  430. package/dist/runtime/services/normalize.d.mts.map +0 -1
  431. package/dist/runtime/services/normalize.mjs.map +0 -1
  432. package/dist/runtime/services/plugin-lifecycle.service.d.cts.map +0 -1
  433. package/dist/runtime/services/plugin-lifecycle.service.d.mts.map +0 -1
  434. package/dist/runtime/services/plugin-loader.service.d.cts.map +0 -1
  435. package/dist/runtime/services/plugin-loader.service.d.mts.map +0 -1
  436. package/dist/runtime/services/secrets.service.d.cts.map +0 -1
  437. package/dist/runtime/services/secrets.service.d.mts.map +0 -1
  438. package/dist/testing/index.cjs +0 -57
  439. package/dist/testing/index.cjs.map +0 -1
  440. package/dist/testing/index.d.cts +0 -54
  441. package/dist/testing/index.d.cts.map +0 -1
  442. package/dist/testing/index.d.mts +0 -54
  443. package/dist/testing/index.d.mts.map +0 -1
  444. package/dist/testing/index.mjs +0 -55
  445. package/dist/testing/index.mjs.map +0 -1
  446. package/dist/zod-core.cjs +0 -9
  447. package/dist/zod-core.d.cts +0 -1
  448. package/dist/zod-core.d.mts +0 -1
  449. package/dist/zod-core.mjs +0 -3
  450. package/dist/zod.cjs +0 -11
  451. package/dist/zod.d.cts +0 -2
  452. package/dist/zod.d.mts +0 -2
  453. package/dist/zod.mjs +0 -3
  454. package/src/build/rspack/dev-server-middleware.ts +0 -324
  455. package/src/build/shared-deps.ts +0 -102
  456. package/src/effect.ts +0 -1
  457. package/src/orpc-openapi.ts +0 -2
  458. package/src/orpc.ts +0 -9
  459. package/src/testing/index.ts +0 -87
  460. package/src/testing/mocks/module-federation.service.ts +0 -41
  461. package/src/zod-core.ts +0 -1
  462. package/src/zod.ts +0 -3
@@ -0,0 +1,58 @@
1
+ interface KillableChild {
2
+ pid?: number | undefined;
3
+ kill: (signal?: NodeJS.Signals) => void;
4
+ exitCode: number | null;
5
+ killed: boolean;
6
+ addListener: (event: "exit", listener: () => void) => unknown;
7
+ removeListener: (event: "exit", listener: () => void) => unknown;
8
+ }
9
+
10
+ const waitForExit = (child: KillableChild, timeoutMs: number): Promise<boolean> =>
11
+ new Promise((resolve) => {
12
+ if (child.exitCode !== null) {
13
+ resolve(true);
14
+ return;
15
+ }
16
+ const onExit = () => {
17
+ clearTimeout(timer);
18
+ resolve(true);
19
+ };
20
+ const timer = setTimeout(() => {
21
+ child.removeListener("exit", onExit);
22
+ resolve(false);
23
+ }, timeoutMs);
24
+ child.addListener("exit", onExit);
25
+ });
26
+
27
+ export const killChildEscalating = async (
28
+ child: KillableChild,
29
+ terminateMs = 2000,
30
+ ): Promise<void> => {
31
+ if (child.exitCode !== null || child.killed) return;
32
+ child.kill("SIGTERM");
33
+ const exited = await waitForExit(child, terminateMs);
34
+ if (!exited) child.kill("SIGKILL");
35
+ };
36
+
37
+ export interface WatchParentDeathOptions {
38
+ intervalMs?: number;
39
+ getPpid?: () => number;
40
+ onParentDeath?: () => void | Promise<void>;
41
+ }
42
+
43
+ export const watchParentDeath = (
44
+ onParentDeath: () => void | Promise<void>,
45
+ opts?: Omit<WatchParentDeathOptions, "onParentDeath">,
46
+ ): { stop: () => void } => {
47
+ const getPpid = opts?.getPpid ?? (() => process.ppid);
48
+ const intervalMs = opts?.intervalMs ?? 200;
49
+ const initialPpid = getPpid();
50
+ const timer = setInterval(() => {
51
+ if (getPpid() !== initialPpid) {
52
+ clearInterval(timer);
53
+ void onParentDeath();
54
+ }
55
+ }, intervalMs);
56
+ timer.unref?.();
57
+ return { stop: () => clearInterval(timer) };
58
+ };
@@ -0,0 +1,25 @@
1
+ import { Context, Effect, Layer, type Scope } from "effect";
2
+
3
+ /**
4
+ * Builds a layer with the current scope and returns the built context.
5
+ *
6
+ * Resources are released when the plugin's scope closes. Use inside
7
+ * `initialize` for multi-service layers; resolve individual services from
8
+ * the returned context with `Context.get`.
9
+ */
10
+ export const buildScopedContext = <A, E, R>(
11
+ layer: Layer.Layer<A, E, R>,
12
+ ): Effect.Effect<Context.Context<A>, E, Scope.Scope | R> =>
13
+ Effect.flatMap(Effect.scope, (scope) => Layer.buildWithScope(layer, scope));
14
+
15
+ /**
16
+ * Builds a layer with the current scope and resolves one service from it.
17
+ *
18
+ * Equivalent to `buildScopedContext` + `Context.get` for single-service
19
+ * layers: `const db = yield* buildScoped(DatabaseTag, DatabaseLive(url))`.
20
+ */
21
+ export const buildScoped = <Identifier, Shape, E, R>(
22
+ tag: Context.Service<Identifier, Shape>,
23
+ layer: Layer.Layer<Identifier, E, R>,
24
+ ): Effect.Effect<Shape, E, Scope.Scope | R> =>
25
+ buildScopedContext(layer).pipe(Effect.map((context) => Context.get(context, tag)));
package/src/errors.ts CHANGED
@@ -1,18 +1,5 @@
1
- import { z } from "./zod";
2
-
3
- /**
4
- * Error pattern constants for categorizing infrastructure errors
5
- */
6
- export const ERROR_PATTERNS = {
7
- CONNECTION_REFUSED: ["ECONNREFUSED"],
8
- HOST_NOT_FOUND: ["ENOTFOUND", "EHOSTUNREACH"],
9
- TIMEOUT: ["ETIMEDOUT", "ESOCKETTIMEDOUT", "timeout"],
10
- CONNECTION_RESET: ["ECONNRESET", "EPIPE"],
11
- PERMISSION: ["EACCES", "EPERM", "permission denied"],
12
- AUTH: ["401", "unauthorized", "authentication failed"],
13
- RATE_LIMITED: ["429", "too many requests", "rate limit"],
14
- SERVICE_UNAVAILABLE: ["503", "service unavailable"],
15
- } as const;
1
+ import { COMMON_ERROR_STATUS_MAP } from "@orpc/server";
2
+ import { z } from "zod";
16
3
 
17
4
  /**
18
5
  * Common error schemas for plugin contracts.
@@ -124,14 +111,26 @@ export const PluginErrors = {
124
111
  } as const;
125
112
 
126
113
  /**
127
- * @deprecated Use individual imports or PluginErrors instead
114
+ * Error-code -> HTTP-status map for handlers.
115
+ *
116
+ * oRPC v2 resolves statuses at the handler boundary via `errorStatusMap`
117
+ * (default `COMMON_ERROR_STATUS_MAP`, where TIMEOUT is 408). Providing a
118
+ * map REPLACES the default entirely, so the standard codes must be spread
119
+ * back in. These custom entries preserve the v1 wire behavior:
120
+ * TIMEOUT -> 504, CONNECTION_ERROR -> 502.
128
121
  */
129
- export const CommonPluginErrors = PluginErrors;
122
+ export const PLUGIN_ERROR_STATUS_MAP: Record<string, number> = {
123
+ ...COMMON_ERROR_STATUS_MAP,
124
+ TIMEOUT: 504,
125
+ CONNECTION_ERROR: 502,
126
+ } as const;
130
127
 
128
+ export type { PluginLoadFailureInfo, PluginWarningInfo } from "./runtime/errors";
131
129
  export {
130
+ classifyPluginFailure,
131
+ defaultMissingSecretWarnings,
132
132
  extractFromFiberFailure,
133
133
  formatORPCError,
134
- isRetryableORPCCode,
135
134
  ModuleFederationError,
136
135
  PluginRuntimeError,
137
136
  toPluginRuntimeError,
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Plugin identity: every name a plugin workspace carries, derived from one
3
+ * input. Two seams live here:
4
+ *
5
+ * - `remoteName`/`containerName` absorb the framework's two normalizers (the
6
+ * Module Federation remote name and the UI container name) — runtime,
7
+ * build, and host consumers delegate to these instead of keeping private
8
+ * copies, so a name can never disagree across contexts.
9
+ * - `identity` derives the full name set from the config layout key (the
10
+ * `plugins/<key>` attachment in `bos.config.json`): the key itself (the
11
+ * composition key), the npm package name under the scaffold convention,
12
+ * and the two normalized build names.
13
+ *
14
+ * Normalization rules:
15
+ * - remote: lowercase, strip a single leading '@', replace '/' with '_',
16
+ * preserve hyphens and other characters
17
+ * ("@scope/my-plugin" → "scope_my-plugin")
18
+ * - container: replace every character outside [A-Za-z0-9_] with '_'
19
+ * ("@everything-dev/auth-plugin" → "_everything_dev_auth_plugin")
20
+ */
21
+ export interface PluginIdentity {
22
+ key: string;
23
+ npm: string;
24
+ remote: string;
25
+ container: string;
26
+ }
27
+
28
+ export const remoteName = (name: string): string =>
29
+ name.toLowerCase().replace(/^@/, "").replace(/\//g, "_");
30
+
31
+ export const containerName = (pkgName: string): string => pkgName.replace(/[^A-Za-z0-9_]/g, "_");
32
+
33
+ export const identity = (key: string): PluginIdentity => {
34
+ const npm = `@everything-dev/${key}-plugin`;
35
+ return { key, npm, remote: remoteName(npm), container: containerName(npm) };
36
+ };
package/src/index.ts CHANGED
@@ -1,3 +1,6 @@
1
+ import "@orpc/openapi/extensions/route";
2
+
3
+ export * from "./effect-helpers";
1
4
  export * from "./errors";
2
5
  export * from "./plugin";
3
6
  export * from "./runtime";
@@ -20,6 +23,7 @@ export type {
20
23
  PluginRouterType,
21
24
  PluginRuntimeConfig,
22
25
  PluginSecrets,
26
+ PluginServicesEntry,
23
27
  PluginVariables,
24
28
  RegisteredPlugins,
25
29
  SecretsConfig,
package/src/plugin.ts CHANGED
@@ -1,9 +1,12 @@
1
1
  import type { AnyContractRouter, AnySchema, InferSchemaOutput } from "@orpc/contract";
2
- import { ORPCError } from "@orpc/contract";
3
- import type { Implementer, Router } from "@orpc/server";
4
- import { implement, onError } from "@orpc/server";
5
- import { Context, Effect, type Context as EffectContext, type Layer, type Scope } from "effect";
6
- import { extractFromFiberFailure, formatORPCError } from "./runtime/errors";
2
+ import type { WithEffectContext } from "@orpc/experimental-effect";
3
+ import "@orpc/experimental-effect/extensions/effect";
4
+ import type { ContractedRouter, Implementer } from "@orpc/server";
5
+ import { implement } from "@orpc/server";
6
+ import type { Scope } from "effect";
7
+ import { Context, Effect, Layer } from "effect";
8
+ import type { PluginWarningInfo } from "./runtime/errors";
9
+ import { type PluginRuntimeError, toPluginRuntimeError } from "./runtime/errors";
7
10
 
8
11
  type ContextOutput<T> = T extends AnySchema ? InferSchemaOutput<T> : Record<string, never>;
9
12
 
@@ -17,28 +20,33 @@ export type PluginConfigFor<
17
20
  context: TRequestContext;
18
21
  };
19
22
 
20
- type PluginInitializeInput<V extends AnySchema, S extends AnySchema> = {
23
+ export type PluginInitializeInput<V extends AnySchema, S extends AnySchema> = {
21
24
  variables: InferSchemaOutput<V>;
22
25
  secrets: InferSchemaOutput<S>;
23
26
  };
24
27
 
25
28
  /**
26
- * Tools provided to plugin initialize/services for building long-lived scoped resources.
29
+ * A plugin's own config-derived warnings, evaluated once with the validated
30
+ * config after initialization. Declaring `warnings` opts the plugin out of
31
+ * the loader's default missing-secret warning — these messages replace it.
27
32
  */
28
- type ServiceOf<T> = T extends EffectContext.Tag<any, infer S> ? S : never;
33
+ export type PluginWarningsFn<V extends AnySchema, S extends AnySchema> = (
34
+ config: PluginInitializeInput<V, S>,
35
+ ) => PluginWarningInfo[] | string[];
29
36
 
30
- export type PluginServicesTools = {
31
- buildService: <T>(tag: T, layer: Layer.Layer<any, any, any>) => Effect.Effect<ServiceOf<T>>;
32
- };
37
+ export class PluginIdTag extends Context.Service<PluginIdTag, string>()("PluginId") {}
33
38
 
34
- export class PluginIdTag extends Context.Tag("PluginId")<PluginIdTag, string>() {}
39
+ /**
40
+ * The `initialize` effect's environment: the plugin lifecycle scope plus the
41
+ * framework-assigned plugin id.
42
+ */
43
+ export type PluginEnv = Scope.Scope | PluginIdTag;
35
44
 
36
45
  type PluginDefinition<
37
46
  V extends AnySchema,
38
47
  S extends AnySchema,
39
48
  TContract extends AnyContractRouter,
40
49
  TRequestContext extends AnySchema | undefined,
41
- TDeps extends Record<string, any>,
42
50
  P extends Record<string, unknown>,
43
51
  > = {
44
52
  variables: V;
@@ -46,20 +54,42 @@ type PluginDefinition<
46
54
  contract: TContract;
47
55
  context?: TRequestContext;
48
56
  /**
49
- * Initialize the plugin and build dependencies.
50
- * A third argument `tools` is provided for building long-lived scoped resources
51
- * (e.g. database pools) via `tools.buildService(tag, layer)`.
57
+ * Optional tag under which `initialize` exposes the plugin's services.
58
+ * The host uses it to read services (e.g. the auth plugin's Better Auth
59
+ * handler) from the built Effect context without importing the plugin
60
+ * module statically.
61
+ */
62
+ servicesTag?: Context.Key<any, any>;
63
+ /**
64
+ * Optional warnings function evaluated once with the validated config after
65
+ * initialization. Returns structured non-fatal warnings (e.g. an optional
66
+ * secret was not set, so the feature depending on it is disabled).
67
+ * Declaring it opts out of the loader's default missing-secret warning.
68
+ */
69
+ warnings?: PluginWarningsFn<V, S>;
70
+ /**
71
+ * Initialize the plugin by returning an Effect `Layer`.
72
+ *
73
+ * The runtime builds the Layer against the plugin's lifecycle scope —
74
+ * scoped resources (db pools, repositories, caches, publishers) release
75
+ * when the plugin shuts down. Services are provided to `.effect()`
76
+ * handlers via the oRPC context (`yield* Tag`).
52
77
  */
53
78
  initialize?: (
54
79
  config: PluginInitializeInput<V, S>,
55
80
  plugins: P,
56
- tools: PluginServicesTools,
57
- ) => Effect.Effect<TDeps, Error, Scope.Scope>;
81
+ ) => Effect.Effect<Layer.Layer<any, Error, PluginEnv>, Error, PluginEnv>;
82
+ /**
83
+ * Creates the strongly-typed oRPC router for this plugin.
84
+ * Services come from the Effect context — access them with
85
+ * `yield* Tag` in `.effect()` handlers, or
86
+ * `Context.get(context["effect/context"], Tag)` in plain handlers.
87
+ * Sibling plugin entries in `plugins` carry `{ client, router }`.
88
+ */
58
89
  createRouter: (
59
- deps: TDeps,
60
- builder: Implementer<TContract, ContextOutput<TRequestContext>, ContextOutput<TRequestContext>>,
61
- ) => Router<TContract, any>;
62
- shutdown?: (deps: TDeps) => Effect.Effect<void, Error, never>;
90
+ builder: Implementer<TContract, ContextOutput<TRequestContext> & WithEffectContext<any>>,
91
+ plugins: P,
92
+ ) => ContractedRouter<TContract, any>;
63
93
  };
64
94
 
65
95
  /**
@@ -70,14 +100,14 @@ export interface LoadedPluginWithBinding<
70
100
  TVariables extends AnySchema,
71
101
  TSecrets extends AnySchema,
72
102
  TRequestContext extends AnySchema | undefined,
73
- TDeps extends Record<string, any> = Record<never, never>,
74
103
  > {
75
- new (): Plugin<TContract, TVariables, TSecrets, TRequestContext, TDeps>;
104
+ new (): Plugin<TContract, TVariables, TSecrets, TRequestContext>;
76
105
  binding: {
77
106
  contract: TContract;
78
107
  variables: TVariables;
79
108
  secrets: TSecrets;
80
109
  context: TRequestContext;
110
+ servicesTag?: Context.Key<any, any>;
81
111
  };
82
112
  }
83
113
 
@@ -89,27 +119,26 @@ export interface Plugin<
89
119
  TVariables extends AnySchema,
90
120
  TSecrets extends AnySchema,
91
121
  TRequestContext extends AnySchema | undefined,
92
- TDeps extends Record<string, any> = Record<never, never>,
93
122
  > {
94
123
  readonly id: string;
95
124
  readonly contract: TContract;
96
125
  readonly configSchema: PluginConfigFor<TVariables, TSecrets, TRequestContext>;
126
+ readonly servicesTag?: Context.Key<any, any>;
127
+ readonly warnings?: PluginWarningsFn<TVariables, TSecrets>;
97
128
 
98
129
  initialize(
99
130
  config: PluginInitializeInput<TVariables, TSecrets>,
100
131
  plugins: Record<string, unknown>,
101
- tools: PluginServicesTools,
102
- ): Effect.Effect<TDeps, unknown, Scope.Scope>;
103
-
104
- shutdown(): Effect.Effect<void, never>;
132
+ ): Effect.Effect<Layer.Layer<any, Error, PluginEnv>, PluginRuntimeError, PluginEnv>;
105
133
 
106
134
  /**
107
135
  * Creates the strongly-typed oRPC router for this plugin.
108
136
  * The router's procedure types are inferred directly from the contract.
109
- * @param deps The initialized plugin dependencies
137
+ * @param plugins Sibling plugin entries (`{ client, router }`) for
138
+ * cross-plugin composition
110
139
  * @returns A router with procedures matching the plugin's contract
111
140
  */
112
- createRouter(deps: TDeps): Router<TContract, any>;
141
+ createRouter(plugins: Record<string, unknown>): ContractedRouter<TContract, any>;
113
142
  }
114
143
 
115
144
  export interface CreatePluginFn {
@@ -118,11 +147,10 @@ export interface CreatePluginFn {
118
147
  S extends AnySchema,
119
148
  TContract extends AnyContractRouter,
120
149
  TRequestContext extends AnySchema | undefined = undefined,
121
- TDeps extends Record<string, any> = Record<never, never>,
122
150
  P extends Record<string, unknown> = Record<string, never>,
123
151
  >(
124
- config: PluginDefinition<V, S, TContract, TRequestContext, TDeps, P>,
125
- ): LoadedPluginWithBinding<TContract, V, S, TRequestContext, TDeps>;
152
+ config: PluginDefinition<V, S, TContract, TRequestContext, P>,
153
+ ): LoadedPluginWithBinding<TContract, V, S, TRequestContext>;
126
154
 
127
155
  withPlugins: <P extends Record<string, unknown>>() => CreatePluginWithPlugins<P>;
128
156
  }
@@ -132,84 +160,54 @@ export const createPlugin: CreatePluginFn = function createPlugin<
132
160
  S extends AnySchema,
133
161
  TContract extends AnyContractRouter,
134
162
  TRequestContext extends AnySchema | undefined = undefined,
135
- TDeps extends Record<string, any> = Record<never, never>,
136
163
  P extends Record<string, unknown> = Record<string, never>,
137
- >(config: PluginDefinition<V, S, TContract, TRequestContext, TDeps, P>) {
164
+ >(config: PluginDefinition<V, S, TContract, TRequestContext, P>) {
138
165
  const configSchema: PluginConfigFor<V, S, TRequestContext> = {
139
166
  variables: config.variables,
140
167
  secrets: config.secrets,
141
168
  context: config.context as TRequestContext,
142
169
  };
143
170
 
144
- class CreatedPlugin implements Plugin<TContract, V, S, TRequestContext, TDeps> {
171
+ class CreatedPlugin implements Plugin<TContract, V, S, TRequestContext> {
145
172
  /** set during instantiation - registry key */
146
173
  id!: string;
147
174
  readonly contract = config.contract;
148
175
  readonly configSchema = configSchema;
149
-
150
- private _deps: TDeps | null = null;
176
+ readonly servicesTag = config.servicesTag;
177
+ readonly warnings = config.warnings;
151
178
 
152
179
  initialize(
153
180
  pluginConfig: PluginInitializeInput<V, S>,
154
181
  plugins: Record<string, unknown> = {},
155
- tools: PluginServicesTools,
156
- ): Effect.Effect<TDeps, unknown, Scope.Scope> {
157
- const init = config.initialize ?? (() => Effect.succeed({} as TDeps));
158
-
159
- return init(pluginConfig, plugins as P, tools).pipe(
160
- Effect.tap((deps) =>
161
- Effect.sync(() => {
162
- this._deps = deps;
163
- }),
182
+ ): Effect.Effect<Layer.Layer<any, Error, PluginEnv>, PluginRuntimeError, PluginEnv> {
183
+ const init = config.initialize;
184
+ if (!init) {
185
+ return Effect.succeed(Layer.empty as unknown as Layer.Layer<any, Error, PluginEnv>);
186
+ }
187
+
188
+ return init(pluginConfig, plugins as P).pipe(
189
+ Effect.mapError((error) =>
190
+ toPluginRuntimeError(error, this.id, undefined, "initialize-plugin"),
164
191
  ),
165
- Effect.map(() => this._deps as TDeps),
166
- Effect.mapError((error) => error as unknown),
167
192
  );
168
193
  }
169
194
 
170
- shutdown(): Effect.Effect<void, never> {
171
- const self = this;
172
- return Effect.gen(function* () {
173
- if (config.shutdown && self._deps) {
174
- yield* config
175
- .shutdown(self._deps)
176
- .pipe(
177
- Effect.catchAll((error) =>
178
- Effect.logWarning(`Plugin shutdown hook failed for ${self.id}`, error),
179
- ),
180
- );
181
- }
182
- self._deps = null;
183
- });
184
- }
185
-
186
- createRouter(deps: TDeps): Router<TContract, any> {
187
- const base = implement(config.contract).$context<ContextOutput<TRequestContext>>();
188
- const errorMiddleware = onError((error: unknown) => {
189
- const unwrapped = extractFromFiberFailure(error);
190
-
191
- if (unwrapped !== error && unwrapped instanceof ORPCError) {
192
- throw unwrapped;
193
- }
194
-
195
- const formatted = formatORPCError(error);
196
- if (formatted) console.error(formatted);
197
- throw error;
198
- }) as any;
199
-
200
- const builder = (base as any).use(errorMiddleware);
201
- const router = config.createRouter(deps, builder as any);
202
- return router as Router<TContract, any>;
195
+ createRouter(plugins: Record<string, unknown>): ContractedRouter<TContract, any> {
196
+ const builder = implement(config.contract).$context<
197
+ ContextOutput<TRequestContext> & WithEffectContext<any>
198
+ >();
199
+ return config.createRouter(builder as any, plugins as P) as ContractedRouter<TContract, any>;
203
200
  }
204
201
  }
205
202
 
206
203
  const PluginConstructor = CreatedPlugin as unknown as {
207
- new (): Plugin<TContract, V, S, TRequestContext, TDeps>;
204
+ new (): Plugin<TContract, V, S, TRequestContext>;
208
205
  binding: {
209
206
  contract: TContract;
210
207
  variables: V;
211
208
  secrets: S;
212
209
  context: TRequestContext;
210
+ servicesTag?: Context.Key<any, any>;
213
211
  };
214
212
  };
215
213
 
@@ -218,9 +216,10 @@ export const createPlugin: CreatePluginFn = function createPlugin<
218
216
  variables: config.variables,
219
217
  secrets: config.secrets,
220
218
  context: config.context as TRequestContext,
219
+ servicesTag: config.servicesTag,
221
220
  };
222
221
 
223
- return PluginConstructor as LoadedPluginWithBinding<TContract, V, S, TRequestContext, TDeps>;
222
+ return PluginConstructor as LoadedPluginWithBinding<TContract, V, S, TRequestContext>;
224
223
  };
225
224
 
226
225
  export type CreatePluginWithPlugins<P extends Record<string, unknown>> = <
@@ -228,10 +227,9 @@ export type CreatePluginWithPlugins<P extends Record<string, unknown>> = <
228
227
  S extends AnySchema,
229
228
  TContract extends AnyContractRouter,
230
229
  TRequestContext extends AnySchema | undefined = undefined,
231
- TDeps extends Record<string, any> = Record<never, never>,
232
230
  >(
233
- config: PluginDefinition<V, S, TContract, TRequestContext, TDeps, P>,
234
- ) => LoadedPluginWithBinding<TContract, V, S, TRequestContext, TDeps>;
231
+ config: PluginDefinition<V, S, TContract, TRequestContext, P>,
232
+ ) => LoadedPluginWithBinding<TContract, V, S, TRequestContext>;
235
233
 
236
234
  export function withPlugins<P extends Record<string, unknown>>(): CreatePluginWithPlugins<P> {
237
235
  return <
@@ -239,10 +237,9 @@ export function withPlugins<P extends Record<string, unknown>>(): CreatePluginWi
239
237
  S extends AnySchema,
240
238
  TContract extends AnyContractRouter,
241
239
  TRequestContext extends AnySchema | undefined = undefined,
242
- TDeps extends Record<string, any> = Record<never, never>,
243
240
  >(
244
- config: PluginDefinition<V, S, TContract, TRequestContext, TDeps, P>,
245
- ) => createPlugin<V, S, TContract, TRequestContext, TDeps, P>(config as any);
241
+ config: PluginDefinition<V, S, TContract, TRequestContext, P>,
242
+ ) => createPlugin<V, S, TContract, TRequestContext, P>(config as any);
246
243
  }
247
244
 
248
245
  createPlugin.withPlugins = withPlugins;
@@ -0,0 +1,171 @@
1
+ /**
2
+ * Remote-entry loading resilience — the ONE contract every MF consumer in
3
+ * the dev stack shares (plugin dev serves, the host's plugin loader).
4
+ *
5
+ * Two failure classes it exists for:
6
+ * 1. Cold compile: remoteEntry.js 404s until the remote's first build —
7
+ * the 404 body gets eval'd as JS ("Unexpected identifier 'Found'").
8
+ * 2. Watch-rebuild poisoning: a failed entry load is memoized forever in
9
+ * `globalThis.__GLOBAL_LOADING_REMOTE_ENTRY__` (runtime-core never evicts
10
+ * rejections), so retries without a purge await the same failure.
11
+ */
12
+ import { Duration, Effect, Schedule } from "effect";
13
+ import type { PluginRuntimeError } from "./runtime/errors";
14
+ import {
15
+ classifyPluginFailure,
16
+ deepestErrorStack,
17
+ type PluginFailureClassification,
18
+ toPluginRuntimeError,
19
+ } from "./runtime/errors";
20
+
21
+ const POLL_INTERVAL_MS = 300;
22
+ const DEFAULT_TIMEOUT_MS = 120_000;
23
+ const RETRY_BASE_DELAY_MS = 500;
24
+ const RETRY_MAX_DELAY_MS = 5_000;
25
+
26
+ export const sleep = (ms: number): Promise<void> =>
27
+ new Promise((resolve) => setTimeout(resolve, ms));
28
+
29
+ /**
30
+ * Deletes the failed remote's keys from the process-global entry-load cache.
31
+ * Deleting a RESOLVED entry would force a wasteful re-eval, so only call
32
+ * this from failure paths.
33
+ */
34
+ export const purgeRemoteEntryCache = (remoteUrl: string): void => {
35
+ const globalLoading = (globalThis as Record<string, unknown>).__GLOBAL_LOADING_REMOTE_ENTRY__ as
36
+ | Record<string, unknown>
37
+ | undefined;
38
+ if (!globalLoading) return;
39
+ for (const key of Object.keys(globalLoading)) {
40
+ if (key.endsWith(`:${remoteUrl}`)) delete globalLoading[key];
41
+ }
42
+ };
43
+
44
+ export const isRemoteEntryBody = (body: string): boolean =>
45
+ !/not found|<(!doctype|html)/i.test(body.slice(0, 64));
46
+
47
+ export const waitForRemoteEntryReady = async (
48
+ label: string,
49
+ url: string,
50
+ timeoutMs = DEFAULT_TIMEOUT_MS,
51
+ ): Promise<void> => {
52
+ const deadline = Date.now() + timeoutMs;
53
+ let announced = false;
54
+ while (Date.now() < deadline) {
55
+ const res = await fetch(url).catch(() => null);
56
+ if (res?.ok && isRemoteEntryBody(await res.text().catch(() => ""))) return;
57
+ if (!announced) {
58
+ announced = true;
59
+ console.log(`⏳ waiting for ${label} to compile (remote entry not ready)…`);
60
+ }
61
+ await sleep(POLL_INTERVAL_MS);
62
+ }
63
+ throw new Error(`${label} remote entry never became ready at ${url}`);
64
+ };
65
+
66
+ export interface PluginLoadAttemptInfo {
67
+ attempt: number;
68
+ classification: PluginFailureClassification;
69
+ }
70
+
71
+ export interface PluginLoadRetryOptions<T> {
72
+ /** short plugin key for log prefixes (host entry key or plugin id) */
73
+ label: string;
74
+ remoteUrl: string;
75
+ load: () => Promise<T>;
76
+ /** wall-clock budget for the retry loop */
77
+ timeoutMs?: number;
78
+ /**
79
+ * Budget for the readiness poll (cold-compile wait) — defaults to the
80
+ * retry budget, preserving the historical behavior. Pass `0` to skip the
81
+ * poll (useful when the caller stubs `load` and does not need network).
82
+ */
83
+ readinessTimeoutMs?: number;
84
+ /**
85
+ * Observes every failed attempt (including non-retryable ones that end the
86
+ * loop). Defaults to classification-deduped console.error under the
87
+ * `[Plugins]` prefix.
88
+ */
89
+ onAttempt?: ((error: unknown, info: PluginLoadAttemptInfo) => void) | undefined;
90
+ }
91
+
92
+ /**
93
+ * The one plugin-load retry policy: poll the remote entry until it is actually
94
+ * served, then load with capped exponential backoff — purging the poisoned
95
+ * global entry cache between attempts so each retry genuinely re-fetches.
96
+ *
97
+ * Recovery policy is `classifyPluginFailure().retryable`: transient network
98
+ * conditions retry until the wall-clock budget runs out; permanent failures
99
+ * (MF identity skew, schema validation, dead remotes, TLS verification) fail
100
+ * fast on the first attempt instead of burning the budget silently.
101
+ *
102
+ * Fails with the ORIGINAL error from `load` — the host builds
103
+ * `PluginBootstrapError.cause` from it and classification walks it.
104
+ */
105
+ export const loadRemoteWithRetry = <T>(
106
+ options: PluginLoadRetryOptions<T>,
107
+ ): Effect.Effect<T, PluginRuntimeError> => {
108
+ const {
109
+ label,
110
+ remoteUrl,
111
+ load,
112
+ timeoutMs = DEFAULT_TIMEOUT_MS,
113
+ readinessTimeoutMs,
114
+ onAttempt,
115
+ } = options;
116
+ const readinessTimeout = readinessTimeoutMs ?? timeoutMs;
117
+
118
+ const schedule = Schedule.exponential(Duration.millis(RETRY_BASE_DELAY_MS)).pipe(
119
+ Schedule.modifyDelay(({ output }) =>
120
+ Effect.succeed(
121
+ Duration.toMillis(output) > RETRY_MAX_DELAY_MS
122
+ ? Duration.millis(RETRY_MAX_DELAY_MS)
123
+ : output,
124
+ ),
125
+ ),
126
+ Schedule.upTo({ duration: Duration.millis(timeoutMs) }),
127
+ );
128
+
129
+ let attempt = 0;
130
+ let lastSignature: string | undefined;
131
+ const reportFailure = (error: unknown): void => {
132
+ attempt += 1;
133
+ purgeRemoteEntryCache(remoteUrl);
134
+ const classification = classifyPluginFailure(error);
135
+ if (onAttempt) {
136
+ onAttempt(error, { attempt, classification });
137
+ return;
138
+ }
139
+ const signature = `${classification.kind}::${classification.message}`;
140
+ if (signature === lastSignature) return;
141
+ lastSignature = signature;
142
+ // The message alone is rarely enough, and the wrapper's own stack points
143
+ // at the wrapping frames — log the DEEPEST cause's stack (the original
144
+ // throw site inside the evaluated remote entry).
145
+ const stack = deepestErrorStack(error);
146
+ console.error(
147
+ `[Plugins][${label}] ❌ ${classification.kind} failure (attempt ${attempt}): ${classification.message}` +
148
+ (classification.suggestion ? `\n[Plugins][${label}] → ${classification.suggestion}` : "") +
149
+ (stack ? `\n[Plugins][${label}] ${stack}` : ""),
150
+ );
151
+ };
152
+
153
+ const loadWithRetry = Effect.tryPromise({
154
+ try: load,
155
+ catch: (error) => toPluginRuntimeError(error, label, undefined, "remote-entry-load"),
156
+ }).pipe(
157
+ Effect.tapError((error) => Effect.sync(() => reportFailure(error))),
158
+ Effect.retry({ schedule, while: (error) => classifyPluginFailure(error).retryable }),
159
+ );
160
+
161
+ // readinessTimeoutMs: 0 skips the cold-compile poll (tests stub `load` and
162
+ // must not race a 1ms wall-clock window against the event loop).
163
+ if (readinessTimeout === 0) {
164
+ return loadWithRetry;
165
+ }
166
+
167
+ return Effect.tryPromise({
168
+ try: () => waitForRemoteEntryReady(label, remoteUrl, readinessTimeout),
169
+ catch: (error) => toPluginRuntimeError(error, label, undefined, "remote-entry-readiness"),
170
+ }).pipe(Effect.flatMap(() => loadWithRetry));
171
+ };