@dxos/app-framework 0.8.4-main.ead640a → 0.8.4-main.effb148878

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 (572) hide show
  1. package/.storybook/main.mts +2 -4
  2. package/.storybook/preview.mts +2 -2
  3. package/LICENSE +102 -5
  4. package/README.md +1 -1
  5. package/dist/lib/browser/capability-C4WE22TJ.mjs +35 -0
  6. package/dist/lib/browser/capability-C4WE22TJ.mjs.map +7 -0
  7. package/dist/lib/browser/chunk-2ZIYRDAF.mjs +95 -0
  8. package/dist/lib/browser/chunk-2ZIYRDAF.mjs.map +7 -0
  9. package/dist/lib/browser/chunk-5GY3YOEL.mjs +28 -0
  10. package/dist/lib/browser/chunk-5GY3YOEL.mjs.map +7 -0
  11. package/dist/lib/browser/chunk-66IXTIVK.mjs +48 -0
  12. package/dist/lib/browser/chunk-66IXTIVK.mjs.map +7 -0
  13. package/dist/lib/browser/chunk-67GCXX5I.mjs +581 -0
  14. package/dist/lib/browser/chunk-67GCXX5I.mjs.map +7 -0
  15. package/dist/lib/browser/chunk-FJ4765WW.mjs +8 -0
  16. package/dist/lib/browser/chunk-FJ4765WW.mjs.map +7 -0
  17. package/dist/lib/browser/chunk-FO3IYSLV.mjs +68 -0
  18. package/dist/lib/browser/chunk-FO3IYSLV.mjs.map +7 -0
  19. package/dist/lib/browser/chunk-IW44C7UL.mjs +83 -0
  20. package/dist/lib/browser/chunk-IW44C7UL.mjs.map +7 -0
  21. package/dist/lib/browser/chunk-J5LGTIGS.mjs +10 -0
  22. package/dist/lib/browser/chunk-KLHQNYJ2.mjs +422 -0
  23. package/dist/lib/browser/chunk-KLHQNYJ2.mjs.map +7 -0
  24. package/dist/lib/browser/chunk-LPWOVOOB.mjs +142 -0
  25. package/dist/lib/browser/chunk-LPWOVOOB.mjs.map +7 -0
  26. package/dist/lib/browser/chunk-LUQOVTWB.mjs +43 -0
  27. package/dist/lib/browser/chunk-LUQOVTWB.mjs.map +7 -0
  28. package/dist/lib/browser/chunk-SLX73WRZ.mjs +218 -0
  29. package/dist/lib/browser/chunk-SLX73WRZ.mjs.map +7 -0
  30. package/dist/lib/browser/chunk-SZMB3K2N.mjs +517 -0
  31. package/dist/lib/browser/chunk-SZMB3K2N.mjs.map +7 -0
  32. package/dist/lib/browser/chunk-VJ5PFAWC.mjs +1446 -0
  33. package/dist/lib/browser/chunk-VJ5PFAWC.mjs.map +7 -0
  34. package/dist/lib/browser/cli/index.mjs +74 -0
  35. package/dist/lib/browser/cli/index.mjs.map +7 -0
  36. package/dist/lib/browser/common/activation-events.mjs +20 -0
  37. package/dist/lib/browser/common/capabilities.mjs +56 -0
  38. package/dist/lib/browser/core/activation-event.mjs +20 -0
  39. package/dist/lib/browser/core/capability.mjs +32 -0
  40. package/dist/lib/browser/core/capability.mjs.map +7 -0
  41. package/dist/lib/browser/core/plugin-manager.mjs +19 -0
  42. package/dist/lib/browser/core/plugin-manager.mjs.map +7 -0
  43. package/dist/lib/browser/core/plugin.mjs +39 -0
  44. package/dist/lib/browser/core/plugin.mjs.map +7 -0
  45. package/dist/lib/browser/core/url-loader.mjs +24 -0
  46. package/dist/lib/browser/core/url-loader.mjs.map +7 -0
  47. package/dist/lib/browser/index.mjs +85 -148
  48. package/dist/lib/browser/index.mjs.map +4 -4
  49. package/dist/lib/browser/meta.json +1 -1
  50. package/dist/lib/browser/process-manager-capability-3Q4TA73T.mjs +89 -0
  51. package/dist/lib/browser/process-manager-capability-3Q4TA73T.mjs.map +7 -0
  52. package/dist/lib/browser/testing/index.mjs +245 -47
  53. package/dist/lib/browser/testing/index.mjs.map +4 -4
  54. package/dist/lib/browser/testing/react.mjs +78 -0
  55. package/dist/lib/browser/testing/react.mjs.map +7 -0
  56. package/dist/lib/browser/ui/index.mjs +54 -0
  57. package/dist/lib/browser/ui/index.mjs.map +7 -0
  58. package/dist/lib/node-esm/capability-GPN6OS6M.mjs +36 -0
  59. package/dist/lib/node-esm/capability-GPN6OS6M.mjs.map +7 -0
  60. package/dist/lib/node-esm/chunk-37Z53PXZ.mjs +10 -0
  61. package/dist/lib/node-esm/chunk-37Z53PXZ.mjs.map +7 -0
  62. package/dist/lib/node-esm/chunk-42UNAKYO.mjs +423 -0
  63. package/dist/lib/node-esm/chunk-42UNAKYO.mjs.map +7 -0
  64. package/dist/lib/node-esm/chunk-6S45OMUP.mjs +219 -0
  65. package/dist/lib/node-esm/chunk-6S45OMUP.mjs.map +7 -0
  66. package/dist/lib/node-esm/chunk-CTKEZHKF.mjs +84 -0
  67. package/dist/lib/node-esm/chunk-CTKEZHKF.mjs.map +7 -0
  68. package/dist/lib/node-esm/chunk-FEVJEUD7.mjs +143 -0
  69. package/dist/lib/node-esm/chunk-FEVJEUD7.mjs.map +7 -0
  70. package/dist/lib/node-esm/chunk-GBHZF46K.mjs +518 -0
  71. package/dist/lib/node-esm/chunk-GBHZF46K.mjs.map +7 -0
  72. package/dist/lib/node-esm/chunk-GUE5V5CG.mjs +582 -0
  73. package/dist/lib/node-esm/chunk-GUE5V5CG.mjs.map +7 -0
  74. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +11 -0
  75. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs.map +7 -0
  76. package/dist/lib/node-esm/chunk-KFZEB6BV.mjs +29 -0
  77. package/dist/lib/node-esm/chunk-KFZEB6BV.mjs.map +7 -0
  78. package/dist/lib/node-esm/chunk-MXWDXYV2.mjs +44 -0
  79. package/dist/lib/node-esm/chunk-MXWDXYV2.mjs.map +7 -0
  80. package/dist/lib/node-esm/chunk-QBUGLR4H.mjs +96 -0
  81. package/dist/lib/node-esm/chunk-QBUGLR4H.mjs.map +7 -0
  82. package/dist/lib/node-esm/chunk-SFYCO3PT.mjs +1447 -0
  83. package/dist/lib/node-esm/chunk-SFYCO3PT.mjs.map +7 -0
  84. package/dist/lib/node-esm/chunk-WK7OIQKI.mjs +70 -0
  85. package/dist/lib/node-esm/chunk-WK7OIQKI.mjs.map +7 -0
  86. package/dist/lib/node-esm/chunk-XOCUANHO.mjs +49 -0
  87. package/dist/lib/node-esm/chunk-XOCUANHO.mjs.map +7 -0
  88. package/dist/lib/node-esm/cli/index.mjs +75 -0
  89. package/dist/lib/node-esm/cli/index.mjs.map +7 -0
  90. package/dist/lib/node-esm/common/activation-events.mjs +21 -0
  91. package/dist/lib/node-esm/common/activation-events.mjs.map +7 -0
  92. package/dist/lib/node-esm/common/capabilities.mjs +57 -0
  93. package/dist/lib/node-esm/common/capabilities.mjs.map +7 -0
  94. package/dist/lib/node-esm/core/activation-event.mjs +21 -0
  95. package/dist/lib/node-esm/core/activation-event.mjs.map +7 -0
  96. package/dist/lib/node-esm/core/capability.mjs +33 -0
  97. package/dist/lib/node-esm/core/capability.mjs.map +7 -0
  98. package/dist/lib/node-esm/core/plugin-manager.mjs +20 -0
  99. package/dist/lib/node-esm/core/plugin-manager.mjs.map +7 -0
  100. package/dist/lib/node-esm/core/plugin.mjs +40 -0
  101. package/dist/lib/node-esm/core/plugin.mjs.map +7 -0
  102. package/dist/lib/node-esm/core/url-loader.mjs +25 -0
  103. package/dist/lib/node-esm/core/url-loader.mjs.map +7 -0
  104. package/dist/lib/node-esm/index.mjs +85 -148
  105. package/dist/lib/node-esm/index.mjs.map +4 -4
  106. package/dist/lib/node-esm/meta.json +1 -1
  107. package/dist/lib/node-esm/process-manager-capability-5KCLSNQM.mjs +90 -0
  108. package/dist/lib/node-esm/process-manager-capability-5KCLSNQM.mjs.map +7 -0
  109. package/dist/lib/node-esm/testing/index.mjs +245 -47
  110. package/dist/lib/node-esm/testing/index.mjs.map +4 -4
  111. package/dist/lib/node-esm/testing/react.mjs +79 -0
  112. package/dist/lib/node-esm/testing/react.mjs.map +7 -0
  113. package/dist/lib/node-esm/ui/index.mjs +55 -0
  114. package/dist/lib/node-esm/ui/index.mjs.map +7 -0
  115. package/dist/plugin/node-esm/index.mjs +893 -0
  116. package/dist/plugin/node-esm/index.mjs.map +7 -0
  117. package/dist/plugin/node-esm/meta.json +1 -0
  118. package/dist/types/src/cli/cli.d.ts +37 -0
  119. package/dist/types/src/cli/cli.d.ts.map +1 -0
  120. package/dist/types/src/cli/index.d.ts +2 -0
  121. package/dist/types/src/cli/index.d.ts.map +1 -0
  122. package/dist/types/src/common/activation-events.d.ts +24 -0
  123. package/dist/types/src/common/activation-events.d.ts.map +1 -0
  124. package/dist/types/src/common/annotations.d.ts +1 -0
  125. package/dist/types/src/common/annotations.d.ts.map +1 -0
  126. package/dist/types/src/common/capabilities.d.ts +214 -199
  127. package/dist/types/src/common/capabilities.d.ts.map +1 -1
  128. package/dist/types/src/common/index.d.ts +4 -8
  129. package/dist/types/src/common/index.d.ts.map +1 -1
  130. package/dist/types/src/common/operations.d.ts +19 -0
  131. package/dist/types/src/common/operations.d.ts.map +1 -0
  132. package/dist/types/src/common/translations.d.ts +7 -7
  133. package/dist/types/src/common/translations.d.ts.map +1 -1
  134. package/dist/types/src/context.d.ts +5 -0
  135. package/dist/types/src/context.d.ts.map +1 -0
  136. package/dist/types/src/core/{events.d.ts → activation-event.d.ts} +11 -11
  137. package/dist/types/src/core/activation-event.d.ts.map +1 -0
  138. package/dist/types/src/core/capability-manager.d.ts +48 -0
  139. package/dist/types/src/core/capability-manager.d.ts.map +1 -0
  140. package/dist/types/src/core/capability-manager.test.d.ts +2 -0
  141. package/dist/types/src/core/capability-manager.test.d.ts.map +1 -0
  142. package/dist/types/src/core/capability.d.ts +161 -0
  143. package/dist/types/src/core/capability.d.ts.map +1 -0
  144. package/dist/types/src/core/edge-registry-plugin-provider.d.ts +30 -0
  145. package/dist/types/src/core/edge-registry-plugin-provider.d.ts.map +1 -0
  146. package/dist/types/src/core/index.d.ts +11 -4
  147. package/dist/types/src/core/index.d.ts.map +1 -1
  148. package/dist/types/src/core/plugin-asset-cache.d.ts +71 -0
  149. package/dist/types/src/core/plugin-asset-cache.d.ts.map +1 -0
  150. package/dist/types/src/core/plugin-manager.d.ts +297 -0
  151. package/dist/types/src/core/plugin-manager.d.ts.map +1 -0
  152. package/dist/types/src/core/plugin-manager.test.d.ts +2 -0
  153. package/dist/types/src/core/plugin-manager.test.d.ts.map +1 -0
  154. package/dist/types/src/core/plugin-manifest.d.ts +101 -0
  155. package/dist/types/src/core/plugin-manifest.d.ts.map +1 -0
  156. package/dist/types/src/core/plugin-manifest.test.d.ts +2 -0
  157. package/dist/types/src/core/plugin-manifest.test.d.ts.map +1 -0
  158. package/dist/types/src/core/plugin.d.ts +276 -39
  159. package/dist/types/src/core/plugin.d.ts.map +1 -1
  160. package/dist/types/src/core/registry.d.ts +107 -0
  161. package/dist/types/src/core/registry.d.ts.map +1 -0
  162. package/dist/types/src/core/url-loader.d.ts +127 -0
  163. package/dist/types/src/core/url-loader.d.ts.map +1 -0
  164. package/dist/types/src/core/url-loader.test.d.ts +2 -0
  165. package/dist/types/src/core/url-loader.test.d.ts.map +1 -0
  166. package/dist/types/src/helpers.d.ts.map +1 -1
  167. package/dist/types/src/index.d.ts +2 -4
  168. package/dist/types/src/index.d.ts.map +1 -1
  169. package/dist/types/src/plugin-process-manager/ProcessManagerPlugin.d.ts +3 -0
  170. package/dist/types/src/plugin-process-manager/ProcessManagerPlugin.d.ts.map +1 -0
  171. package/dist/types/src/plugin-process-manager/history/capability.d.ts +7 -0
  172. package/dist/types/src/plugin-process-manager/history/capability.d.ts.map +1 -0
  173. package/dist/types/src/plugin-process-manager/history/errors.d.ts +32 -0
  174. package/dist/types/src/plugin-process-manager/history/errors.d.ts.map +1 -0
  175. package/dist/types/src/plugin-process-manager/history/history-tracker.d.ts +18 -0
  176. package/dist/types/src/plugin-process-manager/history/history-tracker.d.ts.map +1 -0
  177. package/dist/types/src/plugin-process-manager/history/history-tracker.test.d.ts +2 -0
  178. package/dist/types/src/plugin-process-manager/history/history-tracker.test.d.ts.map +1 -0
  179. package/dist/types/src/plugin-process-manager/history/index.d.ts +6 -0
  180. package/dist/types/src/plugin-process-manager/history/index.d.ts.map +1 -0
  181. package/dist/types/src/plugin-process-manager/history/types.d.ts +13 -0
  182. package/dist/types/src/plugin-process-manager/history/types.d.ts.map +1 -0
  183. package/dist/types/src/plugin-process-manager/history/undo-mapping.d.ts +101 -0
  184. package/dist/types/src/plugin-process-manager/history/undo-mapping.d.ts.map +1 -0
  185. package/dist/types/src/plugin-process-manager/history/undo-registry.d.ts +23 -0
  186. package/dist/types/src/plugin-process-manager/history/undo-registry.d.ts.map +1 -0
  187. package/dist/types/src/plugin-process-manager/history/undo-registry.test.d.ts +2 -0
  188. package/dist/types/src/plugin-process-manager/history/undo-registry.test.d.ts.map +1 -0
  189. package/dist/types/src/plugin-process-manager/index.d.ts +3 -0
  190. package/dist/types/src/plugin-process-manager/index.d.ts.map +1 -0
  191. package/dist/types/src/plugin-process-manager/meta.d.ts +3 -0
  192. package/dist/types/src/plugin-process-manager/meta.d.ts.map +1 -0
  193. package/dist/types/src/plugin-process-manager/process-manager-capability.d.ts +8 -0
  194. package/dist/types/src/plugin-process-manager/process-manager-capability.d.ts.map +1 -0
  195. package/dist/types/src/plugin-process-manager/testing.d.ts +59 -0
  196. package/dist/types/src/plugin-process-manager/testing.d.ts.map +1 -0
  197. package/dist/types/src/testing/harness.d.ts +79 -0
  198. package/dist/types/src/testing/harness.d.ts.map +1 -0
  199. package/dist/types/src/testing/index.d.ts +2 -0
  200. package/dist/types/src/testing/index.d.ts.map +1 -1
  201. package/dist/types/src/testing/react.d.ts +27 -0
  202. package/dist/types/src/testing/react.d.ts.map +1 -0
  203. package/dist/types/src/testing/react.test.d.ts +2 -0
  204. package/dist/types/src/testing/react.test.d.ts.map +1 -0
  205. package/dist/types/src/testing/service.d.ts +8 -0
  206. package/dist/types/src/testing/service.d.ts.map +1 -0
  207. package/dist/types/src/testing/withPluginManager.d.ts +7 -6
  208. package/dist/types/src/testing/withPluginManager.d.ts.map +1 -1
  209. package/dist/types/src/testing/withPluginManager.stories.d.ts.map +1 -1
  210. package/dist/types/src/ui/components/App/App.d.ts +9 -0
  211. package/dist/types/src/ui/components/App/App.d.ts.map +1 -0
  212. package/dist/types/src/ui/components/App/App.stories.d.ts +19 -0
  213. package/dist/types/src/ui/components/App/App.stories.d.ts.map +1 -0
  214. package/dist/types/src/ui/components/App/index.d.ts +2 -0
  215. package/dist/types/src/ui/components/App/index.d.ts.map +1 -0
  216. package/dist/types/src/ui/components/Placeholder/Placeholder.d.ts +64 -0
  217. package/dist/types/src/ui/components/Placeholder/Placeholder.d.ts.map +1 -0
  218. package/dist/types/src/ui/components/Placeholder/Placeholder.stories.d.ts +19 -0
  219. package/dist/types/src/ui/components/Placeholder/Placeholder.stories.d.ts.map +1 -0
  220. package/dist/types/src/ui/components/Placeholder/index.d.ts +2 -0
  221. package/dist/types/src/ui/components/Placeholder/index.d.ts.map +1 -0
  222. package/dist/types/src/{playground/playground.stories.d.ts → ui/components/PluginManager/PluginManagerContext.stories.d.ts} +5 -3
  223. package/dist/types/src/ui/components/PluginManager/PluginManagerContext.stories.d.ts.map +1 -0
  224. package/dist/types/src/ui/components/PluginManager/PluginManagerProvider.d.ts +10 -0
  225. package/dist/types/src/ui/components/PluginManager/PluginManagerProvider.d.ts.map +1 -0
  226. package/dist/types/src/ui/components/PluginManager/index.d.ts +2 -0
  227. package/dist/types/src/ui/components/PluginManager/index.d.ts.map +1 -0
  228. package/dist/types/src/ui/components/Surface/SurfaceComponent.d.ts +24 -0
  229. package/dist/types/src/ui/components/Surface/SurfaceComponent.d.ts.map +1 -0
  230. package/dist/types/src/{components/App.stories.d.ts → ui/components/Surface/SurfaceComponent.stories.d.ts} +1 -1
  231. package/dist/types/src/ui/components/Surface/SurfaceComponent.stories.d.ts.map +1 -0
  232. package/dist/types/src/ui/components/Surface/SurfaceInfo.d.ts +11 -0
  233. package/dist/types/src/ui/components/Surface/SurfaceInfo.d.ts.map +1 -0
  234. package/dist/types/src/ui/components/Surface/SurfaceProfilerContext.d.ts +48 -0
  235. package/dist/types/src/ui/components/Surface/SurfaceProfilerContext.d.ts.map +1 -0
  236. package/dist/types/src/ui/components/Surface/context.d.ts +5 -0
  237. package/dist/types/src/ui/components/Surface/context.d.ts.map +1 -0
  238. package/dist/types/src/ui/components/Surface/index.d.ts +36 -0
  239. package/dist/types/src/ui/components/Surface/index.d.ts.map +1 -0
  240. package/dist/types/src/ui/components/Surface/types.d.ts +197 -0
  241. package/dist/types/src/ui/components/Surface/types.d.ts.map +1 -0
  242. package/dist/types/src/ui/components/Surface/types.test.d.ts +2 -0
  243. package/dist/types/src/ui/components/Surface/types.test.d.ts.map +1 -0
  244. package/dist/types/src/ui/components/index.d.ts +5 -0
  245. package/dist/types/src/ui/components/index.d.ts.map +1 -0
  246. package/dist/types/src/ui/hooks/index.d.ts +7 -0
  247. package/dist/types/src/ui/hooks/index.d.ts.map +1 -0
  248. package/dist/types/src/ui/hooks/useApp.d.ts +86 -0
  249. package/dist/types/src/ui/hooks/useApp.d.ts.map +1 -0
  250. package/dist/types/src/ui/hooks/useApp.test.d.ts +2 -0
  251. package/dist/types/src/ui/hooks/useApp.test.d.ts.map +1 -0
  252. package/dist/types/src/ui/hooks/useCapabilities.d.ts +31 -0
  253. package/dist/types/src/ui/hooks/useCapabilities.d.ts.map +1 -0
  254. package/dist/types/src/{components → ui/hooks}/useLoading.d.ts +1 -2
  255. package/dist/types/src/ui/hooks/useLoading.d.ts.map +1 -0
  256. package/dist/types/src/ui/hooks/useProcessManagerRuntime.d.ts +30 -0
  257. package/dist/types/src/ui/hooks/useProcessManagerRuntime.d.ts.map +1 -0
  258. package/dist/types/src/ui/hooks/useSettingsState.d.ts +10 -0
  259. package/dist/types/src/ui/hooks/useSettingsState.d.ts.map +1 -0
  260. package/dist/types/src/ui/hooks/useSurface.d.ts +3 -0
  261. package/dist/types/src/ui/hooks/useSurface.d.ts.map +1 -0
  262. package/dist/types/src/ui/index.d.ts +3 -0
  263. package/dist/types/src/ui/index.d.ts.map +1 -0
  264. package/dist/types/src/vite-plugin/boot-loader/BootLoader.stories.d.ts +34 -0
  265. package/dist/types/src/vite-plugin/boot-loader/BootLoader.stories.d.ts.map +1 -0
  266. package/dist/types/src/vite-plugin/boot-loader/index.d.ts +2 -0
  267. package/dist/types/src/vite-plugin/boot-loader/index.d.ts.map +1 -0
  268. package/dist/types/src/vite-plugin/boot-loader/loader.d.ts +51 -0
  269. package/dist/types/src/vite-plugin/boot-loader/loader.d.ts.map +1 -0
  270. package/dist/types/src/vite-plugin/composer/index.d.ts +34 -0
  271. package/dist/types/src/vite-plugin/composer/index.d.ts.map +1 -0
  272. package/dist/types/src/vite-plugin/import-map/index.d.ts +28 -0
  273. package/dist/types/src/vite-plugin/import-map/index.d.ts.map +1 -0
  274. package/dist/types/src/vite-plugin/index.d.ts +5 -0
  275. package/dist/types/src/vite-plugin/index.d.ts.map +1 -0
  276. package/dist/types/src/vite-plugin/manifest.d.ts +41 -0
  277. package/dist/types/src/vite-plugin/manifest.d.ts.map +1 -0
  278. package/dist/types/src/vite-plugin/manifest.test.d.ts +2 -0
  279. package/dist/types/src/vite-plugin/manifest.test.d.ts.map +1 -0
  280. package/dist/types/src/vite-plugin/packages.d.ts +13 -0
  281. package/dist/types/src/vite-plugin/packages.d.ts.map +1 -0
  282. package/dist/types/tsconfig.tsbuildinfo +1 -1
  283. package/moon.yml +25 -6
  284. package/package.json +119 -56
  285. package/src/cli/cli.ts +102 -0
  286. package/src/{components → cli}/index.ts +1 -1
  287. package/src/common/activation-events.ts +39 -0
  288. package/src/{playground/layout/index.ts → common/annotations.ts} +0 -2
  289. package/src/common/capabilities.ts +287 -195
  290. package/src/common/index.ts +4 -8
  291. package/src/common/operations.ts +36 -0
  292. package/src/common/translations.ts +17 -9
  293. package/src/context.ts +9 -0
  294. package/src/core/{events.ts → activation-event.ts} +10 -7
  295. package/src/core/capability-manager.test.ts +151 -0
  296. package/src/core/capability-manager.ts +192 -0
  297. package/src/core/capability.ts +254 -0
  298. package/src/core/edge-registry-plugin-provider.ts +92 -0
  299. package/src/core/index.ts +11 -4
  300. package/src/core/plugin-asset-cache.ts +60 -0
  301. package/src/core/plugin-manager.test.ts +1899 -0
  302. package/src/core/plugin-manager.ts +1687 -0
  303. package/src/core/plugin-manifest.test.ts +75 -0
  304. package/src/core/plugin-manifest.ts +134 -0
  305. package/src/core/plugin.ts +415 -45
  306. package/src/core/registry.ts +163 -0
  307. package/src/core/url-loader.test.ts +221 -0
  308. package/src/core/url-loader.ts +388 -0
  309. package/src/index.ts +2 -4
  310. package/src/plugin-process-manager/ProcessManagerPlugin.ts +24 -0
  311. package/src/plugin-process-manager/history/capability.ts +36 -0
  312. package/src/plugin-process-manager/history/errors.ts +7 -0
  313. package/src/plugin-process-manager/history/history-tracker.test.ts +374 -0
  314. package/src/plugin-process-manager/history/history-tracker.ts +128 -0
  315. package/src/plugin-process-manager/history/index.ts +9 -0
  316. package/src/plugin-process-manager/history/types.ts +17 -0
  317. package/src/plugin-process-manager/history/undo-mapping.ts +135 -0
  318. package/src/plugin-process-manager/history/undo-registry.test.ts +72 -0
  319. package/src/plugin-process-manager/history/undo-registry.ts +54 -0
  320. package/src/plugin-process-manager/index.ts +6 -0
  321. package/src/plugin-process-manager/meta.ts +14 -0
  322. package/src/plugin-process-manager/process-manager-capability.ts +178 -0
  323. package/src/plugin-process-manager/testing.ts +155 -0
  324. package/src/testing/harness.ts +247 -0
  325. package/src/testing/index.ts +2 -0
  326. package/src/testing/react.test.tsx +48 -0
  327. package/src/testing/react.tsx +113 -0
  328. package/src/testing/service.ts +52 -0
  329. package/src/testing/withPluginManager.stories.tsx +8 -9
  330. package/src/testing/withPluginManager.tsx +73 -42
  331. package/src/ui/components/App/App.stories.tsx +86 -0
  332. package/src/ui/components/App/App.tsx +81 -0
  333. package/src/{playground/debug → ui/components/App}/index.ts +1 -1
  334. package/src/ui/components/Placeholder/Placeholder.stories.tsx +77 -0
  335. package/src/ui/components/Placeholder/Placeholder.tsx +156 -0
  336. package/src/{playground/logger → ui/components/Placeholder}/index.ts +1 -1
  337. package/src/ui/components/PluginManager/PluginManagerContext.stories.tsx +184 -0
  338. package/src/{react → ui/components/PluginManager}/PluginManagerProvider.ts +3 -3
  339. package/src/ui/components/PluginManager/index.ts +5 -0
  340. package/src/ui/components/Surface/SurfaceComponent.stories.tsx +144 -0
  341. package/src/ui/components/Surface/SurfaceComponent.tsx +303 -0
  342. package/src/ui/components/Surface/SurfaceInfo.tsx +106 -0
  343. package/src/ui/components/Surface/SurfaceProfilerContext.tsx +207 -0
  344. package/src/ui/components/Surface/context.ts +12 -0
  345. package/src/ui/components/Surface/index.ts +54 -0
  346. package/src/ui/components/Surface/types.test.ts +126 -0
  347. package/src/ui/components/Surface/types.ts +269 -0
  348. package/src/ui/components/index.ts +8 -0
  349. package/src/ui/hooks/index.ts +10 -0
  350. package/src/ui/hooks/useApp.test.tsx +159 -0
  351. package/src/ui/hooks/useApp.tsx +418 -0
  352. package/src/ui/hooks/useCapabilities.ts +68 -0
  353. package/src/{components → ui/hooks}/useLoading.tsx +16 -10
  354. package/src/ui/hooks/useProcessManagerRuntime.ts +78 -0
  355. package/src/ui/hooks/useSettingsState.ts +26 -0
  356. package/src/ui/hooks/useSurface.ts +13 -0
  357. package/src/ui/index.ts +6 -0
  358. package/src/vite-plugin/boot-loader/BootLoader.stories.tsx +270 -0
  359. package/src/vite-plugin/boot-loader/boot-loader.css +320 -0
  360. package/src/vite-plugin/boot-loader/boot-loader.js +325 -0
  361. package/src/vite-plugin/boot-loader/index.ts +5 -0
  362. package/src/vite-plugin/boot-loader/loader.ts +123 -0
  363. package/src/vite-plugin/composer/index.ts +306 -0
  364. package/src/vite-plugin/import-map/index.ts +527 -0
  365. package/src/vite-plugin/index.ts +10 -0
  366. package/src/vite-plugin/manifest.test.ts +46 -0
  367. package/src/vite-plugin/manifest.ts +57 -0
  368. package/src/vite-plugin/packages.ts +187 -0
  369. package/tsconfig.json +30 -15
  370. package/tsconfig.node.json +2 -4
  371. package/typedoc.json +2 -4
  372. package/vitest.config.ts +1 -1
  373. package/.swc/plugins/linux_x86_64_19.0.0/727453fb3a62f7f1d952a41e051ca8a6f88cadc45cee43c6a4d1aa45f9b75665.wasmer-v7 +0 -0
  374. package/.swc/plugins/linux_x86_64_19.0.0/fce1bdb8e20a094e4af08bad09cc81497ed0e2e7c51223b07d371063cca18429.wasmer-v7 +0 -0
  375. package/dist/lib/browser/app-graph-builder-LG4RG2LM.mjs +0 -138
  376. package/dist/lib/browser/app-graph-builder-LG4RG2LM.mjs.map +0 -7
  377. package/dist/lib/browser/chunk-2GRQ4QXA.mjs +0 -1646
  378. package/dist/lib/browser/chunk-2GRQ4QXA.mjs.map +0 -7
  379. package/dist/lib/browser/chunk-FRUTKCPG.mjs +0 -467
  380. package/dist/lib/browser/chunk-FRUTKCPG.mjs.map +0 -7
  381. package/dist/lib/browser/chunk-SCPE4ZO2.mjs +0 -35
  382. package/dist/lib/browser/chunk-SCPE4ZO2.mjs.map +0 -7
  383. package/dist/lib/browser/intent-dispatcher-6SHA5B3N.mjs +0 -11
  384. package/dist/lib/browser/intent-resolver-UZZ4OANZ.mjs +0 -39
  385. package/dist/lib/browser/intent-resolver-UZZ4OANZ.mjs.map +0 -7
  386. package/dist/lib/browser/store-ACBEYK4B.mjs +0 -30
  387. package/dist/lib/browser/store-ACBEYK4B.mjs.map +0 -7
  388. package/dist/lib/browser/worker.mjs +0 -77
  389. package/dist/lib/node-esm/app-graph-builder-FMHVHPWA.mjs +0 -139
  390. package/dist/lib/node-esm/app-graph-builder-FMHVHPWA.mjs.map +0 -7
  391. package/dist/lib/node-esm/chunk-CXT6CYPE.mjs +0 -468
  392. package/dist/lib/node-esm/chunk-CXT6CYPE.mjs.map +0 -7
  393. package/dist/lib/node-esm/chunk-KSPOOYT3.mjs +0 -1648
  394. package/dist/lib/node-esm/chunk-KSPOOYT3.mjs.map +0 -7
  395. package/dist/lib/node-esm/chunk-ZX63QUGE.mjs +0 -37
  396. package/dist/lib/node-esm/chunk-ZX63QUGE.mjs.map +0 -7
  397. package/dist/lib/node-esm/intent-dispatcher-SIYQ5ZIU.mjs +0 -12
  398. package/dist/lib/node-esm/intent-resolver-7FYJMXAG.mjs +0 -40
  399. package/dist/lib/node-esm/intent-resolver-7FYJMXAG.mjs.map +0 -7
  400. package/dist/lib/node-esm/store-6OBLTVXC.mjs +0 -31
  401. package/dist/lib/node-esm/store-6OBLTVXC.mjs.map +0 -7
  402. package/dist/lib/node-esm/worker.mjs +0 -78
  403. package/dist/types/src/common/collaboration.d.ts +0 -20
  404. package/dist/types/src/common/collaboration.d.ts.map +0 -1
  405. package/dist/types/src/common/events.d.ts +0 -52
  406. package/dist/types/src/common/events.d.ts.map +0 -1
  407. package/dist/types/src/common/file.d.ts +0 -14
  408. package/dist/types/src/common/file.d.ts.map +0 -1
  409. package/dist/types/src/common/graph.d.ts +0 -21
  410. package/dist/types/src/common/graph.d.ts.map +0 -1
  411. package/dist/types/src/common/layout.d.ts +0 -279
  412. package/dist/types/src/common/layout.d.ts.map +0 -1
  413. package/dist/types/src/common/surface.d.ts +0 -59
  414. package/dist/types/src/common/surface.d.ts.map +0 -1
  415. package/dist/types/src/components/App.d.ts +0 -10
  416. package/dist/types/src/components/App.d.ts.map +0 -1
  417. package/dist/types/src/components/App.stories.d.ts.map +0 -1
  418. package/dist/types/src/components/DefaultFallback.d.ts +0 -8
  419. package/dist/types/src/components/DefaultFallback.d.ts.map +0 -1
  420. package/dist/types/src/components/index.d.ts +0 -2
  421. package/dist/types/src/components/index.d.ts.map +0 -1
  422. package/dist/types/src/components/useApp.d.ts +0 -44
  423. package/dist/types/src/components/useApp.d.ts.map +0 -1
  424. package/dist/types/src/components/useLoading.d.ts.map +0 -1
  425. package/dist/types/src/core/capabilities.d.ts +0 -117
  426. package/dist/types/src/core/capabilities.d.ts.map +0 -1
  427. package/dist/types/src/core/capabilities.test.d.ts +0 -2
  428. package/dist/types/src/core/capabilities.test.d.ts.map +0 -1
  429. package/dist/types/src/core/events.d.ts.map +0 -1
  430. package/dist/types/src/core/manager.d.ts +0 -126
  431. package/dist/types/src/core/manager.d.ts.map +0 -1
  432. package/dist/types/src/core/manager.test.d.ts +0 -2
  433. package/dist/types/src/core/manager.test.d.ts.map +0 -1
  434. package/dist/types/src/playground/debug/Debug.d.ts +0 -6
  435. package/dist/types/src/playground/debug/Debug.d.ts.map +0 -1
  436. package/dist/types/src/playground/debug/index.d.ts +0 -2
  437. package/dist/types/src/playground/debug/index.d.ts.map +0 -1
  438. package/dist/types/src/playground/debug/plugin.d.ts +0 -2
  439. package/dist/types/src/playground/debug/plugin.d.ts.map +0 -1
  440. package/dist/types/src/playground/generator/Main.d.ts +0 -6
  441. package/dist/types/src/playground/generator/Main.d.ts.map +0 -1
  442. package/dist/types/src/playground/generator/Toolbar.d.ts +0 -6
  443. package/dist/types/src/playground/generator/Toolbar.d.ts.map +0 -1
  444. package/dist/types/src/playground/generator/generator.d.ts +0 -7
  445. package/dist/types/src/playground/generator/generator.d.ts.map +0 -1
  446. package/dist/types/src/playground/generator/index.d.ts +0 -3
  447. package/dist/types/src/playground/generator/index.d.ts.map +0 -1
  448. package/dist/types/src/playground/generator/plugin.d.ts +0 -2
  449. package/dist/types/src/playground/generator/plugin.d.ts.map +0 -1
  450. package/dist/types/src/playground/layout/Layout.d.ts +0 -8
  451. package/dist/types/src/playground/layout/Layout.d.ts.map +0 -1
  452. package/dist/types/src/playground/layout/index.d.ts +0 -2
  453. package/dist/types/src/playground/layout/index.d.ts.map +0 -1
  454. package/dist/types/src/playground/layout/plugin.d.ts +0 -2
  455. package/dist/types/src/playground/layout/plugin.d.ts.map +0 -1
  456. package/dist/types/src/playground/logger/Toolbar.d.ts +0 -6
  457. package/dist/types/src/playground/logger/Toolbar.d.ts.map +0 -1
  458. package/dist/types/src/playground/logger/index.d.ts +0 -2
  459. package/dist/types/src/playground/logger/index.d.ts.map +0 -1
  460. package/dist/types/src/playground/logger/plugin.d.ts +0 -2
  461. package/dist/types/src/playground/logger/plugin.d.ts.map +0 -1
  462. package/dist/types/src/playground/logger/schema.d.ts +0 -13
  463. package/dist/types/src/playground/logger/schema.d.ts.map +0 -1
  464. package/dist/types/src/playground/playground.stories.d.ts.map +0 -1
  465. package/dist/types/src/plugin-intent/IntentPlugin.d.ts +0 -2
  466. package/dist/types/src/plugin-intent/IntentPlugin.d.ts.map +0 -1
  467. package/dist/types/src/plugin-intent/actions.d.ts +0 -36
  468. package/dist/types/src/plugin-intent/actions.d.ts.map +0 -1
  469. package/dist/types/src/plugin-intent/errors.d.ts +0 -16
  470. package/dist/types/src/plugin-intent/errors.d.ts.map +0 -1
  471. package/dist/types/src/plugin-intent/index.d.ts +0 -6
  472. package/dist/types/src/plugin-intent/index.d.ts.map +0 -1
  473. package/dist/types/src/plugin-intent/intent-dispatcher.d.ts +0 -139
  474. package/dist/types/src/plugin-intent/intent-dispatcher.d.ts.map +0 -1
  475. package/dist/types/src/plugin-intent/intent-dispatcher.test.d.ts +0 -2
  476. package/dist/types/src/plugin-intent/intent-dispatcher.test.d.ts.map +0 -1
  477. package/dist/types/src/plugin-intent/intent.d.ts +0 -63
  478. package/dist/types/src/plugin-intent/intent.d.ts.map +0 -1
  479. package/dist/types/src/plugin-intent/meta.d.ts +0 -3
  480. package/dist/types/src/plugin-intent/meta.d.ts.map +0 -1
  481. package/dist/types/src/plugin-settings/SettingsPlugin.d.ts +0 -2
  482. package/dist/types/src/plugin-settings/SettingsPlugin.d.ts.map +0 -1
  483. package/dist/types/src/plugin-settings/actions.d.ts +0 -25
  484. package/dist/types/src/plugin-settings/actions.d.ts.map +0 -1
  485. package/dist/types/src/plugin-settings/app-graph-builder.d.ts +0 -4
  486. package/dist/types/src/plugin-settings/app-graph-builder.d.ts.map +0 -1
  487. package/dist/types/src/plugin-settings/index.d.ts +0 -3
  488. package/dist/types/src/plugin-settings/index.d.ts.map +0 -1
  489. package/dist/types/src/plugin-settings/intent-resolver.d.ts +0 -4
  490. package/dist/types/src/plugin-settings/intent-resolver.d.ts.map +0 -1
  491. package/dist/types/src/plugin-settings/meta.d.ts +0 -3
  492. package/dist/types/src/plugin-settings/meta.d.ts.map +0 -1
  493. package/dist/types/src/plugin-settings/store.d.ts +0 -5
  494. package/dist/types/src/plugin-settings/store.d.ts.map +0 -1
  495. package/dist/types/src/plugin-settings/translations.d.ts +0 -11
  496. package/dist/types/src/plugin-settings/translations.d.ts.map +0 -1
  497. package/dist/types/src/react/ErrorBoundary.d.ts +0 -30
  498. package/dist/types/src/react/ErrorBoundary.d.ts.map +0 -1
  499. package/dist/types/src/react/IntentContext.d.ts +0 -8
  500. package/dist/types/src/react/IntentContext.d.ts.map +0 -1
  501. package/dist/types/src/react/PluginManagerProvider.d.ts +0 -10
  502. package/dist/types/src/react/PluginManagerProvider.d.ts.map +0 -1
  503. package/dist/types/src/react/Surface.d.ts +0 -12
  504. package/dist/types/src/react/Surface.d.ts.map +0 -1
  505. package/dist/types/src/react/Surface.stories.d.ts +0 -17
  506. package/dist/types/src/react/Surface.stories.d.ts.map +0 -1
  507. package/dist/types/src/react/common.d.ts +0 -13
  508. package/dist/types/src/react/common.d.ts.map +0 -1
  509. package/dist/types/src/react/index.d.ts +0 -7
  510. package/dist/types/src/react/index.d.ts.map +0 -1
  511. package/dist/types/src/react/useCapabilities.d.ts +0 -13
  512. package/dist/types/src/react/useCapabilities.d.ts.map +0 -1
  513. package/dist/types/src/react/useIntentResolver.d.ts +0 -3
  514. package/dist/types/src/react/useIntentResolver.d.ts.map +0 -1
  515. package/dist/types/src/worker.d.ts +0 -4
  516. package/dist/types/src/worker.d.ts.map +0 -1
  517. package/src/common/collaboration.ts +0 -18
  518. package/src/common/events.ts +0 -79
  519. package/src/common/file.ts +0 -22
  520. package/src/common/graph.ts +0 -30
  521. package/src/common/layout.ts +0 -277
  522. package/src/common/surface.ts +0 -83
  523. package/src/components/App.stories.tsx +0 -33
  524. package/src/components/App.tsx +0 -59
  525. package/src/components/DefaultFallback.tsx +0 -26
  526. package/src/components/useApp.tsx +0 -164
  527. package/src/core/capabilities.test.ts +0 -136
  528. package/src/core/capabilities.ts +0 -259
  529. package/src/core/manager.test.ts +0 -516
  530. package/src/core/manager.ts +0 -604
  531. package/src/playground/debug/Debug.tsx +0 -39
  532. package/src/playground/debug/plugin.ts +0 -16
  533. package/src/playground/generator/Main.tsx +0 -71
  534. package/src/playground/generator/Toolbar.tsx +0 -47
  535. package/src/playground/generator/generator.ts +0 -48
  536. package/src/playground/generator/index.ts +0 -6
  537. package/src/playground/generator/plugin.ts +0 -22
  538. package/src/playground/layout/Layout.tsx +0 -33
  539. package/src/playground/layout/plugin.ts +0 -18
  540. package/src/playground/logger/Toolbar.tsx +0 -30
  541. package/src/playground/logger/plugin.ts +0 -41
  542. package/src/playground/logger/schema.ts +0 -12
  543. package/src/playground/playground.stories.tsx +0 -46
  544. package/src/plugin-intent/IntentPlugin.ts +0 -20
  545. package/src/plugin-intent/actions.ts +0 -31
  546. package/src/plugin-intent/errors.ts +0 -40
  547. package/src/plugin-intent/index.ts +0 -9
  548. package/src/plugin-intent/intent-dispatcher.test.ts +0 -286
  549. package/src/plugin-intent/intent-dispatcher.ts +0 -337
  550. package/src/plugin-intent/intent.ts +0 -154
  551. package/src/plugin-intent/meta.ts +0 -10
  552. package/src/plugin-settings/SettingsPlugin.ts +0 -34
  553. package/src/plugin-settings/actions.ts +0 -25
  554. package/src/plugin-settings/app-graph-builder.ts +0 -160
  555. package/src/plugin-settings/index.ts +0 -6
  556. package/src/plugin-settings/intent-resolver.ts +0 -35
  557. package/src/plugin-settings/meta.ts +0 -10
  558. package/src/plugin-settings/store.ts +0 -33
  559. package/src/plugin-settings/translations.ts +0 -19
  560. package/src/react/ErrorBoundary.tsx +0 -56
  561. package/src/react/IntentContext.tsx +0 -35
  562. package/src/react/Surface.stories.tsx +0 -101
  563. package/src/react/Surface.tsx +0 -86
  564. package/src/react/common.ts +0 -13
  565. package/src/react/index.ts +0 -10
  566. package/src/react/useCapabilities.ts +0 -31
  567. package/src/react/useIntentResolver.ts +0 -22
  568. package/src/worker.ts +0 -11
  569. /package/dist/lib/browser/{intent-dispatcher-6SHA5B3N.mjs.map → chunk-J5LGTIGS.mjs.map} +0 -0
  570. /package/dist/lib/browser/{worker.mjs.map → common/activation-events.mjs.map} +0 -0
  571. /package/dist/lib/{node-esm/intent-dispatcher-SIYQ5ZIU.mjs.map → browser/common/capabilities.mjs.map} +0 -0
  572. /package/dist/lib/{node-esm/worker.mjs.map → browser/core/activation-event.mjs.map} +0 -0
