@dxos/app-framework 0.8.4-main.40e3dcdf1b → 0.8.4-main.43cb759274

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 (389) hide show
  1. package/LICENSE +102 -5
  2. package/README.md +1 -1
  3. package/dist/lib/browser/{capability-LF3OXSCV.mjs → capability-JCUNWZ66.mjs} +12 -11
  4. package/dist/lib/browser/capability-JCUNWZ66.mjs.map +7 -0
  5. package/dist/lib/browser/{chunk-WEBSGU5L.mjs → chunk-2ZIYRDAF.mjs} +20 -5
  6. package/dist/lib/browser/chunk-2ZIYRDAF.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-7MBI66M7.mjs +587 -0
  12. package/dist/lib/browser/chunk-7MBI66M7.mjs.map +7 -0
  13. package/dist/lib/browser/chunk-BMLCIFZW.mjs +1467 -0
  14. package/dist/lib/browser/chunk-BMLCIFZW.mjs.map +7 -0
  15. package/dist/lib/browser/{chunk-7M4467QR.mjs → chunk-DC3WRPBV.mjs} +100 -18
  16. package/dist/lib/browser/chunk-DC3WRPBV.mjs.map +7 -0
  17. package/dist/lib/browser/{chunk-JGWCBVKJ.mjs → chunk-E5DTDNDY.mjs} +28 -55
  18. package/dist/lib/browser/chunk-E5DTDNDY.mjs.map +7 -0
  19. package/dist/lib/browser/{chunk-TGX63LTL.mjs → chunk-FJ4765WW.mjs} +1 -1
  20. package/dist/lib/browser/{chunk-TGX63LTL.mjs.map → chunk-FJ4765WW.mjs.map} +2 -2
  21. package/dist/lib/browser/chunk-FO3IYSLV.mjs +68 -0
  22. package/dist/lib/browser/chunk-FO3IYSLV.mjs.map +7 -0
  23. package/dist/lib/browser/{chunk-YNFPIQGB.mjs → chunk-IW44C7UL.mjs} +9 -2
  24. package/dist/lib/browser/chunk-IW44C7UL.mjs.map +7 -0
  25. package/dist/lib/browser/chunk-KZUDO43J.mjs +422 -0
  26. package/dist/lib/browser/chunk-KZUDO43J.mjs.map +7 -0
  27. package/dist/lib/browser/chunk-Q2GLJTVV.mjs +12 -0
  28. package/dist/lib/browser/chunk-Q2GLJTVV.mjs.map +7 -0
  29. package/dist/lib/browser/chunk-VBG5F5UF.mjs +476 -0
  30. package/dist/lib/browser/chunk-VBG5F5UF.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 +18 -4
  39. package/dist/lib/browser/core/url-loader.mjs +24 -0
  40. package/dist/lib/browser/index.mjs +51 -54
  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-4FUA4TRP.mjs +89 -0
  44. package/dist/lib/browser/process-manager-capability-4FUA4TRP.mjs.map +7 -0
  45. package/dist/lib/browser/testing/index.mjs +198 -54
  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 +22 -15
  50. package/dist/lib/node-esm/{capability-SA6LPYGL.mjs → capability-7TCQK7ZP.mjs} +12 -11
  51. package/dist/lib/node-esm/capability-7TCQK7ZP.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-4BX2AE47.mjs +1468 -0
  55. package/dist/lib/node-esm/chunk-4BX2AE47.mjs.map +7 -0
  56. package/dist/lib/node-esm/{chunk-SB5ODNPX.mjs → chunk-CTKEZHKF.mjs} +9 -2
  57. package/dist/lib/node-esm/chunk-CTKEZHKF.mjs.map +7 -0
  58. package/dist/lib/node-esm/chunk-FPW45EZH.mjs +14 -0
  59. package/dist/lib/node-esm/chunk-FPW45EZH.mjs.map +7 -0
  60. package/dist/lib/node-esm/chunk-GEWHMHM7.mjs +588 -0
  61. package/dist/lib/node-esm/chunk-GEWHMHM7.mjs.map +7 -0
  62. package/dist/lib/node-esm/chunk-KFZEB6BV.mjs +29 -0
  63. package/dist/lib/node-esm/chunk-KFZEB6BV.mjs.map +7 -0
  64. package/dist/lib/node-esm/{chunk-3D66SZHP.mjs → chunk-KSH4OVMY.mjs} +28 -55
  65. package/dist/lib/node-esm/chunk-KSH4OVMY.mjs.map +7 -0
  66. package/dist/lib/node-esm/{chunk-SQICGJBW.mjs → chunk-QBUGLR4H.mjs} +20 -5
  67. package/dist/lib/node-esm/chunk-QBUGLR4H.mjs.map +7 -0
  68. package/dist/lib/node-esm/chunk-WK7OIQKI.mjs +70 -0
  69. package/dist/lib/node-esm/chunk-WK7OIQKI.mjs.map +7 -0
  70. package/dist/lib/node-esm/chunk-XGBUKRCK.mjs +423 -0
  71. package/dist/lib/node-esm/chunk-XGBUKRCK.mjs.map +7 -0
  72. package/dist/lib/node-esm/{chunk-JHFY3HTS.mjs → chunk-XIGPWXCQ.mjs} +100 -18
  73. package/dist/lib/node-esm/chunk-XIGPWXCQ.mjs.map +7 -0
  74. package/dist/lib/node-esm/{chunk-6REV5DE7.mjs → chunk-XOCUANHO.mjs} +3 -2
  75. package/dist/lib/node-esm/chunk-XOCUANHO.mjs.map +7 -0
  76. package/dist/lib/node-esm/chunk-Y7JKXNDU.mjs +477 -0
  77. package/dist/lib/node-esm/chunk-Y7JKXNDU.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 +18 -4
  86. package/dist/lib/node-esm/core/url-loader.mjs +25 -0
  87. package/dist/lib/node-esm/index.mjs +51 -54
  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-F23D62RN.mjs +90 -0
  91. package/dist/lib/node-esm/process-manager-capability-F23D62RN.mjs.map +7 -0
  92. package/dist/lib/node-esm/testing/index.mjs +198 -54
  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 +22 -15
  97. package/dist/plugin/node-esm/index.mjs +971 -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/index.d.ts +0 -1
  109. package/dist/types/src/common/index.d.ts.map +1 -1
  110. package/dist/types/src/common/translations.d.ts +1 -1
  111. package/dist/types/src/core/activation-event.d.ts +4 -4
  112. package/dist/types/src/core/activation-event.d.ts.map +1 -1
  113. package/dist/types/src/core/capability-manager.d.ts +9 -0
  114. package/dist/types/src/core/capability-manager.d.ts.map +1 -1
  115. package/dist/types/src/core/capability.d.ts +13 -2
  116. package/dist/types/src/core/capability.d.ts.map +1 -1
  117. package/dist/types/src/core/edge-registry-plugin-provider.d.ts +30 -0
  118. package/dist/types/src/core/edge-registry-plugin-provider.d.ts.map +1 -0
  119. package/dist/types/src/core/index.d.ts +6 -0
  120. package/dist/types/src/core/index.d.ts.map +1 -1
  121. package/dist/types/src/core/plugin-asset-cache.d.ts +71 -0
  122. package/dist/types/src/core/plugin-asset-cache.d.ts.map +1 -0
  123. package/dist/types/src/core/plugin-manager.d.ts +238 -7
  124. package/dist/types/src/core/plugin-manager.d.ts.map +1 -1
  125. package/dist/types/src/core/plugin-manifest.d.ts +101 -0
  126. package/dist/types/src/core/plugin-manifest.d.ts.map +1 -0
  127. package/dist/types/src/core/plugin-manifest.test.d.ts +2 -0
  128. package/dist/types/src/core/plugin-manifest.test.d.ts.map +1 -0
  129. package/dist/types/src/core/plugin.d.ts +213 -11
  130. package/dist/types/src/core/plugin.d.ts.map +1 -1
  131. package/dist/types/src/core/registry.d.ts +107 -0
  132. package/dist/types/src/core/registry.d.ts.map +1 -0
  133. package/dist/types/src/core/url-loader.d.ts +127 -0
  134. package/dist/types/src/core/url-loader.d.ts.map +1 -0
  135. package/dist/types/src/core/url-loader.test.d.ts +2 -0
  136. package/dist/types/src/core/url-loader.test.d.ts.map +1 -0
  137. package/dist/types/src/helpers.d.ts.map +1 -1
  138. package/dist/types/src/index.d.ts +1 -2
  139. package/dist/types/src/index.d.ts.map +1 -1
  140. package/dist/types/src/plugin-process-manager/ProcessManagerPlugin.d.ts +3 -0
  141. package/dist/types/src/plugin-process-manager/ProcessManagerPlugin.d.ts.map +1 -0
  142. package/dist/types/src/plugin-process-manager/history/capability.d.ts.map +1 -0
  143. package/dist/types/src/plugin-process-manager/history/errors.d.ts +32 -0
  144. package/dist/types/src/plugin-process-manager/history/errors.d.ts.map +1 -0
  145. package/dist/types/src/plugin-process-manager/history/history-tracker.d.ts +32 -0
  146. package/dist/types/src/plugin-process-manager/history/history-tracker.d.ts.map +1 -0
  147. package/dist/types/src/plugin-process-manager/history/history-tracker.test.d.ts.map +1 -0
  148. package/dist/types/src/plugin-process-manager/history/index.d.ts.map +1 -0
  149. package/dist/types/src/{plugin-operation → plugin-process-manager}/history/types.d.ts +1 -1
  150. package/dist/types/src/plugin-process-manager/history/types.d.ts.map +1 -0
  151. package/dist/types/src/{plugin-operation → plugin-process-manager}/history/undo-mapping.d.ts +2 -2
  152. package/dist/types/src/plugin-process-manager/history/undo-mapping.d.ts.map +1 -0
  153. package/dist/types/src/{plugin-operation → plugin-process-manager}/history/undo-registry.d.ts +1 -1
  154. package/dist/types/src/plugin-process-manager/history/undo-registry.d.ts.map +1 -0
  155. package/dist/types/src/plugin-process-manager/history/undo-registry.test.d.ts.map +1 -0
  156. package/dist/types/src/plugin-process-manager/index.d.ts +3 -0
  157. package/dist/types/src/plugin-process-manager/index.d.ts.map +1 -0
  158. package/dist/types/src/plugin-process-manager/meta.d.ts +3 -0
  159. package/dist/types/src/plugin-process-manager/meta.d.ts.map +1 -0
  160. package/dist/types/src/plugin-process-manager/process-manager-capability.d.ts +8 -0
  161. package/dist/types/src/plugin-process-manager/process-manager-capability.d.ts.map +1 -0
  162. package/dist/types/src/plugin-process-manager/testing.d.ts +59 -0
  163. package/dist/types/src/plugin-process-manager/testing.d.ts.map +1 -0
  164. package/dist/types/src/testing/harness.d.ts +79 -0
  165. package/dist/types/src/testing/harness.d.ts.map +1 -0
  166. package/dist/types/src/testing/index.d.ts +1 -0
  167. package/dist/types/src/testing/index.d.ts.map +1 -1
  168. package/dist/types/src/testing/react.d.ts +27 -0
  169. package/dist/types/src/testing/react.d.ts.map +1 -0
  170. package/dist/types/src/testing/react.test.d.ts +2 -0
  171. package/dist/types/src/testing/react.test.d.ts.map +1 -0
  172. package/dist/types/src/testing/service.d.ts.map +1 -1
  173. package/dist/types/src/testing/withPluginManager.d.ts.map +1 -1
  174. package/dist/types/src/testing/withPluginManager.stories.d.ts.map +1 -1
  175. package/dist/types/src/ui/components/App/App.d.ts +36 -3
  176. package/dist/types/src/ui/components/App/App.d.ts.map +1 -1
  177. package/dist/types/src/ui/components/App/App.stories.d.ts +2 -2
  178. package/dist/types/src/ui/components/App/App.stories.d.ts.map +1 -1
  179. package/dist/types/src/ui/components/PluginManager/PluginManagerContext.stories.d.ts.map +1 -1
  180. package/dist/types/src/ui/components/Surface/SurfaceComponent.d.ts +16 -4
  181. package/dist/types/src/ui/components/Surface/SurfaceComponent.d.ts.map +1 -1
  182. package/dist/types/src/ui/components/Surface/SurfaceComponent.stories.d.ts.map +1 -1
  183. package/dist/types/src/ui/components/Surface/SurfaceInfo.d.ts.map +1 -1
  184. package/dist/types/src/ui/components/Surface/SurfaceProfilerContext.d.ts +48 -0
  185. package/dist/types/src/ui/components/Surface/SurfaceProfilerContext.d.ts.map +1 -0
  186. package/dist/types/src/ui/components/Surface/index.d.ts +22 -6
  187. package/dist/types/src/ui/components/Surface/index.d.ts.map +1 -1
  188. package/dist/types/src/ui/components/Surface/types.d.ts +110 -9
  189. package/dist/types/src/ui/components/Surface/types.d.ts.map +1 -1
  190. package/dist/types/src/ui/components/Surface/types.test.d.ts +2 -0
  191. package/dist/types/src/ui/components/Surface/types.test.d.ts.map +1 -0
  192. package/dist/types/src/ui/hooks/index.d.ts +1 -1
  193. package/dist/types/src/ui/hooks/index.d.ts.map +1 -1
  194. package/dist/types/src/ui/hooks/useApp.d.ts +42 -12
  195. package/dist/types/src/ui/hooks/useApp.d.ts.map +1 -1
  196. package/dist/types/src/ui/hooks/useApp.test.d.ts +2 -0
  197. package/dist/types/src/ui/hooks/useApp.test.d.ts.map +1 -0
  198. package/dist/types/src/ui/hooks/useCapabilities.d.ts.map +1 -1
  199. package/dist/types/src/ui/hooks/useLoading.d.ts.map +1 -1
  200. package/dist/types/src/ui/hooks/useProcessManagerRuntime.d.ts +30 -0
  201. package/dist/types/src/ui/hooks/useProcessManagerRuntime.d.ts.map +1 -0
  202. package/dist/types/src/ui/hooks/useSettingsState.d.ts.map +1 -1
  203. package/dist/types/src/vite-plugin/boot-loader/index.d.ts +2 -0
  204. package/dist/types/src/vite-plugin/boot-loader/index.d.ts.map +1 -0
  205. package/dist/types/src/vite-plugin/boot-loader/loader.d.ts +54 -0
  206. package/dist/types/src/vite-plugin/boot-loader/loader.d.ts.map +1 -0
  207. package/dist/types/src/vite-plugin/composer/index.d.ts +34 -0
  208. package/dist/types/src/vite-plugin/composer/index.d.ts.map +1 -0
  209. package/dist/types/src/vite-plugin/import-map/index.d.ts +28 -0
  210. package/dist/types/src/vite-plugin/import-map/index.d.ts.map +1 -0
  211. package/dist/types/src/vite-plugin/index.d.ts +5 -0
  212. package/dist/types/src/vite-plugin/index.d.ts.map +1 -0
  213. package/dist/types/src/vite-plugin/manifest.d.ts +41 -0
  214. package/dist/types/src/vite-plugin/manifest.d.ts.map +1 -0
  215. package/dist/types/src/vite-plugin/manifest.test.d.ts +2 -0
  216. package/dist/types/src/vite-plugin/manifest.test.d.ts.map +1 -0
  217. package/dist/types/src/vite-plugin/packages.d.ts +13 -0
  218. package/dist/types/src/vite-plugin/packages.d.ts.map +1 -0
  219. package/dist/types/tsconfig.tsbuildinfo +1 -1
  220. package/moon.yml +15 -0
  221. package/package.json +61 -57
  222. package/src/cli/cli.ts +2 -7
  223. package/src/common/activation-events.ts +10 -15
  224. package/src/common/annotations.ts +3 -0
  225. package/src/common/capabilities.ts +147 -16
  226. package/src/common/index.ts +0 -1
  227. package/src/common/translations.ts +1 -1
  228. package/src/core/activation-event.ts +4 -1
  229. package/src/core/capability-manager.test.ts +4 -1
  230. package/src/core/capability-manager.ts +44 -2
  231. package/src/core/capability.ts +20 -2
  232. package/src/core/edge-registry-plugin-provider.ts +92 -0
  233. package/src/core/index.ts +6 -0
  234. package/src/core/plugin-asset-cache.ts +60 -0
  235. package/src/core/plugin-manager.test.ts +1103 -19
  236. package/src/core/plugin-manager.ts +1176 -199
  237. package/src/core/plugin-manifest.test.ts +75 -0
  238. package/src/core/plugin-manifest.ts +134 -0
  239. package/src/core/plugin.ts +235 -17
  240. package/src/core/registry.ts +163 -0
  241. package/src/core/url-loader.test.ts +222 -0
  242. package/src/core/url-loader.ts +388 -0
  243. package/src/index.ts +1 -2
  244. package/src/plugin-process-manager/ProcessManagerPlugin.ts +24 -0
  245. package/src/{plugin-operation → plugin-process-manager}/history/capability.ts +1 -2
  246. package/src/plugin-process-manager/history/errors.ts +7 -0
  247. package/src/{plugin-operation → plugin-process-manager}/history/history-tracker.test.ts +61 -88
  248. package/src/{plugin-operation → plugin-process-manager}/history/history-tracker.ts +33 -18
  249. package/src/{plugin-operation → plugin-process-manager}/history/types.ts +1 -1
  250. package/src/{plugin-operation → plugin-process-manager}/history/undo-mapping.ts +2 -2
  251. package/src/{plugin-operation → plugin-process-manager}/history/undo-registry.test.ts +6 -5
  252. package/src/{plugin-operation → plugin-process-manager}/history/undo-registry.ts +1 -1
  253. package/src/{plugin-operation → plugin-process-manager}/index.ts +1 -1
  254. package/src/plugin-process-manager/meta.ts +16 -0
  255. package/src/plugin-process-manager/process-manager-capability.ts +178 -0
  256. package/src/{plugin-operation → plugin-process-manager}/testing.ts +32 -50
  257. package/src/testing/harness.ts +247 -0
  258. package/src/testing/index.ts +1 -0
  259. package/src/testing/react.test.tsx +50 -0
  260. package/src/testing/react.tsx +113 -0
  261. package/src/testing/service.ts +2 -2
  262. package/src/testing/withPluginManager.stories.tsx +1 -2
  263. package/src/testing/withPluginManager.tsx +47 -21
  264. package/src/ui/components/App/App.stories.tsx +12 -20
  265. package/src/ui/components/App/App.tsx +97 -10
  266. package/src/ui/components/PluginManager/PluginManagerContext.stories.tsx +13 -17
  267. package/src/ui/components/Surface/SurfaceComponent.stories.tsx +17 -16
  268. package/src/ui/components/Surface/SurfaceComponent.tsx +111 -55
  269. package/src/ui/components/Surface/SurfaceInfo.tsx +0 -1
  270. package/src/ui/components/Surface/SurfaceProfilerContext.tsx +207 -0
  271. package/src/ui/components/Surface/index.ts +35 -1
  272. package/src/ui/components/Surface/types.test.ts +126 -0
  273. package/src/ui/components/Surface/types.ts +185 -12
  274. package/src/ui/hooks/index.ts +1 -1
  275. package/src/ui/hooks/useApp.test.tsx +161 -0
  276. package/src/ui/hooks/useApp.tsx +215 -24
  277. package/src/ui/hooks/useCapabilities.ts +1 -0
  278. package/src/ui/hooks/useLoading.tsx +14 -6
  279. package/src/ui/hooks/useProcessManagerRuntime.ts +78 -0
  280. package/src/vite-plugin/boot-loader/BootLoader.solid-stories.tsx +198 -0
  281. package/src/vite-plugin/boot-loader/index.ts +5 -0
  282. package/src/vite-plugin/boot-loader/loader-app/Loader.tsx +166 -0
  283. package/src/vite-plugin/boot-loader/loader-app/boot-loader.css +311 -0
  284. package/src/vite-plugin/boot-loader/loader-app/bridge.ts +25 -0
  285. package/src/vite-plugin/boot-loader/loader-app/entry.tsx +21 -0
  286. package/src/vite-plugin/boot-loader/loader-app/mount.tsx +70 -0
  287. package/src/vite-plugin/boot-loader/loader-app/store.test.ts +137 -0
  288. package/src/vite-plugin/boot-loader/loader-app/store.ts +149 -0
  289. package/src/vite-plugin/boot-loader/loader-app/tsconfig.json +11 -0
  290. package/src/vite-plugin/boot-loader/loader-app/types.ts +78 -0
  291. package/src/vite-plugin/boot-loader/loader.ts +193 -0
  292. package/src/vite-plugin/composer/index.ts +306 -0
  293. package/src/vite-plugin/import-map/index.ts +527 -0
  294. package/src/vite-plugin/index.ts +10 -0
  295. package/src/vite-plugin/manifest.test.ts +55 -0
  296. package/src/vite-plugin/manifest.ts +63 -0
  297. package/src/vite-plugin/packages.ts +187 -0
  298. package/tsconfig.json +26 -3
  299. package/tsconfig.node.json +1 -1
  300. package/vitest.config.ts +1 -1
  301. package/.swc/plugins/linux_x86_64_19.0.0/727453fb3a62f7f1d952a41e051ca8a6f88cadc45cee43c6a4d1aa45f9b75665.wasmer-v7 +0 -0
  302. package/dist/lib/browser/capability-6YMUBS54.mjs +0 -37
  303. package/dist/lib/browser/capability-6YMUBS54.mjs.map +0 -7
  304. package/dist/lib/browser/capability-LF3OXSCV.mjs.map +0 -7
  305. package/dist/lib/browser/chunk-272IPLHQ.mjs.map +0 -7
  306. package/dist/lib/browser/chunk-2UI6ACB5.mjs +0 -824
  307. package/dist/lib/browser/chunk-2UI6ACB5.mjs.map +0 -7
  308. package/dist/lib/browser/chunk-7M4467QR.mjs.map +0 -7
  309. package/dist/lib/browser/chunk-JGWCBVKJ.mjs.map +0 -7
  310. package/dist/lib/browser/chunk-M5IC326L.mjs +0 -34
  311. package/dist/lib/browser/chunk-M5IC326L.mjs.map +0 -7
  312. package/dist/lib/browser/chunk-NQPYE365.mjs +0 -703
  313. package/dist/lib/browser/chunk-NQPYE365.mjs.map +0 -7
  314. package/dist/lib/browser/chunk-TIEBZMTF.mjs +0 -44
  315. package/dist/lib/browser/chunk-TIEBZMTF.mjs.map +0 -7
  316. package/dist/lib/browser/chunk-WEBSGU5L.mjs.map +0 -7
  317. package/dist/lib/browser/chunk-YAFEA4GV.mjs +0 -1
  318. package/dist/lib/browser/chunk-YNFPIQGB.mjs.map +0 -7
  319. package/dist/lib/browser/invoker-capability-4AUGUMM5.mjs +0 -36
  320. package/dist/lib/browser/invoker-capability-4AUGUMM5.mjs.map +0 -7
  321. package/dist/lib/node-esm/capability-R5O2OYX4.mjs +0 -38
  322. package/dist/lib/node-esm/capability-R5O2OYX4.mjs.map +0 -7
  323. package/dist/lib/node-esm/capability-SA6LPYGL.mjs.map +0 -7
  324. package/dist/lib/node-esm/chunk-3D66SZHP.mjs.map +0 -7
  325. package/dist/lib/node-esm/chunk-6REV5DE7.mjs.map +0 -7
  326. package/dist/lib/node-esm/chunk-FHWPWQRJ.mjs +0 -704
  327. package/dist/lib/node-esm/chunk-FHWPWQRJ.mjs.map +0 -7
  328. package/dist/lib/node-esm/chunk-JHFY3HTS.mjs.map +0 -7
  329. package/dist/lib/node-esm/chunk-JIVXIJ2T.mjs +0 -825
  330. package/dist/lib/node-esm/chunk-JIVXIJ2T.mjs.map +0 -7
  331. package/dist/lib/node-esm/chunk-NHXBSAQR.mjs +0 -35
  332. package/dist/lib/node-esm/chunk-NHXBSAQR.mjs.map +0 -7
  333. package/dist/lib/node-esm/chunk-SB5ODNPX.mjs.map +0 -7
  334. package/dist/lib/node-esm/chunk-SCDGIGGU.mjs +0 -45
  335. package/dist/lib/node-esm/chunk-SCDGIGGU.mjs.map +0 -7
  336. package/dist/lib/node-esm/chunk-SQICGJBW.mjs.map +0 -7
  337. package/dist/lib/node-esm/chunk-Z4TJPSMP.mjs +0 -2
  338. package/dist/lib/node-esm/invoker-capability-3YDIVDWV.mjs +0 -37
  339. package/dist/lib/node-esm/invoker-capability-3YDIVDWV.mjs.map +0 -7
  340. package/dist/types/src/common/operations.d.ts +0 -33
  341. package/dist/types/src/common/operations.d.ts.map +0 -1
  342. package/dist/types/src/plugin-operation/OperationPlugin.d.ts +0 -3
  343. package/dist/types/src/plugin-operation/OperationPlugin.d.ts.map +0 -1
  344. package/dist/types/src/plugin-operation/history/capability.d.ts.map +0 -1
  345. package/dist/types/src/plugin-operation/history/errors.d.ts +0 -5
  346. package/dist/types/src/plugin-operation/history/errors.d.ts.map +0 -1
  347. package/dist/types/src/plugin-operation/history/history-tracker.d.ts +0 -18
  348. package/dist/types/src/plugin-operation/history/history-tracker.d.ts.map +0 -1
  349. package/dist/types/src/plugin-operation/history/history-tracker.test.d.ts.map +0 -1
  350. package/dist/types/src/plugin-operation/history/index.d.ts.map +0 -1
  351. package/dist/types/src/plugin-operation/history/types.d.ts.map +0 -1
  352. package/dist/types/src/plugin-operation/history/undo-mapping.d.ts.map +0 -1
  353. package/dist/types/src/plugin-operation/history/undo-registry.d.ts.map +0 -1
  354. package/dist/types/src/plugin-operation/history/undo-registry.test.d.ts.map +0 -1
  355. package/dist/types/src/plugin-operation/index.d.ts +0 -3
  356. package/dist/types/src/plugin-operation/index.d.ts.map +0 -1
  357. package/dist/types/src/plugin-operation/invoker-capability.d.ts +0 -6
  358. package/dist/types/src/plugin-operation/invoker-capability.d.ts.map +0 -1
  359. package/dist/types/src/plugin-operation/meta.d.ts +0 -3
  360. package/dist/types/src/plugin-operation/meta.d.ts.map +0 -1
  361. package/dist/types/src/plugin-operation/testing.d.ts +0 -109
  362. package/dist/types/src/plugin-operation/testing.d.ts.map +0 -1
  363. package/dist/types/src/plugin-runtime/RuntimePlugin.d.ts +0 -3
  364. package/dist/types/src/plugin-runtime/RuntimePlugin.d.ts.map +0 -1
  365. package/dist/types/src/plugin-runtime/capability.d.ts +0 -6
  366. package/dist/types/src/plugin-runtime/capability.d.ts.map +0 -1
  367. package/dist/types/src/plugin-runtime/index.d.ts +0 -2
  368. package/dist/types/src/plugin-runtime/index.d.ts.map +0 -1
  369. package/dist/types/src/plugin-runtime/meta.d.ts +0 -3
  370. package/dist/types/src/plugin-runtime/meta.d.ts.map +0 -1
  371. package/dist/types/src/ui/hooks/useOperationResolver.d.ts +0 -19
  372. package/dist/types/src/ui/hooks/useOperationResolver.d.ts.map +0 -1
  373. package/src/common/operations.ts +0 -38
  374. package/src/plugin-operation/OperationPlugin.ts +0 -25
  375. package/src/plugin-operation/history/errors.ts +0 -11
  376. package/src/plugin-operation/invoker-capability.ts +0 -40
  377. package/src/plugin-operation/meta.ts +0 -11
  378. package/src/plugin-runtime/RuntimePlugin.ts +0 -20
  379. package/src/plugin-runtime/capability.ts +0 -53
  380. package/src/plugin-runtime/index.ts +0 -5
  381. package/src/plugin-runtime/meta.ts +0 -11
  382. package/src/ui/hooks/useOperationResolver.ts +0 -40
  383. /package/dist/lib/browser/{chunk-YAFEA4GV.mjs.map → core/url-loader.mjs.map} +0 -0
  384. /package/dist/lib/node-esm/{chunk-Z4TJPSMP.mjs.map → core/url-loader.mjs.map} +0 -0
  385. /package/dist/types/src/{plugin-operation → plugin-process-manager}/history/capability.d.ts +0 -0
  386. /package/dist/types/src/{plugin-operation → plugin-process-manager}/history/history-tracker.test.d.ts +0 -0
  387. /package/dist/types/src/{plugin-operation → plugin-process-manager}/history/index.d.ts +0 -0
  388. /package/dist/types/src/{plugin-operation → plugin-process-manager}/history/undo-registry.test.d.ts +0 -0
  389. /package/src/{plugin-operation → plugin-process-manager}/history/index.ts +0 -0
