@dxos/app-framework 0.8.4-main.8360d9e660 → 0.8.4-main.8baae0fced

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 (380) hide show
  1. package/LICENSE +102 -5
  2. package/README.md +1 -1
  3. package/dist/lib/browser/{capability-5OFLR7J4.mjs → capability-K5XIVCQU.mjs} +12 -11
  4. package/dist/lib/browser/capability-K5XIVCQU.mjs.map +7 -0
  5. package/dist/lib/browser/{chunk-WEBSGU5L.mjs → chunk-5AHASNDW.mjs} +20 -5
  6. package/dist/lib/browser/chunk-5AHASNDW.mjs.map +7 -0
  7. package/dist/lib/browser/chunk-5GY3YOEL.mjs +28 -0
  8. package/dist/lib/browser/chunk-5GY3YOEL.mjs.map +7 -0
  9. package/dist/lib/browser/{chunk-272IPLHQ.mjs → chunk-66IXTIVK.mjs} +3 -2
  10. package/dist/lib/browser/chunk-66IXTIVK.mjs.map +7 -0
  11. package/dist/lib/browser/{chunk-JGWCBVKJ.mjs → chunk-BRK6GYNB.mjs} +14 -42
  12. package/dist/lib/browser/chunk-BRK6GYNB.mjs.map +7 -0
  13. package/dist/lib/browser/{chunk-TGX63LTL.mjs → chunk-FJ4765WW.mjs} +1 -1
  14. package/dist/lib/browser/{chunk-TGX63LTL.mjs.map → chunk-FJ4765WW.mjs.map} +2 -2
  15. package/dist/lib/browser/chunk-FO3IYSLV.mjs +68 -0
  16. package/dist/lib/browser/chunk-FO3IYSLV.mjs.map +7 -0
  17. package/dist/lib/browser/{chunk-YNFPIQGB.mjs → chunk-IW44C7UL.mjs} +9 -2
  18. package/dist/lib/browser/chunk-IW44C7UL.mjs.map +7 -0
  19. package/dist/lib/browser/{chunk-TIEBZMTF.mjs → chunk-KFDF7KR3.mjs} +9 -11
  20. package/dist/lib/browser/{chunk-TIEBZMTF.mjs.map → chunk-KFDF7KR3.mjs.map} +3 -3
  21. package/dist/lib/browser/chunk-KLHQNYJ2.mjs +422 -0
  22. package/dist/lib/browser/chunk-KLHQNYJ2.mjs.map +7 -0
  23. package/dist/lib/browser/chunk-QLML5QFJ.mjs +581 -0
  24. package/dist/lib/browser/chunk-QLML5QFJ.mjs.map +7 -0
  25. package/dist/lib/browser/{chunk-GH3M2LIW.mjs → chunk-SLX73WRZ.mjs} +85 -15
  26. package/dist/lib/browser/chunk-SLX73WRZ.mjs.map +7 -0
  27. package/dist/lib/browser/chunk-UVTGHZQF.mjs +513 -0
  28. package/dist/lib/browser/chunk-UVTGHZQF.mjs.map +7 -0
  29. package/dist/lib/browser/chunk-VJ5PFAWC.mjs +1446 -0
  30. package/dist/lib/browser/chunk-VJ5PFAWC.mjs.map +7 -0
  31. package/dist/lib/browser/cli/index.mjs +15 -30
  32. package/dist/lib/browser/cli/index.mjs.map +3 -3
  33. package/dist/lib/browser/common/activation-events.mjs +11 -14
  34. package/dist/lib/browser/common/capabilities.mjs +19 -8
  35. package/dist/lib/browser/core/activation-event.mjs +1 -1
  36. package/dist/lib/browser/core/capability.mjs +5 -1
  37. package/dist/lib/browser/core/plugin-manager.mjs +8 -4
  38. package/dist/lib/browser/core/plugin.mjs +12 -2
  39. package/dist/lib/browser/core/url-loader.mjs +24 -0
  40. package/dist/lib/browser/index.mjs +47 -49
  41. package/dist/lib/browser/index.mjs.map +4 -4
  42. package/dist/lib/browser/meta.json +1 -1
  43. package/dist/lib/browser/process-manager-capability-JIWLN7SU.mjs +89 -0
  44. package/dist/lib/browser/process-manager-capability-JIWLN7SU.mjs.map +7 -0
  45. package/dist/lib/browser/testing/index.mjs +164 -34
  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 +24 -15
  50. package/dist/lib/node-esm/{capability-CRHZKL6T.mjs → capability-RLKFFLTB.mjs} +12 -11
  51. package/dist/lib/node-esm/capability-RLKFFLTB.mjs.map +7 -0
  52. package/dist/lib/node-esm/{chunk-FKE4Z3D6.mjs → chunk-37Z53PXZ.mjs} +1 -1
  53. package/dist/lib/node-esm/{chunk-FKE4Z3D6.mjs.map → chunk-37Z53PXZ.mjs.map} +2 -2
  54. package/dist/lib/node-esm/chunk-42UNAKYO.mjs +423 -0
  55. package/dist/lib/node-esm/chunk-42UNAKYO.mjs.map +7 -0
  56. package/dist/lib/node-esm/{chunk-LHCJGNXK.mjs → chunk-6S45OMUP.mjs} +85 -15
  57. package/dist/lib/node-esm/chunk-6S45OMUP.mjs.map +7 -0
  58. package/dist/lib/node-esm/{chunk-3D66SZHP.mjs → chunk-BYHYYJZH.mjs} +14 -42
  59. package/dist/lib/node-esm/chunk-BYHYYJZH.mjs.map +7 -0
  60. package/dist/lib/node-esm/{chunk-SB5ODNPX.mjs → chunk-CTKEZHKF.mjs} +9 -2
  61. package/dist/lib/node-esm/chunk-CTKEZHKF.mjs.map +7 -0
  62. package/dist/lib/node-esm/chunk-JNT72ZCN.mjs +514 -0
  63. package/dist/lib/node-esm/chunk-JNT72ZCN.mjs.map +7 -0
  64. package/dist/lib/node-esm/chunk-KFZEB6BV.mjs +29 -0
  65. package/dist/lib/node-esm/chunk-KFZEB6BV.mjs.map +7 -0
  66. package/dist/lib/node-esm/chunk-LJNUFNDO.mjs +582 -0
  67. package/dist/lib/node-esm/chunk-LJNUFNDO.mjs.map +7 -0
  68. package/dist/lib/node-esm/{chunk-SCDGIGGU.mjs → chunk-OUEMWPIW.mjs} +9 -11
  69. package/dist/lib/node-esm/{chunk-SCDGIGGU.mjs.map → chunk-OUEMWPIW.mjs.map} +3 -3
  70. package/dist/lib/node-esm/{chunk-SQICGJBW.mjs → chunk-PW2VYGOS.mjs} +20 -5
  71. package/dist/lib/node-esm/chunk-PW2VYGOS.mjs.map +7 -0
  72. package/dist/lib/node-esm/chunk-SFYCO3PT.mjs +1447 -0
  73. package/dist/lib/node-esm/chunk-SFYCO3PT.mjs.map +7 -0
  74. package/dist/lib/node-esm/chunk-WK7OIQKI.mjs +70 -0
  75. package/dist/lib/node-esm/chunk-WK7OIQKI.mjs.map +7 -0
  76. package/dist/lib/node-esm/{chunk-6REV5DE7.mjs → chunk-XOCUANHO.mjs} +3 -2
  77. package/dist/lib/node-esm/chunk-XOCUANHO.mjs.map +7 -0
  78. package/dist/lib/node-esm/cli/index.mjs +15 -30
  79. package/dist/lib/node-esm/cli/index.mjs.map +3 -3
  80. package/dist/lib/node-esm/common/activation-events.mjs +11 -14
  81. package/dist/lib/node-esm/common/capabilities.mjs +19 -8
  82. package/dist/lib/node-esm/core/activation-event.mjs +1 -1
  83. package/dist/lib/node-esm/core/capability.mjs +5 -1
  84. package/dist/lib/node-esm/core/plugin-manager.mjs +8 -4
  85. package/dist/lib/node-esm/core/plugin.mjs +12 -2
  86. package/dist/lib/node-esm/core/url-loader.mjs +25 -0
  87. package/dist/lib/node-esm/index.mjs +47 -49
  88. package/dist/lib/node-esm/index.mjs.map +4 -4
  89. package/dist/lib/node-esm/meta.json +1 -1
  90. package/dist/lib/node-esm/process-manager-capability-PHKLO2BL.mjs +90 -0
  91. package/dist/lib/node-esm/process-manager-capability-PHKLO2BL.mjs.map +7 -0
  92. package/dist/lib/node-esm/testing/index.mjs +164 -34
  93. package/dist/lib/node-esm/testing/index.mjs.map +4 -4
  94. package/dist/lib/node-esm/testing/react.mjs +79 -0
  95. package/dist/lib/node-esm/testing/react.mjs.map +7 -0
  96. package/dist/lib/node-esm/ui/index.mjs +24 -15
  97. package/dist/plugin/node-esm/index.mjs +893 -0
  98. package/dist/plugin/node-esm/index.mjs.map +7 -0
  99. package/dist/plugin/node-esm/meta.json +1 -0
  100. package/dist/types/src/cli/cli.d.ts +1 -3
  101. package/dist/types/src/cli/cli.d.ts.map +1 -1
  102. package/dist/types/src/common/activation-events.d.ts +10 -13
  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 +113 -12
  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 +4 -4
  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 +13 -2
  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 +232 -7
  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 +176 -6
  129. package/dist/types/src/core/plugin.d.ts.map +1 -1
  130. package/dist/types/src/core/registry.d.ts +107 -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/index.d.ts +1 -2
  138. package/dist/types/src/index.d.ts.map +1 -1
  139. package/dist/types/src/plugin-process-manager/ProcessManagerPlugin.d.ts +3 -0
  140. package/dist/types/src/plugin-process-manager/ProcessManagerPlugin.d.ts.map +1 -0
  141. package/dist/types/src/plugin-process-manager/history/capability.d.ts.map +1 -0
  142. package/dist/types/src/plugin-process-manager/history/errors.d.ts +32 -0
  143. package/dist/types/src/plugin-process-manager/history/errors.d.ts.map +1 -0
  144. package/dist/types/src/{plugin-operation → plugin-process-manager}/history/history-tracker.d.ts +1 -1
  145. package/dist/types/src/plugin-process-manager/history/history-tracker.d.ts.map +1 -0
  146. package/dist/types/src/plugin-process-manager/history/history-tracker.test.d.ts.map +1 -0
  147. package/dist/types/src/plugin-process-manager/history/index.d.ts.map +1 -0
  148. package/dist/types/src/{plugin-operation → plugin-process-manager}/history/types.d.ts +1 -1
  149. package/dist/types/src/plugin-process-manager/history/types.d.ts.map +1 -0
  150. package/dist/types/src/{plugin-operation → plugin-process-manager}/history/undo-mapping.d.ts +1 -1
  151. package/dist/types/src/plugin-process-manager/history/undo-mapping.d.ts.map +1 -0
  152. package/dist/types/src/{plugin-operation → plugin-process-manager}/history/undo-registry.d.ts +1 -1
  153. package/dist/types/src/plugin-process-manager/history/undo-registry.d.ts.map +1 -0
  154. package/dist/types/src/plugin-process-manager/history/undo-registry.test.d.ts.map +1 -0
  155. package/dist/types/src/plugin-process-manager/index.d.ts +3 -0
  156. package/dist/types/src/plugin-process-manager/index.d.ts.map +1 -0
  157. package/dist/types/src/plugin-process-manager/meta.d.ts.map +1 -0
  158. package/dist/types/src/plugin-process-manager/process-manager-capability.d.ts +8 -0
  159. package/dist/types/src/plugin-process-manager/process-manager-capability.d.ts.map +1 -0
  160. package/dist/types/src/plugin-process-manager/testing.d.ts +59 -0
  161. package/dist/types/src/plugin-process-manager/testing.d.ts.map +1 -0
  162. package/dist/types/src/testing/harness.d.ts +79 -0
  163. package/dist/types/src/testing/harness.d.ts.map +1 -0
  164. package/dist/types/src/testing/index.d.ts +1 -0
  165. package/dist/types/src/testing/index.d.ts.map +1 -1
  166. package/dist/types/src/testing/react.d.ts +27 -0
  167. package/dist/types/src/testing/react.d.ts.map +1 -0
  168. package/dist/types/src/testing/react.test.d.ts +2 -0
  169. package/dist/types/src/testing/react.test.d.ts.map +1 -0
  170. package/dist/types/src/testing/service.d.ts.map +1 -1
  171. package/dist/types/src/testing/withPluginManager.d.ts.map +1 -1
  172. package/dist/types/src/testing/withPluginManager.stories.d.ts.map +1 -1
  173. package/dist/types/src/ui/components/App/App.d.ts +3 -2
  174. package/dist/types/src/ui/components/App/App.d.ts.map +1 -1
  175. package/dist/types/src/ui/components/App/App.stories.d.ts +2 -2
  176. package/dist/types/src/ui/components/App/App.stories.d.ts.map +1 -1
  177. package/dist/types/src/ui/components/Placeholder/Placeholder.d.ts +64 -0
  178. package/dist/types/src/ui/components/Placeholder/Placeholder.d.ts.map +1 -0
  179. package/dist/types/src/ui/components/Placeholder/Placeholder.stories.d.ts +19 -0
  180. package/dist/types/src/ui/components/Placeholder/Placeholder.stories.d.ts.map +1 -0
  181. package/dist/types/src/ui/components/Placeholder/index.d.ts +2 -0
  182. package/dist/types/src/ui/components/Placeholder/index.d.ts.map +1 -0
  183. package/dist/types/src/ui/components/PluginManager/PluginManagerContext.stories.d.ts.map +1 -1
  184. package/dist/types/src/ui/components/Surface/SurfaceComponent.d.ts +16 -4
  185. package/dist/types/src/ui/components/Surface/SurfaceComponent.d.ts.map +1 -1
  186. package/dist/types/src/ui/components/Surface/SurfaceComponent.stories.d.ts.map +1 -1
  187. package/dist/types/src/ui/components/Surface/SurfaceInfo.d.ts.map +1 -1
  188. package/dist/types/src/ui/components/Surface/SurfaceProfilerContext.d.ts +48 -0
  189. package/dist/types/src/ui/components/Surface/SurfaceProfilerContext.d.ts.map +1 -0
  190. package/dist/types/src/ui/components/Surface/index.d.ts +22 -6
  191. package/dist/types/src/ui/components/Surface/index.d.ts.map +1 -1
  192. package/dist/types/src/ui/components/Surface/types.d.ts +110 -9
  193. package/dist/types/src/ui/components/Surface/types.d.ts.map +1 -1
  194. package/dist/types/src/ui/components/Surface/types.test.d.ts +2 -0
  195. package/dist/types/src/ui/components/Surface/types.test.d.ts.map +1 -0
  196. package/dist/types/src/ui/components/index.d.ts +1 -0
  197. package/dist/types/src/ui/components/index.d.ts.map +1 -1
  198. package/dist/types/src/ui/hooks/index.d.ts +1 -1
  199. package/dist/types/src/ui/hooks/index.d.ts.map +1 -1
  200. package/dist/types/src/ui/hooks/useApp.d.ts +47 -11
  201. package/dist/types/src/ui/hooks/useApp.d.ts.map +1 -1
  202. package/dist/types/src/ui/hooks/useCapabilities.d.ts.map +1 -1
  203. package/dist/types/src/ui/hooks/useLoading.d.ts.map +1 -1
  204. package/dist/types/src/ui/hooks/useProcessManagerRuntime.d.ts +24 -0
  205. package/dist/types/src/ui/hooks/useProcessManagerRuntime.d.ts.map +1 -0
  206. package/dist/types/src/ui/hooks/useSettingsState.d.ts.map +1 -1
  207. package/dist/types/src/vite-plugin/boot-loader/BootLoader.stories.d.ts +34 -0
  208. package/dist/types/src/vite-plugin/boot-loader/BootLoader.stories.d.ts.map +1 -0
  209. package/dist/types/src/vite-plugin/boot-loader/index.d.ts +2 -0
  210. package/dist/types/src/vite-plugin/boot-loader/index.d.ts.map +1 -0
  211. package/dist/types/src/vite-plugin/boot-loader/loader.d.ts +51 -0
  212. package/dist/types/src/vite-plugin/boot-loader/loader.d.ts.map +1 -0
  213. package/dist/types/src/vite-plugin/composer/index.d.ts +34 -0
  214. package/dist/types/src/vite-plugin/composer/index.d.ts.map +1 -0
  215. package/dist/types/src/vite-plugin/import-map/index.d.ts +28 -0
  216. package/dist/types/src/vite-plugin/import-map/index.d.ts.map +1 -0
  217. package/dist/types/src/vite-plugin/index.d.ts +5 -0
  218. package/dist/types/src/vite-plugin/index.d.ts.map +1 -0
  219. package/dist/types/src/vite-plugin/manifest.d.ts +41 -0
  220. package/dist/types/src/vite-plugin/manifest.d.ts.map +1 -0
  221. package/dist/types/src/vite-plugin/manifest.test.d.ts +2 -0
  222. package/dist/types/src/vite-plugin/manifest.test.d.ts.map +1 -0
  223. package/dist/types/src/vite-plugin/packages.d.ts +13 -0
  224. package/dist/types/src/vite-plugin/packages.d.ts.map +1 -0
  225. package/dist/types/tsconfig.tsbuildinfo +1 -1
  226. package/moon.yml +15 -0
  227. package/package.json +53 -54
  228. package/src/cli/cli.ts +2 -7
  229. package/src/common/activation-events.ts +10 -15
  230. package/src/common/annotations.ts +3 -0
  231. package/src/common/capabilities.ts +147 -16
  232. package/src/common/operations.ts +5 -8
  233. package/src/core/activation-event.ts +4 -1
  234. package/src/core/capability-manager.test.ts +1 -1
  235. package/src/core/capability-manager.ts +22 -1
  236. package/src/core/capability.ts +20 -2
  237. package/src/core/edge-registry-plugin-provider.ts +92 -0
  238. package/src/core/index.ts +6 -0
  239. package/src/core/plugin-asset-cache.ts +60 -0
  240. package/src/core/plugin-manager.test.ts +816 -10
  241. package/src/core/plugin-manager.ts +865 -46
  242. package/src/core/plugin-manifest.test.ts +75 -0
  243. package/src/core/plugin-manifest.ts +134 -0
  244. package/src/core/plugin.ts +185 -10
  245. package/src/core/registry.ts +163 -0
  246. package/src/core/url-loader.test.ts +221 -0
  247. package/src/core/url-loader.ts +388 -0
  248. package/src/index.ts +1 -2
  249. package/src/plugin-process-manager/ProcessManagerPlugin.ts +24 -0
  250. package/src/{plugin-operation → plugin-process-manager}/history/capability.ts +1 -2
  251. package/src/plugin-process-manager/history/errors.ts +7 -0
  252. package/src/{plugin-operation → plugin-process-manager}/history/history-tracker.test.ts +37 -43
  253. package/src/{plugin-operation → plugin-process-manager}/history/history-tracker.ts +1 -2
  254. package/src/{plugin-operation → plugin-process-manager}/history/types.ts +1 -1
  255. package/src/{plugin-operation → plugin-process-manager}/history/undo-mapping.ts +1 -1
  256. package/src/{plugin-operation → plugin-process-manager}/history/undo-registry.test.ts +3 -4
  257. package/src/{plugin-operation → plugin-process-manager}/history/undo-registry.ts +1 -1
  258. package/src/{plugin-operation → plugin-process-manager}/index.ts +1 -1
  259. package/src/plugin-process-manager/meta.ts +14 -0
  260. package/src/plugin-process-manager/process-manager-capability.ts +178 -0
  261. package/src/{plugin-operation → plugin-process-manager}/testing.ts +26 -45
  262. package/src/testing/harness.ts +247 -0
  263. package/src/testing/index.ts +1 -0
  264. package/src/testing/react.test.tsx +48 -0
  265. package/src/testing/react.tsx +113 -0
  266. package/src/testing/service.ts +2 -2
  267. package/src/testing/withPluginManager.stories.tsx +1 -2
  268. package/src/testing/withPluginManager.tsx +5 -4
  269. package/src/ui/components/App/App.stories.tsx +5 -11
  270. package/src/ui/components/App/App.tsx +29 -5
  271. package/src/ui/components/Placeholder/Placeholder.stories.tsx +77 -0
  272. package/src/ui/components/Placeholder/Placeholder.tsx +155 -0
  273. package/src/{plugin-runtime → ui/components/Placeholder}/index.ts +1 -1
  274. package/src/ui/components/PluginManager/PluginManagerContext.stories.tsx +5 -4
  275. package/src/ui/components/Surface/SurfaceComponent.stories.tsx +16 -15
  276. package/src/ui/components/Surface/SurfaceComponent.tsx +111 -55
  277. package/src/ui/components/Surface/SurfaceInfo.tsx +0 -1
  278. package/src/ui/components/Surface/SurfaceProfilerContext.tsx +207 -0
  279. package/src/ui/components/Surface/index.ts +35 -1
  280. package/src/ui/components/Surface/types.test.ts +126 -0
  281. package/src/ui/components/Surface/types.ts +164 -12
  282. package/src/ui/components/index.ts +1 -0
  283. package/src/ui/hooks/index.ts +1 -1
  284. package/src/ui/hooks/useApp.test.tsx +2 -2
  285. package/src/ui/hooks/useApp.tsx +216 -17
  286. package/src/ui/hooks/useLoading.tsx +14 -6
  287. package/src/ui/hooks/useProcessManagerRuntime.ts +68 -0
  288. package/src/vite-plugin/boot-loader/BootLoader.stories.tsx +270 -0
  289. package/src/vite-plugin/boot-loader/boot-loader.css +320 -0
  290. package/src/vite-plugin/boot-loader/boot-loader.js +325 -0
  291. package/src/vite-plugin/boot-loader/index.ts +5 -0
  292. package/src/vite-plugin/boot-loader/loader.ts +123 -0
  293. package/src/vite-plugin/composer/index.ts +306 -0
  294. package/src/vite-plugin/import-map/index.ts +527 -0
  295. package/src/vite-plugin/index.ts +10 -0
  296. package/src/vite-plugin/manifest.test.ts +46 -0
  297. package/src/vite-plugin/manifest.ts +57 -0
  298. package/src/vite-plugin/packages.ts +187 -0
  299. package/tsconfig.json +25 -1
  300. package/tsconfig.node.json +1 -1
  301. package/.swc/plugins/linux_x86_64_19.0.0/727453fb3a62f7f1d952a41e051ca8a6f88cadc45cee43c6a4d1aa45f9b75665.wasmer-v7 +0 -0
  302. package/dist/lib/browser/capability-5OFLR7J4.mjs.map +0 -7
  303. package/dist/lib/browser/capability-ZHQDZRP5.mjs +0 -37
  304. package/dist/lib/browser/capability-ZHQDZRP5.mjs.map +0 -7
  305. package/dist/lib/browser/chunk-272IPLHQ.mjs.map +0 -7
  306. package/dist/lib/browser/chunk-3VXJONTI.mjs +0 -933
  307. package/dist/lib/browser/chunk-3VXJONTI.mjs.map +0 -7
  308. package/dist/lib/browser/chunk-7AL6SKIV.mjs +0 -728
  309. package/dist/lib/browser/chunk-7AL6SKIV.mjs.map +0 -7
  310. package/dist/lib/browser/chunk-GH3M2LIW.mjs.map +0 -7
  311. package/dist/lib/browser/chunk-JGWCBVKJ.mjs.map +0 -7
  312. package/dist/lib/browser/chunk-M5IC326L.mjs +0 -34
  313. package/dist/lib/browser/chunk-M5IC326L.mjs.map +0 -7
  314. package/dist/lib/browser/chunk-WEBSGU5L.mjs.map +0 -7
  315. package/dist/lib/browser/chunk-YAFEA4GV.mjs +0 -1
  316. package/dist/lib/browser/chunk-YNFPIQGB.mjs.map +0 -7
  317. package/dist/lib/browser/invoker-capability-YTTQ2OBB.mjs +0 -36
  318. package/dist/lib/browser/invoker-capability-YTTQ2OBB.mjs.map +0 -7
  319. package/dist/lib/node-esm/capability-CRHZKL6T.mjs.map +0 -7
  320. package/dist/lib/node-esm/capability-W5C5464H.mjs +0 -38
  321. package/dist/lib/node-esm/capability-W5C5464H.mjs.map +0 -7
  322. package/dist/lib/node-esm/chunk-3D66SZHP.mjs.map +0 -7
  323. package/dist/lib/node-esm/chunk-6REV5DE7.mjs.map +0 -7
  324. package/dist/lib/node-esm/chunk-CMDON4NG.mjs +0 -934
  325. package/dist/lib/node-esm/chunk-CMDON4NG.mjs.map +0 -7
  326. package/dist/lib/node-esm/chunk-I7FZT4A7.mjs +0 -729
  327. package/dist/lib/node-esm/chunk-I7FZT4A7.mjs.map +0 -7
  328. package/dist/lib/node-esm/chunk-LHCJGNXK.mjs.map +0 -7
  329. package/dist/lib/node-esm/chunk-NHXBSAQR.mjs +0 -35
  330. package/dist/lib/node-esm/chunk-NHXBSAQR.mjs.map +0 -7
  331. package/dist/lib/node-esm/chunk-SB5ODNPX.mjs.map +0 -7
  332. package/dist/lib/node-esm/chunk-SQICGJBW.mjs.map +0 -7
  333. package/dist/lib/node-esm/chunk-Z4TJPSMP.mjs +0 -2
  334. package/dist/lib/node-esm/invoker-capability-BU26474T.mjs +0 -37
  335. package/dist/lib/node-esm/invoker-capability-BU26474T.mjs.map +0 -7
  336. package/dist/types/src/plugin-operation/OperationPlugin.d.ts +0 -3
  337. package/dist/types/src/plugin-operation/OperationPlugin.d.ts.map +0 -1
  338. package/dist/types/src/plugin-operation/history/capability.d.ts.map +0 -1
  339. package/dist/types/src/plugin-operation/history/errors.d.ts +0 -5
  340. package/dist/types/src/plugin-operation/history/errors.d.ts.map +0 -1
  341. package/dist/types/src/plugin-operation/history/history-tracker.d.ts.map +0 -1
  342. package/dist/types/src/plugin-operation/history/history-tracker.test.d.ts.map +0 -1
  343. package/dist/types/src/plugin-operation/history/index.d.ts.map +0 -1
  344. package/dist/types/src/plugin-operation/history/types.d.ts.map +0 -1
  345. package/dist/types/src/plugin-operation/history/undo-mapping.d.ts.map +0 -1
  346. package/dist/types/src/plugin-operation/history/undo-registry.d.ts.map +0 -1
  347. package/dist/types/src/plugin-operation/history/undo-registry.test.d.ts.map +0 -1
  348. package/dist/types/src/plugin-operation/index.d.ts +0 -3
  349. package/dist/types/src/plugin-operation/index.d.ts.map +0 -1
  350. package/dist/types/src/plugin-operation/invoker-capability.d.ts +0 -6
  351. package/dist/types/src/plugin-operation/invoker-capability.d.ts.map +0 -1
  352. package/dist/types/src/plugin-operation/meta.d.ts.map +0 -1
  353. package/dist/types/src/plugin-operation/testing.d.ts +0 -109
  354. package/dist/types/src/plugin-operation/testing.d.ts.map +0 -1
  355. package/dist/types/src/plugin-runtime/RuntimePlugin.d.ts +0 -3
  356. package/dist/types/src/plugin-runtime/RuntimePlugin.d.ts.map +0 -1
  357. package/dist/types/src/plugin-runtime/capability.d.ts +0 -6
  358. package/dist/types/src/plugin-runtime/capability.d.ts.map +0 -1
  359. package/dist/types/src/plugin-runtime/index.d.ts +0 -2
  360. package/dist/types/src/plugin-runtime/index.d.ts.map +0 -1
  361. package/dist/types/src/plugin-runtime/meta.d.ts +0 -3
  362. package/dist/types/src/plugin-runtime/meta.d.ts.map +0 -1
  363. package/dist/types/src/ui/hooks/useOperationResolver.d.ts +0 -19
  364. package/dist/types/src/ui/hooks/useOperationResolver.d.ts.map +0 -1
  365. package/src/plugin-operation/OperationPlugin.ts +0 -25
  366. package/src/plugin-operation/history/errors.ts +0 -11
  367. package/src/plugin-operation/invoker-capability.ts +0 -40
  368. package/src/plugin-operation/meta.ts +0 -11
  369. package/src/plugin-runtime/RuntimePlugin.ts +0 -20
  370. package/src/plugin-runtime/capability.ts +0 -53
  371. package/src/plugin-runtime/meta.ts +0 -11
  372. package/src/ui/hooks/useOperationResolver.ts +0 -40
  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/{plugin-operation → plugin-process-manager}/history/capability.d.ts +0 -0
  376. /package/dist/types/src/{plugin-operation → plugin-process-manager}/history/history-tracker.test.d.ts +0 -0
  377. /package/dist/types/src/{plugin-operation → plugin-process-manager}/history/index.d.ts +0 -0
  378. /package/dist/types/src/{plugin-operation → plugin-process-manager}/history/undo-registry.test.d.ts +0 -0
  379. /package/dist/types/src/{plugin-operation → plugin-process-manager}/meta.d.ts +0 -0
  380. /package/src/{plugin-operation → plugin-process-manager}/history/index.ts +0 -0
