@dxos/app-framework 0.8.4-main.fffef41 → 0.8.4-staging.60fe92afc8

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 (569) 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-BOPAKKWG.mjs +35 -0
  6. package/dist/lib/browser/capability-BOPAKKWG.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-66IXTIVK.mjs +48 -0
  10. package/dist/lib/browser/chunk-66IXTIVK.mjs.map +7 -0
  11. package/dist/lib/browser/chunk-CO3XLNUX.mjs +95 -0
  12. package/dist/lib/browser/chunk-CO3XLNUX.mjs.map +7 -0
  13. package/dist/lib/browser/chunk-DC3WRPBV.mjs +227 -0
  14. package/dist/lib/browser/chunk-DC3WRPBV.mjs.map +7 -0
  15. package/dist/lib/browser/chunk-FJ4765WW.mjs +8 -0
  16. package/dist/lib/browser/chunk-FJ4765WW.mjs.map +7 -0
  17. package/dist/lib/browser/chunk-FO3IYSLV.mjs +68 -0
  18. package/dist/lib/browser/chunk-FO3IYSLV.mjs.map +7 -0
  19. package/dist/lib/browser/chunk-HFLKXMT7.mjs +587 -0
  20. package/dist/lib/browser/chunk-HFLKXMT7.mjs.map +7 -0
  21. package/dist/lib/browser/chunk-IW44C7UL.mjs +83 -0
  22. package/dist/lib/browser/chunk-IW44C7UL.mjs.map +7 -0
  23. package/dist/lib/browser/chunk-J5LGTIGS.mjs +10 -0
  24. package/dist/lib/browser/chunk-KZUDO43J.mjs +422 -0
  25. package/dist/lib/browser/chunk-KZUDO43J.mjs.map +7 -0
  26. package/dist/lib/browser/chunk-Q2GLJTVV.mjs +12 -0
  27. package/dist/lib/browser/chunk-Q2GLJTVV.mjs.map +7 -0
  28. package/dist/lib/browser/chunk-SYXIYT6T.mjs +143 -0
  29. package/dist/lib/browser/chunk-SYXIYT6T.mjs.map +7 -0
  30. package/dist/lib/browser/chunk-XHS5KDNX.mjs +1471 -0
  31. package/dist/lib/browser/chunk-XHS5KDNX.mjs.map +7 -0
  32. package/dist/lib/browser/chunk-Y66ELD4U.mjs +476 -0
  33. package/dist/lib/browser/chunk-Y66ELD4U.mjs.map +7 -0
  34. package/dist/lib/browser/cli/index.mjs +74 -0
  35. package/dist/lib/browser/cli/index.mjs.map +7 -0
  36. package/dist/lib/browser/common/activation-events.mjs +20 -0
  37. package/dist/lib/browser/common/capabilities.mjs +56 -0
  38. package/dist/lib/browser/core/activation-event.mjs +20 -0
  39. package/dist/lib/browser/core/capability.mjs +32 -0
  40. package/dist/lib/browser/core/capability.mjs.map +7 -0
  41. package/dist/lib/browser/core/plugin-manager.mjs +19 -0
  42. package/dist/lib/browser/core/plugin-manager.mjs.map +7 -0
  43. package/dist/lib/browser/core/plugin.mjs +41 -0
  44. package/dist/lib/browser/core/plugin.mjs.map +7 -0
  45. package/dist/lib/browser/core/url-loader.mjs +24 -0
  46. package/dist/lib/browser/core/url-loader.mjs.map +7 -0
  47. package/dist/lib/browser/index.mjs +86 -122
  48. package/dist/lib/browser/index.mjs.map +4 -4
  49. package/dist/lib/browser/meta.json +1 -1
  50. package/dist/lib/browser/process-manager-capability-GXNUO7AR.mjs +132 -0
  51. package/dist/lib/browser/process-manager-capability-GXNUO7AR.mjs.map +7 -0
  52. package/dist/lib/browser/testing/index.mjs +316 -47
  53. package/dist/lib/browser/testing/index.mjs.map +4 -4
  54. package/dist/lib/browser/testing/react.mjs +78 -0
  55. package/dist/lib/browser/testing/react.mjs.map +7 -0
  56. package/dist/lib/browser/ui/index.mjs +52 -0
  57. package/dist/lib/browser/ui/index.mjs.map +7 -0
  58. package/dist/lib/node-esm/capability-KZWRTX7R.mjs +36 -0
  59. package/dist/lib/node-esm/capability-KZWRTX7R.mjs.map +7 -0
  60. package/dist/lib/node-esm/chunk-37Z53PXZ.mjs +10 -0
  61. package/dist/lib/node-esm/chunk-37Z53PXZ.mjs.map +7 -0
  62. package/dist/lib/node-esm/chunk-A5CHGAZE.mjs +588 -0
  63. package/dist/lib/node-esm/chunk-A5CHGAZE.mjs.map +7 -0
  64. package/dist/lib/node-esm/chunk-COHOWGGJ.mjs +144 -0
  65. package/dist/lib/node-esm/chunk-COHOWGGJ.mjs.map +7 -0
  66. package/dist/lib/node-esm/chunk-CTKEZHKF.mjs +84 -0
  67. package/dist/lib/node-esm/chunk-CTKEZHKF.mjs.map +7 -0
  68. package/dist/lib/node-esm/chunk-FPW45EZH.mjs +14 -0
  69. package/dist/lib/node-esm/chunk-FPW45EZH.mjs.map +7 -0
  70. package/dist/lib/node-esm/chunk-FSVGKTF6.mjs +477 -0
  71. package/dist/lib/node-esm/chunk-FSVGKTF6.mjs.map +7 -0
  72. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +11 -0
  73. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs.map +7 -0
  74. package/dist/lib/node-esm/chunk-KFZEB6BV.mjs +29 -0
  75. package/dist/lib/node-esm/chunk-KFZEB6BV.mjs.map +7 -0
  76. package/dist/lib/node-esm/chunk-NULBHQYS.mjs +96 -0
  77. package/dist/lib/node-esm/chunk-NULBHQYS.mjs.map +7 -0
  78. package/dist/lib/node-esm/chunk-SX5NVETP.mjs +1472 -0
  79. package/dist/lib/node-esm/chunk-SX5NVETP.mjs.map +7 -0
  80. package/dist/lib/node-esm/chunk-WK7OIQKI.mjs +70 -0
  81. package/dist/lib/node-esm/chunk-WK7OIQKI.mjs.map +7 -0
  82. package/dist/lib/node-esm/chunk-XGBUKRCK.mjs +423 -0
  83. package/dist/lib/node-esm/chunk-XGBUKRCK.mjs.map +7 -0
  84. package/dist/lib/node-esm/chunk-XIGPWXCQ.mjs +228 -0
  85. package/dist/lib/node-esm/chunk-XIGPWXCQ.mjs.map +7 -0
  86. package/dist/lib/node-esm/chunk-XOCUANHO.mjs +49 -0
  87. package/dist/lib/node-esm/chunk-XOCUANHO.mjs.map +7 -0
  88. package/dist/lib/node-esm/cli/index.mjs +75 -0
  89. package/dist/lib/node-esm/cli/index.mjs.map +7 -0
  90. package/dist/lib/node-esm/common/activation-events.mjs +21 -0
  91. package/dist/lib/node-esm/common/activation-events.mjs.map +7 -0
  92. package/dist/lib/node-esm/common/capabilities.mjs +57 -0
  93. package/dist/lib/node-esm/common/capabilities.mjs.map +7 -0
  94. package/dist/lib/node-esm/core/activation-event.mjs +21 -0
  95. package/dist/lib/node-esm/core/activation-event.mjs.map +7 -0
  96. package/dist/lib/node-esm/core/capability.mjs +33 -0
  97. package/dist/lib/node-esm/core/capability.mjs.map +7 -0
  98. package/dist/lib/node-esm/core/plugin-manager.mjs +20 -0
  99. package/dist/lib/node-esm/core/plugin-manager.mjs.map +7 -0
  100. package/dist/lib/node-esm/core/plugin.mjs +42 -0
  101. package/dist/lib/node-esm/core/plugin.mjs.map +7 -0
  102. package/dist/lib/node-esm/core/url-loader.mjs +25 -0
  103. package/dist/lib/node-esm/core/url-loader.mjs.map +7 -0
  104. package/dist/lib/node-esm/index.mjs +86 -122
  105. package/dist/lib/node-esm/index.mjs.map +4 -4
  106. package/dist/lib/node-esm/meta.json +1 -1
  107. package/dist/lib/node-esm/process-manager-capability-TX5TA6YN.mjs +133 -0
  108. package/dist/lib/node-esm/process-manager-capability-TX5TA6YN.mjs.map +7 -0
  109. package/dist/lib/node-esm/testing/index.mjs +316 -47
  110. package/dist/lib/node-esm/testing/index.mjs.map +4 -4
  111. package/dist/lib/node-esm/testing/react.mjs +79 -0
  112. package/dist/lib/node-esm/testing/react.mjs.map +7 -0
  113. package/dist/lib/node-esm/ui/index.mjs +53 -0
  114. package/dist/lib/node-esm/ui/index.mjs.map +7 -0
  115. package/dist/plugin/node-esm/index.mjs +977 -0
  116. package/dist/plugin/node-esm/index.mjs.map +7 -0
  117. package/dist/plugin/node-esm/meta.json +1 -0
  118. package/dist/types/src/cli/cli.d.ts +37 -0
  119. package/dist/types/src/cli/cli.d.ts.map +1 -0
  120. package/dist/types/src/cli/index.d.ts +2 -0
  121. package/dist/types/src/cli/index.d.ts.map +1 -0
  122. package/dist/types/src/common/activation-events.d.ts +24 -0
  123. package/dist/types/src/common/activation-events.d.ts.map +1 -0
  124. package/dist/types/src/common/annotations.d.ts +1 -0
  125. package/dist/types/src/common/annotations.d.ts.map +1 -0
  126. package/dist/types/src/common/capabilities.d.ts +214 -193
  127. package/dist/types/src/common/capabilities.d.ts.map +1 -1
  128. package/dist/types/src/common/index.d.ts +3 -8
  129. package/dist/types/src/common/index.d.ts.map +1 -1
  130. package/dist/types/src/common/translations.d.ts +7 -7
  131. package/dist/types/src/common/translations.d.ts.map +1 -1
  132. package/dist/types/src/context.d.ts +5 -0
  133. package/dist/types/src/context.d.ts.map +1 -0
  134. package/dist/types/src/core/{events.d.ts → activation-event.d.ts} +11 -11
  135. package/dist/types/src/core/activation-event.d.ts.map +1 -0
  136. package/dist/types/src/core/capability-manager.d.ts +52 -0
  137. package/dist/types/src/core/capability-manager.d.ts.map +1 -0
  138. package/dist/types/src/core/capability-manager.test.d.ts +2 -0
  139. package/dist/types/src/core/capability-manager.test.d.ts.map +1 -0
  140. package/dist/types/src/core/capability.d.ts +161 -0
  141. package/dist/types/src/core/capability.d.ts.map +1 -0
  142. package/dist/types/src/core/edge-registry-plugin-provider.d.ts +30 -0
  143. package/dist/types/src/core/edge-registry-plugin-provider.d.ts.map +1 -0
  144. package/dist/types/src/core/index.d.ts +11 -4
  145. package/dist/types/src/core/index.d.ts.map +1 -1
  146. package/dist/types/src/core/plugin-asset-cache.d.ts +71 -0
  147. package/dist/types/src/core/plugin-asset-cache.d.ts.map +1 -0
  148. package/dist/types/src/core/plugin-manager.d.ts +297 -0
  149. package/dist/types/src/core/plugin-manager.d.ts.map +1 -0
  150. package/dist/types/src/core/plugin-manager.test.d.ts +2 -0
  151. package/dist/types/src/core/plugin-manager.test.d.ts.map +1 -0
  152. package/dist/types/src/core/plugin-manifest.d.ts +101 -0
  153. package/dist/types/src/core/plugin-manifest.d.ts.map +1 -0
  154. package/dist/types/src/core/plugin-manifest.test.d.ts +2 -0
  155. package/dist/types/src/core/plugin-manifest.test.d.ts.map +1 -0
  156. package/dist/types/src/core/plugin.d.ts +303 -43
  157. package/dist/types/src/core/plugin.d.ts.map +1 -1
  158. package/dist/types/src/core/registry.d.ts +107 -0
  159. package/dist/types/src/core/registry.d.ts.map +1 -0
  160. package/dist/types/src/core/url-loader.d.ts +127 -0
  161. package/dist/types/src/core/url-loader.d.ts.map +1 -0
  162. package/dist/types/src/core/url-loader.test.d.ts +2 -0
  163. package/dist/types/src/core/url-loader.test.d.ts.map +1 -0
  164. package/dist/types/src/helpers.d.ts.map +1 -1
  165. package/dist/types/src/index.d.ts +2 -2
  166. package/dist/types/src/index.d.ts.map +1 -1
  167. package/dist/types/src/plugin-process-manager/ProcessManagerPlugin.d.ts +3 -0
  168. package/dist/types/src/plugin-process-manager/ProcessManagerPlugin.d.ts.map +1 -0
  169. package/dist/types/src/plugin-process-manager/history/capability.d.ts +7 -0
  170. package/dist/types/src/plugin-process-manager/history/capability.d.ts.map +1 -0
  171. package/dist/types/src/plugin-process-manager/history/errors.d.ts +32 -0
  172. package/dist/types/src/plugin-process-manager/history/errors.d.ts.map +1 -0
  173. package/dist/types/src/plugin-process-manager/history/history-tracker.d.ts +32 -0
  174. package/dist/types/src/plugin-process-manager/history/history-tracker.d.ts.map +1 -0
  175. package/dist/types/src/plugin-process-manager/history/history-tracker.test.d.ts +2 -0
  176. package/dist/types/src/plugin-process-manager/history/history-tracker.test.d.ts.map +1 -0
  177. package/dist/types/src/plugin-process-manager/history/index.d.ts +6 -0
  178. package/dist/types/src/plugin-process-manager/history/index.d.ts.map +1 -0
  179. package/dist/types/src/plugin-process-manager/history/types.d.ts +13 -0
  180. package/dist/types/src/plugin-process-manager/history/types.d.ts.map +1 -0
  181. package/dist/types/src/plugin-process-manager/history/undo-mapping.d.ts +101 -0
  182. package/dist/types/src/plugin-process-manager/history/undo-mapping.d.ts.map +1 -0
  183. package/dist/types/src/plugin-process-manager/history/undo-registry.d.ts +23 -0
  184. package/dist/types/src/plugin-process-manager/history/undo-registry.d.ts.map +1 -0
  185. package/dist/types/src/plugin-process-manager/history/undo-registry.test.d.ts +2 -0
  186. package/dist/types/src/plugin-process-manager/history/undo-registry.test.d.ts.map +1 -0
  187. package/dist/types/src/plugin-process-manager/idb-key-value-store.d.ts +10 -0
  188. package/dist/types/src/plugin-process-manager/idb-key-value-store.d.ts.map +1 -0
  189. package/dist/types/src/plugin-process-manager/index.d.ts +3 -0
  190. package/dist/types/src/plugin-process-manager/index.d.ts.map +1 -0
  191. package/dist/types/src/plugin-process-manager/meta.d.ts +3 -0
  192. package/dist/types/src/plugin-process-manager/meta.d.ts.map +1 -0
  193. package/dist/types/src/plugin-process-manager/process-manager-capability.d.ts +8 -0
  194. package/dist/types/src/plugin-process-manager/process-manager-capability.d.ts.map +1 -0
  195. package/dist/types/src/plugin-process-manager/testing.d.ts +59 -0
  196. package/dist/types/src/plugin-process-manager/testing.d.ts.map +1 -0
  197. package/dist/types/src/testing/harness.d.ts +79 -0
  198. package/dist/types/src/testing/harness.d.ts.map +1 -0
  199. package/dist/types/src/testing/index.d.ts +3 -0
  200. package/dist/types/src/testing/index.d.ts.map +1 -1
  201. package/dist/types/src/testing/operationCapture.d.ts +64 -0
  202. package/dist/types/src/testing/operationCapture.d.ts.map +1 -0
  203. package/dist/types/src/testing/react.d.ts +27 -0
  204. package/dist/types/src/testing/react.d.ts.map +1 -0
  205. package/dist/types/src/testing/react.test.d.ts +2 -0
  206. package/dist/types/src/testing/react.test.d.ts.map +1 -0
  207. package/dist/types/src/testing/service.d.ts +8 -0
  208. package/dist/types/src/testing/service.d.ts.map +1 -0
  209. package/dist/types/src/testing/withPluginManager.d.ts +4 -4
  210. package/dist/types/src/testing/withPluginManager.d.ts.map +1 -1
  211. package/dist/types/src/testing/withPluginManager.stories.d.ts.map +1 -1
  212. package/dist/types/src/ui/components/App/App.d.ts +41 -0
  213. package/dist/types/src/ui/components/App/App.d.ts.map +1 -0
  214. package/dist/types/src/ui/components/App/App.stories.d.ts +19 -0
  215. package/dist/types/src/ui/components/App/App.stories.d.ts.map +1 -0
  216. package/dist/types/src/ui/components/App/index.d.ts +2 -0
  217. package/dist/types/src/ui/components/App/index.d.ts.map +1 -0
  218. package/dist/types/src/{react/Surface.stories.d.ts → ui/components/PluginManager/PluginManagerContext.stories.d.ts} +2 -3
  219. package/dist/types/src/ui/components/PluginManager/PluginManagerContext.stories.d.ts.map +1 -0
  220. package/dist/types/src/ui/components/PluginManager/PluginManagerProvider.d.ts +10 -0
  221. package/dist/types/src/ui/components/PluginManager/PluginManagerProvider.d.ts.map +1 -0
  222. package/dist/types/src/ui/components/PluginManager/index.d.ts +2 -0
  223. package/dist/types/src/ui/components/PluginManager/index.d.ts.map +1 -0
  224. package/dist/types/src/ui/components/Surface/SurfaceComponent.d.ts +24 -0
  225. package/dist/types/src/ui/components/Surface/SurfaceComponent.d.ts.map +1 -0
  226. package/dist/types/src/{react/App.stories.d.ts → ui/components/Surface/SurfaceComponent.stories.d.ts} +1 -1
  227. package/dist/types/src/ui/components/Surface/SurfaceComponent.stories.d.ts.map +1 -0
  228. package/dist/types/src/ui/components/Surface/SurfaceInfo.d.ts +11 -0
  229. package/dist/types/src/ui/components/Surface/SurfaceInfo.d.ts.map +1 -0
  230. package/dist/types/src/ui/components/Surface/SurfaceProfilerContext.d.ts +48 -0
  231. package/dist/types/src/ui/components/Surface/SurfaceProfilerContext.d.ts.map +1 -0
  232. package/dist/types/src/ui/components/Surface/context.d.ts +5 -0
  233. package/dist/types/src/ui/components/Surface/context.d.ts.map +1 -0
  234. package/dist/types/src/ui/components/Surface/index.d.ts +36 -0
  235. package/dist/types/src/ui/components/Surface/index.d.ts.map +1 -0
  236. package/dist/types/src/ui/components/Surface/types.d.ts +197 -0
  237. package/dist/types/src/ui/components/Surface/types.d.ts.map +1 -0
  238. package/dist/types/src/ui/components/Surface/types.test.d.ts +2 -0
  239. package/dist/types/src/ui/components/Surface/types.test.d.ts.map +1 -0
  240. package/dist/types/src/ui/components/index.d.ts +4 -0
  241. package/dist/types/src/ui/components/index.d.ts.map +1 -0
  242. package/dist/types/src/ui/hooks/index.d.ts +7 -0
  243. package/dist/types/src/ui/hooks/index.d.ts.map +1 -0
  244. package/dist/types/src/ui/hooks/useApp.d.ts +80 -0
  245. package/dist/types/src/ui/hooks/useApp.d.ts.map +1 -0
  246. package/dist/types/src/ui/hooks/useApp.test.d.ts +2 -0
  247. package/dist/types/src/ui/hooks/useApp.test.d.ts.map +1 -0
  248. package/dist/types/src/ui/hooks/useCapabilities.d.ts +31 -0
  249. package/dist/types/src/ui/hooks/useCapabilities.d.ts.map +1 -0
  250. package/dist/types/src/{react → ui/hooks}/useLoading.d.ts +1 -2
  251. package/dist/types/src/ui/hooks/useLoading.d.ts.map +1 -0
  252. package/dist/types/src/ui/hooks/useProcessManagerRuntime.d.ts +30 -0
  253. package/dist/types/src/ui/hooks/useProcessManagerRuntime.d.ts.map +1 -0
  254. package/dist/types/src/ui/hooks/useSettingsState.d.ts +10 -0
  255. package/dist/types/src/ui/hooks/useSettingsState.d.ts.map +1 -0
  256. package/dist/types/src/ui/hooks/useSurface.d.ts +3 -0
  257. package/dist/types/src/ui/hooks/useSurface.d.ts.map +1 -0
  258. package/dist/types/src/ui/index.d.ts +3 -0
  259. package/dist/types/src/ui/index.d.ts.map +1 -0
  260. package/dist/types/src/vite-plugin/boot-loader/index.d.ts +2 -0
  261. package/dist/types/src/vite-plugin/boot-loader/index.d.ts.map +1 -0
  262. package/dist/types/src/vite-plugin/boot-loader/loader.d.ts +59 -0
  263. package/dist/types/src/vite-plugin/boot-loader/loader.d.ts.map +1 -0
  264. package/dist/types/src/vite-plugin/composer/index.d.ts +34 -0
  265. package/dist/types/src/vite-plugin/composer/index.d.ts.map +1 -0
  266. package/dist/types/src/vite-plugin/import-map/index.d.ts +28 -0
  267. package/dist/types/src/vite-plugin/import-map/index.d.ts.map +1 -0
  268. package/dist/types/src/vite-plugin/index.d.ts +5 -0
  269. package/dist/types/src/vite-plugin/index.d.ts.map +1 -0
  270. package/dist/types/src/vite-plugin/manifest.d.ts +41 -0
  271. package/dist/types/src/vite-plugin/manifest.d.ts.map +1 -0
  272. package/dist/types/src/vite-plugin/manifest.test.d.ts +2 -0
  273. package/dist/types/src/vite-plugin/manifest.test.d.ts.map +1 -0
  274. package/dist/types/src/vite-plugin/packages.d.ts +13 -0
  275. package/dist/types/src/vite-plugin/packages.d.ts.map +1 -0
  276. package/dist/types/tsconfig.tsbuildinfo +1 -1
  277. package/moon.yml +25 -6
  278. package/package.json +125 -59
  279. package/src/cli/cli.ts +102 -0
  280. package/src/{playground/debug → cli}/index.ts +1 -1
  281. package/src/common/activation-events.ts +39 -0
  282. package/src/{playground/logger/index.ts → common/annotations.ts} +0 -2
  283. package/src/common/capabilities.ts +287 -192
  284. package/src/common/index.ts +3 -8
  285. package/src/common/translations.ts +17 -9
  286. package/src/context.ts +9 -0
  287. package/src/core/{events.ts → activation-event.ts} +10 -7
  288. package/src/core/capability-manager.test.ts +154 -0
  289. package/src/core/capability-manager.ts +213 -0
  290. package/src/core/capability.ts +254 -0
  291. package/src/core/edge-registry-plugin-provider.ts +92 -0
  292. package/src/core/index.ts +11 -4
  293. package/src/core/plugin-asset-cache.ts +60 -0
  294. package/src/core/plugin-manager.test.ts +1929 -0
  295. package/src/core/plugin-manager.ts +1696 -0
  296. package/src/core/plugin-manifest.test.ts +75 -0
  297. package/src/core/plugin-manifest.ts +134 -0
  298. package/src/core/plugin.ts +449 -48
  299. package/src/core/registry.ts +163 -0
  300. package/src/core/url-loader.test.ts +222 -0
  301. package/src/core/url-loader.ts +388 -0
  302. package/src/index.ts +2 -2
  303. package/src/plugin-process-manager/ProcessManagerPlugin.ts +24 -0
  304. package/src/plugin-process-manager/history/capability.ts +36 -0
  305. package/src/plugin-process-manager/history/errors.ts +7 -0
  306. package/src/plugin-process-manager/history/history-tracker.test.ts +353 -0
  307. package/src/plugin-process-manager/history/history-tracker.ts +144 -0
  308. package/src/plugin-process-manager/history/index.ts +9 -0
  309. package/src/plugin-process-manager/history/types.ts +17 -0
  310. package/src/plugin-process-manager/history/undo-mapping.ts +135 -0
  311. package/src/plugin-process-manager/history/undo-registry.test.ts +74 -0
  312. package/src/plugin-process-manager/history/undo-registry.ts +54 -0
  313. package/src/plugin-process-manager/idb-key-value-store.ts +64 -0
  314. package/src/plugin-process-manager/index.ts +6 -0
  315. package/src/plugin-process-manager/meta.ts +16 -0
  316. package/src/plugin-process-manager/process-manager-capability.ts +178 -0
  317. package/src/plugin-process-manager/testing.ts +156 -0
  318. package/src/testing/harness.ts +247 -0
  319. package/src/testing/index.ts +3 -0
  320. package/src/testing/operationCapture.ts +144 -0
  321. package/src/testing/react.test.tsx +50 -0
  322. package/src/testing/react.tsx +113 -0
  323. package/src/testing/service.ts +52 -0
  324. package/src/testing/withPluginManager.stories.tsx +8 -9
  325. package/src/testing/withPluginManager.tsx +69 -42
  326. package/src/ui/components/App/App.stories.tsx +84 -0
  327. package/src/ui/components/App/App.tsx +144 -0
  328. package/src/{playground/layout → ui/components/App}/index.ts +1 -1
  329. package/src/ui/components/PluginManager/PluginManagerContext.stories.tsx +179 -0
  330. package/src/{react → ui/components/PluginManager}/PluginManagerProvider.ts +3 -3
  331. package/src/ui/components/PluginManager/index.ts +5 -0
  332. package/src/ui/components/Surface/SurfaceComponent.stories.tsx +144 -0
  333. package/src/ui/components/Surface/SurfaceComponent.tsx +303 -0
  334. package/src/ui/components/Surface/SurfaceInfo.tsx +106 -0
  335. package/src/ui/components/Surface/SurfaceProfilerContext.tsx +207 -0
  336. package/src/ui/components/Surface/context.ts +12 -0
  337. package/src/ui/components/Surface/index.ts +54 -0
  338. package/src/ui/components/Surface/types.test.ts +126 -0
  339. package/src/ui/components/Surface/types.ts +290 -0
  340. package/src/ui/components/index.ts +7 -0
  341. package/src/ui/hooks/index.ts +10 -0
  342. package/src/ui/hooks/useApp.test.tsx +161 -0
  343. package/src/ui/hooks/useApp.tsx +404 -0
  344. package/src/ui/hooks/useCapabilities.ts +68 -0
  345. package/src/{react → ui/hooks}/useLoading.tsx +16 -10
  346. package/src/ui/hooks/useProcessManagerRuntime.ts +78 -0
  347. package/src/ui/hooks/useSettingsState.ts +26 -0
  348. package/src/ui/hooks/useSurface.ts +13 -0
  349. package/src/ui/index.ts +6 -0
  350. package/src/vite-plugin/boot-loader/BootLoader.solid-stories.tsx +198 -0
  351. package/src/vite-plugin/boot-loader/index.ts +5 -0
  352. package/src/vite-plugin/boot-loader/loader-app/Loader.tsx +166 -0
  353. package/src/vite-plugin/boot-loader/loader-app/boot-loader.css +311 -0
  354. package/src/vite-plugin/boot-loader/loader-app/bridge.ts +25 -0
  355. package/src/vite-plugin/boot-loader/loader-app/entry.tsx +21 -0
  356. package/src/vite-plugin/boot-loader/loader-app/mount.tsx +70 -0
  357. package/src/vite-plugin/boot-loader/loader-app/store.test.ts +137 -0
  358. package/src/vite-plugin/boot-loader/loader-app/store.ts +149 -0
  359. package/src/vite-plugin/boot-loader/loader-app/tsconfig.json +11 -0
  360. package/src/vite-plugin/boot-loader/loader-app/types.ts +78 -0
  361. package/src/vite-plugin/boot-loader/loader.ts +204 -0
  362. package/src/vite-plugin/composer/index.ts +306 -0
  363. package/src/vite-plugin/import-map/index.ts +527 -0
  364. package/src/vite-plugin/index.ts +10 -0
  365. package/src/vite-plugin/manifest.test.ts +55 -0
  366. package/src/vite-plugin/manifest.ts +63 -0
  367. package/src/vite-plugin/packages.ts +187 -0
  368. package/tsconfig.json +27 -22
  369. package/tsconfig.node.json +2 -4
  370. package/typedoc.json +2 -4
  371. package/vitest.config.ts +1 -1
  372. package/.swc/plugins/linux_x86_64_19.0.0/727453fb3a62f7f1d952a41e051ca8a6f88cadc45cee43c6a4d1aa45f9b75665.wasmer-v7 +0 -0
  373. package/.swc/plugins/linux_x86_64_19.0.0/fce1bdb8e20a094e4af08bad09cc81497ed0e2e7c51223b07d371063cca18429.wasmer-v7 +0 -0
  374. package/dist/lib/browser/app-graph-builder-OIEZZC45.mjs +0 -138
  375. package/dist/lib/browser/app-graph-builder-OIEZZC45.mjs.map +0 -7
  376. package/dist/lib/browser/chunk-6XKO24JP.mjs +0 -483
  377. package/dist/lib/browser/chunk-6XKO24JP.mjs.map +0 -7
  378. package/dist/lib/browser/chunk-SCPE4ZO2.mjs +0 -35
  379. package/dist/lib/browser/chunk-SCPE4ZO2.mjs.map +0 -7
  380. package/dist/lib/browser/chunk-WPW5VVAX.mjs +0 -1651
  381. package/dist/lib/browser/chunk-WPW5VVAX.mjs.map +0 -7
  382. package/dist/lib/browser/intent-dispatcher-LZ4AE66E.mjs +0 -11
  383. package/dist/lib/browser/intent-resolver-QVCKRX6G.mjs +0 -39
  384. package/dist/lib/browser/intent-resolver-QVCKRX6G.mjs.map +0 -7
  385. package/dist/lib/browser/react/index.mjs +0 -34
  386. package/dist/lib/browser/store-CNPHOYTJ.mjs +0 -30
  387. package/dist/lib/browser/store-CNPHOYTJ.mjs.map +0 -7
  388. package/dist/lib/node-esm/app-graph-builder-EBU4NVWD.mjs +0 -139
  389. package/dist/lib/node-esm/app-graph-builder-EBU4NVWD.mjs.map +0 -7
  390. package/dist/lib/node-esm/chunk-3UPX5OIS.mjs +0 -484
  391. package/dist/lib/node-esm/chunk-3UPX5OIS.mjs.map +0 -7
  392. package/dist/lib/node-esm/chunk-XJZGUJ3H.mjs +0 -1653
  393. package/dist/lib/node-esm/chunk-XJZGUJ3H.mjs.map +0 -7
  394. package/dist/lib/node-esm/chunk-ZX63QUGE.mjs +0 -37
  395. package/dist/lib/node-esm/chunk-ZX63QUGE.mjs.map +0 -7
  396. package/dist/lib/node-esm/intent-dispatcher-MGOJ3CHD.mjs +0 -12
  397. package/dist/lib/node-esm/intent-resolver-URF3HN3G.mjs +0 -40
  398. package/dist/lib/node-esm/intent-resolver-URF3HN3G.mjs.map +0 -7
  399. package/dist/lib/node-esm/react/index.mjs +0 -35
  400. package/dist/lib/node-esm/store-RK5B4XEL.mjs +0 -31
  401. package/dist/lib/node-esm/store-RK5B4XEL.mjs.map +0 -7
  402. package/dist/types/src/common/collaboration.d.ts +0 -20
  403. package/dist/types/src/common/collaboration.d.ts.map +0 -1
  404. package/dist/types/src/common/events.d.ts +0 -52
  405. package/dist/types/src/common/events.d.ts.map +0 -1
  406. package/dist/types/src/common/file.d.ts +0 -14
  407. package/dist/types/src/common/file.d.ts.map +0 -1
  408. package/dist/types/src/common/graph.d.ts +0 -21
  409. package/dist/types/src/common/graph.d.ts.map +0 -1
  410. package/dist/types/src/common/layout.d.ts +0 -279
  411. package/dist/types/src/common/layout.d.ts.map +0 -1
  412. package/dist/types/src/common/surface.d.ts +0 -68
  413. package/dist/types/src/common/surface.d.ts.map +0 -1
  414. package/dist/types/src/core/capabilities.d.ts +0 -117
  415. package/dist/types/src/core/capabilities.d.ts.map +0 -1
  416. package/dist/types/src/core/capabilities.test.d.ts +0 -2
  417. package/dist/types/src/core/capabilities.test.d.ts.map +0 -1
  418. package/dist/types/src/core/events.d.ts.map +0 -1
  419. package/dist/types/src/core/manager.d.ts +0 -126
  420. package/dist/types/src/core/manager.d.ts.map +0 -1
  421. package/dist/types/src/core/manager.test.d.ts +0 -2
  422. package/dist/types/src/core/manager.test.d.ts.map +0 -1
  423. package/dist/types/src/playground/debug/Debug.d.ts +0 -6
  424. package/dist/types/src/playground/debug/Debug.d.ts.map +0 -1
  425. package/dist/types/src/playground/debug/index.d.ts +0 -2
  426. package/dist/types/src/playground/debug/index.d.ts.map +0 -1
  427. package/dist/types/src/playground/debug/plugin.d.ts +0 -2
  428. package/dist/types/src/playground/debug/plugin.d.ts.map +0 -1
  429. package/dist/types/src/playground/generator/Main.d.ts +0 -6
  430. package/dist/types/src/playground/generator/Main.d.ts.map +0 -1
  431. package/dist/types/src/playground/generator/Toolbar.d.ts +0 -6
  432. package/dist/types/src/playground/generator/Toolbar.d.ts.map +0 -1
  433. package/dist/types/src/playground/generator/generator.d.ts +0 -7
  434. package/dist/types/src/playground/generator/generator.d.ts.map +0 -1
  435. package/dist/types/src/playground/generator/index.d.ts +0 -3
  436. package/dist/types/src/playground/generator/index.d.ts.map +0 -1
  437. package/dist/types/src/playground/generator/plugin.d.ts +0 -2
  438. package/dist/types/src/playground/generator/plugin.d.ts.map +0 -1
  439. package/dist/types/src/playground/layout/Layout.d.ts +0 -8
  440. package/dist/types/src/playground/layout/Layout.d.ts.map +0 -1
  441. package/dist/types/src/playground/layout/index.d.ts +0 -2
  442. package/dist/types/src/playground/layout/index.d.ts.map +0 -1
  443. package/dist/types/src/playground/layout/plugin.d.ts +0 -2
  444. package/dist/types/src/playground/layout/plugin.d.ts.map +0 -1
  445. package/dist/types/src/playground/logger/Toolbar.d.ts +0 -6
  446. package/dist/types/src/playground/logger/Toolbar.d.ts.map +0 -1
  447. package/dist/types/src/playground/logger/index.d.ts +0 -2
  448. package/dist/types/src/playground/logger/index.d.ts.map +0 -1
  449. package/dist/types/src/playground/logger/plugin.d.ts +0 -2
  450. package/dist/types/src/playground/logger/plugin.d.ts.map +0 -1
  451. package/dist/types/src/playground/logger/schema.d.ts +0 -13
  452. package/dist/types/src/playground/logger/schema.d.ts.map +0 -1
  453. package/dist/types/src/playground/playground.stories.d.ts +0 -11
  454. package/dist/types/src/playground/playground.stories.d.ts.map +0 -1
  455. package/dist/types/src/plugin-intent/IntentPlugin.d.ts +0 -2
  456. package/dist/types/src/plugin-intent/IntentPlugin.d.ts.map +0 -1
  457. package/dist/types/src/plugin-intent/actions.d.ts +0 -36
  458. package/dist/types/src/plugin-intent/actions.d.ts.map +0 -1
  459. package/dist/types/src/plugin-intent/errors.d.ts +0 -16
  460. package/dist/types/src/plugin-intent/errors.d.ts.map +0 -1
  461. package/dist/types/src/plugin-intent/index.d.ts +0 -6
  462. package/dist/types/src/plugin-intent/index.d.ts.map +0 -1
  463. package/dist/types/src/plugin-intent/intent-dispatcher.d.ts +0 -139
  464. package/dist/types/src/plugin-intent/intent-dispatcher.d.ts.map +0 -1
  465. package/dist/types/src/plugin-intent/intent-dispatcher.test.d.ts +0 -2
  466. package/dist/types/src/plugin-intent/intent-dispatcher.test.d.ts.map +0 -1
  467. package/dist/types/src/plugin-intent/intent.d.ts +0 -63
  468. package/dist/types/src/plugin-intent/intent.d.ts.map +0 -1
  469. package/dist/types/src/plugin-intent/meta.d.ts +0 -3
  470. package/dist/types/src/plugin-intent/meta.d.ts.map +0 -1
  471. package/dist/types/src/plugin-settings/SettingsPlugin.d.ts +0 -2
  472. package/dist/types/src/plugin-settings/SettingsPlugin.d.ts.map +0 -1
  473. package/dist/types/src/plugin-settings/actions.d.ts +0 -25
  474. package/dist/types/src/plugin-settings/actions.d.ts.map +0 -1
  475. package/dist/types/src/plugin-settings/app-graph-builder.d.ts +0 -4
  476. package/dist/types/src/plugin-settings/app-graph-builder.d.ts.map +0 -1
  477. package/dist/types/src/plugin-settings/index.d.ts +0 -3
  478. package/dist/types/src/plugin-settings/index.d.ts.map +0 -1
  479. package/dist/types/src/plugin-settings/intent-resolver.d.ts +0 -4
  480. package/dist/types/src/plugin-settings/intent-resolver.d.ts.map +0 -1
  481. package/dist/types/src/plugin-settings/meta.d.ts +0 -3
  482. package/dist/types/src/plugin-settings/meta.d.ts.map +0 -1
  483. package/dist/types/src/plugin-settings/store.d.ts +0 -5
  484. package/dist/types/src/plugin-settings/store.d.ts.map +0 -1
  485. package/dist/types/src/plugin-settings/translations.d.ts +0 -11
  486. package/dist/types/src/plugin-settings/translations.d.ts.map +0 -1
  487. package/dist/types/src/react/App.d.ts +0 -10
  488. package/dist/types/src/react/App.d.ts.map +0 -1
  489. package/dist/types/src/react/App.stories.d.ts.map +0 -1
  490. package/dist/types/src/react/DefaultFallback.d.ts +0 -8
  491. package/dist/types/src/react/DefaultFallback.d.ts.map +0 -1
  492. package/dist/types/src/react/ErrorBoundary.d.ts +0 -30
  493. package/dist/types/src/react/ErrorBoundary.d.ts.map +0 -1
  494. package/dist/types/src/react/IntentContext.d.ts +0 -8
  495. package/dist/types/src/react/IntentContext.d.ts.map +0 -1
  496. package/dist/types/src/react/PluginManagerProvider.d.ts +0 -10
  497. package/dist/types/src/react/PluginManagerProvider.d.ts.map +0 -1
  498. package/dist/types/src/react/Surface.d.ts +0 -12
  499. package/dist/types/src/react/Surface.d.ts.map +0 -1
  500. package/dist/types/src/react/Surface.stories.d.ts.map +0 -1
  501. package/dist/types/src/react/common.d.ts +0 -13
  502. package/dist/types/src/react/common.d.ts.map +0 -1
  503. package/dist/types/src/react/index.d.ts +0 -9
  504. package/dist/types/src/react/index.d.ts.map +0 -1
  505. package/dist/types/src/react/types.d.ts +0 -14
  506. package/dist/types/src/react/types.d.ts.map +0 -1
  507. package/dist/types/src/react/useApp.d.ts +0 -44
  508. package/dist/types/src/react/useApp.d.ts.map +0 -1
  509. package/dist/types/src/react/useCapabilities.d.ts +0 -13
  510. package/dist/types/src/react/useCapabilities.d.ts.map +0 -1
  511. package/dist/types/src/react/useIntentResolver.d.ts +0 -3
  512. package/dist/types/src/react/useIntentResolver.d.ts.map +0 -1
  513. package/dist/types/src/react/useLoading.d.ts.map +0 -1
  514. package/src/common/collaboration.ts +0 -18
  515. package/src/common/events.ts +0 -79
  516. package/src/common/file.ts +0 -22
  517. package/src/common/graph.ts +0 -30
  518. package/src/common/layout.ts +0 -277
  519. package/src/common/surface.ts +0 -88
  520. package/src/core/capabilities.test.ts +0 -136
  521. package/src/core/capabilities.ts +0 -263
  522. package/src/core/manager.test.ts +0 -516
  523. package/src/core/manager.ts +0 -604
  524. package/src/playground/debug/Debug.tsx +0 -39
  525. package/src/playground/debug/plugin.ts +0 -16
  526. package/src/playground/generator/Main.tsx +0 -70
  527. package/src/playground/generator/Toolbar.tsx +0 -47
  528. package/src/playground/generator/generator.ts +0 -48
  529. package/src/playground/generator/index.ts +0 -6
  530. package/src/playground/generator/plugin.ts +0 -22
  531. package/src/playground/layout/Layout.tsx +0 -33
  532. package/src/playground/layout/plugin.ts +0 -18
  533. package/src/playground/logger/Toolbar.tsx +0 -30
  534. package/src/playground/logger/plugin.ts +0 -41
  535. package/src/playground/logger/schema.ts +0 -12
  536. package/src/playground/playground.stories.tsx +0 -46
  537. package/src/plugin-intent/IntentPlugin.ts +0 -20
  538. package/src/plugin-intent/actions.ts +0 -31
  539. package/src/plugin-intent/errors.ts +0 -40
  540. package/src/plugin-intent/index.ts +0 -9
  541. package/src/plugin-intent/intent-dispatcher.test.ts +0 -286
  542. package/src/plugin-intent/intent-dispatcher.ts +0 -342
  543. package/src/plugin-intent/intent.ts +0 -154
  544. package/src/plugin-intent/meta.ts +0 -10
  545. package/src/plugin-settings/SettingsPlugin.ts +0 -34
  546. package/src/plugin-settings/actions.ts +0 -25
  547. package/src/plugin-settings/app-graph-builder.ts +0 -160
  548. package/src/plugin-settings/index.ts +0 -6
  549. package/src/plugin-settings/intent-resolver.ts +0 -35
  550. package/src/plugin-settings/meta.ts +0 -10
  551. package/src/plugin-settings/store.ts +0 -33
  552. package/src/plugin-settings/translations.ts +0 -19
  553. package/src/react/App.stories.tsx +0 -33
  554. package/src/react/App.tsx +0 -59
  555. package/src/react/DefaultFallback.tsx +0 -26
  556. package/src/react/ErrorBoundary.tsx +0 -56
  557. package/src/react/IntentContext.tsx +0 -35
  558. package/src/react/Surface.stories.tsx +0 -125
  559. package/src/react/Surface.tsx +0 -109
  560. package/src/react/common.ts +0 -13
  561. package/src/react/index.ts +0 -14
  562. package/src/react/types.ts +0 -38
  563. package/src/react/useApp.tsx +0 -165
  564. package/src/react/useCapabilities.ts +0 -31
  565. package/src/react/useIntentResolver.ts +0 -22
  566. /package/dist/lib/browser/{intent-dispatcher-LZ4AE66E.mjs.map → chunk-J5LGTIGS.mjs.map} +0 -0
  567. /package/dist/lib/browser/{react/index.mjs.map → common/activation-events.mjs.map} +0 -0
  568. /package/dist/lib/{node-esm/intent-dispatcher-MGOJ3CHD.mjs.map → browser/common/capabilities.mjs.map} +0 -0
  569. /package/dist/lib/{node-esm/react/index.mjs.map → browser/core/activation-event.mjs.map} +0 -0
