@dxos/app-framework 0.8.4-main.ae835ea → 0.8.4-main.bc2380dfbc

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 (585) 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-HRFPP52W.mjs +35 -0
  6. package/dist/lib/browser/capability-HRFPP52W.mjs.map +7 -0
  7. package/dist/lib/browser/capability-VQ236TY5.mjs +38 -0
  8. package/dist/lib/browser/capability-VQ236TY5.mjs.map +7 -0
  9. package/dist/lib/browser/chunk-23D4SJUE.mjs +42 -0
  10. package/dist/lib/browser/chunk-23D4SJUE.mjs.map +7 -0
  11. package/dist/lib/browser/chunk-3JWJXGLK.mjs +79 -0
  12. package/dist/lib/browser/chunk-3JWJXGLK.mjs.map +7 -0
  13. package/dist/lib/browser/chunk-45CHLTBV.mjs +34 -0
  14. package/dist/lib/browser/chunk-45CHLTBV.mjs.map +7 -0
  15. package/dist/lib/browser/chunk-66IXTIVK.mjs +48 -0
  16. package/dist/lib/browser/chunk-66IXTIVK.mjs.map +7 -0
  17. package/dist/lib/browser/chunk-6GZYCP73.mjs +422 -0
  18. package/dist/lib/browser/chunk-6GZYCP73.mjs.map +7 -0
  19. package/dist/lib/browser/chunk-7VZJR2OA.mjs +581 -0
  20. package/dist/lib/browser/chunk-7VZJR2OA.mjs.map +7 -0
  21. package/dist/lib/browser/chunk-FJ4765WW.mjs +8 -0
  22. package/dist/lib/browser/chunk-FJ4765WW.mjs.map +7 -0
  23. package/dist/lib/browser/chunk-FO3IYSLV.mjs +68 -0
  24. package/dist/lib/browser/chunk-FO3IYSLV.mjs.map +7 -0
  25. package/dist/lib/browser/chunk-G6Q2M2M5.mjs +218 -0
  26. package/dist/lib/browser/chunk-G6Q2M2M5.mjs.map +7 -0
  27. package/dist/lib/browser/chunk-J43JDWAV.mjs +1445 -0
  28. package/dist/lib/browser/chunk-J43JDWAV.mjs.map +7 -0
  29. package/dist/lib/browser/chunk-J5LGTIGS.mjs +10 -0
  30. package/dist/lib/browser/chunk-WBHCSOBW.mjs +80 -0
  31. package/dist/lib/browser/chunk-WBHCSOBW.mjs.map +7 -0
  32. package/dist/lib/browser/chunk-XLYULXAO.mjs +469 -0
  33. package/dist/lib/browser/chunk-XLYULXAO.mjs.map +7 -0
  34. package/dist/lib/browser/chunk-ZGJAZSNE.mjs +142 -0
  35. package/dist/lib/browser/chunk-ZGJAZSNE.mjs.map +7 -0
  36. package/dist/lib/browser/cli/index.mjs +76 -0
  37. package/dist/lib/browser/cli/index.mjs.map +7 -0
  38. package/dist/lib/browser/common/activation-events.mjs +24 -0
  39. package/dist/lib/browser/common/capabilities.mjs +46 -0
  40. package/dist/lib/browser/core/activation-event.mjs +20 -0
  41. package/dist/lib/browser/core/capability.mjs +30 -0
  42. package/dist/lib/browser/core/capability.mjs.map +7 -0
  43. package/dist/lib/browser/core/plugin-manager.mjs +19 -0
  44. package/dist/lib/browser/core/plugin-manager.mjs.map +7 -0
  45. package/dist/lib/browser/core/plugin.mjs +39 -0
  46. package/dist/lib/browser/core/plugin.mjs.map +7 -0
  47. package/dist/lib/browser/core/url-loader.mjs +24 -0
  48. package/dist/lib/browser/core/url-loader.mjs.map +7 -0
  49. package/dist/lib/browser/index.mjs +108 -148
  50. package/dist/lib/browser/index.mjs.map +4 -4
  51. package/dist/lib/browser/invoker-capability-CEL2L6GX.mjs +44 -0
  52. package/dist/lib/browser/invoker-capability-CEL2L6GX.mjs.map +7 -0
  53. package/dist/lib/browser/meta.json +1 -1
  54. package/dist/lib/browser/testing/index.mjs +229 -40
  55. package/dist/lib/browser/testing/index.mjs.map +4 -4
  56. package/dist/lib/browser/testing/react.mjs +78 -0
  57. package/dist/lib/browser/testing/react.mjs.map +7 -0
  58. package/dist/lib/browser/ui/index.mjs +48 -0
  59. package/dist/lib/browser/ui/index.mjs.map +7 -0
  60. package/dist/lib/node-esm/capability-GS3XJH74.mjs +39 -0
  61. package/dist/lib/node-esm/capability-GS3XJH74.mjs.map +7 -0
  62. package/dist/lib/node-esm/capability-I5P7ACFL.mjs +36 -0
  63. package/dist/lib/node-esm/capability-I5P7ACFL.mjs.map +7 -0
  64. package/dist/lib/node-esm/chunk-37Z53PXZ.mjs +10 -0
  65. package/dist/lib/node-esm/chunk-37Z53PXZ.mjs.map +7 -0
  66. package/dist/lib/node-esm/chunk-4RJL37GN.mjs +423 -0
  67. package/dist/lib/node-esm/chunk-4RJL37GN.mjs.map +7 -0
  68. package/dist/lib/node-esm/chunk-6XW6LET6.mjs +35 -0
  69. package/dist/lib/node-esm/chunk-6XW6LET6.mjs.map +7 -0
  70. package/dist/lib/node-esm/chunk-D347W3KO.mjs +143 -0
  71. package/dist/lib/node-esm/chunk-D347W3KO.mjs.map +7 -0
  72. package/dist/lib/node-esm/chunk-DW45NFLW.mjs +1446 -0
  73. package/dist/lib/node-esm/chunk-DW45NFLW.mjs.map +7 -0
  74. package/dist/lib/node-esm/chunk-EI4LYXFY.mjs +470 -0
  75. package/dist/lib/node-esm/chunk-EI4LYXFY.mjs.map +7 -0
  76. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +11 -0
  77. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs.map +7 -0
  78. package/dist/lib/node-esm/chunk-KIFOQXD4.mjs +219 -0
  79. package/dist/lib/node-esm/chunk-KIFOQXD4.mjs.map +7 -0
  80. package/dist/lib/node-esm/chunk-SBS2YMPT.mjs +43 -0
  81. package/dist/lib/node-esm/chunk-SBS2YMPT.mjs.map +7 -0
  82. package/dist/lib/node-esm/chunk-SDJ4B2LU.mjs +80 -0
  83. package/dist/lib/node-esm/chunk-SDJ4B2LU.mjs.map +7 -0
  84. package/dist/lib/node-esm/chunk-V24UWT36.mjs +582 -0
  85. package/dist/lib/node-esm/chunk-V24UWT36.mjs.map +7 -0
  86. package/dist/lib/node-esm/chunk-WFSRZKBP.mjs +81 -0
  87. package/dist/lib/node-esm/chunk-WFSRZKBP.mjs.map +7 -0
  88. package/dist/lib/node-esm/chunk-WK7OIQKI.mjs +70 -0
  89. package/dist/lib/node-esm/chunk-WK7OIQKI.mjs.map +7 -0
  90. package/dist/lib/node-esm/chunk-XOCUANHO.mjs +49 -0
  91. package/dist/lib/node-esm/chunk-XOCUANHO.mjs.map +7 -0
  92. package/dist/lib/node-esm/cli/index.mjs +77 -0
  93. package/dist/lib/node-esm/cli/index.mjs.map +7 -0
  94. package/dist/lib/node-esm/common/activation-events.mjs +25 -0
  95. package/dist/lib/node-esm/common/activation-events.mjs.map +7 -0
  96. package/dist/lib/node-esm/common/capabilities.mjs +47 -0
  97. package/dist/lib/node-esm/common/capabilities.mjs.map +7 -0
  98. package/dist/lib/node-esm/core/activation-event.mjs +21 -0
  99. package/dist/lib/node-esm/core/activation-event.mjs.map +7 -0
  100. package/dist/lib/node-esm/core/capability.mjs +31 -0
  101. package/dist/lib/node-esm/core/capability.mjs.map +7 -0
  102. package/dist/lib/node-esm/core/plugin-manager.mjs +20 -0
  103. package/dist/lib/node-esm/core/plugin-manager.mjs.map +7 -0
  104. package/dist/lib/node-esm/core/plugin.mjs +40 -0
  105. package/dist/lib/node-esm/core/plugin.mjs.map +7 -0
  106. package/dist/lib/node-esm/core/url-loader.mjs +25 -0
  107. package/dist/lib/node-esm/core/url-loader.mjs.map +7 -0
  108. package/dist/lib/node-esm/index.mjs +108 -148
  109. package/dist/lib/node-esm/index.mjs.map +4 -4
  110. package/dist/lib/node-esm/invoker-capability-QKUKN2MF.mjs +45 -0
  111. package/dist/lib/node-esm/invoker-capability-QKUKN2MF.mjs.map +7 -0
  112. package/dist/lib/node-esm/meta.json +1 -1
  113. package/dist/lib/node-esm/testing/index.mjs +229 -40
  114. package/dist/lib/node-esm/testing/index.mjs.map +4 -4
  115. package/dist/lib/node-esm/testing/react.mjs +79 -0
  116. package/dist/lib/node-esm/testing/react.mjs.map +7 -0
  117. package/dist/lib/node-esm/ui/index.mjs +49 -0
  118. package/dist/lib/node-esm/ui/index.mjs.map +7 -0
  119. package/dist/plugin/node-esm/index.mjs +893 -0
  120. package/dist/plugin/node-esm/index.mjs.map +7 -0
  121. package/dist/plugin/node-esm/meta.json +1 -0
  122. package/dist/types/src/cli/cli.d.ts +39 -0
  123. package/dist/types/src/cli/cli.d.ts.map +1 -0
  124. package/dist/types/src/cli/index.d.ts +2 -0
  125. package/dist/types/src/cli/index.d.ts.map +1 -0
  126. package/dist/types/src/common/activation-events.d.ts +27 -0
  127. package/dist/types/src/common/activation-events.d.ts.map +1 -0
  128. package/dist/types/src/common/annotations.d.ts +1 -0
  129. package/dist/types/src/common/annotations.d.ts.map +1 -0
  130. package/dist/types/src/common/capabilities.d.ts +110 -200
  131. package/dist/types/src/common/capabilities.d.ts.map +1 -1
  132. package/dist/types/src/common/index.d.ts +4 -8
  133. package/dist/types/src/common/index.d.ts.map +1 -1
  134. package/dist/types/src/common/operations.d.ts +19 -0
  135. package/dist/types/src/common/operations.d.ts.map +1 -0
  136. package/dist/types/src/common/translations.d.ts +7 -7
  137. package/dist/types/src/common/translations.d.ts.map +1 -1
  138. package/dist/types/src/context.d.ts +5 -0
  139. package/dist/types/src/context.d.ts.map +1 -0
  140. package/dist/types/src/core/{events.d.ts → activation-event.d.ts} +11 -11
  141. package/dist/types/src/core/activation-event.d.ts.map +1 -0
  142. package/dist/types/src/core/capability-manager.d.ts +48 -0
  143. package/dist/types/src/core/capability-manager.d.ts.map +1 -0
  144. package/dist/types/src/core/capability-manager.test.d.ts +2 -0
  145. package/dist/types/src/core/capability-manager.test.d.ts.map +1 -0
  146. package/dist/types/src/core/capability.d.ts +156 -0
  147. package/dist/types/src/core/capability.d.ts.map +1 -0
  148. package/dist/types/src/core/edge-registry-plugin-provider.d.ts +30 -0
  149. package/dist/types/src/core/edge-registry-plugin-provider.d.ts.map +1 -0
  150. package/dist/types/src/core/index.d.ts +11 -4
  151. package/dist/types/src/core/index.d.ts.map +1 -1
  152. package/dist/types/src/core/plugin-asset-cache.d.ts +71 -0
  153. package/dist/types/src/core/plugin-asset-cache.d.ts.map +1 -0
  154. package/dist/types/src/core/plugin-manager.d.ts +298 -0
  155. package/dist/types/src/core/plugin-manager.d.ts.map +1 -0
  156. package/dist/types/src/core/plugin-manager.test.d.ts +2 -0
  157. package/dist/types/src/core/plugin-manager.test.d.ts.map +1 -0
  158. package/dist/types/src/core/plugin-manifest.d.ts +101 -0
  159. package/dist/types/src/core/plugin-manifest.d.ts.map +1 -0
  160. package/dist/types/src/core/plugin-manifest.test.d.ts +2 -0
  161. package/dist/types/src/core/plugin-manifest.test.d.ts.map +1 -0
  162. package/dist/types/src/core/plugin.d.ts +260 -39
  163. package/dist/types/src/core/plugin.d.ts.map +1 -1
  164. package/dist/types/src/core/registry.d.ts +107 -0
  165. package/dist/types/src/core/registry.d.ts.map +1 -0
  166. package/dist/types/src/core/url-loader.d.ts +127 -0
  167. package/dist/types/src/core/url-loader.d.ts.map +1 -0
  168. package/dist/types/src/core/url-loader.test.d.ts +2 -0
  169. package/dist/types/src/core/url-loader.test.d.ts.map +1 -0
  170. package/dist/types/src/helpers.d.ts.map +1 -1
  171. package/dist/types/src/index.d.ts +3 -4
  172. package/dist/types/src/index.d.ts.map +1 -1
  173. package/dist/types/src/plugin-operation/OperationPlugin.d.ts +3 -0
  174. package/dist/types/src/plugin-operation/OperationPlugin.d.ts.map +1 -0
  175. package/dist/types/src/plugin-operation/history/capability.d.ts +7 -0
  176. package/dist/types/src/plugin-operation/history/capability.d.ts.map +1 -0
  177. package/dist/types/src/plugin-operation/history/errors.d.ts +32 -0
  178. package/dist/types/src/plugin-operation/history/errors.d.ts.map +1 -0
  179. package/dist/types/src/plugin-operation/history/history-tracker.d.ts +18 -0
  180. package/dist/types/src/plugin-operation/history/history-tracker.d.ts.map +1 -0
  181. package/dist/types/src/plugin-operation/history/history-tracker.test.d.ts +2 -0
  182. package/dist/types/src/plugin-operation/history/history-tracker.test.d.ts.map +1 -0
  183. package/dist/types/src/plugin-operation/history/index.d.ts +6 -0
  184. package/dist/types/src/plugin-operation/history/index.d.ts.map +1 -0
  185. package/dist/types/src/plugin-operation/history/types.d.ts +13 -0
  186. package/dist/types/src/plugin-operation/history/types.d.ts.map +1 -0
  187. package/dist/types/src/plugin-operation/history/undo-mapping.d.ts +101 -0
  188. package/dist/types/src/plugin-operation/history/undo-mapping.d.ts.map +1 -0
  189. package/dist/types/src/plugin-operation/history/undo-registry.d.ts +23 -0
  190. package/dist/types/src/plugin-operation/history/undo-registry.d.ts.map +1 -0
  191. package/dist/types/src/plugin-operation/history/undo-registry.test.d.ts +2 -0
  192. package/dist/types/src/plugin-operation/history/undo-registry.test.d.ts.map +1 -0
  193. package/dist/types/src/plugin-operation/index.d.ts +3 -0
  194. package/dist/types/src/plugin-operation/index.d.ts.map +1 -0
  195. package/dist/types/src/plugin-operation/invoker-capability.d.ts +6 -0
  196. package/dist/types/src/plugin-operation/invoker-capability.d.ts.map +1 -0
  197. package/dist/types/src/plugin-operation/meta.d.ts +3 -0
  198. package/dist/types/src/plugin-operation/meta.d.ts.map +1 -0
  199. package/dist/types/src/plugin-operation/testing.d.ts +59 -0
  200. package/dist/types/src/plugin-operation/testing.d.ts.map +1 -0
  201. package/dist/types/src/plugin-runtime/RuntimePlugin.d.ts +3 -0
  202. package/dist/types/src/plugin-runtime/RuntimePlugin.d.ts.map +1 -0
  203. package/dist/types/src/plugin-runtime/capability.d.ts +6 -0
  204. package/dist/types/src/plugin-runtime/capability.d.ts.map +1 -0
  205. package/dist/types/src/plugin-runtime/index.d.ts +2 -0
  206. package/dist/types/src/plugin-runtime/index.d.ts.map +1 -0
  207. package/dist/types/src/plugin-runtime/meta.d.ts +3 -0
  208. package/dist/types/src/plugin-runtime/meta.d.ts.map +1 -0
  209. package/dist/types/src/testing/harness.d.ts +67 -0
  210. package/dist/types/src/testing/harness.d.ts.map +1 -0
  211. package/dist/types/src/testing/index.d.ts +2 -0
  212. package/dist/types/src/testing/index.d.ts.map +1 -1
  213. package/dist/types/src/testing/react.d.ts +27 -0
  214. package/dist/types/src/testing/react.d.ts.map +1 -0
  215. package/dist/types/src/testing/react.test.d.ts +2 -0
  216. package/dist/types/src/testing/react.test.d.ts.map +1 -0
  217. package/dist/types/src/testing/service.d.ts +8 -0
  218. package/dist/types/src/testing/service.d.ts.map +1 -0
  219. package/dist/types/src/testing/withPluginManager.d.ts +4 -4
  220. package/dist/types/src/testing/withPluginManager.d.ts.map +1 -1
  221. package/dist/types/src/testing/withPluginManager.stories.d.ts.map +1 -1
  222. package/dist/types/src/ui/components/App/App.d.ts +9 -0
  223. package/dist/types/src/ui/components/App/App.d.ts.map +1 -0
  224. package/dist/types/src/ui/components/App/App.stories.d.ts +19 -0
  225. package/dist/types/src/ui/components/App/App.stories.d.ts.map +1 -0
  226. package/dist/types/src/ui/components/App/index.d.ts +2 -0
  227. package/dist/types/src/ui/components/App/index.d.ts.map +1 -0
  228. package/dist/types/src/ui/components/Placeholder/Placeholder.d.ts +64 -0
  229. package/dist/types/src/ui/components/Placeholder/Placeholder.d.ts.map +1 -0
  230. package/dist/types/src/ui/components/Placeholder/Placeholder.stories.d.ts +19 -0
  231. package/dist/types/src/ui/components/Placeholder/Placeholder.stories.d.ts.map +1 -0
  232. package/dist/types/src/ui/components/Placeholder/index.d.ts +2 -0
  233. package/dist/types/src/ui/components/Placeholder/index.d.ts.map +1 -0
  234. package/dist/types/src/{playground/playground.stories.d.ts → ui/components/PluginManager/PluginManagerContext.stories.d.ts} +5 -3
  235. package/dist/types/src/ui/components/PluginManager/PluginManagerContext.stories.d.ts.map +1 -0
  236. package/dist/types/src/ui/components/PluginManager/PluginManagerProvider.d.ts +10 -0
  237. package/dist/types/src/ui/components/PluginManager/PluginManagerProvider.d.ts.map +1 -0
  238. package/dist/types/src/ui/components/PluginManager/index.d.ts +2 -0
  239. package/dist/types/src/ui/components/PluginManager/index.d.ts.map +1 -0
  240. package/dist/types/src/ui/components/Surface/SurfaceComponent.d.ts +24 -0
  241. package/dist/types/src/ui/components/Surface/SurfaceComponent.d.ts.map +1 -0
  242. package/dist/types/src/{components/App.stories.d.ts → ui/components/Surface/SurfaceComponent.stories.d.ts} +1 -1
  243. package/dist/types/src/ui/components/Surface/SurfaceComponent.stories.d.ts.map +1 -0
  244. package/dist/types/src/ui/components/Surface/SurfaceInfo.d.ts +11 -0
  245. package/dist/types/src/ui/components/Surface/SurfaceInfo.d.ts.map +1 -0
  246. package/dist/types/src/ui/components/Surface/SurfaceProfilerContext.d.ts +48 -0
  247. package/dist/types/src/ui/components/Surface/SurfaceProfilerContext.d.ts.map +1 -0
  248. package/dist/types/src/ui/components/Surface/context.d.ts +5 -0
  249. package/dist/types/src/ui/components/Surface/context.d.ts.map +1 -0
  250. package/dist/types/src/ui/components/Surface/index.d.ts +36 -0
  251. package/dist/types/src/ui/components/Surface/index.d.ts.map +1 -0
  252. package/dist/types/src/ui/components/Surface/types.d.ts +197 -0
  253. package/dist/types/src/ui/components/Surface/types.d.ts.map +1 -0
  254. package/dist/types/src/ui/components/Surface/types.test.d.ts +2 -0
  255. package/dist/types/src/ui/components/Surface/types.test.d.ts.map +1 -0
  256. package/dist/types/src/ui/components/index.d.ts +5 -0
  257. package/dist/types/src/ui/components/index.d.ts.map +1 -0
  258. package/dist/types/src/ui/hooks/index.d.ts +6 -0
  259. package/dist/types/src/ui/hooks/index.d.ts.map +1 -0
  260. package/dist/types/src/ui/hooks/useApp.d.ts +89 -0
  261. package/dist/types/src/ui/hooks/useApp.d.ts.map +1 -0
  262. package/dist/types/src/ui/hooks/useApp.test.d.ts +2 -0
  263. package/dist/types/src/ui/hooks/useApp.test.d.ts.map +1 -0
  264. package/dist/types/src/ui/hooks/useCapabilities.d.ts +31 -0
  265. package/dist/types/src/ui/hooks/useCapabilities.d.ts.map +1 -0
  266. package/dist/types/src/{components → ui/hooks}/useLoading.d.ts +1 -2
  267. package/dist/types/src/ui/hooks/useLoading.d.ts.map +1 -0
  268. package/dist/types/src/ui/hooks/useSettingsState.d.ts +10 -0
  269. package/dist/types/src/ui/hooks/useSettingsState.d.ts.map +1 -0
  270. package/dist/types/src/ui/hooks/useSurface.d.ts +3 -0
  271. package/dist/types/src/ui/hooks/useSurface.d.ts.map +1 -0
  272. package/dist/types/src/ui/index.d.ts +3 -0
  273. package/dist/types/src/ui/index.d.ts.map +1 -0
  274. package/dist/types/src/vite-plugin/boot-loader/BootLoader.stories.d.ts +34 -0
  275. package/dist/types/src/vite-plugin/boot-loader/BootLoader.stories.d.ts.map +1 -0
  276. package/dist/types/src/vite-plugin/boot-loader/index.d.ts +2 -0
  277. package/dist/types/src/vite-plugin/boot-loader/index.d.ts.map +1 -0
  278. package/dist/types/src/vite-plugin/boot-loader/loader.d.ts +51 -0
  279. package/dist/types/src/vite-plugin/boot-loader/loader.d.ts.map +1 -0
  280. package/dist/types/src/vite-plugin/composer/index.d.ts +34 -0
  281. package/dist/types/src/vite-plugin/composer/index.d.ts.map +1 -0
  282. package/dist/types/src/vite-plugin/import-map/index.d.ts +28 -0
  283. package/dist/types/src/vite-plugin/import-map/index.d.ts.map +1 -0
  284. package/dist/types/src/vite-plugin/index.d.ts +5 -0
  285. package/dist/types/src/vite-plugin/index.d.ts.map +1 -0
  286. package/dist/types/src/vite-plugin/manifest.d.ts +41 -0
  287. package/dist/types/src/vite-plugin/manifest.d.ts.map +1 -0
  288. package/dist/types/src/vite-plugin/manifest.test.d.ts +2 -0
  289. package/dist/types/src/vite-plugin/manifest.test.d.ts.map +1 -0
  290. package/dist/types/src/vite-plugin/packages.d.ts +13 -0
  291. package/dist/types/src/vite-plugin/packages.d.ts.map +1 -0
  292. package/dist/types/tsconfig.tsbuildinfo +1 -1
  293. package/moon.yml +25 -6
  294. package/package.json +115 -56
  295. package/src/cli/cli.ts +107 -0
  296. package/src/{components → cli}/index.ts +1 -1
  297. package/src/common/activation-events.ts +44 -0
  298. package/src/{playground/layout/index.ts → common/annotations.ts} +0 -2
  299. package/src/common/capabilities.ts +169 -213
  300. package/src/common/index.ts +4 -8
  301. package/src/common/operations.ts +35 -0
  302. package/src/common/translations.ts +17 -9
  303. package/src/context.ts +9 -0
  304. package/src/core/{events.ts → activation-event.ts} +10 -7
  305. package/src/core/capability-manager.test.ts +151 -0
  306. package/src/core/capability-manager.ts +192 -0
  307. package/src/core/capability.ts +247 -0
  308. package/src/core/edge-registry-plugin-provider.ts +92 -0
  309. package/src/core/index.ts +11 -4
  310. package/src/core/plugin-asset-cache.ts +60 -0
  311. package/src/core/plugin-manager.test.ts +1899 -0
  312. package/src/core/plugin-manager.ts +1685 -0
  313. package/src/core/plugin-manifest.test.ts +75 -0
  314. package/src/core/plugin-manifest.ts +134 -0
  315. package/src/core/plugin.ts +395 -45
  316. package/src/core/registry.ts +163 -0
  317. package/src/core/url-loader.test.ts +221 -0
  318. package/src/core/url-loader.ts +388 -0
  319. package/src/index.ts +3 -4
  320. package/src/plugin-operation/OperationPlugin.ts +24 -0
  321. package/src/plugin-operation/history/capability.ts +36 -0
  322. package/src/plugin-operation/history/errors.ts +7 -0
  323. package/src/plugin-operation/history/history-tracker.test.ts +374 -0
  324. package/src/plugin-operation/history/history-tracker.ts +128 -0
  325. package/src/plugin-operation/history/index.ts +9 -0
  326. package/src/plugin-operation/history/types.ts +17 -0
  327. package/src/plugin-operation/history/undo-mapping.ts +135 -0
  328. package/src/plugin-operation/history/undo-registry.test.ts +72 -0
  329. package/src/plugin-operation/history/undo-registry.ts +54 -0
  330. package/src/plugin-operation/index.ts +6 -0
  331. package/src/plugin-operation/invoker-capability.ts +55 -0
  332. package/src/plugin-operation/meta.ts +12 -0
  333. package/src/plugin-operation/testing.ts +155 -0
  334. package/src/plugin-runtime/RuntimePlugin.ts +19 -0
  335. package/src/plugin-runtime/capability.ts +53 -0
  336. package/src/plugin-runtime/index.ts +5 -0
  337. package/src/plugin-runtime/meta.ts +12 -0
  338. package/src/testing/harness.ts +229 -0
  339. package/src/testing/index.ts +2 -0
  340. package/src/testing/react.test.tsx +48 -0
  341. package/src/testing/react.tsx +113 -0
  342. package/src/testing/service.ts +52 -0
  343. package/src/testing/withPluginManager.stories.tsx +8 -9
  344. package/src/testing/withPluginManager.tsx +61 -38
  345. package/src/ui/components/App/App.stories.tsx +88 -0
  346. package/src/ui/components/App/App.tsx +81 -0
  347. package/src/{playground/debug → ui/components/App}/index.ts +1 -1
  348. package/src/ui/components/Placeholder/Placeholder.stories.tsx +77 -0
  349. package/src/ui/components/Placeholder/Placeholder.tsx +155 -0
  350. package/src/{playground/logger → ui/components/Placeholder}/index.ts +1 -1
  351. package/src/ui/components/PluginManager/PluginManagerContext.stories.tsx +185 -0
  352. package/src/{react → ui/components/PluginManager}/PluginManagerProvider.ts +3 -3
  353. package/src/ui/components/PluginManager/index.ts +5 -0
  354. package/src/ui/components/Surface/SurfaceComponent.stories.tsx +144 -0
  355. package/src/ui/components/Surface/SurfaceComponent.tsx +303 -0
  356. package/src/ui/components/Surface/SurfaceInfo.tsx +106 -0
  357. package/src/ui/components/Surface/SurfaceProfilerContext.tsx +207 -0
  358. package/src/ui/components/Surface/context.ts +12 -0
  359. package/src/ui/components/Surface/index.ts +54 -0
  360. package/src/ui/components/Surface/types.test.ts +126 -0
  361. package/src/ui/components/Surface/types.ts +269 -0
  362. package/src/ui/components/index.ts +8 -0
  363. package/src/ui/hooks/index.ts +9 -0
  364. package/src/ui/hooks/useApp.test.tsx +159 -0
  365. package/src/ui/hooks/useApp.tsx +424 -0
  366. package/src/ui/hooks/useCapabilities.ts +67 -0
  367. package/src/{components → ui/hooks}/useLoading.tsx +16 -10
  368. package/src/ui/hooks/useSettingsState.ts +26 -0
  369. package/src/ui/hooks/useSurface.ts +13 -0
  370. package/src/ui/index.ts +6 -0
  371. package/src/vite-plugin/boot-loader/BootLoader.stories.tsx +270 -0
  372. package/src/vite-plugin/boot-loader/boot-loader.css +320 -0
  373. package/src/vite-plugin/boot-loader/boot-loader.js +325 -0
  374. package/src/vite-plugin/boot-loader/index.ts +5 -0
  375. package/src/vite-plugin/boot-loader/loader.ts +123 -0
  376. package/src/vite-plugin/composer/index.ts +306 -0
  377. package/src/vite-plugin/import-map/index.ts +527 -0
  378. package/src/vite-plugin/index.ts +10 -0
  379. package/src/vite-plugin/manifest.test.ts +46 -0
  380. package/src/vite-plugin/manifest.ts +57 -0
  381. package/src/vite-plugin/packages.ts +187 -0
  382. package/tsconfig.json +24 -15
  383. package/tsconfig.node.json +2 -4
  384. package/typedoc.json +2 -4
  385. package/vitest.config.ts +1 -1
  386. package/.swc/plugins/linux_x86_64_19.0.0/727453fb3a62f7f1d952a41e051ca8a6f88cadc45cee43c6a4d1aa45f9b75665.wasmer-v7 +0 -0
  387. package/.swc/plugins/linux_x86_64_19.0.0/fce1bdb8e20a094e4af08bad09cc81497ed0e2e7c51223b07d371063cca18429.wasmer-v7 +0 -0
  388. package/dist/lib/browser/app-graph-builder-PSA3RESL.mjs +0 -138
  389. package/dist/lib/browser/app-graph-builder-PSA3RESL.mjs.map +0 -7
  390. package/dist/lib/browser/chunk-2VZ4RF4A.mjs +0 -1608
  391. package/dist/lib/browser/chunk-2VZ4RF4A.mjs.map +0 -7
  392. package/dist/lib/browser/chunk-CPVYIS24.mjs +0 -451
  393. package/dist/lib/browser/chunk-CPVYIS24.mjs.map +0 -7
  394. package/dist/lib/browser/chunk-SCPE4ZO2.mjs +0 -35
  395. package/dist/lib/browser/chunk-SCPE4ZO2.mjs.map +0 -7
  396. package/dist/lib/browser/intent-dispatcher-BND6IF4U.mjs +0 -11
  397. package/dist/lib/browser/intent-resolver-27FJAJDE.mjs +0 -39
  398. package/dist/lib/browser/intent-resolver-27FJAJDE.mjs.map +0 -7
  399. package/dist/lib/browser/store-F545UOIR.mjs +0 -30
  400. package/dist/lib/browser/store-F545UOIR.mjs.map +0 -7
  401. package/dist/lib/browser/worker.mjs +0 -77
  402. package/dist/lib/node-esm/app-graph-builder-VJGZ6KH7.mjs +0 -139
  403. package/dist/lib/node-esm/app-graph-builder-VJGZ6KH7.mjs.map +0 -7
  404. package/dist/lib/node-esm/chunk-3RRWO5TD.mjs +0 -1610
  405. package/dist/lib/node-esm/chunk-3RRWO5TD.mjs.map +0 -7
  406. package/dist/lib/node-esm/chunk-MN37WUJ2.mjs +0 -452
  407. package/dist/lib/node-esm/chunk-MN37WUJ2.mjs.map +0 -7
  408. package/dist/lib/node-esm/chunk-ZX63QUGE.mjs +0 -37
  409. package/dist/lib/node-esm/chunk-ZX63QUGE.mjs.map +0 -7
  410. package/dist/lib/node-esm/intent-dispatcher-254AZ6EE.mjs +0 -12
  411. package/dist/lib/node-esm/intent-resolver-NPMOPNFL.mjs +0 -40
  412. package/dist/lib/node-esm/intent-resolver-NPMOPNFL.mjs.map +0 -7
  413. package/dist/lib/node-esm/store-CINC4R4L.mjs +0 -31
  414. package/dist/lib/node-esm/store-CINC4R4L.mjs.map +0 -7
  415. package/dist/lib/node-esm/worker.mjs +0 -78
  416. package/dist/types/src/common/collaboration.d.ts +0 -20
  417. package/dist/types/src/common/collaboration.d.ts.map +0 -1
  418. package/dist/types/src/common/events.d.ts +0 -52
  419. package/dist/types/src/common/events.d.ts.map +0 -1
  420. package/dist/types/src/common/file.d.ts +0 -14
  421. package/dist/types/src/common/file.d.ts.map +0 -1
  422. package/dist/types/src/common/graph.d.ts +0 -21
  423. package/dist/types/src/common/graph.d.ts.map +0 -1
  424. package/dist/types/src/common/layout.d.ts +0 -279
  425. package/dist/types/src/common/layout.d.ts.map +0 -1
  426. package/dist/types/src/common/surface.d.ts +0 -59
  427. package/dist/types/src/common/surface.d.ts.map +0 -1
  428. package/dist/types/src/components/App.d.ts +0 -10
  429. package/dist/types/src/components/App.d.ts.map +0 -1
  430. package/dist/types/src/components/App.stories.d.ts.map +0 -1
  431. package/dist/types/src/components/DefaultFallback.d.ts +0 -8
  432. package/dist/types/src/components/DefaultFallback.d.ts.map +0 -1
  433. package/dist/types/src/components/index.d.ts +0 -2
  434. package/dist/types/src/components/index.d.ts.map +0 -1
  435. package/dist/types/src/components/useApp.d.ts +0 -44
  436. package/dist/types/src/components/useApp.d.ts.map +0 -1
  437. package/dist/types/src/components/useLoading.d.ts.map +0 -1
  438. package/dist/types/src/core/capabilities.d.ts +0 -117
  439. package/dist/types/src/core/capabilities.d.ts.map +0 -1
  440. package/dist/types/src/core/capabilities.test.d.ts +0 -2
  441. package/dist/types/src/core/capabilities.test.d.ts.map +0 -1
  442. package/dist/types/src/core/events.d.ts.map +0 -1
  443. package/dist/types/src/core/manager.d.ts +0 -126
  444. package/dist/types/src/core/manager.d.ts.map +0 -1
  445. package/dist/types/src/core/manager.test.d.ts +0 -2
  446. package/dist/types/src/core/manager.test.d.ts.map +0 -1
  447. package/dist/types/src/playground/debug/Debug.d.ts +0 -6
  448. package/dist/types/src/playground/debug/Debug.d.ts.map +0 -1
  449. package/dist/types/src/playground/debug/index.d.ts +0 -2
  450. package/dist/types/src/playground/debug/index.d.ts.map +0 -1
  451. package/dist/types/src/playground/debug/plugin.d.ts +0 -2
  452. package/dist/types/src/playground/debug/plugin.d.ts.map +0 -1
  453. package/dist/types/src/playground/generator/Main.d.ts +0 -6
  454. package/dist/types/src/playground/generator/Main.d.ts.map +0 -1
  455. package/dist/types/src/playground/generator/Toolbar.d.ts +0 -6
  456. package/dist/types/src/playground/generator/Toolbar.d.ts.map +0 -1
  457. package/dist/types/src/playground/generator/generator.d.ts +0 -7
  458. package/dist/types/src/playground/generator/generator.d.ts.map +0 -1
  459. package/dist/types/src/playground/generator/index.d.ts +0 -3
  460. package/dist/types/src/playground/generator/index.d.ts.map +0 -1
  461. package/dist/types/src/playground/generator/plugin.d.ts +0 -2
  462. package/dist/types/src/playground/generator/plugin.d.ts.map +0 -1
  463. package/dist/types/src/playground/layout/Layout.d.ts +0 -8
  464. package/dist/types/src/playground/layout/Layout.d.ts.map +0 -1
  465. package/dist/types/src/playground/layout/index.d.ts +0 -2
  466. package/dist/types/src/playground/layout/index.d.ts.map +0 -1
  467. package/dist/types/src/playground/layout/plugin.d.ts +0 -2
  468. package/dist/types/src/playground/layout/plugin.d.ts.map +0 -1
  469. package/dist/types/src/playground/logger/Toolbar.d.ts +0 -6
  470. package/dist/types/src/playground/logger/Toolbar.d.ts.map +0 -1
  471. package/dist/types/src/playground/logger/index.d.ts +0 -2
  472. package/dist/types/src/playground/logger/index.d.ts.map +0 -1
  473. package/dist/types/src/playground/logger/plugin.d.ts +0 -2
  474. package/dist/types/src/playground/logger/plugin.d.ts.map +0 -1
  475. package/dist/types/src/playground/logger/schema.d.ts +0 -13
  476. package/dist/types/src/playground/logger/schema.d.ts.map +0 -1
  477. package/dist/types/src/playground/playground.stories.d.ts.map +0 -1
  478. package/dist/types/src/plugin-intent/IntentPlugin.d.ts +0 -2
  479. package/dist/types/src/plugin-intent/IntentPlugin.d.ts.map +0 -1
  480. package/dist/types/src/plugin-intent/actions.d.ts +0 -36
  481. package/dist/types/src/plugin-intent/actions.d.ts.map +0 -1
  482. package/dist/types/src/plugin-intent/errors.d.ts +0 -16
  483. package/dist/types/src/plugin-intent/errors.d.ts.map +0 -1
  484. package/dist/types/src/plugin-intent/index.d.ts +0 -6
  485. package/dist/types/src/plugin-intent/index.d.ts.map +0 -1
  486. package/dist/types/src/plugin-intent/intent-dispatcher.d.ts +0 -139
  487. package/dist/types/src/plugin-intent/intent-dispatcher.d.ts.map +0 -1
  488. package/dist/types/src/plugin-intent/intent-dispatcher.test.d.ts +0 -2
  489. package/dist/types/src/plugin-intent/intent-dispatcher.test.d.ts.map +0 -1
  490. package/dist/types/src/plugin-intent/intent.d.ts +0 -63
  491. package/dist/types/src/plugin-intent/intent.d.ts.map +0 -1
  492. package/dist/types/src/plugin-intent/meta.d.ts +0 -3
  493. package/dist/types/src/plugin-intent/meta.d.ts.map +0 -1
  494. package/dist/types/src/plugin-settings/SettingsPlugin.d.ts +0 -2
  495. package/dist/types/src/plugin-settings/SettingsPlugin.d.ts.map +0 -1
  496. package/dist/types/src/plugin-settings/actions.d.ts +0 -25
  497. package/dist/types/src/plugin-settings/actions.d.ts.map +0 -1
  498. package/dist/types/src/plugin-settings/app-graph-builder.d.ts +0 -4
  499. package/dist/types/src/plugin-settings/app-graph-builder.d.ts.map +0 -1
  500. package/dist/types/src/plugin-settings/index.d.ts +0 -3
  501. package/dist/types/src/plugin-settings/index.d.ts.map +0 -1
  502. package/dist/types/src/plugin-settings/intent-resolver.d.ts +0 -4
  503. package/dist/types/src/plugin-settings/intent-resolver.d.ts.map +0 -1
  504. package/dist/types/src/plugin-settings/meta.d.ts +0 -3
  505. package/dist/types/src/plugin-settings/meta.d.ts.map +0 -1
  506. package/dist/types/src/plugin-settings/store.d.ts +0 -5
  507. package/dist/types/src/plugin-settings/store.d.ts.map +0 -1
  508. package/dist/types/src/plugin-settings/translations.d.ts +0 -11
  509. package/dist/types/src/plugin-settings/translations.d.ts.map +0 -1
  510. package/dist/types/src/react/ErrorBoundary.d.ts +0 -30
  511. package/dist/types/src/react/ErrorBoundary.d.ts.map +0 -1
  512. package/dist/types/src/react/IntentContext.d.ts +0 -8
  513. package/dist/types/src/react/IntentContext.d.ts.map +0 -1
  514. package/dist/types/src/react/PluginManagerProvider.d.ts +0 -10
  515. package/dist/types/src/react/PluginManagerProvider.d.ts.map +0 -1
  516. package/dist/types/src/react/Surface.d.ts +0 -12
  517. package/dist/types/src/react/Surface.d.ts.map +0 -1
  518. package/dist/types/src/react/Surface.stories.d.ts +0 -17
  519. package/dist/types/src/react/Surface.stories.d.ts.map +0 -1
  520. package/dist/types/src/react/common.d.ts +0 -13
  521. package/dist/types/src/react/common.d.ts.map +0 -1
  522. package/dist/types/src/react/index.d.ts +0 -7
  523. package/dist/types/src/react/index.d.ts.map +0 -1
  524. package/dist/types/src/react/useCapabilities.d.ts +0 -13
  525. package/dist/types/src/react/useCapabilities.d.ts.map +0 -1
  526. package/dist/types/src/react/useIntentResolver.d.ts +0 -3
  527. package/dist/types/src/react/useIntentResolver.d.ts.map +0 -1
  528. package/dist/types/src/worker.d.ts +0 -4
  529. package/dist/types/src/worker.d.ts.map +0 -1
  530. package/src/common/collaboration.ts +0 -18
  531. package/src/common/events.ts +0 -79
  532. package/src/common/file.ts +0 -22
  533. package/src/common/graph.ts +0 -30
  534. package/src/common/layout.ts +0 -277
  535. package/src/common/surface.ts +0 -83
  536. package/src/components/App.stories.tsx +0 -33
  537. package/src/components/App.tsx +0 -59
  538. package/src/components/DefaultFallback.tsx +0 -26
  539. package/src/components/useApp.tsx +0 -164
  540. package/src/core/capabilities.test.ts +0 -136
  541. package/src/core/capabilities.ts +0 -263
  542. package/src/core/manager.test.ts +0 -516
  543. package/src/core/manager.ts +0 -604
  544. package/src/playground/debug/Debug.tsx +0 -39
  545. package/src/playground/debug/plugin.ts +0 -16
  546. package/src/playground/generator/Main.tsx +0 -71
  547. package/src/playground/generator/Toolbar.tsx +0 -47
  548. package/src/playground/generator/generator.ts +0 -48
  549. package/src/playground/generator/index.ts +0 -6
  550. package/src/playground/generator/plugin.ts +0 -22
  551. package/src/playground/layout/Layout.tsx +0 -33
  552. package/src/playground/layout/plugin.ts +0 -18
  553. package/src/playground/logger/Toolbar.tsx +0 -30
  554. package/src/playground/logger/plugin.ts +0 -41
  555. package/src/playground/logger/schema.ts +0 -12
  556. package/src/playground/playground.stories.tsx +0 -46
  557. package/src/plugin-intent/IntentPlugin.ts +0 -20
  558. package/src/plugin-intent/actions.ts +0 -31
  559. package/src/plugin-intent/errors.ts +0 -40
  560. package/src/plugin-intent/index.ts +0 -9
  561. package/src/plugin-intent/intent-dispatcher.test.ts +0 -286
  562. package/src/plugin-intent/intent-dispatcher.ts +0 -337
  563. package/src/plugin-intent/intent.ts +0 -154
  564. package/src/plugin-intent/meta.ts +0 -10
  565. package/src/plugin-settings/SettingsPlugin.ts +0 -34
  566. package/src/plugin-settings/actions.ts +0 -25
  567. package/src/plugin-settings/app-graph-builder.ts +0 -160
  568. package/src/plugin-settings/index.ts +0 -6
  569. package/src/plugin-settings/intent-resolver.ts +0 -35
  570. package/src/plugin-settings/meta.ts +0 -10
  571. package/src/plugin-settings/store.ts +0 -33
  572. package/src/plugin-settings/translations.ts +0 -19
  573. package/src/react/ErrorBoundary.tsx +0 -56
  574. package/src/react/IntentContext.tsx +0 -35
  575. package/src/react/Surface.stories.tsx +0 -101
  576. package/src/react/Surface.tsx +0 -86
  577. package/src/react/common.ts +0 -13
  578. package/src/react/index.ts +0 -10
  579. package/src/react/useCapabilities.ts +0 -31
  580. package/src/react/useIntentResolver.ts +0 -22
  581. package/src/worker.ts +0 -11
  582. /package/dist/lib/browser/{intent-dispatcher-BND6IF4U.mjs.map → chunk-J5LGTIGS.mjs.map} +0 -0
  583. /package/dist/lib/browser/{worker.mjs.map → common/activation-events.mjs.map} +0 -0
  584. /package/dist/lib/{node-esm/intent-dispatcher-254AZ6EE.mjs.map → browser/common/capabilities.mjs.map} +0 -0
  585. /package/dist/lib/{node-esm/worker.mjs.map → browser/core/activation-event.mjs.map} +0 -0
