@dxos/app-framework 0.8.4-main.f9ba587 → 0.8.4-main.fffef41

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 (393) hide show
  1. package/.storybook/main.mts +11 -0
  2. package/.storybook/preview.mts +8 -0
  3. package/.swc/plugins/linux_x86_64_19.0.0/727453fb3a62f7f1d952a41e051ca8a6f88cadc45cee43c6a4d1aa45f9b75665.wasmer-v7 +0 -0
  4. package/.swc/plugins/{v7_linux_x86_64_13.0.0/fce1bdb8e20a094e4af08bad09cc81497ed0e2e7c51223b07d371063cca18429 → linux_x86_64_19.0.0/fce1bdb8e20a094e4af08bad09cc81497ed0e2e7c51223b07d371063cca18429.wasmer-v7} +0 -0
  5. package/dist/lib/browser/{app-graph-builder-BGGXLD6T.mjs → app-graph-builder-OIEZZC45.mjs} +32 -31
  6. package/dist/lib/browser/app-graph-builder-OIEZZC45.mjs.map +7 -0
  7. package/dist/lib/browser/{chunk-DHZB7HG7.mjs → chunk-6XKO24JP.mjs} +254 -184
  8. package/dist/lib/browser/chunk-6XKO24JP.mjs.map +7 -0
  9. package/dist/lib/browser/{chunk-ORWHM7CO.mjs → chunk-SCPE4ZO2.mjs} +11 -8
  10. package/dist/lib/browser/chunk-SCPE4ZO2.mjs.map +7 -0
  11. package/dist/lib/browser/{chunk-2636QSIK.mjs → chunk-WPW5VVAX.mjs} +399 -266
  12. package/dist/lib/browser/chunk-WPW5VVAX.mjs.map +7 -0
  13. package/dist/lib/browser/index.mjs +20 -56
  14. package/dist/lib/browser/index.mjs.map +3 -3
  15. package/dist/lib/browser/{intent-dispatcher-TWKB22NI.mjs → intent-dispatcher-LZ4AE66E.mjs} +2 -2
  16. package/dist/lib/browser/{intent-resolver-O67UANYP.mjs → intent-resolver-QVCKRX6G.mjs} +7 -7
  17. package/dist/lib/browser/intent-resolver-QVCKRX6G.mjs.map +7 -0
  18. package/dist/lib/browser/meta.json +1 -1
  19. package/dist/lib/browser/react/index.mjs +34 -0
  20. package/dist/lib/browser/{store-LFKDWHUQ.mjs → store-CNPHOYTJ.mjs} +5 -5
  21. package/dist/lib/browser/store-CNPHOYTJ.mjs.map +7 -0
  22. package/dist/lib/browser/testing/index.mjs +17 -21
  23. package/dist/lib/browser/testing/index.mjs.map +3 -3
  24. package/dist/lib/node-esm/{app-graph-builder-QHIJUYYW.mjs → app-graph-builder-EBU4NVWD.mjs} +32 -31
  25. package/dist/lib/node-esm/app-graph-builder-EBU4NVWD.mjs.map +7 -0
  26. package/dist/lib/node-esm/{chunk-NJAFK626.mjs → chunk-3UPX5OIS.mjs} +254 -184
  27. package/dist/lib/node-esm/chunk-3UPX5OIS.mjs.map +7 -0
  28. package/dist/lib/node-esm/{chunk-VSKRV3NW.mjs → chunk-XJZGUJ3H.mjs} +399 -266
  29. package/dist/lib/node-esm/chunk-XJZGUJ3H.mjs.map +7 -0
  30. package/dist/lib/node-esm/{chunk-UMZQERLE.mjs → chunk-ZX63QUGE.mjs} +11 -8
  31. package/dist/lib/node-esm/chunk-ZX63QUGE.mjs.map +7 -0
  32. package/dist/lib/node-esm/index.mjs +20 -56
  33. package/dist/lib/node-esm/index.mjs.map +3 -3
  34. package/dist/lib/node-esm/{intent-dispatcher-5PRM3KGH.mjs → intent-dispatcher-MGOJ3CHD.mjs} +2 -2
  35. package/dist/lib/node-esm/{intent-resolver-K3D4BXQQ.mjs → intent-resolver-URF3HN3G.mjs} +7 -7
  36. package/dist/lib/node-esm/intent-resolver-URF3HN3G.mjs.map +7 -0
  37. package/dist/lib/node-esm/meta.json +1 -1
  38. package/dist/lib/node-esm/react/index.mjs +35 -0
  39. package/dist/lib/node-esm/{store-53XDUBMD.mjs → store-RK5B4XEL.mjs} +5 -5
  40. package/dist/lib/node-esm/store-RK5B4XEL.mjs.map +7 -0
  41. package/dist/lib/node-esm/testing/index.mjs +17 -21
  42. package/dist/lib/node-esm/testing/index.mjs.map +3 -3
  43. package/dist/types/src/common/capabilities.d.ts +111 -38
  44. package/dist/types/src/common/capabilities.d.ts.map +1 -1
  45. package/dist/types/src/common/collaboration.d.ts +10 -9
  46. package/dist/types/src/common/collaboration.d.ts.map +1 -1
  47. package/dist/types/src/common/events.d.ts.map +1 -1
  48. package/dist/types/src/common/file.d.ts +1 -1
  49. package/dist/types/src/common/file.d.ts.map +1 -1
  50. package/dist/types/src/common/layout.d.ts +1 -3
  51. package/dist/types/src/common/layout.d.ts.map +1 -1
  52. package/dist/types/src/common/surface.d.ts +19 -16
  53. package/dist/types/src/common/surface.d.ts.map +1 -1
  54. package/dist/types/src/common/translations.d.ts +1 -1
  55. package/dist/types/src/common/translations.d.ts.map +1 -1
  56. package/dist/types/src/core/capabilities.d.ts +19 -16
  57. package/dist/types/src/core/capabilities.d.ts.map +1 -1
  58. package/dist/types/src/core/manager.d.ts +7 -3
  59. package/dist/types/src/core/manager.d.ts.map +1 -1
  60. package/dist/types/src/core/plugin.d.ts +8 -1
  61. package/dist/types/src/core/plugin.d.ts.map +1 -1
  62. package/dist/types/src/index.d.ts +0 -2
  63. package/dist/types/src/index.d.ts.map +1 -1
  64. package/dist/types/src/playground/debug/Debug.d.ts +1 -1
  65. package/dist/types/src/playground/debug/plugin.d.ts +1 -1
  66. package/dist/types/src/playground/debug/plugin.d.ts.map +1 -1
  67. package/dist/types/src/playground/generator/Main.d.ts +1 -1
  68. package/dist/types/src/playground/generator/Main.d.ts.map +1 -1
  69. package/dist/types/src/playground/generator/Toolbar.d.ts +1 -1
  70. package/dist/types/src/playground/generator/Toolbar.d.ts.map +1 -1
  71. package/dist/types/src/playground/generator/generator.d.ts +1 -1
  72. package/dist/types/src/playground/generator/generator.d.ts.map +1 -1
  73. package/dist/types/src/playground/generator/plugin.d.ts +1 -1
  74. package/dist/types/src/playground/generator/plugin.d.ts.map +1 -1
  75. package/dist/types/src/playground/layout/Layout.d.ts +2 -2
  76. package/dist/types/src/playground/layout/plugin.d.ts +1 -1
  77. package/dist/types/src/playground/layout/plugin.d.ts.map +1 -1
  78. package/dist/types/src/playground/logger/Toolbar.d.ts +1 -1
  79. package/dist/types/src/playground/logger/Toolbar.d.ts.map +1 -1
  80. package/dist/types/src/playground/logger/plugin.d.ts +1 -1
  81. package/dist/types/src/playground/logger/plugin.d.ts.map +1 -1
  82. package/dist/types/src/playground/logger/schema.d.ts +1 -1
  83. package/dist/types/src/playground/logger/schema.d.ts.map +1 -1
  84. package/dist/types/src/playground/playground.stories.d.ts +5 -4
  85. package/dist/types/src/playground/playground.stories.d.ts.map +1 -1
  86. package/dist/types/src/plugin-intent/IntentPlugin.d.ts +1 -1
  87. package/dist/types/src/plugin-intent/IntentPlugin.d.ts.map +1 -1
  88. package/dist/types/src/plugin-intent/actions.d.ts +5 -7
  89. package/dist/types/src/plugin-intent/actions.d.ts.map +1 -1
  90. package/dist/types/src/plugin-intent/errors.d.ts.map +1 -1
  91. package/dist/types/src/plugin-intent/index.d.ts +1 -0
  92. package/dist/types/src/plugin-intent/index.d.ts.map +1 -1
  93. package/dist/types/src/plugin-intent/intent-dispatcher.d.ts +7 -7
  94. package/dist/types/src/plugin-intent/intent-dispatcher.d.ts.map +1 -1
  95. package/dist/types/src/plugin-intent/intent.d.ts +1 -1
  96. package/dist/types/src/plugin-intent/intent.d.ts.map +1 -1
  97. package/dist/types/src/plugin-intent/meta.d.ts +3 -0
  98. package/dist/types/src/plugin-intent/meta.d.ts.map +1 -0
  99. package/dist/types/src/plugin-settings/SettingsPlugin.d.ts +1 -1
  100. package/dist/types/src/plugin-settings/SettingsPlugin.d.ts.map +1 -1
  101. package/dist/types/src/plugin-settings/actions.d.ts +5 -7
  102. package/dist/types/src/plugin-settings/actions.d.ts.map +1 -1
  103. package/dist/types/src/plugin-settings/app-graph-builder.d.ts +1 -1
  104. package/dist/types/src/plugin-settings/app-graph-builder.d.ts.map +1 -1
  105. package/dist/types/src/plugin-settings/intent-resolver.d.ts +1 -1
  106. package/dist/types/src/plugin-settings/intent-resolver.d.ts.map +1 -1
  107. package/dist/types/src/plugin-settings/meta.d.ts +3 -0
  108. package/dist/types/src/plugin-settings/meta.d.ts.map +1 -0
  109. package/dist/types/src/plugin-settings/store.d.ts +1 -1
  110. package/dist/types/src/plugin-settings/store.d.ts.map +1 -1
  111. package/dist/types/src/plugin-settings/translations.d.ts +2 -1
  112. package/dist/types/src/plugin-settings/translations.d.ts.map +1 -1
  113. package/dist/types/src/react/App.d.ts +10 -0
  114. package/dist/types/src/react/App.d.ts.map +1 -0
  115. package/dist/types/src/react/App.stories.d.ts +14 -0
  116. package/dist/types/src/react/App.stories.d.ts.map +1 -0
  117. package/dist/types/src/react/DefaultFallback.d.ts +8 -0
  118. package/dist/types/src/react/DefaultFallback.d.ts.map +1 -0
  119. package/dist/types/src/react/ErrorBoundary.d.ts +13 -14
  120. package/dist/types/src/react/ErrorBoundary.d.ts.map +1 -1
  121. package/dist/types/src/react/IntentContext.d.ts.map +1 -1
  122. package/dist/types/src/react/Surface.d.ts +5 -5
  123. package/dist/types/src/react/Surface.d.ts.map +1 -1
  124. package/dist/types/src/react/Surface.stories.d.ts +8 -10
  125. package/dist/types/src/react/Surface.stories.d.ts.map +1 -1
  126. package/dist/types/src/react/common.d.ts.map +1 -1
  127. package/dist/types/src/react/index.d.ts +2 -0
  128. package/dist/types/src/react/index.d.ts.map +1 -1
  129. package/dist/types/src/react/types.d.ts +14 -0
  130. package/dist/types/src/react/types.d.ts.map +1 -0
  131. package/dist/types/src/{App.d.ts → react/useApp.d.ts} +7 -6
  132. package/dist/types/src/react/useApp.d.ts.map +1 -0
  133. package/dist/types/src/react/useCapabilities.d.ts.map +1 -1
  134. package/dist/types/src/react/useLoading.d.ts +19 -0
  135. package/dist/types/src/react/useLoading.d.ts.map +1 -0
  136. package/dist/types/src/testing/withPluginManager.d.ts +9 -8
  137. package/dist/types/src/testing/withPluginManager.d.ts.map +1 -1
  138. package/dist/types/src/testing/withPluginManager.stories.d.ts +9 -3
  139. package/dist/types/src/testing/withPluginManager.stories.d.ts.map +1 -1
  140. package/dist/types/tsconfig.tsbuildinfo +1 -1
  141. package/moon.yml +5 -1
  142. package/package.json +46 -38
  143. package/src/common/capabilities.ts +120 -19
  144. package/src/common/collaboration.ts +6 -9
  145. package/src/common/events.ts +3 -1
  146. package/src/common/file.ts +1 -1
  147. package/src/common/layout.ts +3 -4
  148. package/src/common/surface.ts +23 -21
  149. package/src/common/translations.ts +1 -1
  150. package/src/core/capabilities.test.ts +3 -3
  151. package/src/core/capabilities.ts +36 -27
  152. package/src/core/manager.test.ts +22 -21
  153. package/src/core/manager.ts +141 -56
  154. package/src/core/plugin.ts +13 -2
  155. package/src/helpers.test.ts +1 -1
  156. package/src/index.ts +0 -2
  157. package/src/playground/debug/Debug.tsx +1 -1
  158. package/src/playground/debug/plugin.ts +7 -8
  159. package/src/playground/generator/Main.tsx +0 -1
  160. package/src/playground/generator/Toolbar.tsx +2 -1
  161. package/src/playground/generator/generator.ts +4 -4
  162. package/src/playground/generator/plugin.ts +12 -13
  163. package/src/playground/layout/plugin.ts +10 -9
  164. package/src/playground/logger/Toolbar.tsx +2 -1
  165. package/src/playground/logger/plugin.ts +30 -25
  166. package/src/playground/logger/schema.ts +1 -1
  167. package/src/playground/playground.stories.tsx +20 -16
  168. package/src/plugin-intent/IntentPlugin.ts +13 -13
  169. package/src/plugin-intent/actions.ts +4 -6
  170. package/src/plugin-intent/errors.ts +2 -1
  171. package/src/plugin-intent/index.ts +1 -0
  172. package/src/plugin-intent/intent-dispatcher.test.ts +10 -3
  173. package/src/plugin-intent/intent-dispatcher.ts +21 -12
  174. package/src/plugin-intent/intent.ts +1 -1
  175. package/src/plugin-intent/meta.ts +10 -0
  176. package/src/plugin-settings/SettingsPlugin.ts +27 -28
  177. package/src/plugin-settings/actions.ts +9 -13
  178. package/src/plugin-settings/app-graph-builder.ts +25 -22
  179. package/src/plugin-settings/intent-resolver.ts +5 -4
  180. package/src/plugin-settings/meta.ts +10 -0
  181. package/src/plugin-settings/store.ts +3 -3
  182. package/src/plugin-settings/translations.ts +4 -4
  183. package/src/react/App.stories.tsx +33 -0
  184. package/src/react/App.tsx +59 -0
  185. package/src/react/DefaultFallback.tsx +26 -0
  186. package/src/react/ErrorBoundary.tsx +26 -15
  187. package/src/react/IntentContext.tsx +3 -2
  188. package/src/react/Surface.stories.tsx +81 -52
  189. package/src/react/Surface.tsx +70 -38
  190. package/src/react/common.ts +2 -1
  191. package/src/react/index.ts +4 -0
  192. package/src/react/types.ts +38 -0
  193. package/src/react/useApp.tsx +165 -0
  194. package/src/react/useCapabilities.ts +4 -3
  195. package/src/react/useLoading.tsx +70 -0
  196. package/src/testing/withPluginManager.stories.tsx +9 -5
  197. package/src/testing/withPluginManager.tsx +33 -32
  198. package/tsconfig.json +15 -10
  199. package/vitest.config.ts +8 -6
  200. package/.eslintrc.cjs +0 -9
  201. package/.swc/plugins/v7_linux_x86_64_13.0.0/f45bdff002284d9e8f9ef3f0be909de12da36c049cbcf261ac78fc00abb09a2d +0 -0
  202. package/dist/lib/browser/app-graph-builder-BGGXLD6T.mjs.map +0 -7
  203. package/dist/lib/browser/chunk-2636QSIK.mjs.map +0 -7
  204. package/dist/lib/browser/chunk-DHZB7HG7.mjs.map +0 -7
  205. package/dist/lib/browser/chunk-ORWHM7CO.mjs.map +0 -7
  206. package/dist/lib/browser/intent-resolver-O67UANYP.mjs.map +0 -7
  207. package/dist/lib/browser/store-LFKDWHUQ.mjs.map +0 -7
  208. package/dist/lib/browser/worker.mjs +0 -79
  209. package/dist/lib/node-esm/app-graph-builder-QHIJUYYW.mjs.map +0 -7
  210. package/dist/lib/node-esm/chunk-NJAFK626.mjs.map +0 -7
  211. package/dist/lib/node-esm/chunk-UMZQERLE.mjs.map +0 -7
  212. package/dist/lib/node-esm/chunk-VSKRV3NW.mjs.map +0 -7
  213. package/dist/lib/node-esm/intent-resolver-K3D4BXQQ.mjs.map +0 -7
  214. package/dist/lib/node-esm/store-53XDUBMD.mjs.map +0 -7
  215. package/dist/lib/node-esm/worker.mjs +0 -80
  216. package/dist/types/src/App.d.ts.map +0 -1
  217. package/dist/types/src/worker.d.ts +0 -4
  218. package/dist/types/src/worker.d.ts.map +0 -1
  219. package/src/App.tsx +0 -276
  220. package/src/worker.ts +0 -11
  221. package/typedoc/.nojekyll +0 -1
  222. package/typedoc/assets/hierarchy.js +0 -1
  223. package/typedoc/assets/highlight.css +0 -106
  224. package/typedoc/assets/icons.js +0 -18
  225. package/typedoc/assets/icons.svg +0 -1
  226. package/typedoc/assets/main.js +0 -60
  227. package/typedoc/assets/navigation.js +0 -1
  228. package/typedoc/assets/search.js +0 -1
  229. package/typedoc/assets/style.css +0 -1640
  230. package/typedoc/classes/CollaborationActions.InsertContent.html +0 -421
  231. package/typedoc/classes/ErrorBoundary.html +0 -125
  232. package/typedoc/classes/IntentAction.ShowUndo.html +0 -227
  233. package/typedoc/classes/IntentAction.Track.html +0 -266
  234. package/typedoc/classes/LayoutAction.AddToast.html +0 -265
  235. package/typedoc/classes/LayoutAction.Close.html +0 -382
  236. package/typedoc/classes/LayoutAction.Expose.html +0 -265
  237. package/typedoc/classes/LayoutAction.Open.html +0 -1123
  238. package/typedoc/classes/LayoutAction.RevertWorkspace.html +0 -343
  239. package/typedoc/classes/LayoutAction.ScrollIntoView.html +0 -460
  240. package/typedoc/classes/LayoutAction.Set.html +0 -460
  241. package/typedoc/classes/LayoutAction.SetLayoutMode.html +0 -499
  242. package/typedoc/classes/LayoutAction.SwitchWorkspace.html +0 -265
  243. package/typedoc/classes/LayoutAction.UpdateComplementary.html +0 -616
  244. package/typedoc/classes/LayoutAction.UpdateDialog.html +0 -1123
  245. package/typedoc/classes/LayoutAction.UpdateLayout.html +0 -461
  246. package/typedoc/classes/LayoutAction.UpdatePopover.html +0 -1435
  247. package/typedoc/classes/LayoutAction.UpdateSidebar.html +0 -616
  248. package/typedoc/classes/Plugin.html +0 -6
  249. package/typedoc/classes/PluginContext.html +0 -38
  250. package/typedoc/classes/PluginManager.html +0 -43
  251. package/typedoc/classes/PluginModule.html +0 -18
  252. package/typedoc/classes/SettingsAction.Open.html +0 -226
  253. package/typedoc/classes/SettingsAction.OpenPluginRegistry.html +0 -265
  254. package/typedoc/functions/Events.createStateEvent.html +0 -2
  255. package/typedoc/functions/IntentPlugin.html +0 -1
  256. package/typedoc/functions/SettingsPlugin.html +0 -1
  257. package/typedoc/functions/allOf.html +0 -2
  258. package/typedoc/functions/chain.html +0 -3
  259. package/typedoc/functions/contributes.html +0 -2
  260. package/typedoc/functions/createDispatcher.html +0 -3
  261. package/typedoc/functions/createIntent.html +0 -6
  262. package/typedoc/functions/createResolver.html +0 -2
  263. package/typedoc/functions/createSurface.html +0 -2
  264. package/typedoc/functions/defineCapability.html +0 -2
  265. package/typedoc/functions/defineEvent.html +0 -2
  266. package/typedoc/functions/defineModule.html +0 -2
  267. package/typedoc/functions/definePlugin.html +0 -2
  268. package/typedoc/functions/eventKey.html +0 -2
  269. package/typedoc/functions/getEvents.html +0 -2
  270. package/typedoc/functions/isAllOf.html +0 -2
  271. package/typedoc/functions/isOneOf.html +0 -2
  272. package/typedoc/functions/isSurfaceAvailable.html +0 -2
  273. package/typedoc/functions/lazy.html +0 -2
  274. package/typedoc/functions/oneOf.html +0 -2
  275. package/typedoc/functions/useApp.html +0 -6
  276. package/typedoc/functions/useAppGraph.html +0 -1
  277. package/typedoc/functions/useCapabilities.html +0 -3
  278. package/typedoc/functions/useCapability.html +0 -4
  279. package/typedoc/functions/useIntentDispatcher.html +0 -1
  280. package/typedoc/functions/useIntentResolver.html +0 -1
  281. package/typedoc/functions/useLayout.html +0 -1
  282. package/typedoc/functions/usePluginManager.html +0 -2
  283. package/typedoc/hierarchy.html +0 -1
  284. package/typedoc/index.html +0 -12
  285. package/typedoc/interfaces/LayoutAction.Toast.html +0 -10
  286. package/typedoc/media/LICENSE +0 -8
  287. package/typedoc/modules/Capabilities.html +0 -1
  288. package/typedoc/modules/CollaborationActions.html +0 -1
  289. package/typedoc/modules/Events.html +0 -1
  290. package/typedoc/modules/IntentAction.html +0 -1
  291. package/typedoc/modules/LayoutAction.html +0 -2
  292. package/typedoc/modules/SettingsAction.html +0 -1
  293. package/typedoc/modules.html +0 -1
  294. package/typedoc/types/ActivationEvent.html +0 -8
  295. package/typedoc/types/ActivationEvents.html +0 -2
  296. package/typedoc/types/AnyCapability.html +0 -1
  297. package/typedoc/types/AnyIntent.html +0 -1
  298. package/typedoc/types/AnyIntentChain.html +0 -1
  299. package/typedoc/types/AnyIntentEffectResult.html +0 -1
  300. package/typedoc/types/AnyIntentResolver.html +0 -1
  301. package/typedoc/types/AnyIntentResult.html +0 -1
  302. package/typedoc/types/Capabilities.FileUploader.html +0 -1
  303. package/typedoc/types/Capabilities.IntentResolver.html +0 -1
  304. package/typedoc/types/Capabilities.Layout.html +0 -1
  305. package/typedoc/types/Capabilities.Metadata.html +0 -1
  306. package/typedoc/types/Capabilities.ReactContext.html +0 -1
  307. package/typedoc/types/Capabilities.ReactRoot.html +0 -1
  308. package/typedoc/types/Capabilities.ReactSurface.html +0 -1
  309. package/typedoc/types/Capabilities.Settings.html +0 -4
  310. package/typedoc/types/Capability.html +0 -9
  311. package/typedoc/types/CreateAppOptions.html +0 -10
  312. package/typedoc/types/FileInfo.html +0 -1
  313. package/typedoc/types/Intent.html +0 -10
  314. package/typedoc/types/IntentChain.html +0 -6
  315. package/typedoc/types/IntentContext.html +0 -5
  316. package/typedoc/types/IntentData.html +0 -1
  317. package/typedoc/types/IntentDispatcher.html +0 -2
  318. package/typedoc/types/IntentDispatcherResult.html +0 -2
  319. package/typedoc/types/IntentEffectDefinition.html +0 -2
  320. package/typedoc/types/IntentEffectResult.html +0 -15
  321. package/typedoc/types/IntentParams.html +0 -3
  322. package/typedoc/types/IntentResolver.html +0 -2
  323. package/typedoc/types/IntentResultData.html +0 -1
  324. package/typedoc/types/IntentSchema.html +0 -1
  325. package/typedoc/types/IntentUndo.html +0 -2
  326. package/typedoc/types/InterfaceDef.html +0 -4
  327. package/typedoc/types/Label.html +0 -1
  328. package/typedoc/types/NodeSerializer.html +0 -8
  329. package/typedoc/types/PluginManagerOptions.html +0 -6
  330. package/typedoc/types/PluginMeta.html +0 -21
  331. package/typedoc/types/PromiseIntentDispatcher.html +0 -2
  332. package/typedoc/types/PromiseIntentUndo.html +0 -2
  333. package/typedoc/types/Resource.html +0 -1
  334. package/typedoc/types/ResourceKey.html +0 -1
  335. package/typedoc/types/ResourceLanguage.html +0 -1
  336. package/typedoc/types/SerializedNode.html +0 -4
  337. package/typedoc/types/SurfaceComponent.html +0 -2
  338. package/typedoc/types/SurfaceDefinition.html +0 -2
  339. package/typedoc/types/SurfaceProps.html +0 -4
  340. package/typedoc/variables/Capabilities.AnchorSort.html +0 -1
  341. package/typedoc/variables/Capabilities.AppGraph.html +0 -1
  342. package/typedoc/variables/Capabilities.AppGraphBuilder.html +0 -1
  343. package/typedoc/variables/Capabilities.AppGraphSerializer.html +0 -1
  344. package/typedoc/variables/Capabilities.ArtifactDefinition.html +0 -1
  345. package/typedoc/variables/Capabilities.FileUploader.html +0 -1
  346. package/typedoc/variables/Capabilities.IntentDispatcher.html +0 -1
  347. package/typedoc/variables/Capabilities.IntentResolver.html +0 -1
  348. package/typedoc/variables/Capabilities.Layout.html +0 -1
  349. package/typedoc/variables/Capabilities.Metadata.html +0 -1
  350. package/typedoc/variables/Capabilities.Null.html +0 -1
  351. package/typedoc/variables/Capabilities.PluginManager.html +0 -1
  352. package/typedoc/variables/Capabilities.ReactContext.html +0 -1
  353. package/typedoc/variables/Capabilities.ReactRoot.html +0 -1
  354. package/typedoc/variables/Capabilities.ReactSurface.html +0 -1
  355. package/typedoc/variables/Capabilities.RxRegistry.html +0 -1
  356. package/typedoc/variables/Capabilities.Settings.html +0 -1
  357. package/typedoc/variables/Capabilities.SettingsStore.html +0 -1
  358. package/typedoc/variables/Capabilities.Tools.html +0 -1
  359. package/typedoc/variables/Capabilities.Translations.html +0 -1
  360. package/typedoc/variables/Events.AppGraphReady.html +0 -2
  361. package/typedoc/variables/Events.DispatcherReady.html +0 -2
  362. package/typedoc/variables/Events.LayoutReady.html +0 -1
  363. package/typedoc/variables/Events.SettingsReady.html +0 -2
  364. package/typedoc/variables/Events.SetupAppGraph.html +0 -2
  365. package/typedoc/variables/Events.SetupArtifactDefinition.html +0 -2
  366. package/typedoc/variables/Events.SetupIntentResolver.html +0 -2
  367. package/typedoc/variables/Events.SetupMetadata.html +0 -2
  368. package/typedoc/variables/Events.SetupReactSurface.html +0 -2
  369. package/typedoc/variables/Events.SetupSettings.html +0 -2
  370. package/typedoc/variables/Events.SetupTranslations.html +0 -2
  371. package/typedoc/variables/Events.Startup.html +0 -2
  372. package/typedoc/variables/FileInfoSchema.html +0 -1
  373. package/typedoc/variables/INTENT_ACTION.html +0 -1
  374. package/typedoc/variables/INTENT_PLUGIN.html +0 -1
  375. package/typedoc/variables/LAYOUT_ACTION.html +0 -1
  376. package/typedoc/variables/LAYOUT_PLUGIN.html +0 -1
  377. package/typedoc/variables/Label.html +0 -1
  378. package/typedoc/variables/LayoutAction.Toast.html +0 -1
  379. package/typedoc/variables/LayoutAction.UPDATE_LAYOUT.html +0 -1
  380. package/typedoc/variables/PluginManagerProvider.html +0 -2
  381. package/typedoc/variables/Resource.html +0 -2
  382. package/typedoc/variables/ResourceKey.html +0 -1
  383. package/typedoc/variables/ResourceLanguage.html +0 -1
  384. package/typedoc/variables/SETTINGS_ACTION.html +0 -1
  385. package/typedoc/variables/SETTINGS_ID.html +0 -1
  386. package/typedoc/variables/SETTINGS_KEY.html +0 -1
  387. package/typedoc/variables/SETTINGS_PLUGIN.html +0 -1
  388. package/typedoc/variables/Surface.html +0 -2
  389. package/typedoc/variables/defaultFileTypes.html +0 -1
  390. /package/dist/lib/browser/{intent-dispatcher-TWKB22NI.mjs.map → intent-dispatcher-LZ4AE66E.mjs.map} +0 -0
  391. /package/dist/lib/browser/{worker.mjs.map → react/index.mjs.map} +0 -0
  392. /package/dist/lib/node-esm/{intent-dispatcher-5PRM3KGH.mjs.map → intent-dispatcher-MGOJ3CHD.mjs.map} +0 -0
  393. /package/dist/lib/node-esm/{worker.mjs.map → react/index.mjs.map} +0 -0
