@dxos/app-framework 0.8.4-main.3eb6e50203 → 0.8.4-main.3fbcb4aa9b

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 (379) hide show
  1. package/.storybook/main.mts +1 -3
  2. package/dist/lib/browser/{capability-DU35RXMD.mjs → capability-5RRH3WIB.mjs} +11 -10
  3. package/dist/lib/browser/capability-5RRH3WIB.mjs.map +7 -0
  4. package/dist/lib/browser/{capability-7LE5X2NH.mjs → capability-LUKGKUQH.mjs} +10 -9
  5. package/dist/lib/browser/{chunk-4DQMLMGU.mjs → chunk-23D4SJUE.mjs} +11 -13
  6. package/dist/lib/browser/{chunk-4DQMLMGU.mjs.map → chunk-23D4SJUE.mjs.map} +3 -3
  7. package/dist/lib/browser/{chunk-ZQO3UZ4R.mjs → chunk-3JWJXGLK.mjs} +6 -4
  8. package/dist/lib/browser/chunk-3JWJXGLK.mjs.map +7 -0
  9. package/dist/lib/browser/chunk-45CHLTBV.mjs +34 -0
  10. package/dist/lib/browser/chunk-45CHLTBV.mjs.map +7 -0
  11. package/dist/lib/browser/{chunk-PKQT6C53.mjs → chunk-66IXTIVK.mjs} +3 -2
  12. package/dist/lib/browser/chunk-66IXTIVK.mjs.map +7 -0
  13. package/dist/lib/browser/chunk-7VZJR2OA.mjs +581 -0
  14. package/dist/lib/browser/chunk-7VZJR2OA.mjs.map +7 -0
  15. package/dist/lib/browser/chunk-CZ4BIAHH.mjs +422 -0
  16. package/dist/lib/browser/chunk-CZ4BIAHH.mjs.map +7 -0
  17. package/dist/lib/browser/chunk-FJ4765WW.mjs +8 -0
  18. package/dist/lib/browser/{chunk-FHQTHCX7.mjs.map → chunk-FJ4765WW.mjs.map} +3 -3
  19. package/dist/lib/browser/chunk-FO3IYSLV.mjs +68 -0
  20. package/dist/lib/browser/chunk-FO3IYSLV.mjs.map +7 -0
  21. package/dist/lib/browser/chunk-JD3Z5NEF.mjs +469 -0
  22. package/dist/lib/browser/chunk-JD3Z5NEF.mjs.map +7 -0
  23. package/dist/lib/browser/chunk-NBXPP7JR.mjs +1174 -0
  24. package/dist/lib/browser/chunk-NBXPP7JR.mjs.map +7 -0
  25. package/dist/lib/browser/{chunk-IGRQWMWW.mjs → chunk-WBHCSOBW.mjs} +18 -18
  26. package/dist/lib/browser/chunk-WBHCSOBW.mjs.map +7 -0
  27. package/dist/lib/browser/{chunk-KWP6PKIU.mjs → chunk-Z55LVAGN.mjs} +87 -19
  28. package/dist/lib/browser/chunk-Z55LVAGN.mjs.map +7 -0
  29. package/dist/lib/browser/{chunk-EIFGKQSA.mjs → chunk-ZGJAZSNE.mjs} +9 -37
  30. package/dist/lib/browser/chunk-ZGJAZSNE.mjs.map +7 -0
  31. package/dist/lib/browser/cli/index.mjs +16 -29
  32. package/dist/lib/browser/cli/index.mjs.map +3 -3
  33. package/dist/lib/browser/common/activation-events.mjs +9 -8
  34. package/dist/lib/browser/common/capabilities.mjs +9 -8
  35. package/dist/lib/browser/core/activation-event.mjs +1 -1
  36. package/dist/lib/browser/core/capability.mjs +3 -1
  37. package/dist/lib/browser/core/plugin-manager.mjs +8 -4
  38. package/dist/lib/browser/core/plugin.mjs +14 -4
  39. package/dist/lib/browser/core/url-loader.mjs +24 -0
  40. package/dist/lib/browser/index.mjs +45 -24
  41. package/dist/lib/browser/index.mjs.map +3 -3
  42. package/dist/lib/browser/{invoker-capability-7QW56NOM.mjs → invoker-capability-K4GHUFXF.mjs} +22 -14
  43. package/dist/lib/browser/invoker-capability-K4GHUFXF.mjs.map +7 -0
  44. package/dist/lib/browser/meta.json +1 -1
  45. package/dist/lib/browser/testing/index.mjs +184 -45
  46. package/dist/lib/browser/testing/index.mjs.map +4 -4
  47. package/dist/lib/browser/testing/react.mjs +78 -0
  48. package/dist/lib/browser/testing/react.mjs.map +7 -0
  49. package/dist/lib/browser/ui/index.mjs +19 -20
  50. package/dist/lib/node-esm/{capability-OSVYGK4X.mjs → capability-FCGZVIEG.mjs} +10 -9
  51. package/dist/lib/{browser/capability-7LE5X2NH.mjs.map → node-esm/capability-FCGZVIEG.mjs.map} +1 -1
  52. package/dist/lib/node-esm/{capability-SR2EIZFP.mjs → capability-JOIQ2MQE.mjs} +11 -10
  53. package/dist/lib/node-esm/capability-JOIQ2MQE.mjs.map +7 -0
  54. package/dist/lib/node-esm/{chunk-UEWJDI2L.mjs → chunk-37Z53PXZ.mjs} +2 -2
  55. package/dist/lib/node-esm/{chunk-UEWJDI2L.mjs.map → chunk-37Z53PXZ.mjs.map} +3 -3
  56. package/dist/lib/node-esm/chunk-6XW6LET6.mjs +35 -0
  57. package/dist/lib/node-esm/chunk-6XW6LET6.mjs.map +7 -0
  58. package/dist/lib/node-esm/{chunk-DHSHRYIB.mjs → chunk-D347W3KO.mjs} +9 -37
  59. package/dist/lib/node-esm/chunk-D347W3KO.mjs.map +7 -0
  60. package/dist/lib/node-esm/chunk-DRZKO5UZ.mjs +470 -0
  61. package/dist/lib/node-esm/chunk-DRZKO5UZ.mjs.map +7 -0
  62. package/dist/lib/node-esm/{chunk-DZ2XLAGI.mjs → chunk-HTBJU5FX.mjs} +87 -19
  63. package/dist/lib/node-esm/chunk-HTBJU5FX.mjs.map +7 -0
  64. package/dist/lib/node-esm/chunk-M3HKPRPO.mjs +423 -0
  65. package/dist/lib/node-esm/chunk-M3HKPRPO.mjs.map +7 -0
  66. package/dist/lib/node-esm/chunk-MUVUQC3G.mjs +1175 -0
  67. package/dist/lib/node-esm/chunk-MUVUQC3G.mjs.map +7 -0
  68. package/dist/lib/node-esm/{chunk-J2PHTRHC.mjs → chunk-SBS2YMPT.mjs} +11 -13
  69. package/dist/lib/node-esm/{chunk-J2PHTRHC.mjs.map → chunk-SBS2YMPT.mjs.map} +3 -3
  70. package/dist/lib/node-esm/{chunk-64IMLAS2.mjs → chunk-SDJ4B2LU.mjs} +6 -4
  71. package/dist/lib/node-esm/chunk-SDJ4B2LU.mjs.map +7 -0
  72. package/dist/lib/node-esm/chunk-V24UWT36.mjs +582 -0
  73. package/dist/lib/node-esm/chunk-V24UWT36.mjs.map +7 -0
  74. package/dist/lib/node-esm/{chunk-OQYHRZYF.mjs → chunk-WFSRZKBP.mjs} +18 -18
  75. package/dist/lib/node-esm/chunk-WFSRZKBP.mjs.map +7 -0
  76. package/dist/lib/node-esm/chunk-WK7OIQKI.mjs +70 -0
  77. package/dist/lib/node-esm/chunk-WK7OIQKI.mjs.map +7 -0
  78. package/dist/lib/node-esm/{chunk-7OWSHPYK.mjs → chunk-XOCUANHO.mjs} +3 -2
  79. package/dist/lib/node-esm/chunk-XOCUANHO.mjs.map +7 -0
  80. package/dist/lib/node-esm/cli/index.mjs +16 -29
  81. package/dist/lib/node-esm/cli/index.mjs.map +3 -3
  82. package/dist/lib/node-esm/common/activation-events.mjs +9 -8
  83. package/dist/lib/node-esm/common/capabilities.mjs +9 -8
  84. package/dist/lib/node-esm/core/activation-event.mjs +1 -1
  85. package/dist/lib/node-esm/core/capability.mjs +3 -1
  86. package/dist/lib/node-esm/core/plugin-manager.mjs +8 -4
  87. package/dist/lib/node-esm/core/plugin.mjs +14 -4
  88. package/dist/lib/node-esm/core/url-loader.mjs +25 -0
  89. package/dist/lib/node-esm/index.mjs +45 -24
  90. package/dist/lib/node-esm/index.mjs.map +3 -3
  91. package/dist/lib/node-esm/{invoker-capability-CK4AMF2R.mjs → invoker-capability-XEPW5LMJ.mjs} +22 -14
  92. package/dist/lib/node-esm/invoker-capability-XEPW5LMJ.mjs.map +7 -0
  93. package/dist/lib/node-esm/meta.json +1 -1
  94. package/dist/lib/node-esm/testing/index.mjs +184 -45
  95. package/dist/lib/node-esm/testing/index.mjs.map +4 -4
  96. package/dist/lib/node-esm/testing/react.mjs +79 -0
  97. package/dist/lib/node-esm/testing/react.mjs.map +7 -0
  98. package/dist/lib/node-esm/ui/index.mjs +19 -20
  99. package/dist/plugin/node-esm/index.mjs +893 -0
  100. package/dist/plugin/node-esm/index.mjs.map +7 -0
  101. package/dist/plugin/node-esm/meta.json +1 -0
  102. package/dist/types/src/common/activation-events.d.ts +1 -1
  103. package/dist/types/src/common/activation-events.d.ts.map +1 -1
  104. package/dist/types/src/common/annotations.d.ts +1 -0
  105. package/dist/types/src/common/annotations.d.ts.map +1 -0
  106. package/dist/types/src/common/capabilities.d.ts +4 -8
  107. package/dist/types/src/common/capabilities.d.ts.map +1 -1
  108. package/dist/types/src/common/operations.d.ts +8 -22
  109. package/dist/types/src/common/operations.d.ts.map +1 -1
  110. package/dist/types/src/core/activation-event.d.ts +5 -5
  111. package/dist/types/src/core/activation-event.d.ts.map +1 -1
  112. package/dist/types/src/core/capability-manager.d.ts +5 -0
  113. package/dist/types/src/core/capability-manager.d.ts.map +1 -1
  114. package/dist/types/src/core/capability.d.ts +14 -8
  115. package/dist/types/src/core/capability.d.ts.map +1 -1
  116. package/dist/types/src/core/edge-registry-plugin-provider.d.ts +30 -0
  117. package/dist/types/src/core/edge-registry-plugin-provider.d.ts.map +1 -0
  118. package/dist/types/src/core/index.d.ts +6 -0
  119. package/dist/types/src/core/index.d.ts.map +1 -1
  120. package/dist/types/src/core/plugin-asset-cache.d.ts +71 -0
  121. package/dist/types/src/core/plugin-asset-cache.d.ts.map +1 -0
  122. package/dist/types/src/core/plugin-manager.d.ts +177 -4
  123. package/dist/types/src/core/plugin-manager.d.ts.map +1 -1
  124. package/dist/types/src/core/plugin-manifest.d.ts +101 -0
  125. package/dist/types/src/core/plugin-manifest.d.ts.map +1 -0
  126. package/dist/types/src/core/plugin-manifest.test.d.ts +2 -0
  127. package/dist/types/src/core/plugin-manifest.test.d.ts.map +1 -0
  128. package/dist/types/src/core/plugin.d.ts +113 -7
  129. package/dist/types/src/core/plugin.d.ts.map +1 -1
  130. package/dist/types/src/core/registry.d.ts +101 -0
  131. package/dist/types/src/core/registry.d.ts.map +1 -0
  132. package/dist/types/src/core/url-loader.d.ts +127 -0
  133. package/dist/types/src/core/url-loader.d.ts.map +1 -0
  134. package/dist/types/src/core/url-loader.test.d.ts +2 -0
  135. package/dist/types/src/core/url-loader.test.d.ts.map +1 -0
  136. package/dist/types/src/helpers.d.ts.map +1 -1
  137. package/dist/types/src/plugin-operation/OperationPlugin.d.ts.map +1 -1
  138. package/dist/types/src/plugin-operation/history/capability.d.ts +1 -1
  139. package/dist/types/src/plugin-operation/history/capability.d.ts.map +1 -1
  140. package/dist/types/src/plugin-operation/history/errors.d.ts +30 -3
  141. package/dist/types/src/plugin-operation/history/errors.d.ts.map +1 -1
  142. package/dist/types/src/plugin-operation/history/history-tracker.d.ts +1 -1
  143. package/dist/types/src/plugin-operation/history/history-tracker.d.ts.map +1 -1
  144. package/dist/types/src/plugin-operation/history/types.d.ts +1 -1
  145. package/dist/types/src/plugin-operation/history/types.d.ts.map +1 -1
  146. package/dist/types/src/plugin-operation/history/undo-mapping.d.ts +1 -1
  147. package/dist/types/src/plugin-operation/history/undo-mapping.d.ts.map +1 -1
  148. package/dist/types/src/plugin-operation/history/undo-registry.d.ts +1 -1
  149. package/dist/types/src/plugin-operation/history/undo-registry.d.ts.map +1 -1
  150. package/dist/types/src/plugin-operation/invoker-capability.d.ts +1 -1
  151. package/dist/types/src/plugin-operation/invoker-capability.d.ts.map +1 -1
  152. package/dist/types/src/plugin-operation/meta.d.ts.map +1 -1
  153. package/dist/types/src/plugin-operation/testing.d.ts +27 -77
  154. package/dist/types/src/plugin-operation/testing.d.ts.map +1 -1
  155. package/dist/types/src/plugin-runtime/RuntimePlugin.d.ts.map +1 -1
  156. package/dist/types/src/plugin-runtime/capability.d.ts +1 -1
  157. package/dist/types/src/plugin-runtime/capability.d.ts.map +1 -1
  158. package/dist/types/src/plugin-runtime/meta.d.ts.map +1 -1
  159. package/dist/types/src/testing/harness.d.ts +67 -0
  160. package/dist/types/src/testing/harness.d.ts.map +1 -0
  161. package/dist/types/src/testing/index.d.ts +1 -0
  162. package/dist/types/src/testing/index.d.ts.map +1 -1
  163. package/dist/types/src/testing/react.d.ts +27 -0
  164. package/dist/types/src/testing/react.d.ts.map +1 -0
  165. package/dist/types/src/testing/react.test.d.ts +2 -0
  166. package/dist/types/src/testing/react.test.d.ts.map +1 -0
  167. package/dist/types/src/testing/service.d.ts.map +1 -1
  168. package/dist/types/src/testing/withPluginManager.d.ts.map +1 -1
  169. package/dist/types/src/testing/withPluginManager.stories.d.ts.map +1 -1
  170. package/dist/types/src/ui/components/{App.d.ts → App/App.d.ts} +3 -2
  171. package/dist/types/src/ui/components/App/App.d.ts.map +1 -0
  172. package/dist/types/src/ui/components/{App.stories.d.ts → App/App.stories.d.ts} +6 -1
  173. package/dist/types/src/ui/components/App/App.stories.d.ts.map +1 -0
  174. package/dist/types/src/ui/components/App/index.d.ts +2 -0
  175. package/dist/types/src/ui/components/App/index.d.ts.map +1 -0
  176. package/dist/types/src/ui/components/Placeholder/Placeholder.d.ts +64 -0
  177. package/dist/types/src/ui/components/Placeholder/Placeholder.d.ts.map +1 -0
  178. package/dist/types/src/ui/components/Placeholder/Placeholder.stories.d.ts +19 -0
  179. package/dist/types/src/ui/components/Placeholder/Placeholder.stories.d.ts.map +1 -0
  180. package/dist/types/src/ui/components/Placeholder/index.d.ts +2 -0
  181. package/dist/types/src/ui/components/Placeholder/index.d.ts.map +1 -0
  182. package/dist/types/src/ui/components/PluginManager/PluginManagerContext.stories.d.ts.map +1 -0
  183. package/dist/types/src/ui/components/{PluginManagerProvider.d.ts → PluginManager/PluginManagerProvider.d.ts} +1 -1
  184. package/dist/types/src/ui/components/PluginManager/PluginManagerProvider.d.ts.map +1 -0
  185. package/dist/types/src/ui/components/PluginManager/index.d.ts +2 -0
  186. package/dist/types/src/ui/components/PluginManager/index.d.ts.map +1 -0
  187. package/dist/types/src/ui/components/Surface/SurfaceComponent.d.ts +24 -0
  188. package/dist/types/src/ui/components/Surface/SurfaceComponent.d.ts.map +1 -0
  189. package/dist/types/src/ui/components/Surface/SurfaceComponent.stories.d.ts.map +1 -0
  190. package/dist/types/src/ui/components/{surface → Surface}/SurfaceInfo.d.ts.map +1 -1
  191. package/dist/types/src/ui/components/Surface/SurfaceProfilerContext.d.ts +48 -0
  192. package/dist/types/src/ui/components/Surface/SurfaceProfilerContext.d.ts.map +1 -0
  193. package/dist/types/src/ui/components/{surface → Surface}/context.d.ts.map +1 -1
  194. package/dist/types/src/ui/components/Surface/index.d.ts +36 -0
  195. package/dist/types/src/ui/components/Surface/index.d.ts.map +1 -0
  196. package/dist/types/src/ui/components/Surface/types.d.ts +197 -0
  197. package/dist/types/src/ui/components/Surface/types.d.ts.map +1 -0
  198. package/dist/types/src/ui/components/Surface/types.test.d.ts +2 -0
  199. package/dist/types/src/ui/components/Surface/types.test.d.ts.map +1 -0
  200. package/dist/types/src/ui/components/index.d.ts +3 -3
  201. package/dist/types/src/ui/components/index.d.ts.map +1 -1
  202. package/dist/types/src/ui/hooks/index.d.ts +0 -1
  203. package/dist/types/src/ui/hooks/index.d.ts.map +1 -1
  204. package/dist/types/src/ui/hooks/useApp.d.ts +47 -8
  205. package/dist/types/src/ui/hooks/useApp.d.ts.map +1 -1
  206. package/dist/types/src/ui/hooks/useApp.test.d.ts +2 -0
  207. package/dist/types/src/ui/hooks/useApp.test.d.ts.map +1 -0
  208. package/dist/types/src/ui/hooks/useCapabilities.d.ts.map +1 -1
  209. package/dist/types/src/ui/hooks/useLoading.d.ts.map +1 -1
  210. package/dist/types/src/ui/hooks/useSettingsState.d.ts.map +1 -1
  211. package/dist/types/src/ui/hooks/useSurface.d.ts +2 -2
  212. package/dist/types/src/ui/hooks/useSurface.d.ts.map +1 -1
  213. package/dist/types/src/ui/index.d.ts +0 -1
  214. package/dist/types/src/ui/index.d.ts.map +1 -1
  215. package/dist/types/src/vite-plugin/boot-loader/BootLoader.stories.d.ts +34 -0
  216. package/dist/types/src/vite-plugin/boot-loader/BootLoader.stories.d.ts.map +1 -0
  217. package/dist/types/src/vite-plugin/boot-loader/index.d.ts +2 -0
  218. package/dist/types/src/vite-plugin/boot-loader/index.d.ts.map +1 -0
  219. package/dist/types/src/vite-plugin/boot-loader/loader.d.ts +51 -0
  220. package/dist/types/src/vite-plugin/boot-loader/loader.d.ts.map +1 -0
  221. package/dist/types/src/vite-plugin/composer/index.d.ts +34 -0
  222. package/dist/types/src/vite-plugin/composer/index.d.ts.map +1 -0
  223. package/dist/types/src/vite-plugin/import-map/index.d.ts +28 -0
  224. package/dist/types/src/vite-plugin/import-map/index.d.ts.map +1 -0
  225. package/dist/types/src/vite-plugin/index.d.ts +5 -0
  226. package/dist/types/src/vite-plugin/index.d.ts.map +1 -0
  227. package/dist/types/src/vite-plugin/manifest.d.ts +41 -0
  228. package/dist/types/src/vite-plugin/manifest.d.ts.map +1 -0
  229. package/dist/types/src/vite-plugin/manifest.test.d.ts +2 -0
  230. package/dist/types/src/vite-plugin/manifest.test.d.ts.map +1 -0
  231. package/dist/types/src/vite-plugin/packages.d.ts +13 -0
  232. package/dist/types/src/vite-plugin/packages.d.ts.map +1 -0
  233. package/dist/types/tsconfig.tsbuildinfo +1 -1
  234. package/moon.yml +16 -4
  235. package/package.json +58 -62
  236. package/src/cli/cli.ts +3 -3
  237. package/src/common/activation-events.ts +6 -6
  238. package/src/common/annotations.ts +3 -0
  239. package/src/common/capabilities.ts +18 -23
  240. package/src/common/operations.ts +7 -10
  241. package/src/context.ts +1 -1
  242. package/src/core/activation-event.ts +5 -2
  243. package/src/core/capability-manager.test.ts +1 -1
  244. package/src/core/capability-manager.ts +22 -1
  245. package/src/core/capability.ts +21 -10
  246. package/src/core/edge-registry-plugin-provider.ts +92 -0
  247. package/src/core/index.ts +6 -0
  248. package/src/core/plugin-asset-cache.ts +60 -0
  249. package/src/core/plugin-manager.test.ts +855 -29
  250. package/src/core/plugin-manager.ts +818 -179
  251. package/src/core/plugin-manifest.test.ts +75 -0
  252. package/src/core/plugin-manifest.ts +134 -0
  253. package/src/core/plugin.ts +145 -12
  254. package/src/core/registry.ts +157 -0
  255. package/src/core/url-loader.test.ts +221 -0
  256. package/src/core/url-loader.ts +388 -0
  257. package/src/plugin-operation/OperationPlugin.ts +2 -3
  258. package/src/plugin-operation/history/capability.ts +1 -2
  259. package/src/plugin-operation/history/errors.ts +2 -6
  260. package/src/plugin-operation/history/history-tracker.test.ts +37 -43
  261. package/src/plugin-operation/history/history-tracker.ts +1 -2
  262. package/src/plugin-operation/history/types.ts +1 -1
  263. package/src/plugin-operation/history/undo-mapping.ts +1 -1
  264. package/src/plugin-operation/history/undo-registry.test.ts +3 -4
  265. package/src/plugin-operation/history/undo-registry.ts +1 -1
  266. package/src/plugin-operation/invoker-capability.ts +19 -4
  267. package/src/plugin-operation/meta.ts +2 -1
  268. package/src/plugin-operation/testing.ts +26 -45
  269. package/src/plugin-runtime/RuntimePlugin.ts +2 -3
  270. package/src/plugin-runtime/meta.ts +2 -1
  271. package/src/testing/harness.ts +229 -0
  272. package/src/testing/index.ts +1 -0
  273. package/src/testing/react.test.tsx +48 -0
  274. package/src/testing/react.tsx +113 -0
  275. package/src/testing/service.ts +3 -3
  276. package/src/testing/withPluginManager.stories.tsx +1 -2
  277. package/src/testing/withPluginManager.tsx +40 -15
  278. package/src/ui/components/App/App.stories.tsx +88 -0
  279. package/src/ui/components/App/App.tsx +81 -0
  280. package/src/ui/components/App/index.ts +5 -0
  281. package/src/ui/components/Placeholder/Placeholder.stories.tsx +77 -0
  282. package/src/ui/components/Placeholder/Placeholder.tsx +155 -0
  283. package/src/ui/components/Placeholder/index.ts +5 -0
  284. package/src/ui/components/{PluginManagerContext.stories.tsx → PluginManager/PluginManagerContext.stories.tsx} +15 -13
  285. package/src/ui/components/{PluginManagerProvider.ts → PluginManager/PluginManagerProvider.ts} +1 -1
  286. package/src/ui/components/PluginManager/index.ts +5 -0
  287. package/src/ui/components/{surface → Surface}/SurfaceComponent.stories.tsx +25 -23
  288. package/src/ui/components/Surface/SurfaceComponent.tsx +303 -0
  289. package/src/ui/components/{surface → Surface}/SurfaceInfo.tsx +1 -2
  290. package/src/ui/components/Surface/SurfaceProfilerContext.tsx +207 -0
  291. package/src/ui/components/Surface/index.ts +54 -0
  292. package/src/ui/components/Surface/types.test.ts +126 -0
  293. package/src/ui/components/Surface/types.ts +269 -0
  294. package/src/ui/components/index.ts +3 -3
  295. package/src/ui/hooks/index.ts +0 -1
  296. package/src/ui/hooks/useApp.test.tsx +159 -0
  297. package/src/ui/hooks/useApp.tsx +233 -24
  298. package/src/ui/hooks/useCapabilities.ts +1 -1
  299. package/src/ui/hooks/useLoading.tsx +14 -6
  300. package/src/ui/hooks/useSurface.ts +3 -3
  301. package/src/ui/index.ts +0 -1
  302. package/src/vite-plugin/boot-loader/BootLoader.stories.tsx +270 -0
  303. package/src/vite-plugin/boot-loader/boot-loader.css +320 -0
  304. package/src/vite-plugin/boot-loader/boot-loader.js +325 -0
  305. package/src/vite-plugin/boot-loader/index.ts +5 -0
  306. package/src/vite-plugin/boot-loader/loader.ts +123 -0
  307. package/src/vite-plugin/composer/index.ts +306 -0
  308. package/src/vite-plugin/import-map/index.ts +527 -0
  309. package/src/vite-plugin/index.ts +10 -0
  310. package/src/vite-plugin/manifest.test.ts +46 -0
  311. package/src/vite-plugin/manifest.ts +57 -0
  312. package/src/vite-plugin/packages.ts +187 -0
  313. package/tsconfig.json +22 -1
  314. package/tsconfig.node.json +2 -4
  315. package/typedoc.json +2 -4
  316. package/vitest.config.ts +1 -1
  317. package/.swc/plugins/linux_x86_64_19.0.0/727453fb3a62f7f1d952a41e051ca8a6f88cadc45cee43c6a4d1aa45f9b75665.wasmer-v7 +0 -0
  318. package/dist/lib/browser/capability-DU35RXMD.mjs.map +0 -7
  319. package/dist/lib/browser/chunk-EIFGKQSA.mjs.map +0 -7
  320. package/dist/lib/browser/chunk-FHQTHCX7.mjs +0 -8
  321. package/dist/lib/browser/chunk-IGRQWMWW.mjs.map +0 -7
  322. package/dist/lib/browser/chunk-KWP6PKIU.mjs.map +0 -7
  323. package/dist/lib/browser/chunk-NPUEVX42.mjs +0 -34
  324. package/dist/lib/browser/chunk-NPUEVX42.mjs.map +0 -7
  325. package/dist/lib/browser/chunk-PKQT6C53.mjs.map +0 -7
  326. package/dist/lib/browser/chunk-WGWEEBUV.mjs +0 -807
  327. package/dist/lib/browser/chunk-WGWEEBUV.mjs.map +0 -7
  328. package/dist/lib/browser/chunk-YAFEA4GV.mjs +0 -1
  329. package/dist/lib/browser/chunk-YZQ6NFG4.mjs +0 -781
  330. package/dist/lib/browser/chunk-YZQ6NFG4.mjs.map +0 -7
  331. package/dist/lib/browser/chunk-ZQO3UZ4R.mjs.map +0 -7
  332. package/dist/lib/browser/invoker-capability-7QW56NOM.mjs.map +0 -7
  333. package/dist/lib/node-esm/capability-SR2EIZFP.mjs.map +0 -7
  334. package/dist/lib/node-esm/chunk-64IMLAS2.mjs.map +0 -7
  335. package/dist/lib/node-esm/chunk-7OWSHPYK.mjs.map +0 -7
  336. package/dist/lib/node-esm/chunk-DHSHRYIB.mjs.map +0 -7
  337. package/dist/lib/node-esm/chunk-DZ2XLAGI.mjs.map +0 -7
  338. package/dist/lib/node-esm/chunk-JAZVHID3.mjs +0 -35
  339. package/dist/lib/node-esm/chunk-JAZVHID3.mjs.map +0 -7
  340. package/dist/lib/node-esm/chunk-OQYHRZYF.mjs.map +0 -7
  341. package/dist/lib/node-esm/chunk-VV4YHPQQ.mjs +0 -782
  342. package/dist/lib/node-esm/chunk-VV4YHPQQ.mjs.map +0 -7
  343. package/dist/lib/node-esm/chunk-XHAKT6UD.mjs +0 -808
  344. package/dist/lib/node-esm/chunk-XHAKT6UD.mjs.map +0 -7
  345. package/dist/lib/node-esm/chunk-Z4TJPSMP.mjs +0 -2
  346. package/dist/lib/node-esm/invoker-capability-CK4AMF2R.mjs.map +0 -7
  347. package/dist/types/src/ui/components/App.d.ts.map +0 -1
  348. package/dist/types/src/ui/components/App.stories.d.ts.map +0 -1
  349. package/dist/types/src/ui/components/DefaultFallback.d.ts +0 -8
  350. package/dist/types/src/ui/components/DefaultFallback.d.ts.map +0 -1
  351. package/dist/types/src/ui/components/ErrorBoundary.d.ts +0 -30
  352. package/dist/types/src/ui/components/ErrorBoundary.d.ts.map +0 -1
  353. package/dist/types/src/ui/components/PluginManagerContext.stories.d.ts.map +0 -1
  354. package/dist/types/src/ui/components/PluginManagerProvider.d.ts.map +0 -1
  355. package/dist/types/src/ui/components/surface/SurfaceComponent.d.ts +0 -12
  356. package/dist/types/src/ui/components/surface/SurfaceComponent.d.ts.map +0 -1
  357. package/dist/types/src/ui/components/surface/SurfaceComponent.stories.d.ts.map +0 -1
  358. package/dist/types/src/ui/components/surface/index.d.ts +0 -5
  359. package/dist/types/src/ui/components/surface/index.d.ts.map +0 -1
  360. package/dist/types/src/ui/components/surface/types.d.ts +0 -94
  361. package/dist/types/src/ui/components/surface/types.d.ts.map +0 -1
  362. package/dist/types/src/ui/hooks/useOperationResolver.d.ts +0 -19
  363. package/dist/types/src/ui/hooks/useOperationResolver.d.ts.map +0 -1
  364. package/src/ui/components/App.stories.tsx +0 -62
  365. package/src/ui/components/App.tsx +0 -57
  366. package/src/ui/components/DefaultFallback.tsx +0 -26
  367. package/src/ui/components/ErrorBoundary.tsx +0 -56
  368. package/src/ui/components/surface/SurfaceComponent.tsx +0 -262
  369. package/src/ui/components/surface/index.ts +0 -8
  370. package/src/ui/components/surface/types.ts +0 -119
  371. package/src/ui/hooks/useOperationResolver.ts +0 -40
  372. /package/dist/lib/{node-esm/capability-OSVYGK4X.mjs.map → browser/capability-LUKGKUQH.mjs.map} +0 -0
  373. /package/dist/lib/browser/{chunk-YAFEA4GV.mjs.map → core/url-loader.mjs.map} +0 -0
  374. /package/dist/lib/node-esm/{chunk-Z4TJPSMP.mjs.map → core/url-loader.mjs.map} +0 -0
  375. /package/dist/types/src/ui/components/{PluginManagerContext.stories.d.ts → PluginManager/PluginManagerContext.stories.d.ts} +0 -0
  376. /package/dist/types/src/ui/components/{surface → Surface}/SurfaceComponent.stories.d.ts +0 -0
  377. /package/dist/types/src/ui/components/{surface → Surface}/SurfaceInfo.d.ts +0 -0
  378. /package/dist/types/src/ui/components/{surface → Surface}/context.d.ts +0 -0
  379. /package/src/ui/components/{surface → Surface}/context.ts +0 -0