@@ -2,12 +2,83 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { type MaybePromise } from '@dxos/util';
5
+ import * as Context from 'effect/Context';
6
+ import * as Effect from 'effect/Effect';
7
+ import * as Option from 'effect/Option';
8
+ import * as Pipeable from 'effect/Pipeable';
6
9
 
7
- import { type AnyCapability, type PluginContext } from './capabilities';
8
- import { type ActivationEvent, type ActivationEvents } from './events';
10
+ import { BaseError } from '@dxos/errors';
11
+ import { invariant } from '@dxos/invariant';
9
12
 
10
- interface PluginModuleInterface {
13
+ import type * as ActivationEvent from './activation-event';
14
+ import * as Capability from './capability';
15
+ import type * as PluginManager from './plugin-manager';
16
+
17
+ //
18
+ // Plugin Service Layer
19
+ //
20
+
21
+ /**
22
+ * Effect Context.Tag for accessing PluginManager via the Effect layer system.
23
+ * This allows lifecycle operations to access the plugin manager without having it passed as an argument.
24
+ */
25
+ export class Service extends Context.Tag('@dxos/app-framework/PluginManager')<Service, PluginManager.PluginManager>() {}
26
+
27
+ //
28
+ // Lifecycle Functions
29
+ //
30
+
31
+ /**
32
+ * Activates plugins based on the activation event.
33
+ * Accesses the PluginManager via the Effect layer system.
34
+ * @param event The activation event.
35
+ * @returns Whether the activation was successful.
36
+ */
37
+ export const activate = (event: ActivationEvent.ActivationEvent): Effect.Effect<boolean, Error, Service> =>
38
+ Effect.flatMap(Service, (manager) => manager.activate(event));
39
+
40
+ /**
41
+ * Re-activates the modules that were activated by the event.
42
+ * Accesses the PluginManager via the Effect layer system.
43
+ * @param event The activation event.
44
+ * @returns Whether the reset was successful.
45
+ */
46
+ export const reset = (event: ActivationEvent.ActivationEvent): Effect.Effect<boolean, Error, Service> =>
47
+ Effect.flatMap(Service, (manager) => manager.reset(event));
48
+
49
+ /**
50
+ * Shuts down the plugin manager, deactivating all active modules and clearing lifecycle state.
51
+ * Accesses the PluginManager via the Effect layer system.
52
+ */
53
+ export const shutdown = (): Effect.Effect<boolean, Error, Service> =>
54
+ Effect.flatMap(Service, (manager) => manager.shutdown());
55
+
56
+ /**
57
+ * Computes a module ID from plugin ID and export name.
58
+ */
59
+ const computeModuleId = (pluginId: string, moduleName: string): string => {
60
+ return `${pluginId}.module.${moduleName}`;
61
+ };
62
+
63
+ /**
64
+ * Identifier denoting a PluginModule.
65
+ */
66
+ export const PluginModuleTypeId: unique symbol = Symbol.for('@dxos/app-framework/PluginModule');
67
+ export type PluginModuleTypeId = typeof PluginModuleTypeId;
68
+
69
+ /**
70
+ * Type guard to check if a value is a PluginModule.
71
+ */
72
+ export const isPluginModule = (value: unknown): value is PluginModule => {
73
+ return typeof value === 'object' && value !== null && PluginModuleTypeId in value;
74
+ };
75
+
76
+ /**
77
+ * A unit of containment of modular functionality that can be provided to an application.
78
+ * Activation of a module is async allowing for code to split and loaded lazily.
79
+ */
80
+ export interface PluginModule {
81
+ readonly [PluginModuleTypeId]: PluginModuleTypeId;
11
82
  /**
12
83
  * Unique id of the module.
13
84
  */
@@ -16,63 +87,73 @@ interface PluginModuleInterface {
16
87
  /**
17
88
  * Events for which the module will be activated.
18
89
  */
19
- activatesOn: ActivationEvents;
90
+ activatesOn: ActivationEvent.Events;
20
91
 
21
92
  /**
22
- * Events which the plugin depends on being activated.
23
- * Plugin is marked as needing reset a plugin activated by a dependent event is removed.
24
- * Events are automatically activated before activation of the plugin.
93
+ * Events that this module fires *before* its own activation runs.
94
+ *
95
+ * When this module is asked to activate (via {@link activatesOn}), the
96
+ * plugin manager first activates every event listed here, ensuring any
97
+ * other modules that contribute to those events have completed before
98
+ * this module's {@link activate} body executes. These events are fired
99
+ * by the framework on this module's behalf — the module does not need
100
+ * to wait for some other code to fire them.
101
+ *
102
+ * The module is marked as needing reset if a module activated by one
103
+ * of these events is later removed.
104
+ *
105
+ * Read as: "this module fires these events before [its] activation".
25
106
  */
26
- activatesBefore?: ActivationEvent[];
107
+ firesBeforeActivation?: ActivationEvent.ActivationEvent[];
27
108
 
28
109
  /**
29
- * Events which this plugin triggers upon activation.
110
+ * Events that this module fires *after* its own activation completes.
111
+ *
112
+ * Once this module's {@link activate} body has finished executing, the
113
+ * plugin manager activates every event listed here, causing any modules
114
+ * listening on those events to run. These events are fired by the
115
+ * framework on this module's behalf as part of this module's lifecycle.
116
+ *
117
+ * Read as: "this module fires these events after [its] activation".
30
118
  */
31
- activatesAfter?: ActivationEvent[];
119
+ firesAfterActivation?: ActivationEvent.ActivationEvent[];
32
120
 
33
121
  /**
34
122
  * Called when the module is activated.
35
- * @param context The plugin context.
123
+ * CapabilityManager is accessed via the Effect layer system (Capability.Service).
124
+ * PluginManager is accessed via Plugin.Service.
125
+ * @param props Optional props passed to the module.
36
126
  * @returns The capabilities of the module.
37
127
  */
38
- activate: (
39
- context: PluginContext,
40
- ) => MaybePromise<AnyCapability | AnyCapability[]> | Promise<() => Promise<AnyCapability | AnyCapability[]>>;
128
+ activate: (props?: any) => Effect.Effect<Capability.ModuleReturn, Error, Capability.Service | Service | never>;
41
129
  }
42
130
 
43
- /**
44
- * A unit of containment of modular functionality that can be provided to an application.
45
- * Activation of a module is async allowing for code to split and loaded lazily.
46
- */
47
- // NOTE: This is implemented as a class to prevent it from being proxied by PluginManager state.
48
- export class PluginModule implements PluginModuleInterface {
49
- readonly id: PluginModuleInterface['id'];
50
- readonly activatesOn: PluginModuleInterface['activatesOn'];
51
- readonly activatesBefore?: PluginModuleInterface['activatesBefore'];
52
- readonly activatesAfter?: PluginModuleInterface['activatesAfter'];
53
- readonly activate: PluginModuleInterface['activate'];
131
+ export type PluginModuleOptions = Omit<PluginModule, 'id' | typeof PluginModuleTypeId> & { id?: string };
132
+
133
+ class PluginModuleImpl implements PluginModule {
134
+ readonly [PluginModuleTypeId]: PluginModuleTypeId = PluginModuleTypeId;
135
+ readonly id: PluginModule['id'];
136
+ readonly activatesOn: PluginModule['activatesOn'];
137
+ readonly firesBeforeActivation?: PluginModule['firesBeforeActivation'];
138
+ readonly firesAfterActivation?: PluginModule['firesAfterActivation'];
139
+ readonly activate: PluginModule['activate'];
54
140
 
55
- constructor(options: PluginModuleInterface) {
141
+ constructor(options: Omit<PluginModule, typeof PluginModuleTypeId>) {
56
142
  this.id = options.id;
57
143
  this.activatesOn = options.activatesOn;
58
- this.activatesBefore = options.activatesBefore;
59
- this.activatesAfter = options.activatesAfter;
144
+ this.firesBeforeActivation = options.firesBeforeActivation;
145
+ this.firesAfterActivation = options.firesAfterActivation;
60
146
  this.activate = options.activate;
61
147
  }
62
148
  }
63
149
 
64
- /**
65
- * Helper to define a module.
66
- */
67
- export const defineModule = (options: PluginModuleInterface) => new PluginModule(options);
68
-
69
- export type PluginMeta = {
150
+ export type Meta = {
70
151
  /**
71
152
  * Globally unique ID.
72
153
  *
73
154
  * Expected to be in the form of a valid URL.
74
155
  *
75
- * @example dxos.org/plugin/example
156
+ * @example org.dxos.plugin.example
76
157
  */
77
158
  id: string;
78
159
 
@@ -86,6 +167,11 @@ export type PluginMeta = {
86
167
  */
87
168
  description?: string;
88
169
 
170
+ /**
171
+ * Name of the author or organization that created the plugin.
172
+ */
173
+ author?: string;
174
+
89
175
  /**
90
176
  * URL of home page.
91
177
  */
@@ -115,29 +201,293 @@ export type PluginMeta = {
115
201
  * Icon hue (ChromaticPalette).
116
202
  */
117
203
  iconHue?: string;
204
+
205
+ /**
206
+ * IDs of plugins this plugin functionally depends on.
207
+ *
208
+ * Treated as a convenience by the default `PluginManager` flow:
209
+ * - Enabling this plugin auto-enables the transitive closure of `dependsOn`
210
+ * (installing missing entries from the plugin registry when possible).
211
+ * - Disabling a depended-upon plugin surfaces dependents to the caller; the
212
+ * `PluginManager.disable` API supports an opt-in cascade.
213
+ *
214
+ * Not an invariant: low-level `PluginManager` APIs accept opt-outs
215
+ * (`resolveDependencies: false`, `ignoreDependents: true`) so a caller may
216
+ * substitute an alternative implementation that satisfies the dependent's
217
+ * capability needs in its own way.
218
+ */
219
+ dependsOn?: string[];
220
+ };
221
+
222
+ /**
223
+ * Identifier denoting a Plugin.
224
+ */
225
+ export const PluginTypeId: unique symbol = Symbol.for('@dxos/app-framework/Plugin');
226
+ export type PluginTypeId = typeof PluginTypeId;
227
+
228
+ /**
229
+ * Type guard to check if a value is a Plugin.
230
+ */
231
+ export const isPlugin = (value: unknown): value is Plugin => {
232
+ return typeof value === 'object' && value !== null && PluginTypeId in value;
118
233
  };
119
234
 
120
235
  /**
121
236
  * A collection of modules that are be enabled/disabled as a unit.
122
237
  * Plugins provide things such as components, state, actions, etc. to the application.
123
238
  */
124
- // NOTE: This is implemented as a class to prevent it from being proxied by PluginManager state.
125
- export class Plugin {
239
+ // TODO(burdon): Convert to ECHO schema.
240
+ export interface Plugin {
241
+ readonly [PluginTypeId]: PluginTypeId;
242
+ readonly meta: Readonly<Meta>;
243
+ readonly modules: ReadonlyArray<PluginModule>;
244
+ }
245
+
246
+ /**
247
+ * Internal implementation of Plugin.
248
+ * @internal
249
+ */
250
+ class PluginImpl implements Plugin {
251
+ readonly [PluginTypeId]: PluginTypeId = PluginTypeId;
252
+
126
253
  constructor(
127
- readonly meta: PluginMeta,
128
- readonly modules: PluginModule[],
254
+ private readonly _meta: Meta,
255
+ private readonly _modules: PluginModule[],
129
256
  ) {}
257
+
258
+ get meta(): Readonly<Meta> {
259
+ return this._meta;
260
+ }
261
+
262
+ get modules(): ReadonlyArray<PluginModule> {
263
+ return this._modules;
264
+ }
265
+ }
266
+
267
+ /**
268
+ * Builder interface for creating plugins incrementally.
269
+ */
270
+ export interface PluginBuilder<T = void> extends Pipeable.Pipeable {
271
+ readonly meta: Meta;
272
+ readonly modules: ReadonlyArray<PluginModuleOptions | ((options: T) => PluginModuleOptions)>;
273
+ addModule(moduleOptions: PluginModuleOptions | ((options: T) => PluginModuleOptions)): PluginBuilder<T>;
274
+ }
275
+
276
+ /**
277
+ * Builder implementation for creating plugins incrementally.
278
+ */
279
+ class PluginBuilderImpl<T = void> implements PluginBuilder<T> {
280
+ readonly meta: Meta;
281
+ private readonly _modules: Array<PluginModuleOptions | ((options: T) => PluginModuleOptions)> = [];
282
+
283
+ constructor(meta: Meta) {
284
+ this.meta = meta;
285
+ }
286
+
287
+ get modules(): ReadonlyArray<PluginModuleOptions | ((options: T) => PluginModuleOptions)> {
288
+ return this._modules;
289
+ }
290
+
291
+ addModule(moduleOptions: PluginModuleOptions | ((options: T) => PluginModuleOptions)): PluginBuilder<T> {
292
+ this._modules.push(moduleOptions);
293
+ return this;
294
+ }
295
+
296
+ pipe() {
297
+ // eslint-disable-next-line prefer-rest-params
298
+ return Pipeable.pipeArguments(this, arguments);
299
+ }
300
+ }
301
+
302
+ /**
303
+ * Creates a new PluginBuilder to start building a plugin.
304
+ */
305
+ export const define = <T = void>(meta: Meta): PluginBuilder<T> => new PluginBuilderImpl<T>(meta);
306
+
307
+ /**
308
+ * Adds a module to a plugin builder.
309
+ * Supports both pipeline and direct call styles.
310
+ * Modules can be either PluginModuleOptions or functions that receive options.
311
+ */
312
+ export function addModule<T>(
313
+ moduleOptions: PluginModuleOptions | ((options: T) => PluginModuleOptions),
314
+ ): (builder: PluginBuilder<T>) => PluginBuilder<T>;
315
+ export function addModule<T>(
316
+ builder: PluginBuilder<T>,
317
+ moduleOptions: PluginModuleOptions | ((options: T) => PluginModuleOptions),
318
+ ): PluginBuilder<T>;
319
+ export function addModule<T>(
320
+ moduleOptionsOrBuilder: PluginModuleOptions | ((options: T) => PluginModuleOptions) | PluginBuilder<T>,
321
+ moduleOptions?: PluginModuleOptions | ((options: T) => PluginModuleOptions),
322
+ ): ((builder: PluginBuilder<T>) => PluginBuilder<T>) | PluginBuilder<T> {
323
+ // If second arg is provided, it's the direct call style: addModule(builder, moduleOptions)
324
+ if (moduleOptions !== undefined) {
325
+ return (moduleOptionsOrBuilder as PluginBuilder<T>).addModule(moduleOptions);
326
+ }
327
+ // Otherwise it's pipeline style: addModule(moduleOptions) returns a function
328
+ const moduleOpts = moduleOptionsOrBuilder as PluginModuleOptions | ((options: T) => PluginModuleOptions);
329
+ return (builder: PluginBuilder<T>) => builder.addModule(moduleOpts);
130
330
  }
131
331
 
132
- export type PluginFactory<T = void> = ((args: T) => Plugin) & { meta: PluginMeta };
332
+ export type PluginFactory<T = void> = ((options: T) => Plugin) & { meta: Meta };
333
+
334
+ /**
335
+ * Resolves a module from either PluginModuleOptions or a function that returns PluginModuleOptions.
336
+ */
337
+ const resolveModule = (
338
+ meta: Meta,
339
+ module: PluginModuleOptions | ((options: any) => PluginModuleOptions),
340
+ options?: any,
341
+ ): PluginModuleImpl => {
342
+ const moduleOptions = typeof module === 'function' ? module(options) : module;
343
+ const id = Option.fromNullable(moduleOptions.id).pipe(
344
+ Option.match({
345
+ onNone: () => {
346
+ const exportName = Capability.getModuleTag(moduleOptions.activate);
347
+ invariant(exportName, `Plugin module missing name. Plugin: ${meta.id}`);
348
+ return computeModuleId(meta.id, exportName);
349
+ },
350
+ onSome: (id) => computeModuleId(meta.id, id),
351
+ }),
352
+ );
353
+ return new PluginModuleImpl({ ...moduleOptions, id });
354
+ };
133
355
 
134
356
  /**
135
- * Helper to define a plugin.
357
+ * Creates a Plugin from a builder.
358
+ * Supports both pipeline and direct call styles.
359
+ * Always returns a factory function (options: T) => Plugin.
360
+ * When T is void, the function takes no arguments: () => Plugin.
136
361
  */
137
- export const definePlugin = <T = void>(meta: PluginMeta, provider: (args: T) => PluginModule[]): PluginFactory<T> => {
138
- const factory = (args: T) => {
139
- return new Plugin(meta, provider(args));
362
+ export function make<T>(builder: PluginBuilder<T>): PluginFactory<T>;
363
+ export function make<T>(builder: PluginBuilder<T>): PluginFactory<T> {
364
+ const meta = builder.meta;
365
+ invariant(!meta.dependsOn?.includes(meta.id), `Plugin ${meta.id} declares itself as a dependency.`);
366
+
367
+ const factory = (options: T) => {
368
+ const modules = builder.modules.map((module) => resolveModule(meta, module, options));
369
+ return new PluginImpl(meta, modules);
140
370
  };
141
371
 
372
+ return Object.assign(factory, { meta });
373
+ }
374
+
375
+ //
376
+ // Lazy plugin loading
377
+ //
378
+
379
+ /**
380
+ * Symbol used to tag lazy plugin stubs with their loader closure.
381
+ * Hidden from enumeration so plugin manager iteration / serialization paths
382
+ * don't trip over it.
383
+ */
384
+ const LazyTag: unique symbol = Symbol.for('@dxos/app-framework/Plugin/Lazy');
385
+
386
+ /**
387
+ * Async loader for a lazy plugin's real implementation.
388
+ * The default export of the loaded module must be a `PluginFactory<T>` —
389
+ * i.e. the same shape `Plugin.make` produces.
390
+ */
391
+ export type LazyLoader<T = void> = () => Promise<{ default: PluginFactory<T> }>;
392
+
393
+ /** Internal: payload carried on a lazy stub. */
394
+ type LazyPayload = { loader: LazyLoader<any>; options: unknown };
395
+
396
+ /**
397
+ * Defines a lazy plugin whose body is loaded on first enable.
398
+ *
399
+ * The returned factory produces a stub `Plugin` that exposes `meta`
400
+ * synchronously (so callers can read `Plugin.meta.id` for free) but defers
401
+ * loading the real plugin's modules until the manager calls
402
+ * `Plugin.resolveLazy`. This lets the plugin's main entry point ship as a
403
+ * tiny meta-only chunk — the heavy capabilities, schema, React surfaces,
404
+ * etc. live behind the dynamic `import()` and become a separate Rollup
405
+ * chunk that is only fetched when the plugin is enabled.
406
+ *
407
+ * @example
408
+ * ```ts
409
+ * // plugin-markdown/src/index.ts
410
+ * import { Plugin } from '@dxos/app-framework';
411
+ * import { meta } from './meta';
412
+ *
413
+ * export const MarkdownPlugin = Plugin.lazy(meta, () => import('./MarkdownPlugin'));
414
+ *
415
+ * // plugin-markdown/src/MarkdownPlugin.tsx
416
+ * export const MarkdownPlugin = Plugin.define(meta).pipe(...heavy modules..., Plugin.make);
417
+ * export default MarkdownPlugin;
418
+ * ```
419
+ */
420
+ export const lazy = <T = void>(meta: Meta, loader: LazyLoader<T>): PluginFactory<T> => {
421
+ const factory = (options: T): Plugin => {
422
+ const stub = new PluginImpl(meta, []);
423
+ Object.defineProperty(stub, LazyTag, {
424
+ value: { loader, options } satisfies LazyPayload,
425
+ enumerable: false,
426
+ });
427
+ return stub;
428
+ };
142
429
  return Object.assign(factory, { meta });
143
430
  };
431
+
432
+ /**
433
+ * Type guard for lazy plugin stubs produced by {@link lazy}.
434
+ */
435
+ export const isLazy = (plugin: Plugin): boolean => LazyTag in plugin;
436
+
437
+ /**
438
+ * Tagged error for failures during lazy plugin resolution. `context.id` is
439
+ * the lazy plugin's `meta.id`; `context.reason` discriminates the failure
440
+ * mode (`'load-failed' | 'missing-default' | 'invalid-plugin' |
441
+ * 'meta-mismatch'`) so callers can route on it.
442
+ */
443
+ export class LazyPluginError extends BaseError.extend('LazyPluginError', 'Failed to resolve lazy plugin') {}
444
+
445
+ /**
446
+ * Tagged error for plugin-level dependency resolution failures.
447
+ *
448
+ * `context.id` is the plugin id the manager was acting on. `context.reason`
449
+ * discriminates the failure mode:
450
+ * - `'missing'` — declared dep is neither registered nor in the catalog.
451
+ * `context.missing` lists offending ids.
452
+ * - `'install-failed'` — dep was found in the catalog but `add()` failed.
453
+ * `cause` carries the original error.
454
+ * - `'cycle'` — closure walk detected a cycle. `context.path` is the cycle path.
455
+ * - `'core-dependent'` — cascade-disable would have to disable a core plugin.
456
+ * `context.coreDependent` is the blocking id.
457
+ */
458
+ export class PluginDependencyError extends BaseError.extend(
459
+ 'PluginDependencyError',
460
+ 'Plugin dependency resolution failed',
461
+ ) {}
462
+
463
+ /**
464
+ * Resolves a lazy plugin stub to its real plugin.
465
+ * Returns the plugin unchanged if it is not lazy. Failures surface as
466
+ * {@link LazyPluginError} with `context.reason` indicating the failure mode
467
+ * and (for loader failures) `cause` set to the original error.
468
+ */
469
+ export const resolveLazy = (plugin: Plugin): Effect.Effect<Plugin, LazyPluginError> =>
470
+ Effect.gen(function* () {
471
+ if (!isLazy(plugin)) {
472
+ return plugin;
473
+ }
474
+ const id = plugin.meta.id;
475
+ const { loader, options } = (plugin as unknown as { [LazyTag]: LazyPayload })[LazyTag];
476
+ const mod = yield* Effect.tryPromise({
477
+ try: loader,
478
+ catch: (error) => new LazyPluginError({ context: { id, reason: 'load-failed' }, cause: error }),
479
+ });
480
+ if (!mod || typeof mod.default !== 'function') {
481
+ return yield* Effect.fail(new LazyPluginError({ context: { id, reason: 'missing-default' } }));
482
+ }
483
+ const result = mod.default(options);
484
+ if (!isPlugin(result)) {
485
+ return yield* Effect.fail(new LazyPluginError({ context: { id, reason: 'invalid-plugin' } }));
486
+ }
487
+ if (result.meta.id !== id) {
488
+ return yield* Effect.fail(
489
+ new LazyPluginError({ context: { id, reason: 'meta-mismatch', returnedId: result.meta.id } }),
490
+ );
491
+ }
492
+ return result;
493
+ });
@@ -0,0 +1,163 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import { Atom, type Registry as AtomRegistry } from '@effect-atom/atom-react';
6
+ import * as Effect from 'effect/Effect';
7
+
8
+ import { runAndForwardErrors } from '@dxos/effect';
9
+ import { log } from '@dxos/log';
10
+
11
+ /**
12
+ * A registry plugin entry as seen by the plugin manager layer.
13
+ * Populated from the registry catalog; represents the latest available version of a plugin.
14
+ *
15
+ * Independently defined from @dxos/protocols PluginEntry — similar shape but not the same type.
16
+ * Implementations of {@link PluginProvider} (e.g. {@link EdgeRegistryPluginProvider})
17
+ * are responsible for mapping their wire-format entries to this shape.
18
+ */
19
+ export type Plugin = {
20
+ id: string;
21
+ name: string;
22
+ description?: string;
23
+ homePage?: string;
24
+ source?: string;
25
+ screenshots?: string[];
26
+ tags?: string[];
27
+ icon?: string;
28
+ iconHue?: string;
29
+ /**
30
+ * IDs of plugins this entry declares as runtime dependencies. Mirrors
31
+ * {@link Plugin.Meta.dependsOn}. Surfaced in the catalog so the manager can
32
+ * resolve and auto-install transitive deps before they are first loaded.
33
+ */
34
+ dependsOn?: string[];
35
+ /** URL to dynamic-import the latest version of this plugin module. */
36
+ moduleUrl: string;
37
+ /** GitHub repository slug, e.g. `owner/name`. Used to fetch version history. */
38
+ repo: string;
39
+ /**
40
+ * Latest known version string, e.g. `v1.2.0`.
41
+ * Corresponds to releaseTag in the wire-format PluginEntry; named `version` here
42
+ * because the plugin manager layer speaks versions, not release tags.
43
+ */
44
+ version: string;
45
+ };
46
+
47
+ /**
48
+ * A single installable version of a registry plugin.
49
+ */
50
+ export type PluginVersion = {
51
+ /** Version string, e.g. `v1.2.0`. */
52
+ tag: string;
53
+ /** URL to dynamic-import this specific version of the plugin module. */
54
+ moduleUrl: string;
55
+ /** Unix ms of when this version was published (optional; omitted when unknown). */
56
+ releasedAt?: number;
57
+ };
58
+
59
+ /**
60
+ * Abstraction over the plugin registry catalog backend.
61
+ * Implementations may call Edge, a local cache, or a stub.
62
+ *
63
+ * The interface itself is transport-agnostic; concrete implementations live
64
+ * alongside it in this package (see {@link EdgeRegistryPluginProvider}) so we
65
+ * avoid `app-framework ↔ edge-client` cycles, but they only need to satisfy
66
+ * this shape — callers can substitute their own.
67
+ */
68
+ export interface PluginProvider {
69
+ /**
70
+ * Returns all healthy registry plugins (latest version of each).
71
+ */
72
+ listPlugins(): Effect.Effect<readonly Plugin[], Error>;
73
+
74
+ /**
75
+ * Returns all known versions of a plugin identified by its GitHub repo slug.
76
+ * Until the backend implements a versions endpoint, implementations MUST
77
+ * return at least one entry representing the current/latest release.
78
+ */
79
+ listVersions(repo: string): Effect.Effect<readonly PluginVersion[], Error>;
80
+
81
+ /**
82
+ * Returns a single plugin entry for the given repo.
83
+ * If `version` is omitted, returns the latest.
84
+ * Fails if the specified version is not found.
85
+ */
86
+ getPlugin(repo: string, version?: string): Effect.Effect<Plugin, Error>;
87
+ }
88
+
89
+ /**
90
+ * Atomic snapshot of the registry catalog as observed by the host.
91
+ * Exposed via {@link Manager.plugins} so consumers can subscribe reactively
92
+ * (loading state, list contents, last error).
93
+ */
94
+ export type PluginsState = {
95
+ entries: readonly Plugin[];
96
+ loading: boolean;
97
+ error: Error | null;
98
+ };
99
+
100
+ /**
101
+ * Default no-op provider used when no `PluginProvider` is supplied at construction
102
+ * time (e.g. tests, stories, environments without an Edge connection).
103
+ *
104
+ * `listPlugins` returns an empty list (so `Manager.plugins` settles to a stable
105
+ * empty state). `listVersions` and `getPlugin` fail with an explicit error so
106
+ * callers know they need to configure a real provider.
107
+ */
108
+ const NULL_PROVIDER: PluginProvider = {
109
+ listPlugins: () => Effect.succeed([] as readonly Plugin[]),
110
+ listVersions: () => Effect.fail(new Error('No plugin registry provider configured')),
111
+ getPlugin: () => Effect.fail(new Error('No plugin registry provider configured')),
112
+ };
113
+
114
+ /**
115
+ * Owns the cached registry catalog state and forwards `listVersions` / `getPlugin`
116
+ * calls to the underlying {@link PluginProvider}. Lives on the `PluginManager`
117
+ * (as `manager.pluginRegistry`) so consumers can reach it through the manager
118
+ * without a separate capability lookup.
119
+ *
120
+ * On construction the manager kicks off a background fetch via `provider.listPlugins()`
121
+ * and writes the result into the {@link plugins} atom. Subscribers see `loading: true`
122
+ * during the fetch and `loading: false` once it settles.
123
+ */
124
+ export class Manager {
125
+ readonly plugins: Atom.Writable<PluginsState>;
126
+ readonly #provider: PluginProvider;
127
+
128
+ constructor(provider: PluginProvider | undefined, atomRegistry: AtomRegistry.Registry) {
129
+ this.#provider = provider ?? NULL_PROVIDER;
130
+ const initialLoading = provider !== undefined;
131
+ this.plugins = Atom.make<PluginsState>({ entries: [], loading: initialLoading, error: null }).pipe(Atom.keepAlive);
132
+
133
+ if (provider !== undefined) {
134
+ // Fire-and-forget initial load. Errors are surfaced via the atom's `error` field.
135
+ void runAndForwardErrors(
136
+ provider.listPlugins().pipe(
137
+ Effect.match({
138
+ onSuccess: (entries) => atomRegistry.set(this.plugins, { entries, loading: false, error: null }),
139
+ onFailure: (error) => {
140
+ log.catch(error);
141
+ atomRegistry.set(this.plugins, { entries: [], loading: false, error });
142
+ },
143
+ }),
144
+ ),
145
+ );
146
+ }
147
+ }
148
+
149
+ /** Forwards to the underlying provider. */
150
+ listPlugins(): Effect.Effect<readonly Plugin[], Error> {
151
+ return this.#provider.listPlugins();
152
+ }
153
+
154
+ /** Forwards to the underlying provider. */
155
+ listVersions(repo: string): Effect.Effect<readonly PluginVersion[], Error> {
156
+ return this.#provider.listVersions(repo);
157
+ }
158
+
159
+ /** Forwards to the underlying provider. */
160
+ getPlugin(repo: string, version?: string): Effect.Effect<Plugin, Error> {
161
+ return this.#provider.getPlugin(repo, version);
162
+ }
163
+ }