@dxos/app-framework 0.8.4-main.bc674ce → 0.8.4-main.c351d160a8

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 (368) hide show
  1. package/.storybook/main.mts +1 -3
  2. package/dist/lib/browser/capability-5OFLR7J4.mjs +34 -0
  3. package/dist/lib/browser/capability-5OFLR7J4.mjs.map +7 -0
  4. package/dist/lib/browser/{capability-7PCNSWBT.mjs → capability-ZHQDZRP5.mjs} +15 -11
  5. package/dist/lib/browser/capability-ZHQDZRP5.mjs.map +7 -0
  6. package/dist/lib/browser/{chunk-PKQT6C53.mjs → chunk-272IPLHQ.mjs} +1 -1
  7. package/dist/lib/browser/{chunk-PKQT6C53.mjs.map → chunk-272IPLHQ.mjs.map} +1 -1
  8. package/dist/lib/browser/{chunk-FMZN33N4.mjs → chunk-3VXJONTI.mjs} +304 -178
  9. package/dist/lib/browser/chunk-3VXJONTI.mjs.map +7 -0
  10. package/dist/lib/browser/{chunk-XYNO72GQ.mjs → chunk-7AL6SKIV.mjs} +459 -477
  11. package/dist/lib/browser/chunk-7AL6SKIV.mjs.map +7 -0
  12. package/dist/lib/browser/{chunk-TCLLRCS3.mjs → chunk-GH3M2LIW.mjs} +10 -7
  13. package/dist/lib/browser/chunk-GH3M2LIW.mjs.map +7 -0
  14. package/dist/lib/browser/{chunk-7IQHKD4U.mjs → chunk-JGWCBVKJ.mjs} +2 -2
  15. package/dist/lib/browser/chunk-JGWCBVKJ.mjs.map +7 -0
  16. package/dist/lib/browser/chunk-M5IC326L.mjs +34 -0
  17. package/dist/lib/browser/chunk-M5IC326L.mjs.map +7 -0
  18. package/dist/lib/browser/chunk-TGX63LTL.mjs +8 -0
  19. package/dist/lib/browser/{chunk-FHQTHCX7.mjs.map → chunk-TGX63LTL.mjs.map} +1 -1
  20. package/dist/lib/browser/chunk-TIEBZMTF.mjs +44 -0
  21. package/dist/lib/browser/chunk-TIEBZMTF.mjs.map +7 -0
  22. package/dist/lib/browser/chunk-WEBSGU5L.mjs +80 -0
  23. package/dist/lib/browser/chunk-WEBSGU5L.mjs.map +7 -0
  24. package/dist/lib/browser/chunk-YAFEA4GV.mjs +1 -0
  25. package/dist/lib/browser/{chunk-6Y7PZV72.mjs → chunk-YNFPIQGB.mjs} +2 -3
  26. package/dist/lib/browser/{chunk-6Y7PZV72.mjs.map → chunk-YNFPIQGB.mjs.map} +3 -3
  27. package/dist/lib/browser/cli/index.mjs +89 -0
  28. package/dist/lib/browser/cli/index.mjs.map +7 -0
  29. package/dist/lib/browser/common/activation-events.mjs +23 -0
  30. package/dist/lib/browser/common/capabilities.mjs +45 -0
  31. package/dist/lib/browser/core/activation-event.mjs +1 -1
  32. package/dist/lib/browser/core/capability.mjs +1 -1
  33. package/dist/lib/browser/core/plugin-manager.mjs +4 -4
  34. package/dist/lib/browser/core/plugin.mjs +6 -4
  35. package/dist/lib/browser/index.mjs +37 -132
  36. package/dist/lib/browser/index.mjs.map +4 -4
  37. package/dist/lib/browser/{invoker-capability-SZRSTHEH.mjs → invoker-capability-YTTQ2OBB.mjs} +16 -12
  38. package/dist/lib/browser/invoker-capability-YTTQ2OBB.mjs.map +7 -0
  39. package/dist/lib/browser/meta.json +1 -1
  40. package/dist/lib/browser/testing/index.mjs +55 -34
  41. package/dist/lib/browser/testing/index.mjs.map +3 -3
  42. package/dist/lib/browser/{react → ui}/index.mjs +18 -19
  43. package/dist/lib/node-esm/capability-CRHZKL6T.mjs +35 -0
  44. package/dist/lib/node-esm/capability-CRHZKL6T.mjs.map +7 -0
  45. package/dist/lib/node-esm/{capability-CFLQ2QQU.mjs → capability-W5C5464H.mjs} +15 -11
  46. package/dist/lib/node-esm/capability-W5C5464H.mjs.map +7 -0
  47. package/dist/lib/node-esm/{chunk-663A54LQ.mjs → chunk-3D66SZHP.mjs} +2 -2
  48. package/dist/lib/node-esm/chunk-3D66SZHP.mjs.map +7 -0
  49. package/dist/lib/node-esm/{chunk-7OWSHPYK.mjs → chunk-6REV5DE7.mjs} +1 -1
  50. package/dist/lib/node-esm/{chunk-7OWSHPYK.mjs.map → chunk-6REV5DE7.mjs.map} +1 -1
  51. package/dist/lib/node-esm/{chunk-XYQTBFPA.mjs → chunk-CMDON4NG.mjs} +304 -178
  52. package/dist/lib/node-esm/chunk-CMDON4NG.mjs.map +7 -0
  53. package/dist/lib/node-esm/{chunk-UEWJDI2L.mjs → chunk-FKE4Z3D6.mjs} +2 -2
  54. package/dist/lib/node-esm/{chunk-UEWJDI2L.mjs.map → chunk-FKE4Z3D6.mjs.map} +1 -1
  55. package/dist/lib/node-esm/{chunk-6WXBT3EC.mjs → chunk-I7FZT4A7.mjs} +459 -477
  56. package/dist/lib/node-esm/chunk-I7FZT4A7.mjs.map +7 -0
  57. package/dist/lib/node-esm/{chunk-GT6OKM5I.mjs → chunk-LHCJGNXK.mjs} +10 -7
  58. package/dist/lib/node-esm/chunk-LHCJGNXK.mjs.map +7 -0
  59. package/dist/lib/node-esm/chunk-NHXBSAQR.mjs +35 -0
  60. package/dist/lib/node-esm/chunk-NHXBSAQR.mjs.map +7 -0
  61. package/dist/lib/node-esm/{chunk-STMXUEPO.mjs → chunk-SB5ODNPX.mjs} +2 -3
  62. package/dist/lib/node-esm/{chunk-STMXUEPO.mjs.map → chunk-SB5ODNPX.mjs.map} +3 -3
  63. package/dist/lib/node-esm/chunk-SCDGIGGU.mjs +45 -0
  64. package/dist/lib/node-esm/chunk-SCDGIGGU.mjs.map +7 -0
  65. package/dist/lib/node-esm/chunk-SQICGJBW.mjs +81 -0
  66. package/dist/lib/node-esm/chunk-SQICGJBW.mjs.map +7 -0
  67. package/dist/lib/node-esm/chunk-Z4TJPSMP.mjs +2 -0
  68. package/dist/lib/node-esm/chunk-Z4TJPSMP.mjs.map +7 -0
  69. package/dist/lib/node-esm/cli/index.mjs +90 -0
  70. package/dist/lib/node-esm/cli/index.mjs.map +7 -0
  71. package/dist/lib/node-esm/common/activation-events.mjs +24 -0
  72. package/dist/lib/node-esm/common/activation-events.mjs.map +7 -0
  73. package/dist/lib/node-esm/common/capabilities.mjs +46 -0
  74. package/dist/lib/node-esm/common/capabilities.mjs.map +7 -0
  75. package/dist/lib/node-esm/core/activation-event.mjs +1 -1
  76. package/dist/lib/node-esm/core/capability.mjs +1 -1
  77. package/dist/lib/node-esm/core/plugin-manager.mjs +4 -4
  78. package/dist/lib/node-esm/core/plugin.mjs +6 -4
  79. package/dist/lib/node-esm/index.mjs +37 -132
  80. package/dist/lib/node-esm/index.mjs.map +4 -4
  81. package/dist/lib/node-esm/{invoker-capability-PNMA5JOS.mjs → invoker-capability-BU26474T.mjs} +16 -12
  82. package/dist/lib/node-esm/invoker-capability-BU26474T.mjs.map +7 -0
  83. package/dist/lib/node-esm/meta.json +1 -1
  84. package/dist/lib/node-esm/testing/index.mjs +55 -34
  85. package/dist/lib/node-esm/testing/index.mjs.map +3 -3
  86. package/dist/lib/node-esm/{react → ui}/index.mjs +18 -19
  87. package/dist/lib/node-esm/ui/index.mjs.map +7 -0
  88. package/dist/types/src/{cli.d.ts → cli/cli.d.ts} +2 -2
  89. package/dist/types/src/cli/cli.d.ts.map +1 -0
  90. package/dist/types/src/cli/index.d.ts +2 -0
  91. package/dist/types/src/cli/index.d.ts.map +1 -0
  92. package/dist/types/src/common/activation-events.d.ts +27 -0
  93. package/dist/types/src/common/activation-events.d.ts.map +1 -0
  94. package/dist/types/src/common/capabilities.d.ts +115 -0
  95. package/dist/types/src/common/capabilities.d.ts.map +1 -0
  96. package/dist/types/src/common/index.d.ts +4 -9
  97. package/dist/types/src/common/index.d.ts.map +1 -1
  98. package/dist/types/src/common/operations.d.ts +1 -348
  99. package/dist/types/src/common/operations.d.ts.map +1 -1
  100. package/dist/types/src/common/translations.d.ts +0 -9
  101. package/dist/types/src/common/translations.d.ts.map +1 -1
  102. package/dist/types/src/core/activation-event.d.ts +1 -1
  103. package/dist/types/src/core/capability.d.ts +7 -7
  104. package/dist/types/src/core/capability.d.ts.map +1 -1
  105. package/dist/types/src/core/plugin-manager.d.ts +6 -0
  106. package/dist/types/src/core/plugin-manager.d.ts.map +1 -1
  107. package/dist/types/src/core/plugin.d.ts +6 -1
  108. package/dist/types/src/core/plugin.d.ts.map +1 -1
  109. package/dist/types/src/index.d.ts +1 -3
  110. package/dist/types/src/index.d.ts.map +1 -1
  111. package/dist/types/src/plugin-operation/history/capability.d.ts +1 -1
  112. package/dist/types/src/plugin-operation/history/undo-mapping.d.ts +11 -3
  113. package/dist/types/src/plugin-operation/history/undo-mapping.d.ts.map +1 -1
  114. package/dist/types/src/plugin-operation/invoker-capability.d.ts +1 -1
  115. package/dist/types/src/plugin-runtime/capability.d.ts +2 -2
  116. package/dist/types/src/plugin-runtime/capability.d.ts.map +1 -1
  117. package/dist/types/src/testing/withPluginManager.d.ts +1 -1
  118. package/dist/types/src/testing/withPluginManager.d.ts.map +1 -1
  119. package/dist/types/src/{react → ui/components/App}/App.d.ts +1 -1
  120. package/dist/types/src/ui/components/App/App.d.ts.map +1 -0
  121. package/dist/types/src/{react/Surface.stories.d.ts → ui/components/App/App.stories.d.ts} +7 -2
  122. package/dist/types/src/ui/components/App/App.stories.d.ts.map +1 -0
  123. package/dist/types/src/ui/components/App/index.d.ts +2 -0
  124. package/dist/types/src/ui/components/App/index.d.ts.map +1 -0
  125. package/dist/types/src/ui/components/PluginManager/PluginManagerContext.stories.d.ts.map +1 -0
  126. package/dist/types/src/{react → ui/components/PluginManager}/PluginManagerProvider.d.ts +1 -1
  127. package/dist/types/src/ui/components/PluginManager/PluginManagerProvider.d.ts.map +1 -0
  128. package/dist/types/src/ui/components/PluginManager/index.d.ts +2 -0
  129. package/dist/types/src/ui/components/PluginManager/index.d.ts.map +1 -0
  130. package/dist/types/src/ui/components/Surface/SurfaceComponent.d.ts +12 -0
  131. package/dist/types/src/ui/components/Surface/SurfaceComponent.d.ts.map +1 -0
  132. package/dist/types/src/{react/App.stories.d.ts → ui/components/Surface/SurfaceComponent.stories.d.ts} +1 -1
  133. package/dist/types/src/ui/components/Surface/SurfaceComponent.stories.d.ts.map +1 -0
  134. package/dist/types/src/ui/components/Surface/SurfaceInfo.d.ts.map +1 -0
  135. package/dist/types/src/ui/components/Surface/context.d.ts +5 -0
  136. package/dist/types/src/ui/components/Surface/context.d.ts.map +1 -0
  137. package/dist/types/src/ui/components/Surface/index.d.ts +20 -0
  138. package/dist/types/src/ui/components/Surface/index.d.ts.map +1 -0
  139. package/dist/types/src/{common/surface.d.ts → ui/components/Surface/types.d.ts} +20 -18
  140. package/dist/types/src/ui/components/Surface/types.d.ts.map +1 -0
  141. package/dist/types/src/ui/components/index.d.ts +4 -0
  142. package/dist/types/src/ui/components/index.d.ts.map +1 -0
  143. package/dist/types/src/ui/hooks/index.d.ts +7 -0
  144. package/dist/types/src/ui/hooks/index.d.ts.map +1 -0
  145. package/dist/types/src/{react → ui/hooks}/useApp.d.ts +14 -9
  146. package/dist/types/src/ui/hooks/useApp.d.ts.map +1 -0
  147. package/dist/types/src/ui/hooks/useApp.test.d.ts +2 -0
  148. package/dist/types/src/ui/hooks/useApp.test.d.ts.map +1 -0
  149. package/dist/types/src/{react → ui/hooks}/useCapabilities.d.ts +6 -1
  150. package/dist/types/src/ui/hooks/useCapabilities.d.ts.map +1 -0
  151. package/dist/types/src/ui/hooks/useLoading.d.ts.map +1 -0
  152. package/dist/types/src/{react → ui/hooks}/useOperationResolver.d.ts +2 -2
  153. package/dist/types/src/ui/hooks/useOperationResolver.d.ts.map +1 -0
  154. package/dist/types/src/{react/common.d.ts → ui/hooks/useSettingsState.d.ts} +1 -5
  155. package/dist/types/src/ui/hooks/useSettingsState.d.ts.map +1 -0
  156. package/dist/types/src/ui/hooks/useSurface.d.ts +3 -0
  157. package/dist/types/src/ui/hooks/useSurface.d.ts.map +1 -0
  158. package/dist/types/src/ui/index.d.ts +3 -0
  159. package/dist/types/src/ui/index.d.ts.map +1 -0
  160. package/dist/types/tsconfig.tsbuildinfo +1 -1
  161. package/moon.yml +6 -6
  162. package/package.json +72 -64
  163. package/src/{cli.ts → cli/cli.ts} +10 -10
  164. package/src/{playground/debug → cli}/index.ts +1 -1
  165. package/src/common/activation-events.ts +44 -0
  166. package/src/common/capabilities.ts +178 -0
  167. package/src/common/index.ts +4 -9
  168. package/src/common/operations.ts +2 -376
  169. package/src/common/translations.ts +0 -12
  170. package/src/context.ts +1 -1
  171. package/src/core/activation-event.ts +1 -1
  172. package/src/core/capability.ts +9 -9
  173. package/src/core/plugin-manager.test.ts +292 -44
  174. package/src/core/plugin-manager.ts +326 -154
  175. package/src/core/plugin.ts +10 -2
  176. package/src/index.ts +1 -3
  177. package/src/plugin-operation/OperationPlugin.ts +5 -5
  178. package/src/plugin-operation/history/capability.ts +5 -5
  179. package/src/plugin-operation/history/undo-mapping.ts +6 -3
  180. package/src/plugin-operation/invoker-capability.ts +5 -5
  181. package/src/plugin-operation/meta.ts +1 -1
  182. package/src/plugin-runtime/RuntimePlugin.ts +4 -4
  183. package/src/plugin-runtime/capability.ts +5 -5
  184. package/src/plugin-runtime/meta.ts +1 -1
  185. package/src/testing/service.ts +6 -6
  186. package/src/testing/withPluginManager.stories.tsx +6 -6
  187. package/src/testing/withPluginManager.tsx +46 -19
  188. package/src/ui/components/App/App.stories.tsx +92 -0
  189. package/src/{react → ui/components/App}/App.tsx +6 -9
  190. package/src/{playground/layout → ui/components/App}/index.ts +1 -1
  191. package/src/{react → ui/components/PluginManager}/PluginManagerContext.stories.tsx +13 -14
  192. package/src/{react → ui/components/PluginManager}/PluginManagerProvider.ts +1 -1
  193. package/src/ui/components/PluginManager/index.ts +5 -0
  194. package/src/{react/Surface.stories.tsx → ui/components/Surface/SurfaceComponent.stories.tsx} +18 -16
  195. package/src/{react/Surface.tsx → ui/components/Surface/SurfaceComponent.tsx} +36 -56
  196. package/src/{react → ui/components/Surface}/SurfaceInfo.tsx +2 -2
  197. package/src/ui/components/Surface/context.ts +12 -0
  198. package/src/ui/components/Surface/index.ts +20 -0
  199. package/src/{common/surface.ts → ui/components/Surface/types.ts} +22 -25
  200. package/src/ui/components/index.ts +7 -0
  201. package/src/ui/hooks/index.ts +10 -0
  202. package/src/ui/hooks/useApp.test.tsx +159 -0
  203. package/src/{react → ui/hooks}/useApp.tsx +39 -29
  204. package/src/{react → ui/hooks}/useCapabilities.ts +9 -5
  205. package/src/{react → ui/hooks}/useOperationResolver.ts +5 -5
  206. package/src/{react/common.ts → ui/hooks/useSettingsState.ts} +0 -11
  207. package/src/ui/hooks/useSurface.ts +13 -0
  208. package/src/ui/index.ts +6 -0
  209. package/tsconfig.json +2 -29
  210. package/tsconfig.node.json +1 -3
  211. package/typedoc.json +2 -4
  212. package/vitest.config.ts +1 -1
  213. package/dist/lib/browser/app-graph-builder-M2VPYQC6.mjs +0 -149
  214. package/dist/lib/browser/app-graph-builder-M2VPYQC6.mjs.map +0 -7
  215. package/dist/lib/browser/capability-7PCNSWBT.mjs.map +0 -7
  216. package/dist/lib/browser/capability-KP3PFEXD.mjs +0 -31
  217. package/dist/lib/browser/capability-KP3PFEXD.mjs.map +0 -7
  218. package/dist/lib/browser/chunk-7IQHKD4U.mjs.map +0 -7
  219. package/dist/lib/browser/chunk-BLQJSGL3.mjs +0 -732
  220. package/dist/lib/browser/chunk-BLQJSGL3.mjs.map +0 -7
  221. package/dist/lib/browser/chunk-FHQTHCX7.mjs +0 -8
  222. package/dist/lib/browser/chunk-FMZN33N4.mjs.map +0 -7
  223. package/dist/lib/browser/chunk-H4WPA7U7.mjs +0 -77
  224. package/dist/lib/browser/chunk-H4WPA7U7.mjs.map +0 -7
  225. package/dist/lib/browser/chunk-TCLLRCS3.mjs.map +0 -7
  226. package/dist/lib/browser/chunk-XYNO72GQ.mjs.map +0 -7
  227. package/dist/lib/browser/common/index.mjs +0 -38
  228. package/dist/lib/browser/invoker-capability-SZRSTHEH.mjs.map +0 -7
  229. package/dist/lib/browser/operation-resolver-6MP2MYOY.mjs +0 -64
  230. package/dist/lib/browser/operation-resolver-6MP2MYOY.mjs.map +0 -7
  231. package/dist/lib/node-esm/app-graph-builder-LROHGJEM.mjs +0 -150
  232. package/dist/lib/node-esm/app-graph-builder-LROHGJEM.mjs.map +0 -7
  233. package/dist/lib/node-esm/capability-CFLQ2QQU.mjs.map +0 -7
  234. package/dist/lib/node-esm/capability-RCUNM2M7.mjs +0 -32
  235. package/dist/lib/node-esm/capability-RCUNM2M7.mjs.map +0 -7
  236. package/dist/lib/node-esm/chunk-663A54LQ.mjs.map +0 -7
  237. package/dist/lib/node-esm/chunk-6WXBT3EC.mjs.map +0 -7
  238. package/dist/lib/node-esm/chunk-GQEBIGKD.mjs +0 -733
  239. package/dist/lib/node-esm/chunk-GQEBIGKD.mjs.map +0 -7
  240. package/dist/lib/node-esm/chunk-GT6OKM5I.mjs.map +0 -7
  241. package/dist/lib/node-esm/chunk-XR6NMKEP.mjs +0 -78
  242. package/dist/lib/node-esm/chunk-XR6NMKEP.mjs.map +0 -7
  243. package/dist/lib/node-esm/chunk-XYQTBFPA.mjs.map +0 -7
  244. package/dist/lib/node-esm/common/index.mjs +0 -39
  245. package/dist/lib/node-esm/invoker-capability-PNMA5JOS.mjs.map +0 -7
  246. package/dist/lib/node-esm/operation-resolver-7YWDMTNU.mjs +0 -65
  247. package/dist/lib/node-esm/operation-resolver-7YWDMTNU.mjs.map +0 -7
  248. package/dist/types/src/cli.d.ts.map +0 -1
  249. package/dist/types/src/common/activation-event.d.ts +0 -66
  250. package/dist/types/src/common/activation-event.d.ts.map +0 -1
  251. package/dist/types/src/common/capability.d.ts +0 -265
  252. package/dist/types/src/common/capability.d.ts.map +0 -1
  253. package/dist/types/src/common/collaboration.d.ts +0 -26
  254. package/dist/types/src/common/collaboration.d.ts.map +0 -1
  255. package/dist/types/src/common/file.d.ts +0 -14
  256. package/dist/types/src/common/file.d.ts.map +0 -1
  257. package/dist/types/src/common/graph.d.ts +0 -21
  258. package/dist/types/src/common/graph.d.ts.map +0 -1
  259. package/dist/types/src/common/plugin.d.ts +0 -201
  260. package/dist/types/src/common/plugin.d.ts.map +0 -1
  261. package/dist/types/src/common/surface.d.ts.map +0 -1
  262. package/dist/types/src/playground/debug/Debug.d.ts +0 -8
  263. package/dist/types/src/playground/debug/Debug.d.ts.map +0 -1
  264. package/dist/types/src/playground/debug/index.d.ts +0 -2
  265. package/dist/types/src/playground/debug/index.d.ts.map +0 -1
  266. package/dist/types/src/playground/debug/plugin.d.ts +0 -3
  267. package/dist/types/src/playground/debug/plugin.d.ts.map +0 -1
  268. package/dist/types/src/playground/generator/Main.d.ts +0 -8
  269. package/dist/types/src/playground/generator/Main.d.ts.map +0 -1
  270. package/dist/types/src/playground/generator/Toolbar.d.ts +0 -8
  271. package/dist/types/src/playground/generator/Toolbar.d.ts.map +0 -1
  272. package/dist/types/src/playground/generator/generator.d.ts +0 -19
  273. package/dist/types/src/playground/generator/generator.d.ts.map +0 -1
  274. package/dist/types/src/playground/generator/index.d.ts +0 -3
  275. package/dist/types/src/playground/generator/index.d.ts.map +0 -1
  276. package/dist/types/src/playground/generator/plugin.d.ts +0 -3
  277. package/dist/types/src/playground/generator/plugin.d.ts.map +0 -1
  278. package/dist/types/src/playground/layout/Layout.d.ts +0 -10
  279. package/dist/types/src/playground/layout/Layout.d.ts.map +0 -1
  280. package/dist/types/src/playground/layout/index.d.ts +0 -2
  281. package/dist/types/src/playground/layout/index.d.ts.map +0 -1
  282. package/dist/types/src/playground/layout/plugin.d.ts +0 -3
  283. package/dist/types/src/playground/layout/plugin.d.ts.map +0 -1
  284. package/dist/types/src/playground/logger/Toolbar.d.ts +0 -8
  285. package/dist/types/src/playground/logger/Toolbar.d.ts.map +0 -1
  286. package/dist/types/src/playground/logger/index.d.ts +0 -2
  287. package/dist/types/src/playground/logger/index.d.ts.map +0 -1
  288. package/dist/types/src/playground/logger/plugin.d.ts +0 -3
  289. package/dist/types/src/playground/logger/plugin.d.ts.map +0 -1
  290. package/dist/types/src/playground/logger/schema.d.ts +0 -27
  291. package/dist/types/src/playground/logger/schema.d.ts.map +0 -1
  292. package/dist/types/src/playground/playground.stories.d.ts +0 -11
  293. package/dist/types/src/playground/playground.stories.d.ts.map +0 -1
  294. package/dist/types/src/plugin-settings/SettingsPlugin.d.ts +0 -3
  295. package/dist/types/src/plugin-settings/SettingsPlugin.d.ts.map +0 -1
  296. package/dist/types/src/plugin-settings/actions.d.ts +0 -61
  297. package/dist/types/src/plugin-settings/actions.d.ts.map +0 -1
  298. package/dist/types/src/plugin-settings/app-graph-builder.d.ts +0 -6
  299. package/dist/types/src/plugin-settings/app-graph-builder.d.ts.map +0 -1
  300. package/dist/types/src/plugin-settings/index.d.ts +0 -3
  301. package/dist/types/src/plugin-settings/index.d.ts.map +0 -1
  302. package/dist/types/src/plugin-settings/meta.d.ts +0 -3
  303. package/dist/types/src/plugin-settings/meta.d.ts.map +0 -1
  304. package/dist/types/src/plugin-settings/operation-resolver.d.ts +0 -6
  305. package/dist/types/src/plugin-settings/operation-resolver.d.ts.map +0 -1
  306. package/dist/types/src/plugin-settings/translations.d.ts +0 -11
  307. package/dist/types/src/plugin-settings/translations.d.ts.map +0 -1
  308. package/dist/types/src/react/App.d.ts.map +0 -1
  309. package/dist/types/src/react/App.stories.d.ts.map +0 -1
  310. package/dist/types/src/react/DefaultFallback.d.ts +0 -8
  311. package/dist/types/src/react/DefaultFallback.d.ts.map +0 -1
  312. package/dist/types/src/react/ErrorBoundary.d.ts +0 -30
  313. package/dist/types/src/react/ErrorBoundary.d.ts.map +0 -1
  314. package/dist/types/src/react/PluginManagerContext.stories.d.ts.map +0 -1
  315. package/dist/types/src/react/PluginManagerProvider.d.ts.map +0 -1
  316. package/dist/types/src/react/Surface.d.ts +0 -14
  317. package/dist/types/src/react/Surface.d.ts.map +0 -1
  318. package/dist/types/src/react/Surface.stories.d.ts.map +0 -1
  319. package/dist/types/src/react/SurfaceInfo.d.ts.map +0 -1
  320. package/dist/types/src/react/common.d.ts.map +0 -1
  321. package/dist/types/src/react/index.d.ts +0 -9
  322. package/dist/types/src/react/index.d.ts.map +0 -1
  323. package/dist/types/src/react/types.d.ts +0 -12
  324. package/dist/types/src/react/types.d.ts.map +0 -1
  325. package/dist/types/src/react/useApp.d.ts.map +0 -1
  326. package/dist/types/src/react/useCapabilities.d.ts.map +0 -1
  327. package/dist/types/src/react/useLoading.d.ts.map +0 -1
  328. package/dist/types/src/react/useOperationResolver.d.ts.map +0 -1
  329. package/src/common/activation-event.ts +0 -99
  330. package/src/common/capability.ts +0 -343
  331. package/src/common/collaboration.ts +0 -31
  332. package/src/common/file.ts +0 -22
  333. package/src/common/graph.ts +0 -30
  334. package/src/common/plugin.ts +0 -364
  335. package/src/playground/debug/Debug.tsx +0 -49
  336. package/src/playground/debug/plugin.ts +0 -16
  337. package/src/playground/generator/Main.tsx +0 -80
  338. package/src/playground/generator/Toolbar.tsx +0 -57
  339. package/src/playground/generator/generator.ts +0 -48
  340. package/src/playground/generator/index.ts +0 -6
  341. package/src/playground/generator/plugin.ts +0 -21
  342. package/src/playground/layout/Layout.tsx +0 -37
  343. package/src/playground/layout/plugin.ts +0 -18
  344. package/src/playground/logger/Toolbar.tsx +0 -33
  345. package/src/playground/logger/index.ts +0 -5
  346. package/src/playground/logger/plugin.ts +0 -42
  347. package/src/playground/logger/schema.ts +0 -22
  348. package/src/playground/playground.stories.tsx +0 -54
  349. package/src/plugin-settings/SettingsPlugin.ts +0 -19
  350. package/src/plugin-settings/actions.ts +0 -64
  351. package/src/plugin-settings/app-graph-builder.ts +0 -140
  352. package/src/plugin-settings/index.ts +0 -6
  353. package/src/plugin-settings/meta.ts +0 -10
  354. package/src/plugin-settings/operation-resolver.ts +0 -55
  355. package/src/plugin-settings/translations.ts +0 -19
  356. package/src/react/App.stories.tsx +0 -63
  357. package/src/react/DefaultFallback.tsx +0 -26
  358. package/src/react/ErrorBoundary.tsx +0 -56
  359. package/src/react/index.ts +0 -14
  360. package/src/react/types.ts +0 -27
  361. /package/dist/lib/{node-esm/react/index.mjs.map → browser/chunk-YAFEA4GV.mjs.map} +0 -0
  362. /package/dist/lib/{node-esm/common/index.mjs.map → browser/common/activation-events.mjs.map} +0 -0
  363. /package/dist/lib/browser/{react/index.mjs.map → common/capabilities.mjs.map} +0 -0
  364. /package/dist/lib/browser/{common → ui}/index.mjs.map +0 -0
  365. /package/dist/types/src/{react → ui/components/PluginManager}/PluginManagerContext.stories.d.ts +0 -0
  366. /package/dist/types/src/{react → ui/components/Surface}/SurfaceInfo.d.ts +0 -0
  367. /package/dist/types/src/{react → ui/hooks}/useLoading.d.ts +0 -0
  368. /package/src/{react → ui/hooks}/useLoading.tsx +0 -0