@@ -12,22 +12,63 @@ import React, { type FC, useCallback, useEffect, useMemo, useRef, useState } fro
12
12
  import { runAndForwardErrors } from '@dxos/effect';
13
13
  import { invariant } from '@dxos/invariant';
14
14
  import { log } from '@dxos/log';
15
+ import { ErrorBoundary, ErrorFallback, type FallbackProps } from '@dxos/react-error-boundary';
15
16
  import { useAsyncEffect, useDefaultValue } from '@dxos/react-hooks';
16
17
  import { ContextProtocolProvider } from '@dxos/web-context-react';
17
18
 
18
19
  import { ActivationEvents, Capabilities } from '../../common';
19
20
  import { PluginManagerContext } from '../../context';
20
21
  import { type ActivationEvent, type Plugin, PluginManager } from '../../core';
21
- import { App } from '../components/App';
22
- import { DefaultFallback } from '../components/DefaultFallback';
23
- import { ErrorBoundary } from '../components/ErrorBoundary';
24
- import { PluginManagerProvider } from '../components/PluginManagerProvider';
22
+ import { App, PluginManagerProvider } from '../components';
25
23
 
26
- const ENABLED_KEY = 'dxos.org/app-framework/enabled';
24
+ const ENABLED_KEY = 'org.dxos.app-framework.enabled';
25
+
26
+ export type StartupProgress = {
27
+ /** Number of modules that have been activated. */
28
+ activated: number;
29
+ /** Total number of modules registered. */
30
+ total: number;
31
+ /** Fractional progress (0-1). */
32
+ progress: number;
33
+ /**
34
+ * Raw activation event key (e.g. `org.dxos.app-framework.event.startup`).
35
+ * Set on event-level transitions, *and* on module-level transitions where
36
+ * it carries the parent activation event that first triggered the
37
+ * module's load (plumbed through `_loadCapabilitiesForModules` →
38
+ * `_loadModule`). Consumers can use this either as the primary id (when
39
+ * {@link module} is absent) or as an extra "context" field alongside
40
+ * {@link module}.
41
+ */
42
+ event?: string;
43
+ /**
44
+ * Raw module id (e.g. `org.dxos.plugin.observability.module.ReactSurface`)
45
+ * when the in-flight activation is module-level. When present,
46
+ * {@link event} may also be set, identifying the parent activation that
47
+ * triggered this module's load.
48
+ */
49
+ module?: string;
50
+ /**
51
+ * Pre-humanized label for the currently surfaced transition (module
52
+ * label if {@link module} is set, otherwise the event label), supplied
53
+ * for consumers that want a sensible default. Hosts that prefer to
54
+ * render their own label can read the raw {@link event}/{@link module}
55
+ * fields and ignore this — the framework leaves the policy choice
56
+ * (which transitions to surface, how to format them, whether to drop
57
+ * sub-modules entirely) to the host's `Placeholder`.
58
+ */
59
+ humanizedName?: string;
60
+ };
61
+
62
+ export type PlaceholderProps = {
63
+ stage?: number;
64
+ progress?: StartupProgress;
65
+ };
27
66
 