@@ -2,8 +2,8 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { type Registry, Rx } from '@effect-rx/rx-react';
6
- import { Effect } from 'effect';
5
+ import { Atom, type Registry } from '@effect-atom/atom-react';
6
+ import * as Effect from 'effect/Effect';
7
7
 
8
8
  import { Trigger } from '@dxos/async';
9
9
  import { invariant } from '@dxos/invariant';
@@ -22,6 +22,10 @@ export type InterfaceDef<T> = {
22
22
  identifier: string;
23
23
  };
24
24
 
25
+ export namespace InterfaceDef {
26
+ export type Implementation<I extends InterfaceDef<any>> = I extends InterfaceDef<infer T> ? T : never;
27
+ }
28
+
25
29
  /**
26
30
  * Helper to define the interface of a capability.
27
31
  */
@@ -37,17 +41,17 @@ export type Capability<T> = {
37
41
  /**
38
42
  * The interface definition of the capability.
39
43
  */
40
- interface: InterfaceDef<T>;
44
+ readonly interface: InterfaceDef<T>;
41
45
 
42
46
  /**
43
47
  * The implementation of the capability.
44
48
  */
45
- implementation: T;
49
+ readonly implementation: T;
46
50
 
47
51
  /**
48
52
  * Called when the capability is deactivated.
49
53
  */
50
- deactivate?: () => MaybePromise<void> | Effect.Effect<void, Error>;
54
+ readonly deactivate?: () => MaybePromise<void> | Effect.Effect<void, Error>;
51
55
  };