@@ -0,0 +1,86 @@
1
+ //
2
+ // Copyright 2022 DXOS.org
3
+ //
4
+
5
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
6
+ import * as Effect from 'effect/Effect';
7
+ import React, { useEffect } from 'react';
8
+
9
+ import { withTheme } from '@dxos/react-ui/testing';
10
+
11
+ import { ActivationEvents, Capabilities } from '../../../common';
12
+ import { Capability, Plugin } from '../../../core';
13
+ import { useApp } from '../../hooks';
14
+
15
+ // Minimal plugin that contributes a ReactRoot.
16
+ const TestPlugin = Plugin.define<{ error?: boolean }>({
17
+ id: 'org.dxos.plugin.test',
18
+ name: 'Test Plugin',
19
+ tags: ['system'],
20
+ }).pipe(
21
+ Plugin.addModule(({ error }) => ({
22
+ id: 'TestMain',
23
+ activatesOn: ActivationEvents.Startup,
24
+ activate: () =>
25
+ Effect.succeed([
26
+ Capability.contributes(Capabilities.ReactRoot, {
27
+ id: 'org.dxos.plugin.test.root',
28
+ root: () => {
29
+ useEffect(() => {
30
+ let t: NodeJS.Timeout;
31
+ if (error) {
32
+ console.log('Ticking...');
33
+ t = setTimeout(() => {
34
+ console.log('Bang!');
35
+ throw new Error('Runtime error');
36
+ }, 3_000);
37
+ }
38
+
39
+ return () => clearTimeout(t);
40
+ }, [error]);
41
+
42
+ return <h1 className='text-lg'>App Started</h1>;
43
+ },
44
+ }),
45
+ ]),
46
+ })),
47
+ Plugin.make,
48
+ );
49
+
50
+ type DefaultStoryProps = { plugins?: Plugin.Plugin[] };
51
+
52
+ const DefaultStory = ({ plugins }: DefaultStoryProps) => {
53
+ const App = useApp({
54
+ plugins,
55
+ placeholder: () => {
56
+ return <div className='text-description'>Loading...</div>;
57
+ },
58
+ });
59
+
60
+ return <App />;
61
+ };
62
+
63
+ const meta = {
64
+ title: 'sdk/app-framework/components/App',
65
+ render: DefaultStory,
66
+ decorators: [withTheme()],
67
+ parameters: {
68
+ layout: 'centered',
69
+ },
70
+ } satisfies Meta;
71
+
72
+ export default meta;
73
+
74
+ type Story = StoryObj<typeof meta>;
75
+
76
+ export const Default: Story = {
77
+ args: {
78
+ plugins: [TestPlugin({})],
79
+ },
80
+ };
81
+
82
+ export const WithError: Story = {
83
+ args: {
84
+ plugins: [TestPlugin({ error: true })],
85
+ },
86
+ };
@@ -0,0 +1,81 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import React, { type PropsWithChildren, useEffect } from 'react';
6
+
7
+ import { Capabilities } from '../../../common';
8
+ import { topologicalSort } from '../../../helpers';
9
+ import { LoadingState, type StartupProgress, type UseAppOptions, useCapabilities, useLoading } from '../../hooks';
10
+
11
+ export type AppProps = Pick<UseAppOptions, 'placeholder' | 'debounce'> & {
12
+ ready: boolean;
13
+ error: unknown;
14
+ progress?: StartupProgress;
15
+ };
16
+
17
+ const FIRST_INTERACTIVE_MARK = 'app-framework:first-interactive';
18
+
19
+ export const App = ({ placeholder: Placeholder, ready, error, debounce, progress }: AppProps) => {
20
+ const reactContexts = useCapabilities(Capabilities.ReactContext);
21
+ const reactRoots = useCapabilities(Capabilities.ReactRoot);
22
+ const stage = useLoading(ready, debounce);
23
+ const placeholderDismissed = stage >= LoadingState.Done;
24
+
25
+ // Emit a once-per-app `app-framework:first-interactive` mark the first time
26
+ // the placeholder is dismissed and the real app shell renders. Closes the
27
+ // gap between `Startup` activated and the first interactive paint.
28
+ //
29
+ // Also dismisses the native-DOM boot loader from
30
+ // `@dxos/app-framework/vite-plugin` here — the framework owns the
31
+ // handoff-complete signal, so dismissing in `App` covers both hosts that
32
+ // wire in a `Placeholder` (which may have its own dismiss path) and hosts
33
+ // that don't (the loader would otherwise sit forever as a `z-index: 10`
34
+ // overlay covering the rendered shell).
35
+ useEffect(() => {
36
+ if (!placeholderDismissed) {
37
+ return;
38
+ }
39
+ if (performance.getEntriesByName(FIRST_INTERACTIVE_MARK).length === 0) {
40
+ performance.mark(FIRST_INTERACTIVE_MARK);
41
+ }
42
+ (window as { __bootLoader?: { dismiss?: () => void } }).__bootLoader?.dismiss?.();
43
+ }, [placeholderDismissed]);
44
+
45
+ if (error) {
46
+ // This triggers the error boundary to provide UI feedback for the startup error.
47
+ throw error;
48
+ }
49
+
50
+ // TODO(wittjosiah): Consider using Suspense instead.
51
+ if (!placeholderDismissed) {
52
+ if (!Placeholder) {
53
+ return null;
54
+ }
55
+
56
+ return <Placeholder stage={stage} progress={progress} />;
57
+ }
58
+
59
+ const ComposedContext = composeContexts(reactContexts);
60
+ return (
61
+ <ComposedContext>
62
+ {reactRoots.map(({ id, root: Component }) => (
63
+ <Component key={id} />
64
+ ))}
65
+ </ComposedContext>
66
+ );
67
+ };
68
+
69
+ const composeContexts = (contexts: Capabilities.ReactContext[]) => {
70
+ if (contexts.length === 0) {
71
+ return ({ children }: PropsWithChildren) => <>{children}</>;
72
+ }
73
+
74
+ return topologicalSort(contexts)
75
+ .map(({ context }) => context)
76
+ .reduce((Acc, Next) => ({ children }) => (
77
+ <Acc>
78
+ <Next>{children}</Next>
79
+ </Acc>
80
+ ));
81
+ };
@@ -2,4 +2,4 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- export * from './plugin';
5
+ export * from './App';
@@ -0,0 +1,77 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
6
+ import React, { useEffect, useState } from 'react';
7
+ import { expect, within } from 'storybook/test';
8
+
9
+ import { Composer } from '@dxos/brand';
10
+ import { Input, Panel, Toolbar } from '@dxos/react-ui';
11
+ import { withLayout, withTheme } from '@dxos/react-ui/testing';
12
+
13
+ import { Placeholder } from './Placeholder';
14
+
15
+ /**
16
+ * The story renders the brand-agnostic `Placeholder` from `@dxos/app-framework/ui`
17
+ * with the Composer brand icon as its `logo`, so the storybook mirrors what
18
+ * composer-app actually mounts in production. The render function form lets
19
+ * the SVG accept the placeholder's animation `className` directly.
20
+ */
21
+ const meta = {
22
+ title: 'sdk/app-framework/components/Placeholder',
23
+ component: Placeholder,
24
+ render: () => {
25
+ const [stage, setStage] = useState(0);
26
+ const [auto, setAuto] = useState(false);
27
+ useEffect(() => {
28
+ if (!auto) {
29
+ return;
30
+ }
31
+
32
+ const interval = setInterval(() => {
33
+ setStage((prev) => {
34
+ return prev >= 2 ? 0 : prev + 1;
35
+ });
36
+ }, 3_000);
37
+
38
+ return () => clearInterval(interval);
39
+ }, [auto]);
40
+
41
+ return (
42
+ <Panel.Root>
43
+ <Panel.Toolbar asChild>
44
+ <Toolbar.Root classNames='gap-2'>
45
+ <Input.Root>
46
+ <Input.Checkbox checked={auto} onCheckedChange={(checked) => setAuto(checked === true)} />
47
+ <Input.Label>Auto</Input.Label>
48
+ </Input.Root>
49
+ <Toolbar.Button onClick={() => setStage((prev) => (prev < 2 ? prev + 1 : 0))}>Next</Toolbar.Button>
50
+ <Toolbar.Text>{stage}</Toolbar.Text>
51
+ </Toolbar.Root>
52
+ </Panel.Toolbar>
53
+ <Panel.Content>
54
+ <Placeholder stage={stage} logo={(logoProps) => <Composer {...logoProps} />} />
55
+ </Panel.Content>
56
+ </Panel.Root>
57
+ );
58
+ },
59
+ decorators: [withTheme(), withLayout({ layout: 'fullscreen' })],
60
+ tags: ['test'],
61
+ } satisfies Meta<typeof Placeholder>;
62
+
63
+ export default meta;
64
+
65
+ type Story = StoryObj<typeof meta>;
66
+
67
+ export const Default: Story = {
68
+ args: {
69
+ stage: 0,
70
+ },
71
+ play: async ({ canvasElement }) => {
72
+ const canvas = within(canvasElement);
73
+ // Smoke test: the toolbar's `Next` button is rendered alongside the
74
+ // placeholder, so the story mounted without throwing.
75
+ await expect(canvas.getByRole('button', { name: 'Next' })).toBeInTheDocument();
76
+ },
77
+ };
@@ -0,0 +1,156 @@
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 } from '@dxos/react-ui';
9
+ import { mx } from '@dxos/ui-theme';
10
+
11
+ import { type PlaceholderProps as PlaceholderSlotProps } from '../../hooks';
12
+
13
+ declare global {
14
+ interface Window {
15
+ /**
16
+ * Driver injected by `@dxos/app-framework/vite-plugin`'s `bootLoaderPlugin`.
17
+ * Declared here so the {@link Placeholder} can dismiss the native-DOM
18
+ * loader once the React placeholder commits without each host having to
19
+ * re-declare the type.
20
+ */
21
+ __bootLoader?: {
22
+ status: (payload: {
23
+ event?: string;
24
+ module?: string;
25
+ humanized: string;
26
+ /**
27
+ * Optional `(index/total)` tick. When present, the loader replaces the
28
+ * current line in place ("Loading plugins (12/80)") instead of
29
+ * appending a new entry — keeps the visible log compact during long
30
+ * counted phases like plugin chunk-loading or module activation.
31
+ */
32
+ range?: { index: number; total: number };
33
+ }) => void;
34
+ progress: (fraction?: number) => void;
35
+ dismiss: () => void;
36
+ };
37
+ }
38
+ }
39
+
40
+ export type PlaceholderComponentProps = PlaceholderSlotProps & {
41
+ /**
42
+ * Brand mark rendered while the React tree settles. Pass either a static
43
+ * `ReactNode` (the framework wraps it in a sizing/animation div) or a
44
+ * render function that receives the precomputed `className` so the host
45
+ * can apply it directly to its logo (e.g. an SVG that accepts `className`
46
+ * — `composer-app` passes `(p) => <Composer {...p} />` from `@dxos/brand`).
47
+ */
48
+ logo?: ReactNode | ((props: { className: string }) => ReactNode);
49
+ };
50
+
51
+ /**
52
+ * React placeholder. The native-DOM boot loader is the visible UI through
53
+ * stages 0 (Loading) and 1 (FadeIn): we render `null` until `stage >= 2`
54
+ * (FadeOut) and instead feed activation progress + status into the still-
55
+ * alive boot loader. At stage 2 the loader dismisses and the React mark
56
+ * appears for the cross-fade to the real shell:
57
+ *
58
+ * - composer-app fills `0 → 50%` from `getPlugins`'s per-chunk counter.
59
+ * - this component fills `50 → 100%` from `useApp`'s
60
+ * `startupProgress.progress` (`activated / total` modules) and pushes
61
+ * the per-module status text to the loader's status line.
62
+ * - at `stage >= 2` the boot loader is dismissed and the React mark
63
+ * starts its `FadeOut → Done` shrink-and-fade.
64
+ *
65
+ * Stage progression (driven by `useApp`):
66
+ * - `0` — Loading: native-DOM boot loader visible. Placeholder renders nothing.
67
+ * - `1` — FadeIn: same — boot loader still owns the screen.
68
+ * - `2` — FadeOut: boot loader dismissed, React mark visible at full opacity then shrinks.
69
+ */
70
+ export const Placeholder = ({ stage = 1, progress, logo }: PlaceholderComponentProps) => {
71
+ // Used in tests to exercise the error boundary & reset dialog.
72
+ if (location.search === '?throw') {
73
+ throw new Error('Test error');
74
+ }
75
+
76
+ // Phase B: feed activation progress + status to the still-visible boot
77
+ // loader. Maps `[0, 1]` activation → `[0.5, 1]` of the ring; forwards
78
+ // the raw activation source (`event` / `module`) plus the pre-humanised
79
+ // label to `__bootLoader.status` so the loader gets to decide how to
80
+ // render and trace each transition (current default policy: "Activating
81
+ // <humanizedName>"; trace mode and timings track the structured fields).
82
+ // No-op once the loader has been dismissed (its `status()` early-returns
83
+ // when the boot DOM is gone). Skipping `stage >= 2` lets the dismissal
84
+ // run uncontended.
85
+ useEffect(() => {
86
+ if (stage >= 2) {
87
+ return;
88
+ }
89
+ const fraction = progress?.progress ?? 0;
90
+ window.__bootLoader?.progress(0.5 + fraction * 0.5);
91
+ if (progress?.humanizedName) {
92
+ window.__bootLoader?.status({
93
+ event: progress.event,
94
+ module: progress.module,
95
+ humanized: `Activating ${progress.humanizedName}`,
96
+ });
97
+ }
98
+ }, [stage, progress?.progress, progress?.event, progress?.module, progress?.humanizedName]);
99
+
100
+ // Hand off from the native-DOM boot loader once the placeholder starts
101
+ // fading out — keeping the loader visible through `stage 0` and `stage 1`
102
+ // means the ring stays the visible source of truth for activation
103
+ // progress. `useLayoutEffect` runs before the next paint so the loader
104
+ // DOM is removed in the same frame the cross-fade begins.
105
+ useLayoutEffect(() => {
106
+ if (stage >= 2) {
107
+ window.__bootLoader?.dismiss();
108
+ }
109
+ }, [stage]);
110
+
111
+ // Backstop for the fast-load path where `useLoading` can skip straight
112
+ // from stage 0 to `Done` (ready=true at the first debounce tick) — the
113
+ // stage-driven effect above never sees `stage >= 2`, so dismiss on
114
+ // unmount instead. The `stageRef` guard is what keeps StrictMode's
115
+ // synthetic mount → cleanup → remount cycle from prematurely dismissing
116
+ // the loader: the synthetic cleanup runs while `stageRef.current === 0`,
117
+ // skips the dismiss, and the real unmount (later, at stage `Done`)
118
+ // performs it.
119
+ const stageRef = useRef(stage);
120
+ stageRef.current = stage;
121
+ useEffect(() => {
122
+ return () => {
123
+ if (stageRef.current >= 3 /* Done */) {
124
+ window.__bootLoader?.dismiss();
125
+ }
126
+ };
127
+ }, []);
128
+
129
+ // Defer rendering anything until the FadeOut stage. The boot loader owns
130
+ // the screen during stages 0 and 1, so any DOM we render here would just
131
+ // sit invisibly behind it — and rendering null avoids paint cost during
132
+ // the longest part of the loading sequence (plugin activation).
133
+ if (stage < 2) {
134
+ return null;
135
+ }
136
+
137
+ const logoClassName = mx(
138
+ 'h-[300px] w-[300px] scale-600 transition-all duration-500 ease-in-out filter grayscale opacity-0',
139
+ stage >= 1 && 'scale-100 grayscale-0 opacity-70',
140
+ stage >= 2 && 'scale-50 opacity-0',
141
+ );
142
+
143
+ return (
144
+ <ThemeProvider tx={defaultTx}>
145
+ <div className='relative dx-container h-dvh flex flex-col'>
146
+ <div className='flex flex-col grow justify-center items-center'>
147
+ {typeof logo === 'function' ? (
148
+ logo({ className: logoClassName })
149
+ ) : logo ? (
150
+ <div className={logoClassName}>{logo}</div>
151
+ ) : null}
152
+ </div>
153
+ </div>
154
+ </ThemeProvider>
155
+ );
156
+ };
@@ -2,4 +2,4 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- export * from './plugin';
5
+ export * from './Placeholder';
@@ -0,0 +1,184 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { Atom, useAtomValue } from '@effect-atom/atom-react';
6
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
7
+ import * as Effect from 'effect/Effect';
8
+ import React, { useEffect, useMemo, useState } from 'react';
9
+
10
+ import { withLayout, withTheme } from '@dxos/react-ui/testing';
11
+ import { useWebComponentContext } from '@dxos/web-context-react';
12
+
13
+ import { ActivationEvents, Capabilities } from '../../../common';
14
+ import { PluginManagerContext } from '../../../context';
15
+ import { Capability, Plugin } from '../../../core';
16
+ import { useApp } from '../../hooks';
17
+
18
+ // Define the Counter capability
19
+ const Counter = Capability.make<{ count: number; increment: () => void }>('example/counter');
20
+
21
+ const CountStatus = () => {
22
+ const manager = useWebComponentContext(PluginManagerContext);
23
+ const capabilitiesAtom = useMemo(
24
+ () => manager?.capabilities.atom(Counter) ?? Atom.make<{ count: number; increment: () => void }[]>([]),
25
+ [manager],
26
+ );
27
+ const capabilities = useAtomValue(capabilitiesAtom);
28
+ const counter = (capabilities as any)[0];
29
+ const [count, setCount] = useState(counter?.count ?? 0);
30
+
31
+ useEffect(() => {
32
+ if (!counter) {
33
+ return;
34
+ }
35
+ setCount(counter.count);
36
+ if ('subscribe' in counter && typeof counter.subscribe === 'function') {
37
+ return counter.subscribe(() => setCount(counter.count));
38
+ }
39
+ }, [counter]);
40
+
41
+ if (!manager) {
42
+ return null;
43
+ }
44
+
45
+ const isEven = count % 2 === 0;
46
+
47
+ return (
48
+ <div
49
+ className={`mt-4 px-4 py-2 rounded-full text-sm font-medium transition-colors ${
50
+ isEven
51
+ ? 'bg-emerald-100 text-emerald-800 dark:bg-emerald-900/30 dark:text-emerald-400'
52
+ : 'bg-amber-100 text-amber-800 dark:bg-amber-900/30 dark:text-amber-400'
53
+ }`}
54
+ >
55
+ Status: {isEven ? 'Even' : 'Odd'}
56
+ </div>
57
+ );
58
+ };
59
+
60
+ // A component that consumes the PluginManager via web context
61
+ const CounterComponent = () => {
62
+ // Use the web-context hook to get the PluginManager
63
+ const manager = useWebComponentContext(PluginManagerContext);
64
+ const capabilitiesAtom = useMemo(
65
+ () => manager?.capabilities.atom(Counter) ?? Atom.make<{ count: number; increment: () => void }[]>([]),
66
+ [manager],
67
+ );
68
+ const capabilities = useAtomValue(capabilitiesAtom);
69
+ const counter = (capabilities as any)[0];
70
+ const [count, setCount] = useState(counter?.count ?? 0);
71
+
72
+ useEffect(() => {
73
+ if (!counter) {
74
+ return;
75
+ }
76
+ setCount(counter.count);
77
+ if ('subscribe' in counter && typeof counter.subscribe === 'function') {
78
+ return counter.subscribe(() => setCount(counter.count));
79
+ }
80
+ }, [counter]);
81
+
82
+ if (!manager) {
83
+ return <div className='p-4 text-error-text'>Error: Context not found</div>;
84
+ }
85
+
86
+ return (
87
+ <div className='flex flex-col items-center justify-center h-screen bg-neutral-100 dark:bg-neutral-900 text-neutral-900 dark:text-white'>
88
+ <div className='p-8 bg-white dark:bg-neutral-800 rounded-lg shadow-xl border border-neutral-200 dark:border-neutral-700 max-w-md w-full'>
89
+ <h2 className='text-2xl font-bold mb-6 text-center text-primary-600 dark:text-primary-400'>
90
+ Web Context Counter
91
+ </h2>
92
+
93
+ <div className='flex flex-col items-center gap-6'>
94
+ <div className='text-6xl font-mono font-bold tabular-nums tracking-tighter'>{count}</div>
95
+
96
+ <button
97
+ className='px-6 py-3 bg-primary-600 hover:bg-primary-700 text-white font-semibold rounded-full transition-colors shadow-md active:transform active:scale-95'
98
+ onClick={() => {
99
+ const counter = manager.capabilities.get(Counter);
100
+ counter.increment();
101
+ }}
102
+ >
103
+ Increment
104
+ </button>
105
+
106
+ <CountStatus />
107
+ </div>
108
+
109
+ <div className='mt-8 pt-4 border-t border-neutral-200 dark:border-neutral-700 text-center'>
110
+ <p className='text-sm text-neutral-500 dark:text-neutral-400'>
111
+ This component accesses the <code>PluginManager</code> via <code>useWebComponentContext</code>.
112
+ </p>
113
+ </div>
114
+ </div>
115
+ </div>
116
+ );
117
+ };
118
+
119
+ // Plugin that provides the Counter capability and renders the UI
120
+ const CounterPlugin = Plugin.define({
121
+ id: 'org.dxos.plugin.counter',
122
+ name: 'Counter Plugin',
123
+ tags: ['system'],
124
+ }).pipe(
125
+ Plugin.addModule({
126
+ id: 'CounterMain',
127
+ activatesOn: ActivationEvents.Startup,
128
+ activate: () => {
129
+ const listeners = new Set<() => void>();
130
+ const counter = {
131
+ count: 0,
132
+ increment: () => {
133
+ counter.count++;
134
+ listeners.forEach((listener) => listener());
135
+ },
136
+ subscribe: (listener: () => void) => {
137
+ listeners.add(listener);
138
+ return () => listeners.delete(listener);
139
+ },
140
+ };
141
+
142
+ return Effect.succeed([
143
+ // Contribute the state/logic
144
+ Capability.contributes(Counter, counter),
145
+
146
+ // Contribute the UI
147
+ Capability.contributes(Capabilities.ReactRoot, {
148
+ id: 'org.dxos.plugin.counter.root',
149
+ root: CounterComponent,
150
+ }),
151
+ ]);
152
+ },
153
+ }),
154
+ Plugin.make,
155
+ )();
156
+
157
+ const plugins = [CounterPlugin];
158
+ const placeholder = () => (
159
+ <div className='flex h-screen items-center justify-center p-4 text-lg text-neutral-500'>
160
+ Initializing Application...
161
+ </div>
162
+ );
163
+
164
+ const DefaultStory = () => {
165
+ const App = useApp({
166
+ plugins,
167
+ placeholder,
168
+ });
169
+
170
+ return <App />;
171
+ };
172
+
173
+ const meta = {
174
+ title: 'sdk/app-framework/components/PluginManagerContext',
175
+ render: DefaultStory,
176
+ decorators: [withTheme(), withLayout({ layout: 'fullscreen' })],
177
+ parameters: {
178
+ layout: 'fullscreen',
179
+ },
180
+ } satisfies Meta;
181
+
182
+ export default meta;
183
+
184
+ export const Default: StoryObj<typeof meta> = {};
@@ -6,14 +6,14 @@ import { createContext, useContext } from 'react';
6
6
 
7
7
  import { raise } from '@dxos/debug';
8
8
 
9
- import { type PluginManager } from '../core';
9
+ import { type PluginManager } from '../../../core';
10
10
 
11
- const PluginManagerContext = createContext<PluginManager | undefined>(undefined);
11
+ const PluginManagerContext = createContext<PluginManager.PluginManager | undefined>(undefined);
12
12
 
13
13
  /**
14
14
  * Get the plugin manager.
15
15
  */
16
- export const usePluginManager = (): PluginManager =>
16
+ export const usePluginManager = (): PluginManager.PluginManager =>
17
17
  useContext(PluginManagerContext) ?? raise(new Error('Missing PluginManagerContext'));
18
18
 
19
19
  /**
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ export * from './PluginManagerProvider';