28
67
  export type UseAppOptions = {
29
68
  pluginManager?: PluginManager.PluginManager;
30
69
  pluginLoader?: PluginManager.ManagerOptions['pluginLoader'];
70
+ onPluginRemove?: PluginManager.ManagerOptions['onRemove'];
71
+ pluginRegistryProvider?: PluginManager.ManagerOptions['pluginRegistryProvider'];
31
72
  plugins?: Plugin.Plugin[];
32
73
  core?: string[];
33
74
  defaults?: string[];
@@ -36,12 +77,12 @@ export type UseAppOptions = {
36
77
  * These are fired alongside SetupReactSurface before the Startup event.
37
78
  */
38
79
  setupEvents?: ActivationEvent.ActivationEvent[];
39
- placeholder?: FC<{ stage: number }>;
40
- fallback?: ErrorBoundary['props']['fallback'];
41
80
  cacheEnabled?: boolean;
42
81
  safeMode?: boolean;
43
82
  debounce?: number;
44
83
  timeout?: number;
84
+ fallback?: FC<FallbackProps>;
85
+ placeholder?: FC<PlaceholderProps>;
45
86
  };
46
87
 
47
88
  /**
@@ -64,20 +105,22 @@ export type UseAppOptions = {
64
105
  * @param params.plugins All plugins available to the application.
65
106
  * @param params.core Core plugins which will always be enabled.
66
107
  * @param params.defaults Default plugins are enabled by default but can be disabled by the user.
67
- * @param params.placeholder Placeholder component to render during startup.
68
- * @param params.fallback Fallback component to render if an error occurs during startup.
69
108
  * @param params.cacheEnabled Whether to cache enabled plugins in localStorage.
70
109
  * @param params.safeMode Whether to enable safe mode, which disables optional plugins.
110
+ * @param params.fallback Fallback component to render if an error occurs during startup.
111
+ * @param params.placeholder Placeholder component to render during startup.
71
112
  */
72
113
  export const useApp = ({
73
114
  pluginManager,
74
115
  pluginLoader: pluginLoaderProp,
116
+ onPluginRemove,
117
+ pluginRegistryProvider,
75
118
  plugins: pluginsProp,
76
119
  core: coreProp,
77
120
  defaults: defaultsProp,
78
121
  setupEvents: setupEventsProp,
79
122
  placeholder,
80
- fallback = DefaultFallback,
123
+ fallback = ErrorFallback,
81
124
  cacheEnabled = false,
82
125
  safeMode = false,
83
126
  debounce = 0,
@@ -88,7 +131,6 @@ export const useApp = ({
88
131
  const defaults = useDefaultValue(defaultsProp, () => []);
89
132
  const setupEvents = useDefaultValue(setupEventsProp, () => []);
90
133
 
91
- // TODO(wittjosiah): Provide a custom plugin loader which supports loading via url.
92
134
  const pluginLoader = useMemo(
93
135
  () =>
94
136
  pluginLoaderProp ??
@@ -96,7 +138,7 @@ export const useApp = ({
96
138
  Effect.sync(() => {
97
139
  const plugin = plugins.find((plugin) => plugin.meta.id === id);
98
140
  invariant(plugin, `Plugin not found: ${id}`);
99
- return plugin;
141
+ return { plugin };
100
142
  })),
101
143
  [pluginLoaderProp, plugins],
102
144
  );
@@ -105,16 +147,32 @@ export const useApp = ({
105
147
  const [ready, setReady] = useState(false);
106
148
  const errorRef = useRef<unknown>(null);
107
149
  const [error, setError] = useState<unknown>(null);
150
+ const [startupProgress, setStartupProgress] = useState<StartupProgress>({
151
+ activated: 0,
152
+ total: 0,
153
+ progress: 0,
154
+ });
108
155
  // TODO(wittjosiah): Migrate to Atom.kvs for isomorphic storage.
109
156
  const cached: string[] = useMemo(() => JSON.parse(localStorage.getItem(ENABLED_KEY) ?? '[]'), []);
110
157
  const enabled = useMemo(
111
158
  () => (safeMode ? [] : cacheEnabled && cached.length > 0 ? cached : defaults),
112
159
  [safeMode, cacheEnabled, cached, defaults],
113
160
  );
114
- const manager = useMemo(
115
- () => pluginManager ?? PluginManager.make({ pluginLoader, plugins, core, enabled }),
116
- [pluginManager, pluginLoader, plugins, core, enabled],
117
- );
161
+ const isExternalManager = !!pluginManager;
162
+ const manager = useMemo(() => {
163
+ const mgr =
164
+ pluginManager ??
165
+ PluginManager.make({
166
+ pluginLoader,
167
+ plugins,
168
+ core,
169
+ enabled,
170
+ onRemove: onPluginRemove,
171
+ pluginRegistryProvider,
172
+ });
173
+ log('useApp: useMemo created/reused manager', { provided: !!pluginManager });
174
+ return mgr;
175
+ }, [pluginManager, pluginLoader, plugins, core, enabled, onPluginRemove, pluginRegistryProvider]);
118
176
 
119
177
  useEffect(() => {
120
178
  if (!cacheEnabled) {
@@ -130,28 +188,103 @@ export const useApp = ({
130
188
  }, [manager]);
131
189
 
132
190
  useAsyncEffect(async () => {
191
+ log('useApp: effect mount');
192
+
133
193
  manager.capabilities.contribute({
134
194
  interface: Capabilities.PluginManager,
135
195
  implementation: manager,
136
- module: 'dxos.org/app-framework/plugin-manager',
196
+ module: 'org.dxos.app-framework.plugin-manager',
137
197
  });
138
198
 
139
199
  manager.capabilities.contribute({
140
200
  interface: Capabilities.AtomRegistry,
141
201
  implementation: manager.registry,
142
- module: 'dxos.org/app-framework/atom-registry',
202
+ module: 'org.dxos.app-framework.atom-registry',
143
203
  });
144
204
 
145
205
  const fiber = Effect.gen(function* () {
146
206
  const queue = yield* PubSub.subscribe(manager.activation);
147
207
  const listener = yield* Effect.forkDaemon(
148
208
  Queue.take(queue).pipe(
149
- Effect.tap(({ event, state, error: error$ }) =>
209
+ Effect.tap(({ event, state, module, error: error$ }) =>
150
210
  Effect.sync(() => {
151
- if (event === ActivationEvents.Startup.id && state === 'activated') {
211
+ // Event-level Startup activated (no `module` field) fires once,
212
+ // after every module triggered by Startup has finished. Module
213
+ // activations now also carry their parent event id (so the trace
214
+ // can attribute a module to its triggering event), which means
215
+ // each module activated under Startup publishes
216
+ // `{ event: 'startup', state: 'activated', module: <id> }`. Without
217
+ // the `!module` guard the listener would mark the app ready on
218
+ // the *first* such module rather than waiting for the event-level
219
+ // completion — leaving downstream capabilities (operation-invoker,
220
+ // app-graph, …) un-registered when the placeholder dismisses.
221
+ if (event === ActivationEvents.Startup.id && state === 'activated' && !module) {
152
222
  clearTimeout(timeoutId);
153
223
  setReady(true);
154
224
  readyRef.current = true;
225
+ // Trigger startup profiler dump if available.
226
+ (globalThis as any).composer?.profiler?.dump();
227
+ // Notify any host observability layer that startup completed.
228
+ // A `CustomEvent` keeps this generic — app-framework doesn't
229
+ // import a provider, and consumers can capture the startup
230
+ // summary without us picking one.
231
+ if (typeof window !== 'undefined') {
232
+ window.dispatchEvent(new CustomEvent('app-framework:startup-activated'));
233
+ }
234
+ return;
235
+ }
236
+ // `activating` is the start-of-load signal. Surface the raw
237
+ // `module` (or `event`) plus a pre-humanized label so the
238
+ // host placeholder can decide what to render — show
239
+ // everything, suppress noisy sub-modules, group by plugin,
240
+ // or apply its own formatting. We intentionally do NOT touch
241
+ // these fields on `activated`: pairing the two would cause
242
+ // back-to-back identical updates to the host's effect, which
243
+ // the boot loader treats as a re-trigger because
244
+ // `progress.progress` moved. Leaving the label alone on
245
+ // completion keeps it accurate ("now activating X") until
246
+ // the next module starts.
247
+ if (module && state === 'activating' && !readyRef.current) {
248
+ setStartupProgress((current) => ({
249
+ ...current,
250
+ // `event` here is the activation event that first
251
+ // triggered this module load (plumbed through
252
+ // `_loadCapabilitiesForModules` → `_loadModule`).
253
+ // Falsy/empty falls back to undefined so consumers can
254
+ // tell "no parent context" from "parent context: <X>".
255
+ event: event || undefined,
256
+ module,
257
+ humanizedName: humanizeModuleId(module),
258
+ }));
259
+ }
260
+ // Update the activation count when a module commits. The
261
+ // ring's fraction comes from this; `event`/`module`/
262
+ // `humanizedName` were set by the matching `activating`
263
+ // message above and are left alone so the count can advance
264
+ // without re-firing the host's status callback.
265
+ if (module && state === 'activated' && !readyRef.current) {
266
+ const active = manager.getActive();
267
+ const total = manager.getModules().length;
268
+ setStartupProgress((current) => ({
269
+ ...current,
270
+ activated: active.length,
271
+ total,
272
+ progress: total > 0 ? active.length / total : 0,
273
+ }));
274
+ }
275
+ // Event-level `activating` (no `module`) — fired at the start
276
+ // of `_activateModulesForEvent` and recursively for each
277
+ // before/after event. Surfaces a label during the gap before
278
+ // the first module-level message lands; subsequent module
279
+ // updates immediately overwrite this with a more specific
280
+ // label.
281
+ if (event && !module && state === 'activating' && !readyRef.current) {
282
+ setStartupProgress((current) => ({
283
+ ...current,
284
+ event,
285
+ module: undefined,
286
+ humanizedName: humanizeEventKey(event),
287
+ }));
155
288
  }
156
289
  if (error$ && !readyRef.current) {
157
290
  setError(error$);
@@ -186,20 +319,31 @@ export const useApp = ({
186
319
  }, timeout);
187
320
 
188
321
  return () => {
322
+ log('useApp: effect cleanup');
189
323
  clearTimeout(timeoutId);
190
324
  void runAndForwardErrors(Fiber.interrupt(fiber));
191
- manager.capabilities.remove(Capabilities.PluginManager, manager);
192
- manager.capabilities.remove(Capabilities.AtomRegistry, manager.registry);
325
+ if (!isExternalManager) {
326
+ void runAndForwardErrors(manager.shutdown());
327
+ }
193
328
  };
194
329
  }, [manager]);
195
330
 
331
+ const progressRef = useRef(startupProgress);
332
+ progressRef.current = startupProgress;
333
+
196
334
  return useCallback(
197
335
  () => (
198
- <ErrorBoundary fallback={fallback}>
336
+ <ErrorBoundary name='app' FallbackComponent={fallback}>
199
337
  <PluginManagerProvider value={manager}>
200
338
  <ContextProtocolProvider value={manager} context={PluginManagerContext}>
201
339
  <RegistryContext.Provider value={manager.registry}>
202
- <App placeholder={placeholder} ready={ready} error={error} debounce={debounce} />
340
+ <App
341
+ placeholder={placeholder}
342
+ ready={ready}
343
+ error={error}
344
+ debounce={debounce}
345
+ progress={progressRef.current}
346
+ />
203
347
  </RegistryContext.Provider>
204
348
  </ContextProtocolProvider>
205
349
  </PluginManagerProvider>
@@ -213,3 +357,68 @@ const setupDevtools = (manager: PluginManager.PluginManager) => {
213
357
  (globalThis as any).composer ??= {};
214
358
  (globalThis as any).composer.manager = manager;
215
359
  };
360
+
361
+ /**
362
+ * Extracts a human-readable label from a module ID.
363
+ *
364
+ * Module IDs follow `org.dxos.plugin.<plugin-slug>.module.<module-name>`,
365
+ * where `<plugin-slug>` is kebab-case and `<module-name>` is either an
366
+ * explicit string (often kebab-case, e.g. `'observability'`, `'namespace'`)
367
+ * or a capability tag in PascalCase from `Capability.getModuleTag(...)`
368
+ * (e.g. `'ReactSurface'`, `'AppGraphBuilder'`). The output is
369
+ * `"Title Case Plugin: kebab-module"` so the visible status names both the
370
+ * plugin and the aspect being activated, helping disambiguate the multiple
371
+ * modules a plugin contributes.
372
+ *
373
+ * Examples:
374
+ * - "org.dxos.plugin.markdown.module.ReactSurface" → "Markdown: react-surface"
375
+ * - "org.dxos.plugin.observability.module.AppGraphBuilder" → "Observability: app-graph-builder"
376
+ * - "org.dxos.plugin.observability.module.observability" → "Observability"
377
+ * (the module name matches the plugin slug — collapsed to avoid
378
+ * "Observability: observability" noise.)
379
+ */
380
+ const humanizeModuleId = (moduleId: string): string => {
381
+ const match = moduleId.match(/\.plugin\.([^.]+)\.module\.(.+)$/);
382
+ if (!match) {
383
+ // Fallback: use the last segment.
384
+ const parts = moduleId.split('.');
385
+ return parts[parts.length - 1];
386
+ }
387
+ const [, pluginSlug, moduleName] = match;
388
+ const pluginLabel = pluginSlug
389
+ .split('-')
390
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
391
+ .join(' ');
392
+ // Normalise the module name to kebab-case so PascalCase capability tags
393
+ // ("ReactSurface") read consistently with explicit kebab IDs
394
+ // ("operation-handler"). The two-step substitution handles consecutive
395
+ // uppercase runs (`URLLoader` → `url-loader`) without splitting them
396
+ // mid-acronym.
397
+ const moduleLabel = moduleName
398
+ .replace(/([a-z0-9])([A-Z])/g, '$1-$2')
399
+ .replace(/([A-Z]+)([A-Z][a-z])/g, '$1-$2')
400
+ .toLowerCase();
401
+ // Capability modules whose name matches the plugin slug (e.g. the
402
+ // observability plugin's `observability` capability module) would render
403
+ // as "Observability: observability" — drop the redundant suffix.
404
+ if (moduleLabel === pluginSlug) {
405
+ return pluginLabel;
406
+ }
407
+ return `${pluginLabel}: ${moduleLabel}`;
408
+ };
409
+
410
+ /**
411
+ * Extracts a human-readable label from an activation event key.
412
+ * E.g., "org.dxos.app-framework.event.setup-react-surface" → "Setup React Surface".
413
+ */
414
+ const humanizeEventKey = (eventKey: string): string => {
415
+ // Strip a leading specifier (composite key form: "<id>:<specifier>").
416
+ const id = eventKey.split(':')[0];
417
+ // Match the trailing segment after `.event.`.
418
+ const match = id.match(/\.event\.(.+)$/);
419
+ const slug = match ? match[1] : (id.split('.').pop() ?? id);
420
+ return slug
421
+ .split('-')
422
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
423
+ .join(' ');
424
+ };
@@ -9,7 +9,7 @@ import { invariant } from '@dxos/invariant';
9
9
 
10
10
  import { Capabilities } from '../../common';
11
11
  import { type Capability } from '../../core';
12
- import { usePluginManager } from '../components/PluginManagerProvider';
12
+ import { usePluginManager } from '../components';
13
13
 
14
14
  /**
15
15
  * Hook to request capabilities from the plugin context.
@@ -2,7 +2,7 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { useEffect, useState } from 'react';
5
+ import { useEffect, useRef, useState } from 'react';
6
6
 
7
7
  export enum LoadingState {
8
8
  Loading = 0,
@@ -23,6 +23,14 @@ export enum LoadingState {
23
23
  */
24
24
  export const useLoading = (ready: boolean, debounce = 0) => {
25
25
  const [stage, setStage] = useState<LoadingState>(LoadingState.Loading);
26
+ // Mirror `ready` into a ref so the interval's `setStage` callback can read
27
+ // the latest value without depending on the effect re-running. The pure
28
+ // closure-capture pattern (with `ready` in deps) sticks the FSM at
29
+ // `FadeIn` whenever HMR doesn't propagate the dep change end-to-end —
30
+ // a ref sidesteps that entirely and fires the read on every tick.
31
+ const readyRef = useRef(ready);
32
+ readyRef.current = ready;
33
+
26
34
  useEffect(() => {
27
35
  if (!debounce) {
28
36
  return;
@@ -30,18 +38,18 @@ export const useLoading = (ready: boolean, debounce = 0) => {
30
38
 
31
39
  const i = setInterval(() => {
32
40
  setStage((stage) => {
41
+ const isReady = readyRef.current;
33
42
  switch (stage) {
34
43
  case LoadingState.Loading: {
35
- if (!ready) {
44
+ if (!isReady) {
36
45
  return LoadingState.FadeIn;
37
- } else {
38
- clearInterval(i);
39
- return LoadingState.Done;
40
46
  }
47
+ clearInterval(i);
48
+ return LoadingState.Done;
41
49
  }
42
50
 
43
51
  case LoadingState.FadeIn: {
44
- if (ready) {
52
+ if (isReady) {
45
53
  return LoadingState.FadeOut;
46
54
  }
47
55
  break;
@@ -6,8 +6,8 @@ import { useContext } from 'react';
6
6
 
7
7
  import { raise } from '@dxos/debug';
8
8
 
9
- import { SurfaceContext } from '../components/surface/context';
9
+ import { Surface } from '../components';
10
10
 
11
- export const useSurface = (): SurfaceContext => {
12
- return useContext(SurfaceContext) ?? raise(new Error('Missing SurfaceContext'));
11
+ export const useSurface = (): Surface.Context => {
12
+ return useContext(Surface.Context) ?? raise(new Error('Missing SurfaceContext'));
13
13
  };
package/src/ui/index.ts CHANGED
@@ -4,4 +4,3 @@
4
4
 
5
5
  export * from './components';
6
6
  export * from './hooks';
7
- export * as Surface from './components/surface';