52
56
 
53
57
  export type AnyCapability = Capability<any>;
@@ -69,16 +73,21 @@ class CapabilityImpl<T> {
69
73
  /**
70
74
  * Helper to define the implementation of a capability.
71
75
  */
72
- export const contributes = <T>(
73
- interfaceDef: Capability<T>['interface'],
74
- implementation: Capability<T>['implementation'],
75
- deactivate?: Capability<T>['deactivate'],
76
- ): Capability<T> => {
77
- return { interface: interfaceDef, implementation, deactivate } satisfies Capability<T>;
76
+ export const contributes = <I extends InterfaceDef<any>>(
77
+ interfaceDef: I,
78
+ implementation: Capability<InterfaceDef.Implementation<I>>['implementation'],
79
+ deactivate?: Capability<InterfaceDef.Implementation<I>>['deactivate'],
80
+ ): Capability<I> => {
81
+ return {
82
+ interface: interfaceDef,
83
+ implementation,
84
+ deactivate,
85
+ } satisfies Capability<I>;
78
86
  };
79
87
 
80
88
  type LoadCapability<T, U> = () => Promise<{ default: (props: T) => MaybePromise<Capability<U>> }>;
81
89
  type LoadCapabilities<T> = () => Promise<{ default: (props: T) => MaybePromise<AnyCapability[]> }>;
90
+
82
91
  // TODO(wittjosiah): Not having the array be `any` causes type errors when using the lazy capability.
83
92
  type LazyCapability<T, U> = (props?: T) => Promise<() => Promise<Capability<U> | AnyCapability[]>>;
84
93
 
@@ -100,19 +109,19 @@ export const lazy =
100
109
  export class PluginContext {
101
110
  private readonly _registry: Registry.Registry;
102
111
 
103
- private readonly _capabilityImpls = Rx.family<string, Rx.Writable<CapabilityImpl<unknown>[]>>(() => {
104
- return Rx.make<CapabilityImpl<unknown>[]>([]).pipe(Rx.keepAlive);
112
+ private readonly _capabilityImpls = Atom.family<string, Atom.Writable<CapabilityImpl<unknown>[]>>(() => {
113
+ return Atom.make<CapabilityImpl<unknown>[]>([]).pipe(Atom.keepAlive);
105
114
  });
106
115
 
107
- readonly _capabilities = Rx.family<string, Rx.Rx<unknown[]>>((id: string) => {
108
- return Rx.make((get) => {
116
+ readonly _capabilities = Atom.family<string, Atom.Atom<unknown[]>>((id: string) => {
117
+ return Atom.make((get) => {
109
118
  const current = get(this._capabilityImpls(id));
110
119
  return current.map((c) => c.implementation);
111
120
  });
112
121
  });
113
122
 
114
- readonly _capability = Rx.family<string, Rx.Rx<unknown>>((id: string) => {
115
- return Rx.make((get) => {
123
+ readonly _capability = Atom.family<string, Atom.Atom<unknown>>((id: string) => {
124
+ return Atom.make((get) => {
116
125
  const current = get(this._capabilities(id));
117
126
  invariant(current.length > 0, `No capability found for ${id}`);
118
127
  return current[0];
@@ -184,26 +193,26 @@ export class PluginContext {
184
193
  }
185
194
 
186
195
  /**
187
- * Get the Rx reference to the available capabilities for a given interface.
188
- * Primarily useful for deriving other Rx values based on the capabilities or
196
+ * Get the Atom reference to the available capabilities for a given interface.
197
+ * Primarily useful for deriving other Atom values based on the capabilities or
189
198
  * for subscribing to changes in the capabilities.
190
- * @returns An Rx reference to the available capabilities.
199
+ * @returns An atom reference to the available capabilities.
191
200
  */
192
- capabilities<T>(interfaceDef: InterfaceDef<T>): Rx.Rx<T[]> {
201
+ capabilities<T>(interfaceDef: InterfaceDef<T>): Atom.Atom<T[]> {
193
202
  // NOTE: This the type-checking for capabilities is done at the time of contribution.
194
- return this._capabilities(interfaceDef.identifier) as Rx.Rx<T[]>;
203
+ return this._capabilities(interfaceDef.identifier) as Atom.Atom<T[]>;
195
204
  }
196
205
 
197
206
  /**
198
- * Get the Rx reference to the available capabilities for a given interface.
199
- * Primarily useful for deriving other Rx values based on the capability or
207
+ * Get the Atom reference to the available capabilities for a given interface.
208
+ * Primarily useful for deriving other Atom values based on the capability or
200
209
  * for subscribing to changes in the capability.
201
- * @returns An Rx reference to the available capability.
210
+ * @returns An atom reference to the available capability.
202
211
  * @throws If no capability is found.
203
212
  */
204
- capability<T>(interfaceDef: InterfaceDef<T>): Rx.Rx<T> {
213
+ capability<T>(interfaceDef: InterfaceDef<T>): Atom.Atom<T> {
205
214
  // NOTE: This the type-checking for capabilities is done at the time of contribution.
206
- return this._capability(interfaceDef.identifier) as Rx.Rx<T>;
215
+ return this._capability(interfaceDef.identifier) as Atom.Atom<T>;
207
216
  }
208
217
 
209
218
  /**
@@ -7,16 +7,17 @@ import { afterEach, describe, expect, it } from 'vitest';
7
7
 
8
8
  import { Trigger } from '@dxos/async';
9
9
  import { raise } from '@dxos/debug';
10
- import { updateCounter } from '@dxos/echo-schema/testing';
10
+ import { updateCounter } from '@dxos/echo/testing';
11
11
  import { registerSignalsRuntime } from '@dxos/echo-signals';
12
12
  import { invariant } from '@dxos/invariant';
13
13
  import { live } from '@dxos/live-object';
14
14
 
15
- import { contributes, defineCapability, type PluginContext } from './capabilities';
15
+ import { Events } from '../common';
16
+
17
+ import { type PluginContext, contributes, defineCapability } from './capabilities';
16
18
  import { allOf, defineEvent, oneOf } from './events';
17
19
  import { PluginManager } from './manager';
18
- import { definePlugin, defineModule, type Plugin } from './plugin';
19
- import { Events } from '../common';
20
+ import { Plugin, defineModule } from './plugin';
20
21
 
21
22
  registerSignalsRuntime();
22
23
 
@@ -42,7 +43,7 @@ describe('PluginManager', () => {
42
43
  });
43
44
 
44
45
  it('should be able to add and remove plugins', async () => {
45
- const Test = definePlugin(testMeta, []);
46
+ const Test = new Plugin(testMeta, []);
46
47
  plugins = [Test];
47
48
 
48
49
  const manager = new PluginManager({ pluginLoader });
@@ -58,7 +59,7 @@ describe('PluginManager', () => {
58
59
  activatesOn: Events.Startup,
59
60
  activate: () => contributes(String, { string: 'hello' }),
60
61
  });
61
- const Test = definePlugin(testMeta, [Hello]);
62
+ const Test = new Plugin(testMeta, [Hello]);
62
63
 
63
64
  const manager = new PluginManager({ plugins: [Test], core: [], pluginLoader });
64
65
  await manager.enable(testMeta.id);
@@ -75,7 +76,7 @@ describe('PluginManager', () => {
75
76
  activatesOn: Events.Startup,
76
77
  activate: () => contributes(String, { string: 'hello' }),
77
78
  });
78
- const Test = definePlugin(testMeta, [Hello]);
79
+ const Test = new Plugin(testMeta, [Hello]);
79
80
 
80
81
  const manager = new PluginManager({ plugins: [Test], enabled: [Test.meta.id], pluginLoader });
81
82
  expect(manager.plugins).toEqual([Test]);
@@ -94,7 +95,7 @@ describe('PluginManager', () => {
94
95
  activatesOn: FailEvent,
95
96
  activate: async () => raise(new Error('test')),
96
97
  });
97
- plugins = [definePlugin(testMeta, [Fail])];
98
+ plugins = [new Plugin(testMeta, [Fail])];
98
99
 
99
100
  const manager = new PluginManager({ pluginLoader });
100
101
  await manager.add(testMeta.id);
@@ -113,7 +114,7 @@ describe('PluginManager', () => {
113
114
  // TODO(wittjosiah): Test and catch more failure modes.
114
115
  activate: async () => async () => raise(new Error('test')),
115
116
  });
116
- plugins = [definePlugin(testMeta, [Hello, Fail])];
117
+ plugins = [new Plugin(testMeta, [Hello, Fail])];
117
118
 
118
119
  const manager = new PluginManager({ pluginLoader });
119
120
  const activating = new Trigger<boolean>();
@@ -148,7 +149,7 @@ describe('PluginManager', () => {
148
149
  return contributes(String, { string: 'hello' });
149
150
  },
150
151
  });
151
- plugins = [definePlugin(testMeta, [Hello])];
152
+ plugins = [new Plugin(testMeta, [Hello])];
152
153
 
153
154
  const manager = new PluginManager({ pluginLoader });
154
155
 
@@ -179,21 +180,21 @@ describe('PluginManager', () => {
179
180
  });
180
181
 
181
182
  it('should be able to fire custom activation events', async () => {
182
- const Plugin1 = definePlugin({ id: 'dxos.org/test/plugin-1', name: 'Plugin 1' }, [
183
+ const Plugin1 = new Plugin({ id: 'dxos.org/test/plugin-1', name: 'Plugin 1' }, [
183
184
  defineModule({
184
185
  id: 'dxos.org/test/plugin-1',
185
186
  activatesOn: CountEvent,
186
187
  activate: () => [contributes(Number, { number: 1 })],
187
188
  }),
188
189
  ]);
189
- const Plugin2 = definePlugin({ id: 'dxos.org/test/plugin-2', name: 'Plugin 2' }, [
190
+ const Plugin2 = new Plugin({ id: 'dxos.org/test/plugin-2', name: 'Plugin 2' }, [
190
191
  defineModule({
191
192
  id: 'dxos.org/test/plugin-2',
192
193
  activatesOn: CountEvent,
193
194
  activate: () => [contributes(Number, { number: 2 })],
194
195
  }),
195
196
  ]);
196
- const Plugin3 = definePlugin({ id: 'dxos.org/test/plugin-3', name: 'Plugin 3' }, [
197
+ const Plugin3 = new Plugin({ id: 'dxos.org/test/plugin-3', name: 'Plugin 3' }, [
197
198
  defineModule({
198
199
  id: 'dxos.org/test/plugin-3',
199
200
  activatesOn: CountEvent,
@@ -230,7 +231,7 @@ describe('PluginManager', () => {
230
231
  return contributes(String, { string: 'hello' });
231
232
  },
232
233
  });
233
- plugins = [definePlugin(testMeta, [Hello])];
234
+ plugins = [new Plugin(testMeta, [Hello])];
234
235
 
235
236
  const manager = new PluginManager({ pluginLoader });
236
237
  expect(manager.active).toEqual([]);
@@ -256,7 +257,7 @@ describe('PluginManager', () => {
256
257
  return contributes(String, { string: 'hello' });
257
258
  },
258
259
  });
259
- plugins = [definePlugin(testMeta, [Hello])];
260
+ plugins = [new Plugin(testMeta, [Hello])];
260
261
 
261
262
  const manager = new PluginManager({ pluginLoader });
262
263
  expect(manager.active).toEqual([]);
@@ -282,7 +283,7 @@ describe('PluginManager', () => {
282
283
  state.total = numbers.reduce((acc, n) => acc + n.number, 0);
283
284
  };
284
285
 
285
- const Count = definePlugin({ id: 'dxos.org/test/count', name: 'Count' }, [
286
+ const Count = new Plugin({ id: 'dxos.org/test/count', name: 'Count' }, [
286
287
  defineModule({
287
288
  id: 'dxos.org/test/count',
288
289
  activatesOn: Events.Startup,
@@ -294,7 +295,7 @@ describe('PluginManager', () => {
294
295
  }),
295
296
  ]);
296
297
 
297
- const Test = definePlugin(testMeta, [
298
+ const Test = new Plugin(testMeta, [
298
299
  defineModule({
299
300
  id: 'dxos.org/test/plugin-1',
300
301
  activatesOn: CountEvent,
@@ -352,7 +353,7 @@ describe('PluginManager', () => {
352
353
  const id = 'dxos.org/test/counter';
353
354
  const stateEvent = Events.createStateEvent(id);
354
355
 
355
- const Test = definePlugin(testMeta, [
356
+ const Test = new Plugin(testMeta, [
356
357
  defineModule({
357
358
  id,
358
359
  activatesOn: Events.Startup,
@@ -389,21 +390,21 @@ describe('PluginManager', () => {
389
390
  });
390
391
 
391
392
  it('should be reactive', async () => {
392
- const Plugin1 = definePlugin({ id: 'dxos.org/test/plugin-1', name: 'Plugin 1' }, [
393
+ const Plugin1 = new Plugin({ id: 'dxos.org/test/plugin-1', name: 'Plugin 1' }, [
393
394
  defineModule({
394
395
  id: 'dxos.org/test/plugin-1',
395
396
  activatesOn: CountEvent,
396
397
  activate: () => [contributes(Number, { number: 1 })],
397
398
  }),
398
399
  ]);
399
- const Plugin2 = definePlugin({ id: 'dxos.org/test/plugin-2', name: 'Plugin 2' }, [
400
+ const Plugin2 = new Plugin({ id: 'dxos.org/test/plugin-2', name: 'Plugin 2' }, [
400
401
  defineModule({
401
402
  id: 'dxos.org/test/plugin-2',
402
403
  activatesOn: CountEvent,
403
404
  activate: () => [contributes(Number, { number: 2 })],
404
405
  }),
405
406
  ]);
406
- const Plugin3 = definePlugin({ id: 'dxos.org/test/plugin-3', name: 'Plugin 3' }, [
407
+ const Plugin3 = new Plugin({ id: 'dxos.org/test/plugin-3', name: 'Plugin 3' }, [
407
408
  defineModule({
408
409
  id: 'dxos.org/test/plugin-3',
409
410
  activatesOn: CountEvent,
@@ -2,18 +2,25 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { Registry } from '@effect-rx/rx-react';
5
+ import { Registry } from '@effect-atom/atom-react';
6
6
  import { untracked } from '@preact/signals-core';
7
- import { Array as A, Effect, Either, Match, pipe } from 'effect';
7
+ import * as Array from 'effect/Array';
8
+ import * as Duration from 'effect/Duration';
9
+ import * as Effect from 'effect/Effect';
10
+ import * as Fiber from 'effect/Fiber';
11
+ import * as Function from 'effect/Function';
12
+ import * as HashSet from 'effect/HashSet';
13
+ import * as Match from 'effect/Match';
14
+ import * as Ref from 'effect/Ref';
8
15
 
9
16
  import { Event } from '@dxos/async';
10
- import { live, type Live } from '@dxos/live-object';
17
+ import { type Live, live } from '@dxos/live-object';
11
18
  import { log } from '@dxos/log';
12
19
  import { type MaybePromise } from '@dxos/util';
13
20
 
14
21
  import { type AnyCapability, PluginContext } from './capabilities';
15
22
  import { type ActivationEvent, eventKey, getEvents, isAllOf } from './events';
16
- import { type PluginModule, type Plugin } from './plugin';
23
+ import { type Plugin, type PluginModule } from './plugin';
17
24
 
18
25
  // TODO(wittjosiah): Factor out?
19
26
  const isPromise = (value: unknown): value is Promise<unknown> => {
@@ -48,10 +55,13 @@ export class PluginManager {
48
55
  readonly context: PluginContext;
49
56
  readonly registry: Registry.Registry;
50
57
 
51
- // TODO(wittjosiah): Replace with Rx.
58
+ // TODO(wittjosiah): Replace with Atom.
52
59
  private readonly _state: Live<PluginManagerState>;
53
60
  private readonly _pluginLoader: PluginManagerOptions['pluginLoader'];
54
61
  private readonly _capabilities = new Map<string, AnyCapability[]>();
62
+ private readonly _moduleMemoMap = new Map<PluginModule['id'], Promise<AnyCapability[]>>();
63
+ private readonly _activatingEvents = Effect.runSync(Ref.make<string[]>([]));
64
+ private readonly _activatingModules = Effect.runSync(Ref.make<string[]>([]));
55
65
 
56
66
  constructor({
57
67
  pluginLoader,
@@ -74,8 +84,8 @@ export class PluginManager {
74
84
  enabled,
75
85
  modules: [],
76
86
  active: [],
77
- pendingReset: [],
78
87
  eventsFired: [],
88
+ pendingReset: [],
79
89
  });
80
90
  plugins.forEach((plugin) => this._addPlugin(plugin));
81
91
  core.forEach((id) => this.enable(id));
@@ -268,6 +278,7 @@ export class PluginManager {
268
278
  private _addPlugin(plugin: Plugin): void {
269
279
  untracked(() => {
270
280
  log('add plugin', { id: plugin.meta.id });
281
+ // TODO(wittjosiah): Find a way to add a warning for duplicate plugins that doesn't cause log spam.
271
282
  if (!this._state.plugins.includes(plugin)) {
272
283
  this._state.plugins.push(plugin);
273
284
  }
@@ -287,6 +298,7 @@ export class PluginManager {
287
298
  private _addModule(module: PluginModule): void {
288
299
  untracked(() => {
289
300
  log('add module', { id: module.id });
301
+ // TODO(wittjosiah): Find a way to add a warning for duplicate modules that doesn't cause log spam.
290
302
  if (!this._state.modules.includes(module)) {
291
303
  this._state.modules.push(module);
292
304
  }
@@ -329,7 +341,7 @@ export class PluginManager {
329
341
  .map(eventKey)
330
342
  .filter((key) => this._state.eventsFired.includes(key));
331
343
 
332
- const pendingReset = Array.from(new Set(activationEvents)).filter(
344
+ const pendingReset = Array.fromIterable(new Set(activationEvents)).filter(
333
345
  (event) => !this._state.pendingReset.includes(event),
334
346
  );
335
347
  if (pendingReset.length > 0) {
@@ -343,24 +355,42 @@ export class PluginManager {
343
355
  * @internal
344
356
  */
345
357
  // TODO(wittjosiah): Improve error typing.
346
- _activate(event: ActivationEvent | string): Effect.Effect<boolean, Error> {
358
+ _activate(
359
+ event: ActivationEvent | string,
360
+ params?: { before?: string; after?: string },
361
+ ): Effect.Effect<boolean, Error> {
347
362
  return Effect.gen(this, function* () {
348
363
  const key = typeof event === 'string' ? event : eventKey(event);
349
- log('activating', { key });
364
+ log('activating', { key, ...params });
365
+ yield* Ref.update(this._activatingEvents, (activating) => Array.append(activating, key));
350
366
  const pendingIndex = this._state.pendingReset.findIndex((event) => event === key);
351
367
  if (pendingIndex !== -1) {
352
368
  this._state.pendingReset.splice(pendingIndex, 1);
353
369
  }
354
370
 
371
+ const activatingEvents = yield* this._activatingEvents;
372
+ const activatingModules = yield* this._activatingModules;
355
373
  const modules = this._getInactiveModulesByEvent(key).filter((module) => {
356
374
  const allOf = isAllOf(module.activatesOn);
357
375
  if (!allOf) {
358
376
  return true;
359
377
  }
360
378
 
379
+ // Check to see if all of the events in the `allOf` have been fired.
380
+ // An event can be considered "fired" if it is in the `eventsFired` list or if it is currently being activated.
361
381
  const events = module.activatesOn.events.filter((event) => eventKey(event) !== key);
362
- return events.every((event) => this._state.eventsFired.includes(eventKey(event)));
382
+ return (
383
+ events.every(
384
+ (event) => this._state.eventsFired.includes(eventKey(event)) || activatingEvents.includes(eventKey(event)),
385
+ ) && !activatingModules.includes(module.id)
386
+ );
363
387
  });
388
+ yield* Ref.update(this._activatingModules, (activating) =>
389
+ Array.appendAll(
390
+ activating,
391
+ modules.map((module) => module.id),
392
+ ),
393
+ );
364
394
  if (modules.length === 0) {
365
395
  log('no modules to activate', { key });
366
396
  if (!this._state.eventsFired.includes(key)) {
@@ -372,31 +402,53 @@ export class PluginManager {
372
402
  log('activating modules', { key, modules: modules.map((module) => module.id) });
373
403
  this.activation.emit({ event: key, state: 'activating' });
374
404
 
405
+ // Fire activatesBefore events.
406
+ yield* Function.pipe(
407
+ modules,
408
+ Array.flatMap((module) => module.activatesBefore ?? []),
409
+ HashSet.fromIterable,
410
+ HashSet.toValues,
411
+ Array.filter((event) => !activatingEvents.includes(eventKey(event))),
412
+ Array.map((event) => this._activate(event, { before: key })),
413
+ Effect.allWith({ concurrency: 'unbounded' }),
414
+ );
415
+
375
416
  // Concurrently triggers loading of lazy capabilities.
376
- const getCapabilities = yield* Effect.all(
377
- modules.map(({ activate }) =>
378
- Effect.tryPromise({
379
- try: async () => activate(this.context),
380
- catch: (error) => error as Error,
381
- }),
382
- ),
383
- { concurrency: 'unbounded' },
417
+ const getCapabilities = yield* Function.pipe(
418
+ modules,
419
+ Array.map((mod) => this._loadModule(mod)),
420
+ Effect.allWith({ concurrency: 'unbounded' }),
421
+ Effect.catchAll((error) => {
422
+ this.activation.emit({ event: key, state: 'error', error });
423
+ return Effect.fail(error);
424
+ }),
384
425
  );
385
426
 
386
- const result = yield* pipe(
427
+ // Contribute the capabilities from the activated modules.
428
+ yield* Function.pipe(
387
429
  modules,
388
- A.zip(getCapabilities),
389
- A.map(([module, getCapabilities]) => this._activateModule(module, getCapabilities)),
430
+ Array.zip(getCapabilities),
431
+ Array.map(([module, capabilities]) => this._contributeCapabilities(module, capabilities)),
390
432
  // TODO(wittjosiah): This currently can't be run in parallel.
391
433
  // Running this with concurrency causes races with `allOf` activation events.
392
434
  Effect.all,
393
- Effect.either,
394
435
  );
395
436
 
396
- if (Either.isLeft(result)) {
397
- this.activation.emit({ event: key, state: 'error', error: result.left });
398
- yield* Effect.fail(result.left);
399
- }
437
+ // Fire activatesAfter events.
438
+ yield* Function.pipe(
439
+ modules,
440
+ Array.flatMap((module) => module.activatesAfter ?? []),
441
+ HashSet.fromIterable,
442
+ HashSet.toValues,
443
+ Array.filter((event) => !activatingEvents.includes(eventKey(event))),
444
+ Array.map((event) => this._activate(event, { after: key })),
445
+ Effect.allWith({ concurrency: 'unbounded' }),
446
+ );
447
+
448
+ yield* Ref.update(this._activatingEvents, (activating) => Array.filter(activating, (event) => event !== key));
449
+ yield* Ref.update(this._activatingModules, (activating) =>
450
+ Array.filter(activating, (module) => !modules.map((module) => module.id).includes(module)),
451
+ );
400
452
 
401
453
  if (!this._state.eventsFired.includes(key)) {
402
454
  this._state.eventsFired.push(key);
@@ -409,43 +461,60 @@ export class PluginManager {
409
461
  });
410
462
  }
411
463
 
412
- private _activateModule(
413
- module: PluginModule,
414
- getCapabilities: AnyCapability | AnyCapability[] | (() => Promise<AnyCapability | AnyCapability[]>),
415
- ): Effect.Effect<void, Error> {
416
- return Effect.gen(this, function* () {
417
- yield* Effect.all(module.activatesBefore?.map((event) => this._activate(event)) ?? [], {
418
- concurrency: 'unbounded',
419
- });
464
+ // Memoized with _moduleMemoMap
465
+ private _loadModule = (mod: PluginModule): Effect.Effect<AnyCapability[], Error> =>
466
+ Effect.tryPromise({
467
+ try: async () => {
468
+ const entry = this._moduleMemoMap.get(mod.id);
469
+ if (entry) {
470
+ return entry;
471
+ }
420
472
 
421
- log('activating module...', { module: module.id });
422
- // TODO(wittjosiah): This is not handling errors thrown if this is synchronous.
423
- const maybeCapabilities = typeof getCapabilities === 'function' ? getCapabilities() : getCapabilities;
424
- const resolvedCapabilities = yield* Match.value(maybeCapabilities).pipe(
425
- // TODO(wittjosiah): Activate with an effect?
426
- // Match.when(Effect.isEffect, (effect) => effect),
427
- Match.when(isPromise, (promise) =>
428
- Effect.tryPromise({
429
- try: () => promise,
430
- catch: (error) => error as Error,
431
- }),
473
+ const promise = (async () => {
474
+ const start = performance.now();
475
+ let failed = false;
476
+ try {
477
+ log('loading module', { module: mod.id });
478
+ // TODO(wittjosiah): Support activation with an effect.
479
+ let activationResult = await mod.activate(this.context);
480
+ if (typeof activationResult === 'function') {
481
+ activationResult = await activationResult();
482
+ }
483
+ return Array.isArray(activationResult) ? activationResult : [activationResult];
484
+ } catch (error) {
485
+ failed = true;
486
+ throw error;
487
+ } finally {
488
+ performance.measure('activate-module', {
489
+ start,
490
+ end: performance.now(),
491
+ detail: {
492
+ module: mod.id,
493
+ },
494
+ });
495
+ log('loaded module', { module: mod.id, elapsed: performance.now() - start, failed });
496
+ }
497
+ })();
498
+ this._moduleMemoMap.set(mod.id, promise);
499
+ return promise;
500
+ },
501
+ catch: (error) => error as Error,
502
+ }).pipe(
503
+ Effect.withSpan('PluginManager._loadModule'),
504
+ together(
505
+ Effect.sleep(Duration.seconds(10)).pipe(
506
+ Effect.andThen(Effect.sync(() => log.warn(`module is taking a long time to activate`, { module: mod.id }))),
432
507
  ),
433
- Match.orElse((program) => Effect.succeed(program)),
434
- );
435
- const capabilities = Match.value(resolvedCapabilities).pipe(
436
- Match.when(Array.isArray, (array) => array),
437
- Match.orElse((value) => [value]),
438
- );
508
+ ),
509
+ );
510
+
511
+ private _contributeCapabilities(module: PluginModule, capabilities: AnyCapability[]): Effect.Effect<void, Error> {
512
+ return Effect.gen(this, function* () {
439
513
  capabilities.forEach((capability) => {
440
514
  this.context.contributeCapability({ module: module.id, ...capability });
441
515
  });
442
516
  this._state.active.push(module.id);
443
517
  this._capabilities.set(module.id, capabilities);
444
- log('activated module', { module: module.id });
445
-
446
- yield* Effect.all(module.activatesAfter?.map((event) => this._activate(event)) ?? [], {
447
- concurrency: 'unbounded',
448
- });
449
518
  });
450
519
  }
451
520
 
@@ -469,6 +538,7 @@ export class PluginManager {
469
538
  return Effect.gen(this, function* () {
470
539
  const id = module.id;
471
540
  log('deactivating', { id });
541
+ this._moduleMemoMap.delete(id);
472
542
 
473
543
  const capabilities = this._capabilities.get(id);
474
544
  if (capabilities) {
@@ -517,3 +587,18 @@ export class PluginManager {
517
587
  });
518
588
  }
519
589
  }
590
+
591
+ /**
592
+ * Runs an effect concurrently with another effect.
593
+ * If the first effect completes, the second effect is interrupted.
594
+ */
595
+ // TODO(dmaretskyi): Effect.race > Effect.asVoid
596
+ const together =
597
+ <R1>(togetherEffect: Effect.Effect<void, never, R1>) =>
598
+ <A, E, R2>(effect: Effect.Effect<A, E, R2>): Effect.Effect<A, E, R1 | R2> =>
599
+ Effect.gen(function* () {
600
+ const togetherFiber = yield* Effect.fork(togetherEffect);
601
+ const result = yield* effect;
602
+ yield* Fiber.interrupt(togetherFiber);
603
+ return result;
604
+ });
@@ -110,6 +110,11 @@ export type PluginMeta = {
110
110
  * A grep-able symbol string which can be resolved to an icon asset by @ch-ui/icons, via @ch-ui/vite-plugin-icons.
111
111
  */
112
112
  icon?: string;
113
+
114
+ /**
115
+ * Icon hue (ChromaticPalette).
116
+ */
117
+ iconHue?: string;
113
118
  };
114
119
 
115
120
  /**
@@ -124,9 +129,15 @@ export class Plugin {
124
129
  ) {}
125
130
  }
126
131
 
132
+ export type PluginFactory<T = void> = ((args: T) => Plugin) & { meta: PluginMeta };
133
+
127
134
  /**
128
135
  * Helper to define a plugin.
129
136
  */
130
- export const definePlugin = (meta: PluginMeta, modules: PluginModule[]) => {
131
- return new Plugin(meta, modules);
137
+ export const definePlugin = <T = void>(meta: PluginMeta, provider: (args: T) => PluginModule[]): PluginFactory<T> => {
138
+ const factory = (args: T) => {
139
+ return new Plugin(meta, provider(args));
140
+ };
141
+
142
+ return Object.assign(factory, { meta });
132
143
  };
@@ -2,7 +2,7 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { describe, it, expect } from 'vitest';
5
+ import { describe, expect, it } from 'vitest';
6
6
 
7
7
  import { topologicalSort } from './helpers';
8
8
 
package/src/index.ts CHANGED
@@ -2,9 +2,7 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- export * from './App';
6
5
  export * from './common';
7
6
  export * from './core';
8
7
  export * from './plugin-intent';
9
8
  export * from './plugin-settings';
10
- export * from './react';