@@ -15,6 +15,7 @@ import * as PubSub from 'effect/PubSub';
15
15
  import * as Ref from 'effect/Ref';
16
16
 
17
17
  import { runAndForwardErrors } from '@dxos/effect';
18
+ import { Performance } from '@dxos/effect';
18
19
  import { log } from '@dxos/log';
19
20
 
20
21
  import * as ActivationEvent from './activation-event';
@@ -74,6 +75,13 @@ export interface PluginManager {
74
75
  ): Effect.Effect<boolean, Error>;
75
76
  deactivate(id: string): Effect.Effect<boolean, Error>;
76
77
  reset(event: ActivationEvent.ActivationEvent | string): Effect.Effect<boolean, Error>;
78
+
79
+ /**
80
+ * Shuts down the manager by deactivating all active modules in reverse activation order,
81
+ * clearing all capabilities, and resetting lifecycle bookkeeping.
82
+ * Plugins, core, enabled, and modules remain intact so the manager can be reused.
83
+ */
84
+ shutdown(): Effect.Effect<boolean, Error>;
77
85
  }
78
86
 
79
87
  /**
@@ -105,6 +113,9 @@ class ManagerImpl implements PluginManager {
105
113
  private readonly _moduleSemaphores = new Map<Plugin.PluginModule['id'], Effect.Semaphore>();
106
114
  private readonly _activatingEvents = Effect.runSync(Ref.make<string[]>([]));
107
115
  private readonly _activatingModules = Effect.runSync(Ref.make<string[]>([]));
116
+ private readonly _inFlightFibers = Effect.runSync(Ref.make<Array<Fiber.Fiber<unknown, unknown>>>([]));
117
+ private readonly _shutdownSemaphore = Effect.runSync(Effect.makeSemaphore(1));
118
+ private readonly _shuttingDown = Effect.runSync(Ref.make(false));
108
119
 
109
120
  constructor({
110
121
  pluginLoader,
@@ -299,146 +310,30 @@ class ManagerImpl implements PluginManager {
299
310
  ): Effect.Effect<boolean, Error> {
300
311
  const key = typeof event === 'string' ? event : ActivationEvent.eventKey(event);
301
312
  return Effect.gen(this, function* () {
302
- log('activating', { key, ...params });
303
- yield* Ref.update(this._activatingEvents, (activating) => Array.append(activating, key));
304
- const pendingIndex = this._get(this._pendingResetAtom).findIndex((event) => event === key);
305
- if (pendingIndex !== -1) {
306
- this._update(this._pendingResetAtom, (pending) => pending.filter((event) => event !== key));
307
- }
308
-
309
- const activatingEvents = yield* this._activatingEvents;
310
- const activatingModules = yield* this._activatingModules;
311
- const modules = this._getInactiveModulesByEvent(key).filter((module) => {
312
- const allOf = ActivationEvent.isAllOf(module.activatesOn);
313
- if (!allOf) {
314
- return true;
315
- }
316
-
317
- // Check to see if all of the events in the `allOf` have been fired.
318
- // An event can be considered "fired" if it is in the `eventsFired` list or if it is currently being activated.
319
- const events = ActivationEvent.getEvents(module.activatesOn).filter(
320
- (event) => ActivationEvent.eventKey(event) !== key,
321
- );
322
- return (
323
- events.every(
324
- (event) =>
325
- this._get(this._eventsFiredAtom).includes(ActivationEvent.eventKey(event)) ||
326
- activatingEvents.includes(ActivationEvent.eventKey(event)),
327
- ) && !activatingModules.includes(module.id)
328
- );
329
- });
330
- yield* Ref.update(this._activatingModules, (activating) =>
331
- Array.appendAll(
332
- activating,
333
- modules.map((module) => module.id),
334
- ),
335
- );
336
- if (modules.length === 0) {
337
- log('no modules to activate', { key });
338
- if (!this._get(this._eventsFiredAtom).includes(key)) {
339
- this._update(this._eventsFiredAtom, (events) => [...events, key]);
340
- }
313
+ if (yield* this._isShuttingDown()) {
314
+ log('skipping activation during shutdown', { key, ...params });
341
315
  return false;
342
316
  }
343
317
 
344
- log('activating modules', { key, modules: modules.map((module) => module.id) });
345
- yield* PubSub.publish(this.activation, { event: key, state: 'activating' });
346
-
347
- // Fire activatesBefore events.
348
- const beforeEvents = Function.pipe(
349
- modules,
350
- Array.flatMap((module) => module.activatesBefore ?? []),
351
- HashSet.fromIterable,
352
- HashSet.toValues,
353
- Array.filter((event) => !activatingEvents.includes(ActivationEvent.eventKey(event))),
354
- );
355
- yield* Function.pipe(
356
- beforeEvents,
357
- Array.map((event) => this.activate(event, { before: key })),
358
- Effect.allWith({ concurrency: 'unbounded' }),
359
- together(
360
- Effect.sleep(Duration.seconds(10)).pipe(
361
- Effect.andThen(
362
- Effect.sync(() =>
363
- log.warn('activatesBefore is taking a long time', {
364
- event: key,
365
- beforeEvents: beforeEvents.map(ActivationEvent.eventKey),
366
- }),
367
- ),
368
- ),
369
- ),
370
- ),
371
- );
372
-
373
- // Concurrently triggers loading of lazy capabilities.
374
- const getCapabilities = yield* Function.pipe(
375
- modules,
376
- Array.map((mod) => this._loadModule(mod)),
377
- Effect.allWith({ concurrency: 'unbounded' }),
378
- Effect.catchAll((error) => {
379
- return Effect.gen(this, function* () {
380
- yield* PubSub.publish(this.activation, { event: key, state: 'error', error });
381
- return yield* Effect.fail(error);
382
- });
383
- }),
384
- );
385
-
386
- // Contribute the capabilities from the activated modules.
387
- yield* Function.pipe(
388
- modules,
389
- Array.zip(getCapabilities),
390
- Array.map(([module, capabilities]) => this._contributeCapabilities(module, capabilities)),
391
- // TODO(wittjosiah): This currently can't be run in parallel.
392
- // Running this with concurrency causes races with `allOf` activation events.
393
- Effect.all,
394
- );
395
-
396
- // Fire activatesAfter events.
397
- const afterEvents = Function.pipe(
398
- modules,
399
- Array.flatMap((module) => module.activatesAfter ?? []),
400
- HashSet.fromIterable,
401
- HashSet.toValues,
402
- Array.filter((event) => !activatingEvents.includes(ActivationEvent.eventKey(event))),
403
- );
404
- yield* Function.pipe(
405
- afterEvents,
406
- Array.map((event) => this.activate(event, { after: key })),
407
- Effect.allWith({ concurrency: 'unbounded' }),
408
- together(
409
- Effect.sleep(Duration.seconds(10)).pipe(
410
- Effect.andThen(
411
- Effect.sync(() =>
412
- log.warn('activatesAfter is taking a long time', {
413
- event: key,
414
- afterEvents: afterEvents.map(ActivationEvent.eventKey),
415
- }),
416
- ),
318
+ return yield* Effect.withFiberRuntime<boolean, Error>((fiber) =>
319
+ this._activateEvent(key, params, fiber).pipe(
320
+ together(
321
+ Effect.sleep(Duration.seconds(15)).pipe(
322
+ Effect.andThen(Effect.sync(() => log.warn('event activation is taking a long time', { event: key }))),
417
323
  ),
418
324
  ),
325
+ Performance.addTrackEntry({
326
+ name: typeof event === 'string' ? event : ActivationEvent.eventKey(event),
327
+ devtools: {
328
+ dataType: 'track-entry',
329
+ track: 'Event Activation',
330
+ trackGroup: 'Composer',
331
+ color: 'primary',
332
+ },
333
+ }),
419
334
  ),
420
335
  );
421
-
422
- yield* Ref.update(this._activatingEvents, (activating) => Array.filter(activating, (event) => event !== key));
423
- yield* Ref.update(this._activatingModules, (activating) =>
424
- Array.filter(activating, (module) => !modules.map((module) => module.id).includes(module)),
425
- );
426
-
427
- if (!this._get(this._eventsFiredAtom).includes(key)) {
428
- this._update(this._eventsFiredAtom, (events) => [...events, key]);
429
- }
430
-
431
- yield* PubSub.publish(this.activation, { event: key, state: 'activated' });
432
- log('activated', { key });
433
-
434
- return true;
435
- }).pipe(
436
- together(
437
- Effect.sleep(Duration.seconds(15)).pipe(
438
- Effect.andThen(Effect.sync(() => log.warn('event activation is taking a long time', { event: key }))),
439
- ),
440
- ),
441
- );
336
+ });
442
337
  }
443
338
 
444
339
  /**
@@ -485,6 +380,40 @@ class ManagerImpl implements PluginManager {
485
380
  });
486
381
  }
487
382
 
383
+ shutdown(): Effect.Effect<boolean, Error> {
384
+ return this._shutdownSemaphore.withPermits(1)(
385
+ Effect.gen(this, function* () {
386
+ yield* Ref.set(this._shuttingDown, true);
387
+ log('shutdown');
388
+
389
+ yield* this._interruptInFlightActivations();
390
+
391
+ const activeIds = [...this._get(this._activeAtom)].reverse();
392
+ const allModules = this._get(this._modulesAtom);
393
+ const modulesToDeactivate = activeIds
394
+ .map((id) => allModules.find((module) => module.id === id))
395
+ .filter((module): module is Plugin.PluginModule => module != null);
396
+
397
+ for (const module of modulesToDeactivate) {
398
+ yield* this._deactivateModule(module);
399
+ }
400
+
401
+ this._set(this._eventsFiredAtom, []);
402
+ this._set(this._pendingResetAtom, []);
403
+ this._moduleMemoMap.clear();
404
+ yield* Ref.set(this._activatingEvents, []);
405
+ yield* Ref.set(this._activatingModules, []);
406
+
407
+ log('shutdown complete');
408
+ return true;
409
+ }).pipe(Effect.ensuring(Ref.set(this._shuttingDown, false))),
410
+ );
411
+ }
412
+
413
+ //
414
+ // State helpers
415
+ //
416
+
488
417
  private _get<T>(atom: Atom.Atom<T>): T {
489
418
  return this.registry.get(atom);
490
419
  }
@@ -497,26 +426,8 @@ class ManagerImpl implements PluginManager {
497
426
  this._set(atom, updater(this._get(atom)));
498
427
  }
499
428
 
500
- private _addPlugin(plugin: Plugin.Plugin): void {
501
- log('add plugin', { id: plugin.meta.id });
502
- // TODO(wittjosiah): Find a way to add a warning for duplicate plugins that doesn't cause log spam.
503
- this._update(this._pluginsAtom, (plugins) => (plugins.includes(plugin) ? plugins : [...plugins, plugin]));
504
- }
505
-
506
- private _removePlugin(id: string): void {
507
- log('remove plugin', { id });
508
- this._update(this._pluginsAtom, (plugins) => plugins.filter((plugin) => plugin.meta.id !== id));
509
- }
510
-
511
- private _addModule(module: Plugin.PluginModule): void {
512
- log('add module', { id: module.id });
513
- // TODO(wittjosiah): Find a way to add a warning for duplicate modules that doesn't cause log spam.
514
- this._update(this._modulesAtom, (modules) => (modules.includes(module) ? modules : [...modules, module]));
515
- }
516
-
517
- private _removeModule(id: string): void {
518
- log('remove module', { id });
519
- this._update(this._modulesAtom, (modules) => modules.filter((module) => module.id !== id));
429
+ private _isShuttingDown(): Effect.Effect<boolean> {
430
+ return Ref.get(this._shuttingDown);
520
431
  }
521
432
 
522
433
  private _getPlugin(id: string): Plugin.Plugin | undefined {
@@ -560,6 +471,254 @@ class ManagerImpl implements PluginManager {
560
471
  }
561
472
  }
562
473
 
474
+ private _clearPendingReset(key: string): void {
475
+ const pendingIndex = this._get(this._pendingResetAtom).findIndex((event) => event === key);
476
+ if (pendingIndex !== -1) {
477
+ this._update(this._pendingResetAtom, (pending) => pending.filter((event) => event !== key));
478
+ }
479
+ }
480
+
481
+ //
482
+ // Fiber helpers
483
+ //
484
+
485
+ private _interruptInFlightActivations(): Effect.Effect<void> {
486
+ return Effect.gen(this, function* () {
487
+ const inFlightFibers = yield* Ref.get(this._inFlightFibers);
488
+ yield* Effect.forEach(inFlightFibers, (fiber) => Fiber.interrupt(fiber), {
489
+ concurrency: 'unbounded',
490
+ });
491
+ });
492
+ }
493
+
494
+ private _trackFiber(
495
+ ref: Ref.Ref<Array<Fiber.Fiber<unknown, unknown>>>,
496
+ fiber: Fiber.Fiber<unknown, unknown>,
497
+ ): Effect.Effect<void> {
498
+ return Ref.update(ref, (fibers) => [...fibers, fiber]);
499
+ }
500
+
501
+ private _untrackFiber(
502
+ ref: Ref.Ref<Array<Fiber.Fiber<unknown, unknown>>>,
503
+ fiber: Fiber.Fiber<unknown, unknown>,
504
+ ): Effect.Effect<void> {
505
+ return Ref.update(ref, (fibers) => fibers.filter((trackedFiber) => trackedFiber !== fiber));
506
+ }
507
+
508
+ //
509
+ // Registration helpers
510
+ //
511
+
512
+ private _addPlugin(plugin: Plugin.Plugin): void {
513
+ log('add plugin', { id: plugin.meta.id });
514
+ // TODO(wittjosiah): Find a way to add a warning for duplicate plugins that doesn't cause log spam.
515
+ this._update(this._pluginsAtom, (plugins) => (plugins.includes(plugin) ? plugins : [...plugins, plugin]));
516
+ }
517
+
518
+ private _removePlugin(id: string): void {
519
+ log('remove plugin', { id });
520
+ this._update(this._pluginsAtom, (plugins) => plugins.filter((plugin) => plugin.meta.id !== id));
521
+ }
522
+
523
+ private _addModule(module: Plugin.PluginModule): void {
524
+ log('add module', { id: module.id });
525
+ // TODO(wittjosiah): Find a way to add a warning for duplicate modules that doesn't cause log spam.
526
+ this._update(this._modulesAtom, (modules) => (modules.includes(module) ? modules : [...modules, module]));
527
+ }
528
+
529
+ private _removeModule(id: string): void {
530
+ log('remove module', { id });
531
+ this._update(this._modulesAtom, (modules) => modules.filter((module) => module.id !== id));
532
+ }
533
+
534
+ //
535
+ // Activation helpers
536
+ //
537
+
538
+ private _activateEvent(
539
+ key: string,
540
+ params: { before?: string; after?: string } | undefined,
541
+ fiber: Fiber.Fiber<unknown, unknown>,
542
+ ): Effect.Effect<boolean, Error> {
543
+ return Effect.gen(this, function* () {
544
+ yield* this._trackFiber(this._inFlightFibers, fiber);
545
+ log('activating', { key, ...params });
546
+ yield* Ref.update(this._activatingEvents, (activating) => Array.append(activating, key));
547
+ this._clearPendingReset(key);
548
+
549
+ const activatingEvents = yield* this._activatingEvents;
550
+ const activatingModules = yield* this._activatingModules;
551
+ const modules = this._getModulesForActivation(key, activatingEvents, activatingModules);
552
+ if (modules.length === 0) {
553
+ log('no modules to activate', { key });
554
+ if (!this._get(this._eventsFiredAtom).includes(key)) {
555
+ this._update(this._eventsFiredAtom, (events) => [...events, key]);
556
+ }
557
+ return false;
558
+ }
559
+
560
+ return yield* this._activateModulesForEvent(key, modules, activatingEvents);
561
+ }).pipe(
562
+ Effect.ensuring(
563
+ Effect.all([
564
+ this._untrackFiber(this._inFlightFibers, fiber),
565
+ Ref.update(this._activatingEvents, (activating) => Array.filter(activating, (event) => event !== key)),
566
+ ]),
567
+ ),
568
+ );
569
+ }
570
+
571
+ private _activateModulesForEvent(
572
+ key: string,
573
+ modules: Plugin.PluginModule[],
574
+ activatingEvents: string[],
575
+ ): Effect.Effect<boolean, Error> {
576
+ const activatingModuleIds = modules.map((module) => module.id);
577
+ return Effect.gen(this, function* () {
578
+ yield* Ref.update(this._activatingModules, (activating) => Array.appendAll(activating, activatingModuleIds));
579
+
580
+ log('activating modules', { key, modules: activatingModuleIds });
581
+ yield* PubSub.publish(this.activation, { event: key, state: 'activating' });
582
+
583
+ yield* this._activateRelatedEvents(key, this._getBeforeEvents(modules, activatingEvents), 'before');
584
+
585
+ const capabilities = yield* this._loadCapabilitiesForModules(key, modules);
586
+ yield* this._contributeCapabilitiesForModules(modules, capabilities);
587
+
588
+ yield* this._activateRelatedEvents(key, this._getAfterEvents(modules, activatingEvents), 'after');
589
+
590
+ if (!this._get(this._eventsFiredAtom).includes(key)) {
591
+ this._update(this._eventsFiredAtom, (events) => [...events, key]);
592
+ }
593
+
594
+ yield* PubSub.publish(this.activation, { event: key, state: 'activated' });
595
+ log('activated', { key });
596
+
597
+ return true;
598
+ }).pipe(
599
+ Effect.ensuring(
600
+ Ref.update(this._activatingModules, (activating) =>
601
+ Array.filter(activating, (module) => !activatingModuleIds.includes(module)),
602
+ ),
603
+ ),
604
+ );
605
+ }
606
+
607
+ private _getModulesForActivation(
608
+ key: string,
609
+ activatingEvents: string[],
610
+ activatingModules: string[],
611
+ ): Plugin.PluginModule[] {
612
+ return this._getInactiveModulesByEvent(key).filter((module) => {
613
+ const allOf = ActivationEvent.isAllOf(module.activatesOn);
614
+ if (!allOf) {
615
+ return true;
616
+ }
617
+
618
+ // Check to see if all of the events in the `allOf` have been fired.
619
+ // An event can be considered "fired" if it is in the `eventsFired` list or if it is currently being activated.
620
+ const events = ActivationEvent.getEvents(module.activatesOn).filter(
621
+ (event) => ActivationEvent.eventKey(event) !== key,
622
+ );
623
+ return (
624
+ events.every(
625
+ (event) =>
626
+ this._get(this._eventsFiredAtom).includes(ActivationEvent.eventKey(event)) ||
627
+ activatingEvents.includes(ActivationEvent.eventKey(event)),
628
+ ) && !activatingModules.includes(module.id)
629
+ );
630
+ });
631
+ }
632
+
633
+ private _getBeforeEvents(
634
+ modules: Plugin.PluginModule[],
635
+ activatingEvents: string[],
636
+ ): ActivationEvent.ActivationEvent[] {
637
+ return Function.pipe(
638
+ modules,
639
+ Array.flatMap((module) => module.activatesBefore ?? []),
640
+ HashSet.fromIterable,
641
+ HashSet.toValues,
642
+ Array.filter((event) => !activatingEvents.includes(ActivationEvent.eventKey(event))),
643
+ );
644
+ }
645
+
646
+ private _getAfterEvents(
647
+ modules: Plugin.PluginModule[],
648
+ activatingEvents: string[],
649
+ ): ActivationEvent.ActivationEvent[] {
650
+ return Function.pipe(
651
+ modules,
652
+ Array.flatMap((module) => module.activatesAfter ?? []),
653
+ HashSet.fromIterable,
654
+ HashSet.toValues,
655
+ Array.filter((event) => !activatingEvents.includes(ActivationEvent.eventKey(event))),
656
+ );
657
+ }
658
+
659
+ private _activateRelatedEvents(
660
+ key: string,
661
+ events: ActivationEvent.ActivationEvent[],
662
+ phase: 'before' | 'after',
663
+ ): Effect.Effect<void, Error> {
664
+ const logLabel = phase === 'before' ? 'activatesBefore' : 'activatesAfter';
665
+ const eventKey = phase === 'before' ? 'beforeEvents' : 'afterEvents';
666
+ return Function.pipe(
667
+ events,
668
+ Array.map((event) => this.activate(event, phase === 'before' ? { before: key } : { after: key })),
669
+ Effect.allWith({ concurrency: 'unbounded' }),
670
+ together(
671
+ Effect.sleep(Duration.seconds(10)).pipe(
672
+ Effect.andThen(
673
+ Effect.sync(() =>
674
+ log.warn(`${logLabel} is taking a long time`, {
675
+ event: key,
676
+ [eventKey]: events.map(ActivationEvent.eventKey),
677
+ }),
678
+ ),
679
+ ),
680
+ ),
681
+ ),
682
+ Effect.asVoid,
683
+ );
684
+ }
685
+
686
+ //
687
+ // Module lifecycle helpers
688
+ //
689
+
690
+ private _loadCapabilitiesForModules(
691
+ key: string,
692
+ modules: Plugin.PluginModule[],
693
+ ): Effect.Effect<Capability.Any[][], Error> {
694
+ return Function.pipe(
695
+ modules,
696
+ Array.map((mod) => this._loadModule(mod)),
697
+ Effect.allWith({ concurrency: 'unbounded' }),
698
+ Effect.catchAll((error) => {
699
+ return Effect.gen(this, function* () {
700
+ yield* PubSub.publish(this.activation, { event: key, state: 'error', error });
701
+ return yield* Effect.fail(error);
702
+ });
703
+ }),
704
+ );
705
+ }
706
+
707
+ private _contributeCapabilitiesForModules(
708
+ modules: Plugin.PluginModule[],
709
+ capabilities: Capability.Any[][],
710
+ ): Effect.Effect<void, Error> {
711
+ return Function.pipe(
712
+ modules,
713
+ Array.zip(capabilities),
714
+ Array.map(([module, capabilitySet]) => this._contributeCapabilities(module, capabilitySet)),
715
+ // TODO(wittjosiah): This currently can't be run in parallel.
716
+ // Running this with concurrency causes races with `allOf` activation events.
717
+ Effect.all,
718
+ Effect.asVoid,
719
+ );
720
+ }
721
+
563
722
  private _getModuleSemaphore(moduleId: Plugin.PluginModule['id']): Effect.Semaphore {
564
723
  let semaphore = this._moduleSemaphores.get(moduleId);
565
724
  if (!semaphore) {
@@ -609,10 +768,19 @@ class ManagerImpl implements PluginManager {
609
768
  ),
610
769
  ),
611
770
  ),
771
+ Performance.addTrackEntry({
772
+ name: module.id,
773
+ devtools: {
774
+ dataType: 'track-entry',
775
+ track: 'Module Activation',
776
+ trackGroup: 'Composer',
777
+ color: 'primary',
778
+ },
779
+ }),
612
780
  );
613
781
 
614
782
  // Fork the load to run in background, completing the deferred when done.
615
- yield* Effect.forkDaemon(
783
+ const fiber = yield* Effect.forkDaemon(
616
784
  loadEffect.pipe(
617
785
  Effect.tap((result) => Deferred.succeed(deferred, result)),
618
786
  Effect.catchAllCause((cause) => {
@@ -627,6 +795,10 @@ class ManagerImpl implements PluginManager {
627
795
  }),
628
796
  ),
629
797
  );
798
+ yield* this._trackFiber(this._inFlightFibers, fiber);
799
+ yield* Effect.forkDaemon(
800
+ Fiber.await(fiber).pipe(Effect.andThen(() => this._untrackFiber(this._inFlightFibers, fiber))),
801
+ );
630
802
 
631
803
  return deferred;
632
804
  }).pipe(semaphore.withPermits(1));
@@ -45,11 +45,18 @@ export const activate = (event: ActivationEvent.ActivationEvent): Effect.Effect<
45
45
  export const reset = (event: ActivationEvent.ActivationEvent): Effect.Effect<boolean, Error, Service> =>
46
46
  Effect.flatMap(Service, (manager) => manager.reset(event));
47
47
 
48
+ /**
49
+ * Shuts down the plugin manager, deactivating all active modules and clearing lifecycle state.
50
+ * Accesses the PluginManager via the Effect layer system.
51
+ */
52
+ export const shutdown = (): Effect.Effect<boolean, Error, Service> =>
53
+ Effect.flatMap(Service, (manager) => manager.shutdown());
54
+
48
55
  /**
49
56
  * Computes a module ID from plugin ID and export name.
50
57
  */