@@ -0,0 +1,113 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import { RegistryContext } from '@effect-atom/atom-react';
6
+ import { render as rtlRender, type RenderOptions, type RenderResult } from '@testing-library/react';
7
+ import React, { type FC, Fragment, type PropsWithChildren, type ReactNode } from 'react';
8
+
9
+ import { ContextProtocolProvider } from '@dxos/web-context-react';
10
+
11
+ import { Capabilities } from '../common';
12
+ import { PluginManagerContext } from '../context';
13
+ import { topologicalSort } from '../helpers';
14
+ import { PluginManagerProvider } from '../ui/components/PluginManager/PluginManagerProvider';
15
+ import { SurfaceComponent } from '../ui/components/Surface/SurfaceComponent';
16
+ import { type TestHarness } from './harness';
17
+
18
+ export type HarnessRenderOptions = Omit<RenderOptions, 'wrapper'> & {
19
+ /** Additional providers to wrap around the harness tree (applied innermost first). */
20
+ reactContexts?: FC<PropsWithChildren>[];
21
+ };
22
+
23
+ /**
24
+ * Renders `ui` wrapped in the same provider tree as `useApp` plus every contributed
25
+ * `Capabilities.ReactContext`.
26
+ */
27
+ export const render = (harness: TestHarness, ui: ReactNode, options?: HarnessRenderOptions): RenderResult => {
28
+ const { reactContexts = [], ...rest } = options ?? {};
29
+ const Wrapper = ({ children }: PropsWithChildren) => (
30
+ <HarnessProviders harness={harness} extra={reactContexts}>
31
+ {children}
32
+ </HarnessProviders>
33
+ );
34
+ return rtlRender(<>{ui}</>, { ...rest, wrapper: Wrapper });
35
+ };
36
+
37
+ export type RenderSurfaceProps = {
38
+ role: string;
39
+ data?: unknown;
40
+ limit?: number;
41
+ fallback?: FC<{ error: Error; data?: any }>;
42
+ placeholder?: ReactNode;
43
+ };
44
+
45
+ /**
46
+ * Renders a `Surface` with the given role/data inside the harness provider tree.
47
+ */
48
+ export const renderSurface = (
49
+ harness: TestHarness,
50
+ props: RenderSurfaceProps,
51
+ options?: HarnessRenderOptions,
52
+ ): RenderResult => {
53
+ const { role, data, limit, fallback, placeholder } = props;
54
+ return render(
55
+ harness,
56
+ <SurfaceComponent role={role} data={data as any} limit={limit} fallback={fallback} placeholder={placeholder} />,
57
+ options,
58
+ );
59
+ };
60
+
61
+ type HarnessProvidersProps = PropsWithChildren<{
62
+ harness: TestHarness;
63
+ extra: FC<PropsWithChildren>[];
64
+ }>;
65
+
66
+ const HarnessProviders = ({ harness, extra, children }: HarnessProvidersProps) => {
67
+ const contributed = harness.getAll(Capabilities.ReactContext);
68
+ const ContributedContext = composeContexts(contributed);
69
+ const ExtraContext = composeExtra(extra);
70
+ return (
71
+ <PluginManagerProvider value={harness.manager}>
72
+ <ContextProtocolProvider value={harness.manager} context={PluginManagerContext}>
73
+ <RegistryContext.Provider value={harness.registry}>
74
+ <ContributedContext>
75
+ <ExtraContext>{children}</ExtraContext>
76
+ </ContributedContext>
77
+ </RegistryContext.Provider>
78
+ </ContextProtocolProvider>
79
+ </PluginManagerProvider>
80
+ );
81
+ };
82
+
83
+ const composeContexts = (contexts: Capabilities.ReactContext[]): FC<PropsWithChildren> => {
84
+ if (contexts.length === 0) {
85
+ return Passthrough;
86
+ }
87
+ return topologicalSort(contexts)
88
+ .map(({ context }) => context)
89
+ .reduce((Acc, Next) => ({ children }: PropsWithChildren) => (
90
+ <Acc>
91
+ <Next>{children}</Next>
92
+ </Acc>
93
+ ));
94
+ };
95
+
96
+ // Composes in innermost-first order: the first context in the array wraps
97
+ // `children` directly; subsequent contexts wrap the accumulator.
98
+ const composeExtra = (contexts: FC<PropsWithChildren>[]): FC<PropsWithChildren> => {
99
+ if (contexts.length === 0) {
100
+ return Passthrough;
101
+ }
102
+ return contexts.reduce<FC<PropsWithChildren>>(
103
+ (Acc, Next) =>
104
+ ({ children }: PropsWithChildren) => (
105
+ <Next>
106
+ <Acc>{children}</Acc>
107
+ </Next>
108
+ ),
109
+ Passthrough,
110
+ );
111
+ };
112
+
113
+ const Passthrough: FC<PropsWithChildren> = ({ children }) => <Fragment>{children}</Fragment>;
@@ -24,13 +24,13 @@ export const fromPlugins = (plugins: Plugin.Plugin[]) =>
24
24
  Effect.sync(() => {
25
25
  const plugin = plugins.find((plugin) => plugin.meta.id === id);
26
26
  invariant(plugin, `Plugin not found: ${id}`);
27
- return plugin;
27
+ return { plugin };
28
28
  });