@@ -0,0 +1,155 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import React, { type ReactNode, useEffect, useLayoutEffect, useRef } from 'react';
6
+
7
+ import { ThemeProvider } from '@dxos/react-ui';
8
+ import { defaultTx, mx } from '@dxos/ui-theme';
9
+
10
+ import { type PlaceholderProps as PlaceholderSlotProps } from '../../hooks';
11
+
12
+ declare global {
13
+ interface Window {
14
+ /**
15
+ * Driver injected by `@dxos/app-framework/vite-plugin`'s `bootLoaderPlugin`.
16
+ * Declared here so the {@link Placeholder} can dismiss the native-DOM
17
+ * loader once the React placeholder commits without each host having to
18
+ * re-declare the type.
19
+ */
20
+ __bootLoader?: {
21
+ status: (payload: {
22
+ event?: string;
23
+ module?: string;
24
+ humanized: string;
25
+ /**
26
+ * Optional `(index/total)` tick. When present, the loader replaces the
27
+ * current line in place ("Loading plugins (12/80)") instead of
28
+ * appending a new entry — keeps the visible log compact during long
29
+ * counted phases like plugin chunk-loading or module activation.
30
+ */
31
+ range?: { index: number; total: number };
32
+ }) => void;
33
+ progress: (fraction?: number) => void;
34
+ dismiss: () => void;
35
+ };
36
+ }
37
+ }
38
+
39
+ export type PlaceholderComponentProps = PlaceholderSlotProps & {
40
+ /**
41
+ * Brand mark rendered while the React tree settles. Pass either a static
42
+ * `ReactNode` (the framework wraps it in a sizing/animation div) or a
43
+ * render function that receives the precomputed `className` so the host
44
+ * can apply it directly to its logo (e.g. an SVG that accepts `className`
45
+ * — `composer-app` passes `(p) => <Composer {...p} />` from `@dxos/brand`).
46
+ */
47
+ logo?: ReactNode | ((props: { className: string }) => ReactNode);
48
+ };
49
+
50
+ /**
51
+ * React placeholder. The native-DOM boot loader is the visible UI through
52
+ * stages 0 (Loading) and 1 (FadeIn): we render `null` until `stage >= 2`
53
+ * (FadeOut) and instead feed activation progress + status into the still-
54
+ * alive boot loader. At stage 2 the loader dismisses and the React mark
55
+ * appears for the cross-fade to the real shell:
56
+ *
57
+ * - composer-app fills `0 → 50%` from `getPlugins`'s per-chunk counter.
58
+ * - this component fills `50 → 100%` from `useApp`'s
59
+ * `startupProgress.progress` (`activated / total` modules) and pushes
60
+ * the per-module status text to the loader's status line.
61
+ * - at `stage >= 2` the boot loader is dismissed and the React mark
62
+ * starts its `FadeOut → Done` shrink-and-fade.
63
+ *
64
+ * Stage progression (driven by `useApp`):
65
+ * - `0` — Loading: native-DOM boot loader visible. Placeholder renders nothing.
66
+ * - `1` — FadeIn: same — boot loader still owns the screen.
67
+ * - `2` — FadeOut: boot loader dismissed, React mark visible at full opacity then shrinks.
68
+ */
69
+ export const Placeholder = ({ stage = 1, progress, logo }: PlaceholderComponentProps) => {
70
+ // Used in tests to exercise the error boundary & reset dialog.
71
+ if (location.search === '?throw') {
72
+ throw new Error('Test error');
73
+ }
74
+
75
+ // Phase B: feed activation progress + status to the still-visible boot
76
+ // loader. Maps `[0, 1]` activation → `[0.5, 1]` of the ring; forwards
77
+ // the raw activation source (`event` / `module`) plus the pre-humanised
78
+ // label to `__bootLoader.status` so the loader gets to decide how to
79
+ // render and trace each transition (current default policy: "Activating
80
+ // <humanizedName>"; trace mode and timings track the structured fields).
81
+ // No-op once the loader has been dismissed (its `status()` early-returns
82
+ // when the boot DOM is gone). Skipping `stage >= 2` lets the dismissal
83
+ // run uncontended.
84
+ useEffect(() => {
85
+ if (stage >= 2) {
86
+ return;
87
+ }
88
+ const fraction = progress?.progress ?? 0;
89
+ window.__bootLoader?.progress(0.5 + fraction * 0.5);
90
+ if (progress?.humanizedName) {
91
+ window.__bootLoader?.status({
92
+ event: progress.event,
93
+ module: progress.module,
94
+ humanized: `Activating ${progress.humanizedName}`,
95
+ });
96
+ }
97
+ }, [stage, progress?.progress, progress?.event, progress?.module, progress?.humanizedName]);
98
+
99
+ // Hand off from the native-DOM boot loader once the placeholder starts
100
+ // fading out — keeping the loader visible through `stage 0` and `stage 1`
101
+ // means the ring stays the visible source of truth for activation
102
+ // progress. `useLayoutEffect` runs before the next paint so the loader
103
+ // DOM is removed in the same frame the cross-fade begins.
104
+ useLayoutEffect(() => {
105
+ if (stage >= 2) {
106
+ window.__bootLoader?.dismiss();
107
+ }
108
+ }, [stage]);
109
+
110
+ // Backstop for the fast-load path where `useLoading` can skip straight
111
+ // from stage 0 to `Done` (ready=true at the first debounce tick) — the
112
+ // stage-driven effect above never sees `stage >= 2`, so dismiss on
113
+ // unmount instead. The `stageRef` guard is what keeps StrictMode's
114
+ // synthetic mount → cleanup → remount cycle from prematurely dismissing
115
+ // the loader: the synthetic cleanup runs while `stageRef.current === 0`,
116
+ // skips the dismiss, and the real unmount (later, at stage `Done`)
117
+ // performs it.
118
+ const stageRef = useRef(stage);
119
+ stageRef.current = stage;
120
+ useEffect(() => {
121
+ return () => {
122
+ if (stageRef.current >= 3 /* Done */) {
123
+ window.__bootLoader?.dismiss();
124
+ }
125
+ };
126
+ }, []);
127
+
128
+ // Defer rendering anything until the FadeOut stage. The boot loader owns
129
+ // the screen during stages 0 and 1, so any DOM we render here would just
130
+ // sit invisibly behind it — and rendering null avoids paint cost during
131
+ // the longest part of the loading sequence (plugin activation).
132
+ if (stage < 2) {
133
+ return null;
134
+ }
135
+
136
+ const logoClassName = mx(
137
+ 'h-[300px] w-[300px] scale-600 transition-all duration-500 ease-in-out filter grayscale opacity-0',
138
+ stage >= 1 && 'scale-100 grayscale-0 opacity-70',
139
+ stage >= 2 && 'scale-50 opacity-0',
140
+ );
141
+
142
+ return (
143
+ <ThemeProvider tx={defaultTx}>
144
+ <div className='relative dx-container h-dvh flex flex-col'>
145
+ <div className='flex flex-col grow justify-center items-center'>
146
+ {typeof logo === 'function' ? (
147
+ logo({ className: logoClassName })
148
+ ) : logo ? (
149
+ <div className={logoClassName}>{logo}</div>
150
+ ) : null}
151
+ </div>
152
+ </div>
153
+ </ThemeProvider>
154
+ );
155
+ };
@@ -2,4 +2,4 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- export * from './RuntimePlugin';
5
+ export * from './Placeholder';
@@ -38,7 +38,9 @@ const CountStatus = () => {
38
38
  }