@@ -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 { EffectEx } 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 EffectEx.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
+ }
@@ -0,0 +1,222 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import { assert, describe, it } from '@effect/vitest';
6
+ import * as Effect from 'effect/Effect';
7
+
8
+ import { EffectEx } from '@dxos/effect';
9
+ import { DXN } from '@dxos/keys';
10
+
11
+ import * as Plugin from './plugin';
12
+ import * as PluginAssetCache from './plugin-asset-cache';
13
+ import * as UrlLoader from './url-loader';
14
+
15
+ const testMeta = Plugin.makeMeta({ key: DXN.make('org.dxos.plugin.test'), name: 'Test' });
16
+
17
+ const memoryStorage = (initial: string | null = null): UrlLoader.Storage => {
18
+ let value = initial;
19
+ return {
20
+ get: () => value,
21
+ set: (_key, next) => {
22
+ value = next;
23
+ },
24
+ };
25
+ };
26
+
27
+ type CacheCall = { method: 'cache' | 'evict' | 'resolve'; pluginId: string; urls?: readonly string[]; url?: string };
28
+
29
+ const recordingCache = (): { cache: PluginAssetCache.Cache; calls: CacheCall[] } => {
30
+ const calls: CacheCall[] = [];
31
+ return {
32
+ calls,
33
+ cache: {
34
+ cache: (pluginId, urls) =>
35
+ Effect.sync(() => {
36
+ calls.push({ method: 'cache', pluginId, urls });
37
+ }),
38
+ evict: (pluginId) =>
39
+ Effect.sync(() => {
40
+ calls.push({ method: 'evict', pluginId });
41
+ }),
42
+ resolve: (pluginId, url) =>
43
+ Effect.sync(() => {
44
+ calls.push({ method: 'resolve', pluginId, url });
45
+ return url;
46
+ }),
47
+ list: () => Effect.succeed([] as readonly string[]),
48
+ },
49
+ };
50
+ };
51
+
52
+ describe('UrlLoader', () => {
53
+ describe('isLocalUrl', () => {
54
+ it('matches localhost, 127.0.0.1, and ::1', ({ expect }) => {
55
+ expect(UrlLoader.isLocalUrl('http://localhost:5173/plugin.mjs')).toBe(true);
56
+ expect(UrlLoader.isLocalUrl('https://LOCALHOST/plugin.mjs')).toBe(true);
57
+ expect(UrlLoader.isLocalUrl('http://127.0.0.1:8080/plugin.mjs')).toBe(true);
58
+ expect(UrlLoader.isLocalUrl('http://[::1]:8080/plugin.mjs')).toBe(true);
59
+ });
60
+
61
+ it('rejects public and malformed URLs', ({ expect }) => {
62
+ expect(UrlLoader.isLocalUrl('https://example.com/plugin.mjs')).toBe(false);
63
+ expect(UrlLoader.isLocalUrl('https://192.168.1.10/plugin.mjs')).toBe(false);
64
+ expect(UrlLoader.isLocalUrl('not a url')).toBe(false);
65
+ expect(UrlLoader.isLocalUrl('')).toBe(false);
66
+ });
67
+ });
68
+
69
+ describe('getRemoteEntries', () => {
70
+ it('returns persisted entries from storage', ({ expect }) => {
71
+ const storage: UrlLoader.Storage = {
72
+ get: () => '[{"id":"p1","url":"http://localhost:5173/p.mjs"}]',
73
+ set: () => {},
74
+ };
75
+ expect(UrlLoader.getRemoteEntries({ storage })).toEqual([{ id: 'p1', url: 'http://localhost:5173/p.mjs' }]);
76
+ });
77
+
78
+ it('returns an empty array when storage is empty or malformed', ({ expect }) => {
79
+ const empty: UrlLoader.Storage = { get: () => null, set: () => {} };
80
+ const malformed: UrlLoader.Storage = { get: () => '{not json', set: () => {} };
81
+ expect(UrlLoader.getRemoteEntries({ storage: empty })).toEqual([]);
82
+ expect(UrlLoader.getRemoteEntries({ storage: malformed })).toEqual([]);
83
+ });
84
+ });
85
+
86
+ describe('setInstalledVersion / getInstalledVersion', () => {
87
+ it('stores and retrieves an installed version', ({ expect }) => {
88
+ const stored: Record<string, string> = {};
89
+ const storage: UrlLoader.Storage = {
90
+ get: (key) => stored[key] ?? null,
91
+ set: (key, value) => {
92
+ stored[key] = value;
93
+ },
94
+ };
95
+
96
+ // Seed a remote entry without a version.
97
+ storage.set('test-key', JSON.stringify([{ id: 'org.dxos.plugin.foo', url: 'http://example.com/p.mjs' }]));
98
+
99
+ UrlLoader.setInstalledVersion('org.dxos.plugin.foo', 'v1.0.0', { storage, key: 'test-key' });
100
+
101
+ expect(UrlLoader.getInstalledVersion('org.dxos.plugin.foo', { storage, key: 'test-key' })).toBe('v1.0.0');
102
+ });
103
+
104
+ it('returns undefined when plugin is not persisted', ({ expect }) => {
105
+ const storage: UrlLoader.Storage = { get: () => null, set: () => {} };
106
+ expect(UrlLoader.getInstalledVersion('org.dxos.plugin.missing', { storage })).toBeUndefined();
107
+ });
108
+
109
+ it('overwrites an existing version when called again', ({ expect }) => {
110
+ const stored: Record<string, string> = {};
111
+ const storage: UrlLoader.Storage = {
112
+ get: (key) => stored[key] ?? null,
113
+ set: (key, value) => {
114
+ stored[key] = value;
115
+ },
116
+ };
117
+ storage.set(
118
+ 'test-key',
119
+ JSON.stringify([{ id: 'org.dxos.plugin.foo', url: 'http://example.com/p.mjs', version: 'v1.0.0' }]),
120
+ );
121
+
122
+ UrlLoader.setInstalledVersion('org.dxos.plugin.foo', 'v2.0.0', { storage, key: 'test-key' });
123
+ expect(UrlLoader.getInstalledVersion('org.dxos.plugin.foo', { storage, key: 'test-key' })).toBe('v2.0.0');
124
+ });
125
+ });
126
+
127
+ describe('make', () => {
128
+ it.effect('resolves built-in plugins by meta.id', () =>
129
+ Effect.gen(function* () {
130
+ const testPlugin = Plugin.make(Plugin.define(testMeta))();
131
+ const loader = UrlLoader.make([testPlugin]);
132
+ const result = yield* loader(testMeta.id);
133
+ assert.strictEqual(result.plugin.meta.id, testMeta.id);
134
+ // Builtins are not dev plugins.
135
+ assert.notOk(result.dev);
136
+ }),
137
+ );
138
+
139
+ it.effect('fails for unknown non-URL locator', () =>
140
+ Effect.gen(function* () {
141
+ const loader = UrlLoader.make([]);
142
+ const exit = yield* Effect.exit(loader('not-a-url'));
143
+ assert.isTrue(exit._tag === 'Failure');
144
+ }),
145
+ );
146
+ });
147
+
148
+ describe('preload', () => {
149
+ it('returns empty array when storage has no entries', async ({ expect }) => {
150
+ const storage: UrlLoader.Storage = {
151
+ get: () => null,
152
+ set: () => {},
153
+ };
154
+ const result = await EffectEx.runAndForwardErrors(UrlLoader.preload({ storage }));
155
+ expect(result).toEqual([]);
156
+ });
157
+
158
+ it('returns empty array when storage has invalid JSON', async ({ expect }) => {
159
+ const storage: UrlLoader.Storage = {
160
+ get: () => '{{invalid json',
161
+ set: () => {},
162
+ };
163
+ const result = await EffectEx.runAndForwardErrors(UrlLoader.preload({ storage }));
164
+ expect(result).toEqual([]);
165
+ });
166
+
167
+ it('returns empty array when storage contains null', async ({ expect }) => {
168
+ const storage: UrlLoader.Storage = {
169
+ get: () => 'null',
170
+ set: () => {},
171
+ };
172
+ const result = await EffectEx.runAndForwardErrors(UrlLoader.preload({ storage }));
173
+ expect(result).toEqual([]);
174
+ });
175
+
176
+ it('returns empty array when storage contains an object', async ({ expect }) => {
177
+ const storage: UrlLoader.Storage = {
178
+ get: () => '{}',
179
+ set: () => {},
180
+ };
181
+ const result = await EffectEx.runAndForwardErrors(UrlLoader.preload({ storage }));
182
+ expect(result).toEqual([]);
183
+ });
184
+
185
+ it('returns empty array when entries are missing required fields', async ({ expect }) => {
186
+ const storage: UrlLoader.Storage = {
187
+ get: () => '[{"title":"no url"}]',
188
+ set: () => {},
189
+ };
190
+ const result = await EffectEx.runAndForwardErrors(UrlLoader.preload({ storage }));
191
+ expect(result).toEqual([]);
192
+ });
193
+ });
194
+
195
+ describe('uninstall', () => {
196
+ it('removes the persisted entry and evicts cached assets', async ({ expect }) => {
197
+ const storage = memoryStorage('[{"id":"p1","url":"https://x/p1.json"},{"id":"p2","url":"https://x/p2.json"}]');
198
+ const { cache, calls } = recordingCache();
199
+ await EffectEx.runAndForwardErrors(UrlLoader.uninstall('p1', { storage, cache }));
200
+ expect(UrlLoader.getRemoteEntries({ storage })).toEqual([{ id: 'p2', url: 'https://x/p2.json' }]);
201
+ expect(calls).toEqual([{ method: 'evict', pluginId: 'p1' }]);
202
+ });
203
+
204
+ it('still removes entry when cache eviction fails', async ({ expect }) => {
205
+ const storage = memoryStorage('[{"id":"p1","url":"https://x/p1.json"}]');
206
+ const cache: PluginAssetCache.Cache = {
207
+ cache: () => Effect.void,
208
+ evict: () =>
209
+ Effect.fail(
210
+ new PluginAssetCache.PluginAssetCacheError({
211
+ context: { operation: 'evict', pluginId: 'p1' },
212
+ cause: 'boom',
213
+ }),
214
+ ),
215
+ resolve: (_id, url) => Effect.succeed(url),
216
+ list: () => Effect.succeed([] as readonly string[]),
217
+ };
218
+ await EffectEx.runAndForwardErrors(UrlLoader.uninstall('p1', { storage, cache }));
219
+ expect(UrlLoader.getRemoteEntries({ storage })).toEqual([]);
220
+ });
221
+ });
222
+ });