29
29
 
30
30
  const manager = PluginManager.make({
31
31
  pluginLoader,
32
32
  plugins,
33
- core: plugins.map((plugin) => plugin.meta.id),
33
+ enabled: plugins.map((plugin) => plugin.meta.id),
34
34
  });
35
35
 
36
36
  manager.capabilities.contribute({
@@ -10,7 +10,6 @@ import { withTheme } from '@dxos/react-ui/testing';
10
10
  import { Capabilities } from '../common';
11
11
  import { Capability } from '../core';
12
12
  import { Surface } from '../ui';
13
-
14
13
  import { withPluginManager } from './withPluginManager';
15
14
 
16
15
  const DefaultStory = () => {
@@ -24,7 +23,7 @@ const DefaultStory = () => {
24
23
  };
25
24
 
26
25
  const meta = {
27
- title: 'sdk/app-framework/withPluginManager',
26
+ title: 'sdk/app-framework/testing/withPluginManager',
28
27
  render: DefaultStory,
29
28
  decorators: [
30
29
  withTheme(),
@@ -4,9 +4,11 @@
4
4
 
5
5
  import { type Decorator, type StoryContext } from '@storybook/react';
6
6
  import * as Effect from 'effect/Effect';
7
- import React, { useEffect, useMemo } from 'react';
7
+ import React, { useEffect, useState } from 'react';
8
8
 
9
9
  import { raise } from '@dxos/debug';
10
+ import { runAndForwardErrors } from '@dxos/effect';
11
+ import { DXN } from '@dxos/keys';
10
12
  import { useAsyncEffect } from '@dxos/react-hooks';
11
13
  import { type MaybeProvider, getProviderValue } from '@dxos/util';
12
14
 
@@ -20,13 +22,15 @@ import { type UseAppOptions, useApp } from '../ui';
20
22
  export const setupPluginManager = ({
21
23
  capabilities,
22
24
  plugins = [],
23
- core = plugins.map(({ meta }) => meta.id),
24
25
  ...options
25
26
  }: UseAppOptions & Pick<WithPluginManagerOptions, 'capabilities'> = {}) => {
27
+ // Auto-enable every non-system plugin so stories don't have to spell out
28
+ // enablement. System-tagged plugins are force-enabled by the manager.
29
+ const enabled = plugins.filter(({ meta }) => !meta.tags?.includes('system')).map(({ meta }) => meta.id);
26
30
  const pluginManager = PluginManager.make({
27
31
  pluginLoader: () => raise(new Error('Not implemented')),
28
32
  plugins: [StoryPlugin, ...plugins],
29
- core: [StoryPlugin.meta.id, ...core],
33
+ enabled,
30
34
  ...options,
31
35
  });
32
36
 
@@ -43,6 +47,13 @@ export const setupPluginManager = ({
43
47
  return pluginManager;
44
48
  };
45
49
 
50
+ type ManagedPluginManagerState = {
51
+ fireEvents?: (ActivationEvent.ActivationEvent | string)[];
52
+ pluginManager: PluginManager.PluginManager;
53
+ setupEvents?: ActivationEvent.ActivationEvent[];
54
+ storyId: string;
55
+ };
56
+
46
57
  export type WithPluginManagerOptions = UseAppOptions & {
47
58
  /** @deprecated */
48
59
  capabilities?: MaybeProvider<Capability.Any[], CapabilityManager.CapabilityManager>;
@@ -60,16 +71,15 @@ export type WithPluginManagerInitializer<Args = void> =
60
71
  */
61
72
  export const withPluginManager = <Args,>(init: WithPluginManagerInitializer<Args> = {}): Decorator => {
62
73
  return (Story, context) => {
74
+ const storyId = context.id;
63
75
  const options = typeof init === 'function' ? init(context as any) : init;
64
- const { pluginManager, setupEvents } = useMemo(
65
- () => ({ pluginManager: setupPluginManager(options), setupEvents: options.setupEvents }),
66
- [init],
67
- );
76
+ const [managerState, setManagerState] = useState<ManagedPluginManagerState>();
68
77
 
69
- // Set-up root capability.
78
+ // Storybook replaces the full context object often, so key manager ownership by story id.
70
79
  useEffect(() => {
80
+ const pluginManager = setupPluginManager(options);
71
81
  const capability = Capability.contributes(Capabilities.ReactRoot, {
72
- id: context.id,
82
+ id: storyId,
73
83
  root: () => <Story />,
74
84
  });
75
85
 
@@ -78,28 +88,44 @@ export const withPluginManager = <Args,>(init: WithPluginManagerInitializer<Args
78
88
  module: 'org.dxos.app-framework.with-plugin-manager',
79
89
  });
80
90
 
91
+ setManagerState({
92
+ pluginManager,
93
+ setupEvents: options.setupEvents,
94
+ fireEvents: options.fireEvents,
95
+ storyId,
96
+ });
97
+
81
98
  return () => {
82
99
  pluginManager.capabilities.remove(capability.interface, capability.implementation);
100
+ void runAndForwardErrors(pluginManager.shutdown());
83
101
  };
84
- }, [pluginManager, context]);
102
+ }, [storyId, init]);
85
103
 
86
- // Fire events.
87
- useAsyncEffect(async () => {
88
- await Promise.all(options.fireEvents?.map((event) => pluginManager.activate(event)) ?? []);
89
- }, [pluginManager]);
104
+ // Avoid mounting useApp with a stale manager from the previous story.
105
+ if (!managerState || managerState.storyId !== storyId) {
106
+ return <></>;
107
+ }
90
108
 
91
- // Create app.
92
- const App = useApp({ pluginManager, setupEvents });
93
-
94
- return <App />;
109
+ return <WithPluginManagerApp {...managerState} />;
95
110
  };
96
111
  };
97
112
 
98
- const storyMeta = {
99
- id: 'org.dxos.app-framework.story',
100
- name: 'Story',
113
+ const WithPluginManagerApp = ({ fireEvents, pluginManager, setupEvents, storyId }: ManagedPluginManagerState) => {
114
+ // Fire deprecated events only after the effect-owned manager for this story exists.
115
+ useAsyncEffect(async () => {
116
+ await Promise.all(fireEvents?.map((event) => pluginManager.activate(event)) ?? []);
117
+ }, [fireEvents, pluginManager, storyId]);
118
+
119
+ const App = useApp({ pluginManager, setupEvents });
120
+ return <App />;
101
121
  };
102
122
 
123
+ const storyMeta = Plugin.makeMeta({
124
+ key: DXN.make('org.dxos.appFramework.story'),
125
+ name: 'Story',
126
+ tags: ['system'],
127
+ });
128
+
103
129
  // No-op plugin to ensure there exists at least one plugin for the startup event.
104
130
  // This is necessary because `createApp` expects the startup event to complete before the app is ready.
105
131
  const StoryPlugin = Plugin.define(storyMeta).pipe(
@@ -6,6 +6,7 @@ import { type Meta, type StoryObj } from '@storybook/react-vite';
6
6
  import * as Effect from 'effect/Effect';
7
7
  import React, { useEffect } from 'react';
8
8
 
9
+ import { DXN } from '@dxos/keys';
9
10
  import { withTheme } from '@dxos/react-ui/testing';
10
11
 
11
12
  import { ActivationEvents, Capabilities } from '../../../common';
@@ -13,10 +14,13 @@ import { Capability, Plugin } from '../../../core';
13
14
  import { useApp } from '../../hooks';
14
15
 
15
16
  // Minimal plugin that contributes a ReactRoot.
16
- const TestPlugin = Plugin.define<{ error?: boolean }>({
17
- id: 'org.dxos.plugin.test',
18
- name: 'Test Plugin',
19
- }).pipe(
17
+ const TestPlugin = Plugin.define<{ error?: boolean }>(
18
+ Plugin.makeMeta({
19
+ key: DXN.make('org.dxos.plugin.test'),
20
+ name: 'Test Plugin',
21
+ tags: ['system'],
22
+ }),
23
+ ).pipe(
20
24
  Plugin.addModule(({ error }) => ({
21
25
  id: 'TestMain',
22
26
  activatesOn: ActivationEvents.Startup,
@@ -46,28 +50,16 @@ const TestPlugin = Plugin.define<{ error?: boolean }>({
46
50
  Plugin.make,
47
51
  );
48
52
 
49
- const core = [TestPlugin.meta.id];
53
+ type DefaultStoryProps = { plugins?: Plugin.Plugin[] };
50
54
 
51
- type StoryProps = { plugins?: Plugin.Plugin[] };
52
-
53
- const DefaultStory = ({ plugins }: StoryProps) => {
54
- const App = useApp({
55
- plugins,
56
- core,
57
- placeholder: () => {
58
- return (
59
- <div role='none' className='text-description'>
60
- Loading...
61
- </div>
62
- );
63
- },
64
- });
55
+ const DefaultStory = ({ plugins }: DefaultStoryProps) => {
56
+ const App = useApp({ plugins });
65
57
 
66
58
  return <App />;
67
59
  };
68
60
 
69
61
  const meta = {
70
- title: 'sdk/app-framework/App',
62
+ title: 'sdk/app-framework/components/App',
71
63
  render: DefaultStory,
72
64
  decorators: [withTheme()],
73
65
  parameters: {
@@ -2,34 +2,121 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import React, { type PropsWithChildren } from 'react';
5
+ import React, { type PropsWithChildren, useEffect, useLayoutEffect } from 'react';
6
6
 
7
7
  import { Capabilities } from '../../../common';
8
8
  import { topologicalSort } from '../../../helpers';
9
- import { LoadingState, type UseAppOptions, useCapabilities, useLoading } from '../../hooks';
9
+ import { LoadingState, type StartupProgress, type UseAppOptions, useCapabilities, useLoading } from '../../hooks';
10
10
 
11
- export type AppProps = Pick<UseAppOptions, 'placeholder' | 'debounce'> & {
11
+ declare global {
12
+ interface Window {
13
+ /**
14
+ * Driver injected by `@dxos/app-framework/vite-plugin`'s `bootLoaderPlugin`
15
+ * (a Solid app inlined into `index.html`). Declared here — on a module that
16
+ * is part of the `@dxos/app-framework/ui` export surface — so the React side
17
+ * and host apps (e.g. composer-app) can drive the loader without each
18
+ * re-declaring the type. The canonical definition lives in the plugin's
19
+ * `loader-app/types.ts`; this mirror exists because that source compiles in a
20
+ * separate (Solid) program that doesn't ship its globals to consumers.
21
+ */
22
+ __bootLoader?: {
23
+ status: (payload: {
24
+ event?: string;
25
+ module?: string;
26
+ humanized: string;
27
+ /**
28
+ * Optional `(index/total)` tick. When present, the loader replaces the
29
+ * current line in place ("Loading plugins (12/80)") instead of appending
30
+ * a new entry — keeps the visible log compact during long counted phases.
31
+ */
32
+ range?: { index: number; total: number };
33
+ }) => void;
34
+ progress: (fraction?: number) => void;
35
+ ready: () => void;
36
+ dismiss: () => void;
37
+ };
38
+ }
39
+ }
40
+
41
+ export type AppProps = Pick<UseAppOptions, 'debounce'> & {
12
42
  ready: boolean;
13
43
  error: unknown;
44
+ progress?: StartupProgress;
14
45
  };
15
46
 
16
- export const App = ({ placeholder: Placeholder, ready, error, debounce }: AppProps) => {
47
+ const FIRST_INTERACTIVE_MARK = 'app-framework:first-interactive';
48
+
49
+ export const App = ({ ready, error, debounce, progress }: AppProps) => {
17
50
  const reactContexts = useCapabilities(Capabilities.ReactContext);
18
51
  const reactRoots = useCapabilities(Capabilities.ReactRoot);
19
52
  const stage = useLoading(ready, debounce);
53
+ const placeholderDismissed = stage >= LoadingState.Done;
54
+
55
+ // Relay the startup lifecycle into the boot loader injected by
56
+ // `@dxos/app-framework/vite-plugin` (a Solid app inlined into `index.html`,
57
+ // the only visible loading UI). Plugin activation fills the `[0.5, 1]` half
58
+ // of the ring; the raw `event` / `module` ids ride along so the loader owns
59
+ // how each transition is rendered and traced. No-op once the outro has
60
+ // started (`FadeOut`), so the dismissal runs uncontended.
61
+ useEffect(() => {
62
+ if (stage >= LoadingState.FadeOut) {
63
+ return;
64
+ }
65
+ const fraction = progress?.progress ?? 0;
66
+ window.__bootLoader?.progress(0.5 + fraction * 0.5);
67
+ if (progress?.humanizedName) {
68
+ window.__bootLoader?.status({
69
+ event: progress.event,
70
+ module: progress.module,
71
+ humanized: `Activating ${progress.humanizedName}`,
72
+ });
73
+ }
74
+ }, [stage, progress?.progress, progress?.event, progress?.module, progress?.humanizedName]);
75
+
76
+ // Hand off at fade-out: play the loader's graceful shrink-and-fade outro.
77
+ // `useLayoutEffect` runs before the next paint so the outro begins in the
78
+ // same frame the real shell starts rendering beneath it.
79
+ useLayoutEffect(() => {
80
+ if (stage >= LoadingState.FadeOut) {
81
+ window.__bootLoader?.ready();
82
+ }
83
+ }, [stage]);
84
+
85
+ // Emit a once-per-app `app-framework:first-interactive` mark the first time
86
+ // the loader is dismissed and the real app shell renders. Closes the gap
87
+ // between `Startup` activated and the first interactive paint.
88
+ //
89
+ // Also the framework-owned handoff-complete signal: `dismiss()` removes the
90
+ // loader immediately on the fast-load path (where `useLoading` skips
91
+ // `FadeOut`), and is a no-op once an outro is already in flight, so it never
92
+ // cuts the animation short.
93
+ useEffect(() => {
94
+ if (!placeholderDismissed) {
95
+ return;
96
+ }
97
+ if (performance.getEntriesByName(FIRST_INTERACTIVE_MARK).length === 0) {
98
+ performance.mark(FIRST_INTERACTIVE_MARK);
99
+ }
100
+ window.__bootLoader?.dismiss();
101
+ }, [placeholderDismissed]);
102
+
103
+ // Used in tests to exercise the error boundary & reset dialog (see
104
+ // composer-app's `basic.spec.ts`). Thrown into the surrounding `ErrorBoundary`.
105
+ if (location.search === '?throw') {
106
+ throw new Error('Test error');
107
+ }
20
108
 
21
109
  if (error) {
22
110
  // This triggers the error boundary to provide UI feedback for the startup error.
23
111
  throw error;
24
112
  }
25
113
 
114
+ // The boot loader owns the screen until handoff completes; render nothing
115
+ // until then (any DOM here would sit invisibly behind the `z-index: 10`
116
+ // loader anyway).
26
117
  // TODO(wittjosiah): Consider using Suspense instead.
27
- if (stage < LoadingState.Done) {
28
- if (!Placeholder) {
29
- return null;
30
- }
31
-
32
- return <Placeholder stage={stage} />;
118
+ if (!placeholderDismissed) {
119
+ return null;
33
120
  }
34
121
 
35
122
  const ComposedContext = composeContexts(reactContexts);
@@ -7,6 +7,7 @@ import { type Meta, type StoryObj } from '@storybook/react-vite';
7
7
  import * as Effect from 'effect/Effect';
8
8
  import React, { useEffect, useMemo, useState } from 'react';
9
9
 
10
+ import { DXN } from '@dxos/keys';
10
11
  import { withLayout, withTheme } from '@dxos/react-ui/testing';
11
12
  import { useWebComponentContext } from '@dxos/web-context-react';
12
13
 
@@ -38,7 +39,9 @@ const CountStatus = () => {
38
39
  }
39
40
  }, [counter]);
40
41
 
41
- if (!manager) return null;
42
+ if (!manager) {
43
+ return null;
44
+ }
42
45
 
43
46
  const isEven = count % 2 === 0;
44
47
 
@@ -115,10 +118,13 @@ const CounterComponent = () => {
115
118
  };
116
119
 
117
120
  // Plugin that provides the Counter capability and renders the UI
118
- const CounterPlugin = Plugin.define({
119
- id: 'org.dxos.plugin.counter',
120
- name: 'Counter Plugin',
121
- }).pipe(
121
+ const CounterPlugin = Plugin.define(
122
+ Plugin.makeMeta({
123
+ key: DXN.make('org.dxos.plugin.counter'),
124
+ name: 'Counter Plugin',
125
+ tags: ['system'],
126
+ }),
127
+ ).pipe(
122
128
  Plugin.addModule({
123
129
  id: 'CounterMain',
124
130
  activatesOn: ActivationEvents.Startup,
@@ -152,25 +158,15 @@ const CounterPlugin = Plugin.define({
152
158
  )();
153
159
 
154
160
  const plugins = [CounterPlugin];
155
- const core = ['org.dxos.plugin.counter'];
156
- const placeholder = () => (
157
- <div className='flex h-screen items-center justify-center p-4 text-lg text-neutral-500'>
158
- Initializing Application...
159
- </div>
160
- );
161
161
 
162
162
  const DefaultStory = () => {
163
- const App = useApp({
164
- plugins,
165
- core,
166
- placeholder,
167
- });
163
+ const App = useApp({ plugins });
168
164
 
169
165
  return <App />;
170
166
  };
171
167
 
172
168
  const meta = {
173
- title: 'sdk/app-framework/PluginManagerContext',
169
+ title: 'sdk/app-framework/components/PluginManagerContext',
174
170
  render: DefaultStory,
175
171
  decorators: [withTheme(), withLayout({ layout: 'fullscreen' })],
176
172
  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(() => {
@@ -88,7 +87,7 @@ const DefaultStory = () => {
88
87
  }
89
88
 
90
89
  return (
91
- <div className='flex justify-center items-center border border-rose-fill rounded-sm'>
90
+ <div className='flex justify-center items-center border border-rose-bg rounded-sm'>
92
91
  <span className='font-mono'>Ticking... {count}</span>
93
92
  </div>
94
93
  );
@@ -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: {