39
39
  }, [counter]);
40
40
 
41
- if (!manager) return null;
41
+ if (!manager) {
42
+ return null;
43
+ }
42
44
 
43
45
  const isEven = count % 2 === 0;
44
46
 
@@ -118,6 +120,7 @@ const CounterComponent = () => {
118
120
  const CounterPlugin = Plugin.define({
119
121
  id: 'org.dxos.plugin.counter',
120
122
  name: 'Counter Plugin',
123
+ tags: ['system'],
121
124
  }).pipe(
122
125
  Plugin.addModule({
123
126
  id: 'CounterMain',
@@ -152,7 +155,6 @@ const CounterPlugin = Plugin.define({
152
155
  )();
153
156
 
154
157
  const plugins = [CounterPlugin];
155
- const core = ['org.dxos.plugin.counter'];
156
158
  const placeholder = () => (
157
159
  <div className='flex h-screen items-center justify-center p-4 text-lg text-neutral-500'>
158
160
  Initializing Application...
@@ -162,7 +164,6 @@ const placeholder = () => (
162
164
  const DefaultStory = () => {
163
165
  const App = useApp({
164
166
  plugins,
165
- core,
166
167
  placeholder,
167
168
  });
168
169
 
@@ -170,7 +171,7 @@ const DefaultStory = () => {
170
171
  };
171
172
 
172
173
  const meta = {
173
- title: 'sdk/app-framework/PluginManagerContext',
174
+ title: 'sdk/app-framework/components/PluginManagerContext',
174
175
  render: DefaultStory,
175
176
  decorators: [withTheme(), withLayout({ layout: 'fullscreen' })],
176
177
  parameters: {
@@ -5,15 +5,14 @@
5
5
  import { type Meta, type StoryObj } from '@storybook/react-vite';
6
6
  import React, { forwardRef, useCallback, useEffect, useRef, useState } from 'react';
7
7
 
8
- import { faker } from '@dxos/random';
9
- import { List, ListItem, Toolbar } from '@dxos/react-ui';
8
+ import { random } from '@dxos/random';
9
+ import { List, ListItem, Panel, Toolbar } from '@dxos/react-ui';
10
10
  import { withLayout, withTheme } from '@dxos/react-ui/testing';
11
11
  import { type ColorStyles, getHashStyles, mx } from '@dxos/ui-theme';
12
12
 
13
13
  import { Capabilities } from '../../../common';
14
14
  import { withPluginManager } from '../../../testing';
15
15
  import { usePluginManager } from '../PluginManager';
16
-
17
16
  import { SurfaceComponent, useSurfaces } from './SurfaceComponent';
18
17
  import { create } from './types';
19
18
 
@@ -39,7 +38,7 @@ const DefaultStory = () => {
39
38
  const [selected, setSelected] = useState<string | undefined>();
40
39
 
41
40
  const handleAdd = useCallback(() => {
42
- const id = `test-${faker.number.int({ min: 0, max: 1_000 })}`;
41
+ const id = `test-${random.number.int({ min: 0, max: 1_000 })}`;
43
42
  const styles = getHashStyles(id);
44
43
 
45
44
  manager.capabilities.contribute({
@@ -57,7 +56,7 @@ const DefaultStory = () => {
57
56
  }, [manager]);
58
57
 
59
58
  const handleSelect = useCallback(() => {
60
- setSelected(faker.helpers.arrayElement(surfaces)?.id);
59
+ setSelected(random.helpers.arrayElement(surfaces)?.id);
61
60
  }, [surfaces]);
62
61
 
63
62
  const handleError = useCallback(() => {
@@ -105,13 +104,15 @@ const DefaultStory = () => {
105
104
  }, [ref]);
106
105
 
107
106
  return (
108
- <div className='flex flex-col h-full overflow-hidden'>
109
- <Toolbar.Root>
110
- <Toolbar.Button onClick={handleAdd}>Add</Toolbar.Button>
111
- <Toolbar.Button onClick={handleSelect}>Pick</Toolbar.Button>
112
- <Toolbar.Button onClick={handleError}>Error</Toolbar.Button>
113
- </Toolbar.Root>
114
- <div className='grid grid-cols-2 h-full gap-4 overflow-hidden'>
107
+ <Panel.Root>
108
+ <Panel.Toolbar asChild>
109
+ <Toolbar.Root>
110
+ <Toolbar.Button onClick={handleAdd}>Add</Toolbar.Button>
111
+ <Toolbar.Button onClick={handleSelect}>Pick</Toolbar.Button>
112
+ <Toolbar.Button onClick={handleError}>Error</Toolbar.Button>
113
+ </Toolbar.Root>
114
+ </Panel.Toolbar>
115
+ <Panel.Content className='grid grid-cols-2 h-full gap-4 overflow-hidden'>
115
116
  <SurfaceComponent role='item' data={selected ? { id: selected } : undefined} limit={1} ref={ref} />
116
117
  <div className='overflow-y-auto h-full'>
117
118
  <List>
@@ -122,13 +123,13 @@ const DefaultStory = () => {
122
123
  ))}
123
124
  </List>
124
125
  </div>
125
- </div>
126
- </div>
126
+ </Panel.Content>
127
+ </Panel.Root>
127
128
  );
128
129
  };
129
130
 
130
131
  const meta = {
131
- title: 'sdk/app-framework/Surface',
132
+ title: 'sdk/app-framework/components/Surface',
132
133
  render: DefaultStory,
133
134
  decorators: [withTheme(), withLayout({ layout: 'fullscreen' }), withPluginManager({ capabilities: [] })],
134
135
  parameters: {
@@ -2,9 +2,11 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
+ import { useAtomValue } from '@effect-atom/atom-react';
5
6
  import React, {
6
7
  Fragment,
7
8
  type NamedExoticComponent,
9
+ Profiler,
8
10
  type RefAttributes,
9
11
  Suspense,
10
12
  forwardRef,
@@ -21,22 +23,29 @@ import { byPosition } from '@dxos/util';
21
23
 
22
24
  import { Capabilities } from '../../../common';
23
25
  import { type CapabilityManager } from '../../../core';
24
- import { useCapabilities } from '../../hooks';
25
-
26
+ import { usePluginManager } from '../PluginManager/PluginManagerProvider';
26
27
  import { SurfaceContext } from './context';
27
28
  import { SurfaceInfo } from './SurfaceInfo';
28
- import { type Definition, type Props, type WebComponentDefinition } from './types';
29
-
30
- const DEFAULT_PLACEHOLDER = <Fragment />;
29
+ import { useSurfaceProfilerCallback } from './SurfaceProfilerContext';
30
+ import {
31
+ type Definition,
32
+ type Props,
33
+ type RoleToken,
34
+ type TokenData,
35
+ type TypedProps,
36
+ type WebComponentDefinition,
37
+ } from './types';
31
38
 
32
39
  const DEBUG = import.meta.env.VITE_DEBUG;
33
40
 
41
+ const DEFAULT_PLACEHOLDER = <Fragment />;
42
+
34
43
  /**
35
44
  * Wrapper component for rendering Web Component surfaces.
36
45
  * Handles creation, prop setting, and cleanup of Web Components.
37
46
  */
38
47
  const WebComponentWrapper = memo(
39
- forwardRef<HTMLElement, Props & { definition: WebComponentDefinition }>(
48
+ forwardRef<HTMLElement, Omit<Props, 'role'> & { role: string; definition: WebComponentDefinition }>(
40
49
  ({ id, role, data, limit, definition, ...rest }, forwardedRef) => {
41
50
  const containerRef = useRef<HTMLDivElement>(null);
42
51
  const elementRef = useRef<HTMLElement | null>(null);
@@ -106,9 +115,11 @@ WebComponentWrapper.displayName = 'WebComponentWrapper';
106
115
  */
107
116
  // TODO(burdon): Allow DebugPlugin to provide different fallback using react-ui ErrorFallback.
108
117
  const SurfaceContextProvider = memo(
109
- forwardRef<HTMLElement, Props & { definition: Definition }>(
118
+ forwardRef<HTMLElement, Omit<Props, 'role'> & { role: string; definition: Definition }>(
110
119
  ({ id, role, data, limit, fallback = ErrorFallback, definition, ...rest }, forwardedRef) => {
111
120
  const contextValue = useMemo(() => ({ id, role, data }), [id, role, data]);
121
+ const onProfilerRender = useSurfaceProfilerCallback();
122
+ const profilerId = `surface/${id}/${role}`;
112
123
 
113
124
  // Handle Web Component surfaces
114
125
  if (definition.kind === 'web-component') {
@@ -137,10 +148,16 @@ const SurfaceContextProvider = memo(
137
148
  if (debug) {
138
149
  return (
139
150
  <ErrorBoundary name='surface' resetKeys={[data]} FallbackComponent={fallback}>
140
- <div role='none' className='contents' data-id={id} data-role={role}>
151
+ <div className='contents' data-id={id} data-role={role}>
141
152
  <SurfaceContext.Provider value={contextValue}>
142
153
  <SurfaceInfo ref={forwardedRef}>
143
- <Component id={id} role={role} data={data} limit={limit} {...rest} />
154
+ {onProfilerRender && !profilerId.includes('org.dxos.plugin.debug') ? (
155
+ <Profiler id={profilerId} onRender={onProfilerRender}>
156
+ <Component id={id} role={role} data={data} limit={limit} {...rest} />
157
+ </Profiler>
158
+ ) : (
159
+ <Component id={id} role={role} data={data} limit={limit} {...rest} />
160
+ )}
144
161
  </SurfaceInfo>
145
162
  </SurfaceContext.Provider>
146
163
  </div>
@@ -150,7 +167,7 @@ const SurfaceContextProvider = memo(
150
167
 
151
168
  return (
152
169
  <ErrorBoundary name='surface' resetKeys={[data]} FallbackComponent={fallback}>
153
- <div role='none' className='contents' data-id={id} data-role={role}>
170
+ <div className='contents' data-id={id} data-role={role}>
154
171
  <SurfaceContext.Provider value={contextValue}>
155
172
  <Component id={id} role={role} data={data} limit={limit} {...rest} ref={forwardedRef} />
156
173
  </SurfaceContext.Provider>
@@ -167,43 +184,53 @@ SurfaceContextProvider.displayName = 'SurfaceContextProvider';
167
184
  * A surface is a named region of the screen that can be populated by plugins.
168
185
  */
169
186
  // TODO(burdon): Remove `ref` since relying on this would be error prone.
170
- export const SurfaceComponent: NamedExoticComponent<Props & RefAttributes<HTMLElement>> = memo(
171
- forwardRef(({ id: _id, role, data: dataProp, limit, placeholder = DEFAULT_PLACEHOLDER, ...rest }, forwardedRef) => {
172
- const data = useDefaultValue(dataProp, () => ({}));
173
-
174
- // TODO(wittjosiah): This will make all surfaces depend on a single signal.
175
- // This isn't ideal because it means that any change to the data will cause all surfaces to re-render.
176
- // This effectively means that plugin modules which contribute surfaces need to all be activated at startup.
177
- // This should be fine for now because it's how it worked prior to capabilities api anyway.
178
- // In the future, it would be nice to be able to bucket the surface contributions by role.
179
- const surfaces = useSurfaces();
180
-
181
- // NOTE: Memoizing the candidates makes the surface not re-render based on reactivity within data.
182
- const definitions = findCandidates(surfaces, { role, data });
183
- const candidates = limit ? definitions.slice(0, limit) : definitions;
184
- if (DEBUG && candidates.length === 0) {
185
- log.warn('no candidates for surface', { role, data });
186
- return null;
187
- }
187
+ export const SurfaceComponent = memo(
188
+ forwardRef<HTMLElement, Props & { type?: RoleToken<any> }>(
189
+ ({ id: _id, role, type, data: dataProp, limit, placeholder = DEFAULT_PLACEHOLDER, ...rest }, forwardedRef) => {
190
+ const data = useDefaultValue(dataProp, () => ({}));
191
+ // TODO(wittjosiah): This will make all surfaces depend on a single signal.
192
+ // This isn't ideal because it means that any change to the data will cause all surfaces to re-render.
193
+ // This effectively means that plugin modules which contribute surfaces need to all be activated at startup.
194
+ // This should be fine for now because it's how it worked prior to capabilities api anyway.
195
+ // In the future, it would be nice to be able to bucket the surface contributions by role.
196
+ const surfaces = useSurfaces();
197
+
198
+ const effectiveRole = role ?? type?.role;
199
+ if (effectiveRole == null) {
200
+ if (DEBUG) {
201
+ log.warn('Surface has neither `role` nor `type` prop', { id: _id });
202
+ }
203
+ return null;
204
+ }
188
205
 
189
- return (
190
- <Suspense fallback={placeholder}>
191
- {candidates.map((definition) => (
192
- <SurfaceContextProvider
193
- key={definition.id}
194
- id={definition.id}
195
- role={role}
196
- data={data}
197
- limit={limit}
198
- definition={definition}
199
- ref={forwardedRef}
200
- {...rest}
201
- />
202
- ))}
203
- </Suspense>
204
- );
205
- }),
206
- );
206
+ // NOTE: Memoizing the candidates makes the surface not re-render based on reactivity within data.
207
+ const definitions = findCandidates(surfaces, { role: effectiveRole, data });
208
+ const candidates = limit ? definitions.slice(0, limit) : definitions;
209
+ if (DEBUG && candidates.length === 0) {
210
+ log.warn('no candidates for surface', { role: effectiveRole, data });
211
+ return null;
212
+ }
213
+
214
+ return (
215
+ <Suspense fallback={placeholder}>
216
+ {candidates.map((definition) => (
217
+ <SurfaceContextProvider
218
+ key={definition.id}
219
+ id={definition.id}
220
+ role={effectiveRole}
221
+ data={data}
222
+ limit={limit}
223
+ definition={definition}
224
+ ref={forwardedRef}
225
+ {...rest}
226
+ />
227
+ ))}
228
+ </Suspense>
229
+ );
230
+ },
231
+ ),
232
+ ) as (<TToken extends RoleToken<any>>(props: TypedProps<TToken> & RefAttributes<HTMLElement>) => React.ReactNode) &
233
+ NamedExoticComponent<Props & RefAttributes<HTMLElement>>;
207
234
 
208
235
  SurfaceComponent.displayName = 'Surface';
209
236
 
@@ -217,12 +244,12 @@ const ErrorFallback = ({ error }: Props) => {
217
244
  );
218
245
  };
219
246
 
220
- const findCandidates = (surfaces: Definition[], { role, data }: Pick<Props, 'role' | 'data'>) => {
247
+ const findCandidates = (surfaces: Definition[], { role, data }: { role: string; data: Props['data'] }) => {
221
248
  return Object.values(surfaces)
222
249
  .filter((definition) =>
223
250
  Array.isArray(definition.role) ? definition.role.includes(role) : definition.role === role,
224
251
  )
225
- .filter(({ filter }) => (filter ? filter(data ?? {}) : true))
252
+ .filter(({ filter }) => (filter ? filter(data ?? {}, role) : true))
226
253
  .toSorted(byPosition);
227
254
  };
228
255
 
@@ -230,18 +257,47 @@ const findCandidates = (surfaces: Definition[], { role, data }: Pick<Props, 'rol
230
257
  * @internal
231
258
  */
232
259
  export const useSurfaces = () => {
233
- const surfaces = useCapabilities(Capabilities.ReactSurface);
234
- return useMemo(() => surfaces.flat(), [surfaces]);
260
+ const manager = usePluginManager();
261
+ const surfacesByModule = useAtomValue(manager.capabilities.atomByModule(Capabilities.ReactSurface));
262
+ return useMemo(() => {
263
+ const result: Definition[] = [];
264
+ for (const [moduleId, surfaces] of Object.entries(surfacesByModule)) {
265
+ for (const def of surfaces.flat()) {
266
+ result.push({ ...def, id: `${moduleId}.${def.id}` });
267
+ }
268
+ }
269
+ return result;
270
+ }, [surfacesByModule]);
235
271
  };
236
272
 
237
273
  /**
238
274
  * @returns `true` if there is a contributed surface which matches the specified role & data, `false` otherwise.
275
+ *
276
+ * Two overloads:
277
+ * - Typed: pass a `type` role token and `data` is constrained to the token's
278
+ * declared contract (e.g. `AppSurface.Section` requires `attendableId`).
279
+ * - Legacy: pass a string `role` and `data` is untyped.
239
280
  */
240
- export const isSurfaceAvailable = (
281
+ export function isSurfaceAvailable<TToken extends RoleToken<any>>(
282
+ capabilityManager: CapabilityManager.CapabilityManager,
283
+ args: { type: TToken; data?: TokenData<TToken>; role?: never },
284
+ ): boolean;
285
+ export function isSurfaceAvailable(
241
286
  capabilityManager: CapabilityManager.CapabilityManager,
242
- { role, data }: Pick<Props, 'role' | 'data'>,
243
- ) => {
287
+ args: Pick<Props, 'role' | 'data'> & { type?: undefined },
288
+ ): boolean;
289
+ export function isSurfaceAvailable(
290
+ capabilityManager: CapabilityManager.CapabilityManager,
291
+ { role, type, data }: { role?: string; type?: RoleToken<any>; data?: unknown },
292
+ ): boolean {
293
+ const effectiveRole = role ?? type?.role;
294
+ if (effectiveRole == null) {
295
+ return false;
296
+ }
244
297
  const surfaces = capabilityManager.getAll(Capabilities.ReactSurface);
245
- const candidates = findCandidates(surfaces.flat(), { role, data });
298
+ const candidates = findCandidates(surfaces.flat(), {
299
+ role: effectiveRole,
300
+ data: data as Props['data'],
301
+ });
246
302
  return candidates.length > 0;
247
- };
303
+ }
@@ -65,7 +65,6 @@ export const SurfaceInfo = forwardRef<HTMLElement, SurfaceInfoProps>(({ children
65
65
  {rect &&
66
66
  createPortal(
67
67
  <div
68
- role='none'
69
68
  className='z-[100] fixed flex flex-col-reverse scrollbar-none overflow-auto pointer-events-none'
70
69
  style={{
71
70
  top: rect.top + padding,