51
58
  const computeModuleId = (pluginId: string, moduleName: string): string => {
52
- return `${pluginId}/module/${moduleName}`;
59
+ return `${pluginId}.module.${moduleName}`;
53
60
  };
54
61
 
55
62
  /**
@@ -128,7 +135,7 @@ export type Meta = {
128
135
  *
129
136
  * Expected to be in the form of a valid URL.
130
137
  *
131
- * @example dxos.org/plugin/example
138
+ * @example org.dxos.plugin.example
132
139
  */
133
140
  id: string;
134
141
 
@@ -190,6 +197,7 @@ export const isPlugin = (value: unknown): value is Plugin => {
190
197
  * A collection of modules that are be enabled/disabled as a unit.
191
198
  * Plugins provide things such as components, state, actions, etc. to the application.
192
199
  */
200
+ // TODO(burdon): Convert to ECHO schema.
193
201
  export interface Plugin {
194
202
  readonly [PluginTypeId]: PluginTypeId;
195
203
  readonly meta: Readonly<Meta>;
package/src/index.ts CHANGED
@@ -2,10 +2,8 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- export * from './cli';
6
- export * as Common from './common';
5
+ export * from './common';
7
6
  export * from './context';
8
7
  export * from './core';
9
8
  export * from './plugin-operation';
10
9
  export * from './plugin-runtime';
11
- export * from './plugin-settings';
@@ -2,7 +2,7 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import * as Common from '../common';
5
+ import { ActivationEvents } from '../common';
6
6
  import { Capability, Plugin } from '../core';
7
7
 
8
8
  import { meta } from './meta';
@@ -12,13 +12,13 @@ const HistoryCapabilities = Capability.lazy('HistoryCapabilities', () => import(
12
12
 
13
13
  export const OperationPlugin = Plugin.define(meta).pipe(
14
14
  Plugin.addModule({
15
- activatesOn: Common.ActivationEvent.ManagedRuntimeReady,
16
- activatesBefore: [Common.ActivationEvent.SetupOperationResolver],
17
- activatesAfter: [Common.ActivationEvent.OperationInvokerReady],
15
+ activatesOn: ActivationEvents.ManagedRuntimeReady,
16
+ activatesBefore: [ActivationEvents.SetupOperationResolver],
17
+ activatesAfter: [ActivationEvents.OperationInvokerReady],
18
18
  activate: OperationInvoker,
19
19
  }),
20
20
  Plugin.addModule({
21
- activatesOn: Common.ActivationEvent.OperationInvokerReady,
21
+ activatesOn: ActivationEvents.OperationInvokerReady,
22
22
  activate: HistoryCapabilities,
23
23
  }),
24
24
  Plugin.make,
@@ -6,7 +6,7 @@ import * as Effect from 'effect/Effect';
6
6
 
7
7
  import { type OperationInvoker } from '@dxos/operation';
8
8
 
9
- import * as Common from '../../common';
9
+ import { Capabilities } from '../../common';
10
10
  import { Capability } from '../../core';
11
11
 
12
12
  import * as HistoryTracker from './history-tracker';
@@ -22,16 +22,16 @@ export default Capability.makeModule(
22
22
  const capabilities = yield* Capability.Service;
23
23
 
24
24
  // Create UndoRegistry.
25
- const undoRegistry = UndoRegistry.make(() => capabilities.getAll(Common.Capability.UndoMapping).flat());
25
+ const undoRegistry = UndoRegistry.make(() => capabilities.getAll(Capabilities.UndoMapping).flat());
26
26
 
27
27
  // Create HistoryTracker (depends on UndoRegistry and OperationInvoker).
28
- const invoker = yield* Capability.get(Common.Capability.OperationInvoker);
28
+ const invoker = yield* Capability.get(Capabilities.OperationInvoker);
29
29
  // Cast to internal type - the factory always returns OperationInvokerInternal.
30
30
  const historyTracker = HistoryTracker.make(invoker as OperationInvoker.OperationInvokerInternal, undoRegistry);
31
31
 
32
32
  return [
33
- Capability.contributes(Common.Capability.UndoRegistry, undoRegistry),
34
- Capability.contributes(Common.Capability.HistoryTracker, historyTracker),
33
+ Capability.contributes(Capabilities.UndoRegistry, undoRegistry),
34
+ Capability.contributes(Capabilities.HistoryTracker, historyTracker),
35
35
  ];
36
36
  }),
37
37
  );
@@ -4,7 +4,10 @@
4
4
 
5
5
  import type { Operation } from '@dxos/operation';
6
6
 
7
- import type { Label } from '../../common/translations';
7
+ /**
8
+ * Label type for translatable text (canonical definition in @dxos/app-toolkit).
9
+ */
10
+ type Label = string | [string, { ns: string; count?: number; defaultValue?: string }];
8
11
 
9
12
  /**
10
13
  * Extract the input type from an OperationDefinition.
@@ -95,7 +98,7 @@ export interface UndoMappingProps<
95
98
  * thread: output.thread,
96
99
  * anchor: output.anchor,
97
100
  * }),
98
- * message: ['thread deleted label', { ns: 'plugin-thread' }],
101
+ * message: ['thread deleted label', { ns: '@dxos/plugin-thread' }],
99
102
  * });
100
103
  *
101
104
  * // Dynamic message based on input/output
@@ -106,7 +109,7 @@ export interface UndoMappingProps<
106
109
  * message: (input, _output) =>
107
110
  * input.objects.length === 1
108
111
  * ? ['object deleted label', { ns: getTypename(input.objects[0]) }]
109
- * : ['objects deleted label', { ns: 'plugin-space' }],
112
+ * : ['objects deleted label', { ns: '@dxos/plugin-space' }],
110
113
  * });
111
114
  * ```
112
115
  */