@dxos/app-framework 0.8.4-main.937b3ca → 0.8.4-main.9be5663bfe

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 (430) hide show
  1. package/.storybook/main.mts +1 -3
  2. package/dist/lib/browser/{capability-7PCNSWBT.mjs → capability-BBBBAPDI.mjs} +16 -11
  3. package/dist/lib/browser/capability-BBBBAPDI.mjs.map +7 -0
  4. package/dist/lib/browser/capability-OP63CD5N.mjs +35 -0
  5. package/dist/lib/browser/capability-OP63CD5N.mjs.map +7 -0
  6. package/dist/lib/browser/{chunk-6Y7PZV72.mjs → chunk-2CKCJ6PN.mjs} +6 -4
  7. package/dist/lib/browser/chunk-2CKCJ6PN.mjs.map +7 -0
  8. package/dist/lib/browser/{chunk-7IQHKD4U.mjs → chunk-F7FW2RK2.mjs} +9 -12
  9. package/dist/lib/browser/chunk-F7FW2RK2.mjs.map +7 -0
  10. package/dist/lib/browser/{chunk-TCLLRCS3.mjs → chunk-FU4GAFUQ.mjs} +10 -7
  11. package/dist/lib/browser/chunk-FU4GAFUQ.mjs.map +7 -0
  12. package/dist/lib/browser/{chunk-FMZN33N4.mjs → chunk-GX4TUNM6.mjs} +343 -187
  13. package/dist/lib/browser/chunk-GX4TUNM6.mjs.map +7 -0
  14. package/dist/lib/browser/chunk-I34GF4NG.mjs +34 -0
  15. package/dist/lib/browser/chunk-I34GF4NG.mjs.map +7 -0
  16. package/dist/lib/browser/chunk-JKWMHZP6.mjs +80 -0
  17. package/dist/lib/browser/chunk-JKWMHZP6.mjs.map +7 -0
  18. package/dist/lib/browser/chunk-LVJW5EFU.mjs +157 -0
  19. package/dist/lib/browser/chunk-LVJW5EFU.mjs.map +7 -0
  20. package/dist/lib/browser/{chunk-PKQT6C53.mjs → chunk-QSXYHXCE.mjs} +3 -2
  21. package/dist/lib/browser/chunk-QSXYHXCE.mjs.map +7 -0
  22. package/dist/lib/browser/chunk-RFSO3JRG.mjs +1 -0
  23. package/dist/lib/browser/chunk-T3Y4AEKX.mjs +42 -0
  24. package/dist/lib/browser/chunk-T3Y4AEKX.mjs.map +7 -0
  25. package/dist/lib/browser/chunk-TGX63LTL.mjs +8 -0
  26. package/dist/lib/browser/{chunk-FHQTHCX7.mjs.map → chunk-TGX63LTL.mjs.map} +1 -1
  27. package/dist/lib/browser/chunk-WPE6AL7I.mjs +905 -0
  28. package/dist/lib/browser/chunk-WPE6AL7I.mjs.map +7 -0
  29. package/dist/lib/browser/cli/index.mjs +90 -0
  30. package/dist/lib/browser/cli/index.mjs.map +7 -0
  31. package/dist/lib/browser/common/activation-events.mjs +24 -0
  32. package/dist/lib/browser/common/capabilities.mjs +46 -0
  33. package/dist/lib/browser/core/activation-event.mjs +1 -1
  34. package/dist/lib/browser/core/capability.mjs +3 -1
  35. package/dist/lib/browser/core/plugin-manager.mjs +4 -4
  36. package/dist/lib/browser/core/plugin.mjs +6 -4
  37. package/dist/lib/browser/core/url-loader.mjs +12 -0
  38. package/dist/lib/browser/index.mjs +40 -131
  39. package/dist/lib/browser/index.mjs.map +4 -4
  40. package/dist/lib/browser/invoker-capability-H5PPENOC.mjs +43 -0
  41. package/dist/lib/browser/invoker-capability-H5PPENOC.mjs.map +7 -0
  42. package/dist/lib/browser/meta.json +1 -1
  43. package/dist/lib/browser/testing/index.mjs +56 -34
  44. package/dist/lib/browser/testing/index.mjs.map +3 -3
  45. package/dist/lib/browser/{react → ui}/index.mjs +19 -21
  46. package/dist/lib/browser/ui/index.mjs.map +7 -0
  47. package/dist/lib/node-esm/{capability-CFLQ2QQU.mjs → capability-AWBEMRYR.mjs} +16 -11
  48. package/dist/lib/node-esm/capability-AWBEMRYR.mjs.map +7 -0
  49. package/dist/lib/node-esm/capability-WFEG6CIZ.mjs +36 -0
  50. package/dist/lib/node-esm/capability-WFEG6CIZ.mjs.map +7 -0
  51. package/dist/lib/node-esm/{chunk-STMXUEPO.mjs → chunk-42KBWDE4.mjs} +6 -4
  52. package/dist/lib/node-esm/chunk-42KBWDE4.mjs.map +7 -0
  53. package/dist/lib/node-esm/chunk-4A3ZCMI3.mjs +158 -0
  54. package/dist/lib/node-esm/chunk-4A3ZCMI3.mjs.map +7 -0
  55. package/dist/lib/node-esm/{chunk-XYQTBFPA.mjs → chunk-BCEOLX47.mjs} +343 -187
  56. package/dist/lib/node-esm/chunk-BCEOLX47.mjs.map +7 -0
  57. package/dist/lib/node-esm/chunk-EL3R25OQ.mjs +2 -0
  58. package/dist/lib/node-esm/chunk-EL3R25OQ.mjs.map +7 -0
  59. package/dist/lib/node-esm/{chunk-UEWJDI2L.mjs → chunk-FKE4Z3D6.mjs} +2 -2
  60. package/dist/lib/node-esm/{chunk-UEWJDI2L.mjs.map → chunk-FKE4Z3D6.mjs.map} +1 -1
  61. package/dist/lib/node-esm/chunk-G3RTFSNG.mjs +81 -0
  62. package/dist/lib/node-esm/chunk-G3RTFSNG.mjs.map +7 -0
  63. package/dist/lib/node-esm/chunk-LQKOTNJW.mjs +906 -0
  64. package/dist/lib/node-esm/chunk-LQKOTNJW.mjs.map +7 -0
  65. package/dist/lib/node-esm/{chunk-GT6OKM5I.mjs → chunk-ULUEXB7Q.mjs} +10 -7
  66. package/dist/lib/node-esm/chunk-ULUEXB7Q.mjs.map +7 -0
  67. package/dist/lib/node-esm/{chunk-663A54LQ.mjs → chunk-URWHJQT2.mjs} +9 -12
  68. package/dist/lib/node-esm/chunk-URWHJQT2.mjs.map +7 -0
  69. package/dist/lib/node-esm/chunk-VKHGNEDB.mjs +43 -0
  70. package/dist/lib/node-esm/chunk-VKHGNEDB.mjs.map +7 -0
  71. package/dist/lib/node-esm/chunk-WZCSOX5Q.mjs +35 -0
  72. package/dist/lib/node-esm/chunk-WZCSOX5Q.mjs.map +7 -0
  73. package/dist/lib/node-esm/{chunk-7OWSHPYK.mjs → chunk-ZZ7CKK6W.mjs} +3 -2
  74. package/dist/lib/node-esm/chunk-ZZ7CKK6W.mjs.map +7 -0
  75. package/dist/lib/node-esm/cli/index.mjs +91 -0
  76. package/dist/lib/node-esm/cli/index.mjs.map +7 -0
  77. package/dist/lib/node-esm/common/activation-events.mjs +25 -0
  78. package/dist/lib/node-esm/common/activation-events.mjs.map +7 -0
  79. package/dist/lib/node-esm/common/capabilities.mjs +47 -0
  80. package/dist/lib/node-esm/common/capabilities.mjs.map +7 -0
  81. package/dist/lib/node-esm/core/activation-event.mjs +1 -1
  82. package/dist/lib/node-esm/core/capability.mjs +3 -1
  83. package/dist/lib/node-esm/core/plugin-manager.mjs +4 -4
  84. package/dist/lib/node-esm/core/plugin.mjs +6 -4
  85. package/dist/lib/node-esm/core/url-loader.mjs +13 -0
  86. package/dist/lib/node-esm/core/url-loader.mjs.map +7 -0
  87. package/dist/lib/node-esm/index.mjs +40 -131
  88. package/dist/lib/node-esm/index.mjs.map +4 -4
  89. package/dist/lib/node-esm/invoker-capability-S3ZA527J.mjs +44 -0
  90. package/dist/lib/node-esm/invoker-capability-S3ZA527J.mjs.map +7 -0
  91. package/dist/lib/node-esm/meta.json +1 -1
  92. package/dist/lib/node-esm/testing/index.mjs +56 -34
  93. package/dist/lib/node-esm/testing/index.mjs.map +3 -3
  94. package/dist/lib/node-esm/{react → ui}/index.mjs +19 -21
  95. package/dist/lib/node-esm/ui/index.mjs.map +7 -0
  96. package/dist/plugin/node-esm/index.mjs +384 -0
  97. package/dist/plugin/node-esm/index.mjs.map +7 -0
  98. package/dist/plugin/node-esm/meta.json +1 -0
  99. package/dist/types/src/{cli.d.ts → cli/cli.d.ts} +2 -2
  100. package/dist/types/src/cli/cli.d.ts.map +1 -0
  101. package/dist/types/src/cli/index.d.ts +2 -0
  102. package/dist/types/src/cli/index.d.ts.map +1 -0
  103. package/dist/types/src/common/activation-events.d.ts +27 -0
  104. package/dist/types/src/common/activation-events.d.ts.map +1 -0
  105. package/dist/types/src/common/capabilities.d.ts +110 -0
  106. package/dist/types/src/common/capabilities.d.ts.map +1 -0
  107. package/dist/types/src/common/index.d.ts +4 -9
  108. package/dist/types/src/common/index.d.ts.map +1 -1
  109. package/dist/types/src/common/operations.d.ts +8 -369
  110. package/dist/types/src/common/operations.d.ts.map +1 -1
  111. package/dist/types/src/common/translations.d.ts +0 -9
  112. package/dist/types/src/common/translations.d.ts.map +1 -1
  113. package/dist/types/src/core/activation-event.d.ts +1 -1
  114. package/dist/types/src/core/activation-event.d.ts.map +1 -1
  115. package/dist/types/src/core/capability-manager.d.ts +5 -0
  116. package/dist/types/src/core/capability-manager.d.ts.map +1 -1
  117. package/dist/types/src/core/capability.d.ts +13 -7
  118. package/dist/types/src/core/capability.d.ts.map +1 -1
  119. package/dist/types/src/core/index.d.ts +1 -0
  120. package/dist/types/src/core/index.d.ts.map +1 -1
  121. package/dist/types/src/core/plugin-manager.d.ts +9 -2
  122. package/dist/types/src/core/plugin-manager.d.ts.map +1 -1
  123. package/dist/types/src/core/plugin.d.ts +6 -1
  124. package/dist/types/src/core/plugin.d.ts.map +1 -1
  125. package/dist/types/src/core/url-loader.d.ts +25 -0
  126. package/dist/types/src/core/url-loader.d.ts.map +1 -0
  127. package/dist/types/src/core/url-loader.test.d.ts +2 -0
  128. package/dist/types/src/core/url-loader.test.d.ts.map +1 -0
  129. package/dist/types/src/index.d.ts +1 -3
  130. package/dist/types/src/index.d.ts.map +1 -1
  131. package/dist/types/src/plugin-operation/OperationPlugin.d.ts.map +1 -1
  132. package/dist/types/src/plugin-operation/history/capability.d.ts +1 -1
  133. package/dist/types/src/plugin-operation/history/capability.d.ts.map +1 -1
  134. package/dist/types/src/plugin-operation/history/errors.d.ts +30 -3
  135. package/dist/types/src/plugin-operation/history/errors.d.ts.map +1 -1
  136. package/dist/types/src/plugin-operation/history/history-tracker.d.ts.map +1 -1
  137. package/dist/types/src/plugin-operation/history/undo-mapping.d.ts +11 -3
  138. package/dist/types/src/plugin-operation/history/undo-mapping.d.ts.map +1 -1
  139. package/dist/types/src/plugin-operation/invoker-capability.d.ts +1 -1
  140. package/dist/types/src/plugin-operation/invoker-capability.d.ts.map +1 -1
  141. package/dist/types/src/plugin-operation/testing.d.ts +26 -77
  142. package/dist/types/src/plugin-operation/testing.d.ts.map +1 -1
  143. package/dist/types/src/plugin-runtime/RuntimePlugin.d.ts.map +1 -1
  144. package/dist/types/src/plugin-runtime/capability.d.ts +2 -2
  145. package/dist/types/src/plugin-runtime/capability.d.ts.map +1 -1
  146. package/dist/types/src/testing/withPluginManager.d.ts +1 -1
  147. package/dist/types/src/testing/withPluginManager.d.ts.map +1 -1
  148. package/dist/types/src/testing/withPluginManager.stories.d.ts.map +1 -1
  149. package/dist/types/src/{react → ui/components/App}/App.d.ts +3 -2
  150. package/dist/types/src/ui/components/App/App.d.ts.map +1 -0
  151. package/dist/types/src/{react/Surface.stories.d.ts → ui/components/App/App.stories.d.ts} +7 -2
  152. package/dist/types/src/ui/components/App/App.stories.d.ts.map +1 -0
  153. package/dist/types/src/ui/components/App/index.d.ts +2 -0
  154. package/dist/types/src/ui/components/App/index.d.ts.map +1 -0
  155. package/dist/types/src/ui/components/PluginManager/PluginManagerContext.stories.d.ts.map +1 -0
  156. package/dist/types/src/{react → ui/components/PluginManager}/PluginManagerProvider.d.ts +1 -1
  157. package/dist/types/src/ui/components/PluginManager/PluginManagerProvider.d.ts.map +1 -0
  158. package/dist/types/src/ui/components/PluginManager/index.d.ts +2 -0
  159. package/dist/types/src/ui/components/PluginManager/index.d.ts.map +1 -0
  160. package/dist/types/src/ui/components/Surface/SurfaceComponent.d.ts +12 -0
  161. package/dist/types/src/ui/components/Surface/SurfaceComponent.d.ts.map +1 -0
  162. package/dist/types/src/{react/App.stories.d.ts → ui/components/Surface/SurfaceComponent.stories.d.ts} +1 -1
  163. package/dist/types/src/ui/components/Surface/SurfaceComponent.stories.d.ts.map +1 -0
  164. package/dist/types/src/ui/components/Surface/SurfaceInfo.d.ts.map +1 -0
  165. package/dist/types/src/ui/components/Surface/SurfaceProfilerContext.d.ts +48 -0
  166. package/dist/types/src/ui/components/Surface/SurfaceProfilerContext.d.ts.map +1 -0
  167. package/dist/types/src/ui/components/Surface/context.d.ts +5 -0
  168. package/dist/types/src/ui/components/Surface/context.d.ts.map +1 -0
  169. package/dist/types/src/ui/components/Surface/index.d.ts +26 -0
  170. package/dist/types/src/ui/components/Surface/index.d.ts.map +1 -0
  171. package/dist/types/src/{common/surface.d.ts → ui/components/Surface/types.d.ts} +20 -18
  172. package/dist/types/src/ui/components/Surface/types.d.ts.map +1 -0
  173. package/dist/types/src/ui/components/index.d.ts +4 -0
  174. package/dist/types/src/ui/components/index.d.ts.map +1 -0
  175. package/dist/types/src/ui/hooks/index.d.ts +6 -0
  176. package/dist/types/src/ui/hooks/index.d.ts.map +1 -0
  177. package/dist/types/src/{react → ui/hooks}/useApp.d.ts +26 -9
  178. package/dist/types/src/ui/hooks/useApp.d.ts.map +1 -0
  179. package/dist/types/src/ui/hooks/useApp.test.d.ts +2 -0
  180. package/dist/types/src/ui/hooks/useApp.test.d.ts.map +1 -0
  181. package/dist/types/src/{react → ui/hooks}/useCapabilities.d.ts +6 -1
  182. package/dist/types/src/ui/hooks/useCapabilities.d.ts.map +1 -0
  183. package/dist/types/src/ui/hooks/useLoading.d.ts.map +1 -0
  184. package/dist/types/src/{react/common.d.ts → ui/hooks/useSettingsState.d.ts} +1 -5
  185. package/dist/types/src/ui/hooks/useSettingsState.d.ts.map +1 -0
  186. package/dist/types/src/ui/hooks/useSurface.d.ts +3 -0
  187. package/dist/types/src/ui/hooks/useSurface.d.ts.map +1 -0
  188. package/dist/types/src/ui/index.d.ts +3 -0
  189. package/dist/types/src/ui/index.d.ts.map +1 -0
  190. package/dist/types/src/vite-plugin/composer-plugin.d.ts +18 -0
  191. package/dist/types/src/vite-plugin/composer-plugin.d.ts.map +1 -0
  192. package/dist/types/src/vite-plugin/import-map-plugin.d.ts +16 -0
  193. package/dist/types/src/vite-plugin/import-map-plugin.d.ts.map +1 -0
  194. package/dist/types/src/vite-plugin/index.d.ts +3 -0
  195. package/dist/types/src/vite-plugin/index.d.ts.map +1 -0
  196. package/dist/types/src/vite-plugin/packages.d.ts +7 -0
  197. package/dist/types/src/vite-plugin/packages.d.ts.map +1 -0
  198. package/dist/types/tsconfig.tsbuildinfo +1 -1
  199. package/moon.yml +20 -6
  200. package/package.json +91 -64
  201. package/src/{cli.ts → cli/cli.ts} +10 -10
  202. package/src/{playground/debug → cli}/index.ts +1 -1
  203. package/src/common/activation-events.ts +44 -0
  204. package/src/common/capabilities.ts +172 -0
  205. package/src/common/index.ts +4 -9
  206. package/src/common/operations.ts +6 -383
  207. package/src/common/translations.ts +0 -12
  208. package/src/context.ts +1 -1
  209. package/src/core/activation-event.ts +5 -2
  210. package/src/core/capability-manager.test.ts +1 -1
  211. package/src/core/capability-manager.ts +22 -1
  212. package/src/core/capability.ts +21 -10
  213. package/src/core/index.ts +1 -0
  214. package/src/core/plugin-manager.test.ts +314 -46
  215. package/src/core/plugin-manager.ts +344 -157
  216. package/src/core/plugin.ts +10 -2
  217. package/src/core/url-loader.test.ts +79 -0
  218. package/src/core/url-loader.ts +148 -0
  219. package/src/index.ts +1 -3
  220. package/src/plugin-operation/OperationPlugin.ts +5 -6
  221. package/src/plugin-operation/history/capability.ts +5 -6
  222. package/src/plugin-operation/history/errors.ts +2 -6
  223. package/src/plugin-operation/history/history-tracker.test.ts +36 -43
  224. package/src/plugin-operation/history/history-tracker.ts +0 -1
  225. package/src/plugin-operation/history/undo-mapping.ts +6 -3
  226. package/src/plugin-operation/history/undo-registry.test.ts +3 -4
  227. package/src/plugin-operation/invoker-capability.ts +21 -7
  228. package/src/plugin-operation/meta.ts +1 -1
  229. package/src/plugin-operation/testing.ts +25 -45
  230. package/src/plugin-runtime/RuntimePlugin.ts +4 -5
  231. package/src/plugin-runtime/capability.ts +5 -5
  232. package/src/plugin-runtime/meta.ts +1 -1
  233. package/src/testing/service.ts +6 -6
  234. package/src/testing/withPluginManager.stories.tsx +6 -7
  235. package/src/testing/withPluginManager.tsx +44 -19
  236. package/src/ui/components/App/App.stories.tsx +92 -0
  237. package/src/{react → ui/components/App}/App.tsx +9 -11
  238. package/src/{playground/layout → ui/components/App}/index.ts +1 -1
  239. package/src/{react → ui/components/PluginManager}/PluginManagerContext.stories.tsx +13 -14
  240. package/src/{react → ui/components/PluginManager}/PluginManagerProvider.ts +1 -1
  241. package/src/ui/components/PluginManager/index.ts +5 -0
  242. package/src/{react/Surface.stories.tsx → ui/components/Surface/SurfaceComponent.stories.tsx} +31 -28
  243. package/src/{react/Surface.tsx → ui/components/Surface/SurfaceComponent.tsx} +59 -60
  244. package/src/{react → ui/components/Surface}/SurfaceInfo.tsx +2 -2
  245. package/src/ui/components/Surface/SurfaceProfilerContext.tsx +207 -0
  246. package/src/ui/components/Surface/context.ts +12 -0
  247. package/src/ui/components/Surface/index.ts +35 -0
  248. package/src/{common/surface.ts → ui/components/Surface/types.ts} +22 -25
  249. package/src/ui/components/index.ts +7 -0
  250. package/src/ui/hooks/index.ts +9 -0
  251. package/src/ui/hooks/useApp.test.tsx +159 -0
  252. package/src/{react → ui/hooks}/useApp.tsx +110 -30
  253. package/src/{react → ui/hooks}/useCapabilities.ts +9 -5
  254. package/src/{react/common.ts → ui/hooks/useSettingsState.ts} +0 -11
  255. package/src/ui/hooks/useSurface.ts +13 -0
  256. package/src/ui/index.ts +6 -0
  257. package/src/vite-plugin/composer-plugin.ts +128 -0
  258. package/src/vite-plugin/import-map-plugin.ts +314 -0
  259. package/src/vite-plugin/index.ts +6 -0
  260. package/src/vite-plugin/packages.ts +29 -0
  261. package/tsconfig.json +4 -28
  262. package/tsconfig.node.json +2 -4
  263. package/typedoc.json +2 -4
  264. package/vitest.config.ts +1 -1
  265. package/dist/lib/browser/app-graph-builder-M2VPYQC6.mjs +0 -149
  266. package/dist/lib/browser/app-graph-builder-M2VPYQC6.mjs.map +0 -7
  267. package/dist/lib/browser/capability-7PCNSWBT.mjs.map +0 -7
  268. package/dist/lib/browser/capability-KP3PFEXD.mjs +0 -31
  269. package/dist/lib/browser/capability-KP3PFEXD.mjs.map +0 -7
  270. package/dist/lib/browser/chunk-6Y7PZV72.mjs.map +0 -7
  271. package/dist/lib/browser/chunk-7IQHKD4U.mjs.map +0 -7
  272. package/dist/lib/browser/chunk-BLQJSGL3.mjs +0 -732
  273. package/dist/lib/browser/chunk-BLQJSGL3.mjs.map +0 -7
  274. package/dist/lib/browser/chunk-FHQTHCX7.mjs +0 -8
  275. package/dist/lib/browser/chunk-FMZN33N4.mjs.map +0 -7
  276. package/dist/lib/browser/chunk-H4WPA7U7.mjs +0 -77
  277. package/dist/lib/browser/chunk-H4WPA7U7.mjs.map +0 -7
  278. package/dist/lib/browser/chunk-PKQT6C53.mjs.map +0 -7
  279. package/dist/lib/browser/chunk-TCLLRCS3.mjs.map +0 -7
  280. package/dist/lib/browser/chunk-XYNO72GQ.mjs +0 -746
  281. package/dist/lib/browser/chunk-XYNO72GQ.mjs.map +0 -7
  282. package/dist/lib/browser/common/index.mjs +0 -38
  283. package/dist/lib/browser/invoker-capability-SZRSTHEH.mjs +0 -32
  284. package/dist/lib/browser/invoker-capability-SZRSTHEH.mjs.map +0 -7
  285. package/dist/lib/browser/operation-resolver-6MP2MYOY.mjs +0 -64
  286. package/dist/lib/browser/operation-resolver-6MP2MYOY.mjs.map +0 -7
  287. package/dist/lib/node-esm/app-graph-builder-LROHGJEM.mjs +0 -150
  288. package/dist/lib/node-esm/app-graph-builder-LROHGJEM.mjs.map +0 -7
  289. package/dist/lib/node-esm/capability-CFLQ2QQU.mjs.map +0 -7
  290. package/dist/lib/node-esm/capability-RCUNM2M7.mjs +0 -32
  291. package/dist/lib/node-esm/capability-RCUNM2M7.mjs.map +0 -7
  292. package/dist/lib/node-esm/chunk-663A54LQ.mjs.map +0 -7
  293. package/dist/lib/node-esm/chunk-6WXBT3EC.mjs +0 -747
  294. package/dist/lib/node-esm/chunk-6WXBT3EC.mjs.map +0 -7
  295. package/dist/lib/node-esm/chunk-7OWSHPYK.mjs.map +0 -7
  296. package/dist/lib/node-esm/chunk-GQEBIGKD.mjs +0 -733
  297. package/dist/lib/node-esm/chunk-GQEBIGKD.mjs.map +0 -7
  298. package/dist/lib/node-esm/chunk-GT6OKM5I.mjs.map +0 -7
  299. package/dist/lib/node-esm/chunk-STMXUEPO.mjs.map +0 -7
  300. package/dist/lib/node-esm/chunk-XR6NMKEP.mjs +0 -78
  301. package/dist/lib/node-esm/chunk-XR6NMKEP.mjs.map +0 -7
  302. package/dist/lib/node-esm/chunk-XYQTBFPA.mjs.map +0 -7
  303. package/dist/lib/node-esm/common/index.mjs +0 -39
  304. package/dist/lib/node-esm/invoker-capability-PNMA5JOS.mjs +0 -33
  305. package/dist/lib/node-esm/invoker-capability-PNMA5JOS.mjs.map +0 -7
  306. package/dist/lib/node-esm/operation-resolver-7YWDMTNU.mjs +0 -65
  307. package/dist/lib/node-esm/operation-resolver-7YWDMTNU.mjs.map +0 -7
  308. package/dist/types/src/cli.d.ts.map +0 -1
  309. package/dist/types/src/common/activation-event.d.ts +0 -66
  310. package/dist/types/src/common/activation-event.d.ts.map +0 -1
  311. package/dist/types/src/common/capability.d.ts +0 -265
  312. package/dist/types/src/common/capability.d.ts.map +0 -1
  313. package/dist/types/src/common/collaboration.d.ts +0 -26
  314. package/dist/types/src/common/collaboration.d.ts.map +0 -1
  315. package/dist/types/src/common/file.d.ts +0 -14
  316. package/dist/types/src/common/file.d.ts.map +0 -1
  317. package/dist/types/src/common/graph.d.ts +0 -21
  318. package/dist/types/src/common/graph.d.ts.map +0 -1
  319. package/dist/types/src/common/plugin.d.ts +0 -201
  320. package/dist/types/src/common/plugin.d.ts.map +0 -1
  321. package/dist/types/src/common/surface.d.ts.map +0 -1
  322. package/dist/types/src/playground/debug/Debug.d.ts +0 -8
  323. package/dist/types/src/playground/debug/Debug.d.ts.map +0 -1
  324. package/dist/types/src/playground/debug/index.d.ts +0 -2
  325. package/dist/types/src/playground/debug/index.d.ts.map +0 -1
  326. package/dist/types/src/playground/debug/plugin.d.ts +0 -3
  327. package/dist/types/src/playground/debug/plugin.d.ts.map +0 -1
  328. package/dist/types/src/playground/generator/Main.d.ts +0 -8
  329. package/dist/types/src/playground/generator/Main.d.ts.map +0 -1
  330. package/dist/types/src/playground/generator/Toolbar.d.ts +0 -8
  331. package/dist/types/src/playground/generator/Toolbar.d.ts.map +0 -1
  332. package/dist/types/src/playground/generator/generator.d.ts +0 -19
  333. package/dist/types/src/playground/generator/generator.d.ts.map +0 -1
  334. package/dist/types/src/playground/generator/index.d.ts +0 -3
  335. package/dist/types/src/playground/generator/index.d.ts.map +0 -1
  336. package/dist/types/src/playground/generator/plugin.d.ts +0 -3
  337. package/dist/types/src/playground/generator/plugin.d.ts.map +0 -1
  338. package/dist/types/src/playground/layout/Layout.d.ts +0 -10
  339. package/dist/types/src/playground/layout/Layout.d.ts.map +0 -1
  340. package/dist/types/src/playground/layout/index.d.ts +0 -2
  341. package/dist/types/src/playground/layout/index.d.ts.map +0 -1
  342. package/dist/types/src/playground/layout/plugin.d.ts +0 -3
  343. package/dist/types/src/playground/layout/plugin.d.ts.map +0 -1
  344. package/dist/types/src/playground/logger/Toolbar.d.ts +0 -8
  345. package/dist/types/src/playground/logger/Toolbar.d.ts.map +0 -1
  346. package/dist/types/src/playground/logger/index.d.ts +0 -2
  347. package/dist/types/src/playground/logger/index.d.ts.map +0 -1
  348. package/dist/types/src/playground/logger/plugin.d.ts +0 -3
  349. package/dist/types/src/playground/logger/plugin.d.ts.map +0 -1
  350. package/dist/types/src/playground/logger/schema.d.ts +0 -27
  351. package/dist/types/src/playground/logger/schema.d.ts.map +0 -1
  352. package/dist/types/src/playground/playground.stories.d.ts +0 -11
  353. package/dist/types/src/playground/playground.stories.d.ts.map +0 -1
  354. package/dist/types/src/plugin-settings/SettingsPlugin.d.ts +0 -3
  355. package/dist/types/src/plugin-settings/SettingsPlugin.d.ts.map +0 -1
  356. package/dist/types/src/plugin-settings/actions.d.ts +0 -61
  357. package/dist/types/src/plugin-settings/actions.d.ts.map +0 -1
  358. package/dist/types/src/plugin-settings/app-graph-builder.d.ts +0 -6
  359. package/dist/types/src/plugin-settings/app-graph-builder.d.ts.map +0 -1
  360. package/dist/types/src/plugin-settings/index.d.ts +0 -3
  361. package/dist/types/src/plugin-settings/index.d.ts.map +0 -1
  362. package/dist/types/src/plugin-settings/meta.d.ts +0 -3
  363. package/dist/types/src/plugin-settings/meta.d.ts.map +0 -1
  364. package/dist/types/src/plugin-settings/operation-resolver.d.ts +0 -6
  365. package/dist/types/src/plugin-settings/operation-resolver.d.ts.map +0 -1
  366. package/dist/types/src/plugin-settings/translations.d.ts +0 -11
  367. package/dist/types/src/plugin-settings/translations.d.ts.map +0 -1
  368. package/dist/types/src/react/App.d.ts.map +0 -1
  369. package/dist/types/src/react/App.stories.d.ts.map +0 -1
  370. package/dist/types/src/react/DefaultFallback.d.ts +0 -8
  371. package/dist/types/src/react/DefaultFallback.d.ts.map +0 -1
  372. package/dist/types/src/react/ErrorBoundary.d.ts +0 -30
  373. package/dist/types/src/react/ErrorBoundary.d.ts.map +0 -1
  374. package/dist/types/src/react/PluginManagerContext.stories.d.ts.map +0 -1
  375. package/dist/types/src/react/PluginManagerProvider.d.ts.map +0 -1
  376. package/dist/types/src/react/Surface.d.ts +0 -14
  377. package/dist/types/src/react/Surface.d.ts.map +0 -1
  378. package/dist/types/src/react/Surface.stories.d.ts.map +0 -1
  379. package/dist/types/src/react/SurfaceInfo.d.ts.map +0 -1
  380. package/dist/types/src/react/common.d.ts.map +0 -1
  381. package/dist/types/src/react/index.d.ts +0 -9
  382. package/dist/types/src/react/index.d.ts.map +0 -1
  383. package/dist/types/src/react/types.d.ts +0 -12
  384. package/dist/types/src/react/types.d.ts.map +0 -1
  385. package/dist/types/src/react/useApp.d.ts.map +0 -1
  386. package/dist/types/src/react/useCapabilities.d.ts.map +0 -1
  387. package/dist/types/src/react/useLoading.d.ts.map +0 -1
  388. package/dist/types/src/react/useOperationResolver.d.ts +0 -19
  389. package/dist/types/src/react/useOperationResolver.d.ts.map +0 -1
  390. package/src/common/activation-event.ts +0 -99
  391. package/src/common/capability.ts +0 -343
  392. package/src/common/collaboration.ts +0 -31
  393. package/src/common/file.ts +0 -22
  394. package/src/common/graph.ts +0 -30
  395. package/src/common/plugin.ts +0 -364
  396. package/src/playground/debug/Debug.tsx +0 -49
  397. package/src/playground/debug/plugin.ts +0 -16
  398. package/src/playground/generator/Main.tsx +0 -80
  399. package/src/playground/generator/Toolbar.tsx +0 -57
  400. package/src/playground/generator/generator.ts +0 -48
  401. package/src/playground/generator/index.ts +0 -6
  402. package/src/playground/generator/plugin.ts +0 -21
  403. package/src/playground/layout/Layout.tsx +0 -37
  404. package/src/playground/layout/plugin.ts +0 -18
  405. package/src/playground/logger/Toolbar.tsx +0 -33
  406. package/src/playground/logger/index.ts +0 -5
  407. package/src/playground/logger/plugin.ts +0 -42
  408. package/src/playground/logger/schema.ts +0 -22
  409. package/src/playground/playground.stories.tsx +0 -54
  410. package/src/plugin-settings/SettingsPlugin.ts +0 -19
  411. package/src/plugin-settings/actions.ts +0 -64
  412. package/src/plugin-settings/app-graph-builder.ts +0 -140
  413. package/src/plugin-settings/index.ts +0 -6
  414. package/src/plugin-settings/meta.ts +0 -10
  415. package/src/plugin-settings/operation-resolver.ts +0 -55
  416. package/src/plugin-settings/translations.ts +0 -19
  417. package/src/react/App.stories.tsx +0 -63
  418. package/src/react/DefaultFallback.tsx +0 -26
  419. package/src/react/ErrorBoundary.tsx +0 -56
  420. package/src/react/index.ts +0 -14
  421. package/src/react/types.ts +0 -27
  422. package/src/react/useOperationResolver.ts +0 -40
  423. /package/dist/lib/{node-esm/react/index.mjs.map → browser/chunk-RFSO3JRG.mjs.map} +0 -0
  424. /package/dist/lib/{node-esm/common/index.mjs.map → browser/common/activation-events.mjs.map} +0 -0
  425. /package/dist/lib/browser/{react/index.mjs.map → common/capabilities.mjs.map} +0 -0
  426. /package/dist/lib/browser/{common/index.mjs.map → core/url-loader.mjs.map} +0 -0
  427. /package/dist/types/src/{react → ui/components/PluginManager}/PluginManagerContext.stories.d.ts +0 -0
  428. /package/dist/types/src/{react → ui/components/Surface}/SurfaceInfo.d.ts +0 -0
  429. /package/dist/types/src/{react → ui/hooks}/useLoading.d.ts +0 -0
  430. /package/src/{react → ui/hooks}/useLoading.tsx +0 -0
@@ -0,0 +1,79 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import { assert, describe, it } from '@effect/vitest';
6
+ import * as Effect from 'effect/Effect';
7
+
8
+ import * as Plugin from './plugin';
9
+ import * as UrlLoader from './url-loader';
10
+
11
+ const testMeta = { id: 'org.dxos.plugin.test', name: 'Test' };
12
+
13
+ describe('UrlLoader', () => {
14
+ describe('make', () => {
15
+ it.effect('resolves built-in plugins by meta.id', () =>
16
+ Effect.gen(function* () {
17
+ const testPlugin = Plugin.make(Plugin.define(testMeta))();
18
+ const loader = UrlLoader.make([testPlugin]);
19
+ const result = yield* loader(testMeta.id);
20
+ assert.strictEqual(result.meta.id, testMeta.id);
21
+ }),
22
+ );
23
+
24
+ it.effect('fails for unknown non-URL locator', () =>
25
+ Effect.gen(function* () {
26
+ const loader = UrlLoader.make([]);
27
+ const exit = yield* Effect.exit(loader('not-a-url'));
28
+ assert.isTrue(exit._tag === 'Failure');
29
+ }),
30
+ );
31
+ });
32
+
33
+ describe('preload', () => {
34
+ it('returns empty array when storage has no entries', async ({ expect }) => {
35
+ const storage: UrlLoader.Storage = {
36
+ get: () => null,
37
+ set: () => {},
38
+ };
39
+ const result = await UrlLoader.preload({ storage });
40
+ expect(result).toEqual([]);
41
+ });
42
+
43
+ it('returns empty array when storage has invalid JSON', async ({ expect }) => {
44
+ const storage: UrlLoader.Storage = {
45
+ get: () => '{{invalid json',
46
+ set: () => {},
47
+ };
48
+ const result = await UrlLoader.preload({ storage });
49
+ expect(result).toEqual([]);
50
+ });
51
+
52
+ it('returns empty array when storage contains null', async ({ expect }) => {
53
+ const storage: UrlLoader.Storage = {
54
+ get: () => 'null',
55
+ set: () => {},
56
+ };
57
+ const result = await UrlLoader.preload({ storage });
58
+ expect(result).toEqual([]);
59
+ });
60
+
61
+ it('returns empty array when storage contains an object', async ({ expect }) => {
62
+ const storage: UrlLoader.Storage = {
63
+ get: () => '{}',
64
+ set: () => {},
65
+ };
66
+ const result = await UrlLoader.preload({ storage });
67
+ expect(result).toEqual([]);
68
+ });
69
+
70
+ it('returns empty array when entries are missing required fields', async ({ expect }) => {
71
+ const storage: UrlLoader.Storage = {
72
+ get: () => '[{"title":"no url"}]',
73
+ set: () => {},
74
+ };
75
+ const result = await UrlLoader.preload({ storage });
76
+ expect(result).toEqual([]);
77
+ });
78
+ });
79
+ });
@@ -0,0 +1,148 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import * as Effect from 'effect/Effect';
6
+
7
+ import { log } from '@dxos/log';
8
+
9
+ import * as Plugin from './plugin';
10
+
11
+ const DEFAULT_KEY = 'org.dxos.composer.remote-plugins';
12
+
13
+ /**
14
+ * Abstraction over key-value storage (defaults to localStorage).
15
+ */
16
+ export type Storage = {
17
+ get(key: string): string | null;
18
+ set(key: string, value: string): void;
19
+ };
20
+
21
+ /**
22
+ * Options for configuring the URL loader.
23
+ */
24
+ export type Options = {
25
+ storage?: Storage;
26
+ key?: string;
27
+ };
28
+
29
+ type RemotePluginEntry = { id: string; url: string };
30
+
31
+ const defaultStorage = (): Storage => ({
32
+ get: (key) => localStorage.getItem(key),
33
+ set: (key, value) => localStorage.setItem(key, value),
34
+ });
35
+
36
+ const getPersistedRemotePlugins = (storage: Storage, key: string): RemotePluginEntry[] => {
37
+ try {
38
+ const parsed: unknown = JSON.parse(storage.get(key) ?? '[]');
39
+ if (!Array.isArray(parsed)) {
40
+ return [];
41
+ }
42
+ return parsed.filter(
43
+ (entry): entry is RemotePluginEntry =>
44
+ typeof entry === 'object' && entry !== null && typeof entry.id === 'string' && typeof entry.url === 'string',
45
+ );
46
+ } catch {
47
+ return [];
48
+ }
49
+ };
50
+
51
+ const persistRemotePlugin = (storage: Storage, key: string, entry: RemotePluginEntry): void => {
52
+ try {
53
+ const entries = getPersistedRemotePlugins(storage, key).filter((existing) => existing.id !== entry.id);
54
+ entries.push(entry);
55
+ storage.set(key, JSON.stringify(entries));
56
+ } catch (error) {
57
+ log.warn('failed to persist remote plugin entry', { entry, error });
58
+ }
59
+ };
60
+
61
+ const isUrl = (locator: string): boolean => {
62
+ try {
63
+ const url = new URL(locator);
64
+ return url.protocol === 'http:' || url.protocol === 'https:';
65
+ } catch {
66
+ return false;
67
+ }
68
+ };
69
+
70
+ const normalizePluginExport = (mod: Record<string, unknown>): Plugin.Plugin => {
71
+ const exported = mod.default;
72
+ if (Plugin.isPlugin(exported)) {
73
+ return exported;
74
+ }
75
+ if (typeof exported === 'function') {
76
+ const result = (exported as () => unknown)();
77
+ if (Plugin.isPlugin(result)) {
78
+ return result;
79
+ }
80
+ }
81
+ throw new Error('Remote module default export is not a Plugin or a zero-arg plugin factory.');
82
+ };
83
+
84
+ const loadRemotePlugin = async (url: string): Promise<Plugin.Plugin> => {
85
+ log.info('loading remote plugin', { url });
86
+ const mod = await import(/* @vite-ignore */ url);
87
+ const plugin = normalizePluginExport(mod);
88
+ if (!plugin.meta.id || !plugin.meta.name) {
89
+ throw new Error(`Remote plugin at ${url} is missing required meta.id or meta.name.`);
90
+ }
91
+ return plugin;
92
+ };
93
+
94
+ /**
95
+ * Preloads previously persisted remote plugins from storage.
96
+ */
97
+ export const preload = async (options: Options = {}): Promise<Plugin.Plugin[]> => {
98
+ const storage = options.storage ?? defaultStorage();
99
+ const key = options.key ?? DEFAULT_KEY;
100
+
101
+ const entries = getPersistedRemotePlugins(storage, key);
102
+ if (entries.length === 0) {
103
+ return [];
104
+ }
105
+ log.info('preloading remote plugins', { count: entries.length });
106
+ const results = await Promise.allSettled(entries.map((entry) => loadRemotePlugin(entry.url)));
107
+ const plugins: Plugin.Plugin[] = [];
108
+ for (let index = 0; index < results.length; index++) {
109
+ const result = results[index];
110
+ if (result.status === 'fulfilled') {
111
+ plugins.push(result.value);
112
+ } else {
113
+ log.warn('failed to preload remote plugin', { entry: entries[index], error: result.reason });
114
+ }
115
+ }
116
+ return plugins;
117
+ };
118
+
119
+ /**
120
+ * Creates a plugin loader that resolves built-in plugins by ID or loads remote plugins from URLs.
121
+ */
122
+ export const make = (builtinPlugins: Plugin.Plugin[], options: Options = {}) => {
123
+ const storage = options.storage ?? defaultStorage();
124
+ const key = options.key ?? DEFAULT_KEY;
125
+
126
+ return (locator: string): Effect.Effect<Plugin.Plugin, Error> =>
127
+ Effect.gen(function* () {
128
+ const builtin = builtinPlugins.find((plugin) => plugin.meta.id === locator);
129
+ if (builtin) {
130
+ return builtin;
131
+ }
132
+ if (!isUrl(locator)) {
133
+ return yield* Effect.fail(new Error(`Plugin not found and locator is not a URL: ${locator}`));
134
+ }
135
+ const plugin = yield* Effect.tryPromise({
136
+ try: () => loadRemotePlugin(locator),
137
+ catch: (error) => new Error(`Failed to load remote plugin from ${locator}: ${error}`),
138
+ });
139
+ const duplicate = builtinPlugins.find((existing) => existing.meta.id === plugin.meta.id);
140
+ if (duplicate) {
141
+ return yield* Effect.fail(
142
+ new Error(`Remote plugin ${plugin.meta.id} conflicts with built-in plugin of the same id.`),
143
+ );
144
+ }
145
+ persistRemotePlugin(storage, key, { id: plugin.meta.id, url: locator });
146
+ return plugin;
147
+ });
148
+ };
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,9 +2,8 @@
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
-
8
7
  import { meta } from './meta';
9
8
 
10
9
  const OperationInvoker = Capability.lazy('OperationInvoker', () => import('./invoker-capability'));
@@ -12,13 +11,13 @@ const HistoryCapabilities = Capability.lazy('HistoryCapabilities', () => import(
12
11
 
13
12
  export const OperationPlugin = Plugin.define(meta).pipe(
14
13
  Plugin.addModule({
15
- activatesOn: Common.ActivationEvent.ManagedRuntimeReady,
16
- activatesBefore: [Common.ActivationEvent.SetupOperationResolver],
17
- activatesAfter: [Common.ActivationEvent.OperationInvokerReady],
14
+ activatesOn: ActivationEvents.ManagedRuntimeReady,
15
+ activatesBefore: [ActivationEvents.SetupOperationHandler],
16
+ activatesAfter: [ActivationEvents.OperationInvokerReady],
18
17
  activate: OperationInvoker,
19
18
  }),
20
19
  Plugin.addModule({
21
- activatesOn: Common.ActivationEvent.OperationInvokerReady,
20
+ activatesOn: ActivationEvents.OperationInvokerReady,
22
21
  activate: HistoryCapabilities,
23
22
  }),
24
23
  Plugin.make,
@@ -6,9 +6,8 @@ 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
-
12
11
  import * as HistoryTracker from './history-tracker';
13
12
  import * as UndoRegistry from './undo-registry';
14
13
 
@@ -22,16 +21,16 @@ export default Capability.makeModule(
22
21
  const capabilities = yield* Capability.Service;
23
22
 
24
23
  // Create UndoRegistry.
25
- const undoRegistry = UndoRegistry.make(() => capabilities.getAll(Common.Capability.UndoMapping).flat());
24
+ const undoRegistry = UndoRegistry.make(() => capabilities.getAll(Capabilities.UndoMapping).flat());
26
25
 
27
26
  // Create HistoryTracker (depends on UndoRegistry and OperationInvoker).
28
- const invoker = yield* Capability.get(Common.Capability.OperationInvoker);
27
+ const invoker = yield* Capability.get(Capabilities.OperationInvoker);
29
28
  // Cast to internal type - the factory always returns OperationInvokerInternal.
30
29
  const historyTracker = HistoryTracker.make(invoker as OperationInvoker.OperationInvokerInternal, undoRegistry);
31
30
 
32
31
  return [
33
- Capability.contributes(Common.Capability.UndoRegistry, undoRegistry),
34
- Capability.contributes(Common.Capability.HistoryTracker, historyTracker),
32
+ Capability.contributes(Capabilities.UndoRegistry, undoRegistry),
33
+ Capability.contributes(Capabilities.HistoryTracker, historyTracker),
35
34
  ];
36
35
  }),
37
36
  );
@@ -2,10 +2,6 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { OperationError } from '@dxos/operation';
5
+ import { BaseError } from '@dxos/errors';
6
6
 
7
- export class EmptyHistoryError extends OperationError {
8
- constructor() {
9
- super('EMPTY_HISTORY', 'Cannot undo: history is empty.');
10
- }
11
- }
7
+ export class EmptyHistoryError extends BaseError.extend('EmptyHistoryError', 'Cannot undo: history is empty.') {}
@@ -5,10 +5,14 @@
5
5
  import { it } from '@effect/vitest';
6
6
  import * as Effect from 'effect/Effect';
7
7
  import * as Fiber from 'effect/Fiber';
8
+ import * as Layer from 'effect/Layer';
9
+ import * as ManagedRuntime from 'effect/ManagedRuntime';
8
10
  import * as TestClock from 'effect/TestClock';
9
11
  import { describe, expect } from 'vitest';
10
12
 
11
- import { OperationInvoker, OperationResolver } from '@dxos/operation';
13
+ import { Operation, OperationInvoker } from '@dxos/operation';
14
+
15
+ const testRuntime = ManagedRuntime.make(Layer.empty) as unknown as ManagedRuntime.ManagedRuntime<any, any>;
12
16
 
13
17
  import { UndoOperation } from '../../common';
14
18
  import {
@@ -21,7 +25,6 @@ import {
21
25
  toStringHandler,
22
26
  waitUntil,
23
27
  } from '../testing';
24
-
25
28
  import * as HistoryTracker from './history-tracker';
26
29
  import * as UndoMapping from './undo-mapping';
27
30
  import * as UndoRegistry from './undo-registry';
@@ -35,7 +38,7 @@ describe('HistoryTracker', () => {
35
38
  deriveContext: (_input, output) => ({ value: output.value }),
36
39
  });
37
40
 
38
- const invoker = OperationInvoker.make(() => Effect.succeed([computeHandler, halveComputeHandler]));
41
+ const invoker = OperationInvoker.make(() => Effect.succeed([computeHandler, halveComputeHandler]), testRuntime);
39
42
  const undoRegistry = UndoRegistry.make(() => [undoMapping]);
40
43
  const tracker = HistoryTracker.make(invoker, undoRegistry);
41
44
 
@@ -55,7 +58,7 @@ describe('HistoryTracker', () => {
55
58
 
56
59
  it.effect('does not track operations without undo mapping', () =>
57
60
  Effect.gen(function* () {
58
- const invoker = OperationInvoker.make(() => Effect.succeed([toStringHandler]));
61
+ const invoker = OperationInvoker.make(() => Effect.succeed([toStringHandler]), testRuntime);
59
62
  const undoRegistry = UndoRegistry.make(() => []);
60
63
  const tracker = HistoryTracker.make(invoker, undoRegistry);
61
64
  const collector = yield* createEventCollector(invoker);
@@ -81,15 +84,12 @@ describe('HistoryTracker', () => {
81
84
  });
82
85
 
83
86
  let halveWasCalled = false;
84
- const trackingHalveHandler = OperationResolver.make({
85
- operation: HalveCompute,
86
- handler: (data) => {
87
- halveWasCalled = true;
88
- return Effect.succeed({ value: data.value / 2 });
89
- },
87
+ const trackingHalveHandler = Operation.withHandler(HalveCompute, (data) => {
88
+ halveWasCalled = true;
89
+ return Effect.succeed({ value: data.value / 2 });
90
90
  });
91
91
 
92
- const invoker = OperationInvoker.make(() => Effect.succeed([computeHandler, trackingHalveHandler]));
92
+ const invoker = OperationInvoker.make(() => Effect.succeed([computeHandler, trackingHalveHandler]), testRuntime);
93
93
  const undoRegistry = UndoRegistry.make(() => [undoMapping]);
94
94
  const tracker = HistoryTracker.make(invoker, undoRegistry);
95
95
 
@@ -117,7 +117,7 @@ describe('HistoryTracker', () => {
117
117
  deriveContext: (_input, output) => ({ value: output.value }),
118
118
  });
119
119
 
120
- const invoker = OperationInvoker.make(() => Effect.succeed([computeHandler, halveComputeHandler]));
120
+ const invoker = OperationInvoker.make(() => Effect.succeed([computeHandler, halveComputeHandler]), testRuntime);
121
121
  const undoRegistry = UndoRegistry.make(() => [undoMapping]);
122
122
  const tracker = HistoryTracker.make(invoker, undoRegistry);
123
123
  const collector = yield* createEventCollector(invoker);
@@ -152,15 +152,12 @@ describe('HistoryTracker', () => {
152
152
  });
153
153
 
154
154
  const halveInputs: number[] = [];
155
- const trackingHalveHandler = OperationResolver.make({
156
- operation: HalveCompute,
157
- handler: (data) => {
158
- halveInputs.push(data.value);
159
- return Effect.succeed({ value: data.value / 2 });
160
- },
155
+ const trackingHalveHandler = Operation.withHandler(HalveCompute, (data) => {
156
+ halveInputs.push(data.value);
157
+ return Effect.succeed({ value: data.value / 2 });
161
158
  });
162
159
 
163
- const invoker = OperationInvoker.make(() => Effect.succeed([computeHandler, trackingHalveHandler]));
160
+ const invoker = OperationInvoker.make(() => Effect.succeed([computeHandler, trackingHalveHandler]), testRuntime);
164
161
  const undoRegistry = UndoRegistry.make(() => [undoMapping]);
165
162
  const tracker = HistoryTracker.make(invoker, undoRegistry);
166
163
  const collector = yield* createEventCollector(invoker);
@@ -194,7 +191,7 @@ describe('HistoryTracker', () => {
194
191
 
195
192
  it.effect('undo on empty history returns error', () =>
196
193
  Effect.gen(function* () {
197
- const invoker = OperationInvoker.make(() => Effect.succeed([]));
194
+ const invoker = OperationInvoker.make(() => Effect.succeed([]), testRuntime);
198
195
  const undoRegistry = UndoRegistry.make(() => []);
199
196
  const tracker = HistoryTracker.make(invoker, undoRegistry);
200
197
 
@@ -208,7 +205,7 @@ describe('HistoryTracker', () => {
208
205
 
209
206
  it.effect('fires ShowUndo operation when undoable operation is tracked', () =>
210
207
  Effect.gen(function* () {
211
- const testMessage: [string, { ns: string }] = ['test undo message', { ns: 'test' }];
208
+ const testMessage: [string, { ns: string }] = ['test-undo.message', { ns: 'test' }];
212
209
  const undoMapping = UndoMapping.make({
213
210
  operation: Compute,
214
211
  inverse: HalveCompute,
@@ -218,17 +215,15 @@ describe('HistoryTracker', () => {
218
215
 
219
216
  let showUndoWasCalled = false;
220
217
  let showUndoMessage: unknown = undefined;
221
- const showUndoHandler = OperationResolver.make({
222
- operation: UndoOperation.ShowUndo,
223
- handler: (input) => {
224
- showUndoWasCalled = true;
225
- showUndoMessage = input.message;
226
- return Effect.succeed(undefined);
227
- },
218
+ const showUndoHandler = Operation.withHandler(UndoOperation.ShowUndo, (input) => {
219
+ showUndoWasCalled = true;
220
+ showUndoMessage = input.message;
221
+ return Effect.succeed(undefined);
228
222
  });
229
223
 
230
- const invoker = OperationInvoker.make(() =>
231
- Effect.succeed([computeHandler, halveComputeHandler, showUndoHandler]),
224
+ const invoker = OperationInvoker.make(
225
+ () => Effect.succeed([computeHandler, halveComputeHandler, showUndoHandler]),
226
+ testRuntime,
232
227
  );
233
228
  const undoRegistry = UndoRegistry.make(() => [undoMapping]);
234
229
  const tracker = HistoryTracker.make(invoker, undoRegistry);
@@ -254,7 +249,7 @@ describe('HistoryTracker', () => {
254
249
  Effect.gen(function* () {
255
250
  // Dynamic message that depends on input/output.
256
251
  const dynamicMessage = (input: { value: number }, output: { value: number }): [string, { ns: string }] => [
257
- `computed ${input.value} to ${output.value}`,
252
+ `computed-${input.value}-to-${output.value}`,
258
253
  { ns: 'test' },
259
254
  ];
260
255
  const undoMapping = UndoMapping.make({
@@ -266,17 +261,15 @@ describe('HistoryTracker', () => {
266
261
 
267
262
  let showUndoWasCalled = false;
268
263
  let showUndoMessage: unknown = undefined;
269
- const showUndoHandler = OperationResolver.make({
270
- operation: UndoOperation.ShowUndo,
271
- handler: (input) => {
272
- showUndoWasCalled = true;
273
- showUndoMessage = input.message;
274
- return Effect.succeed(undefined);
275
- },
264
+ const showUndoHandler = Operation.withHandler(UndoOperation.ShowUndo, (input) => {
265
+ showUndoWasCalled = true;
266
+ showUndoMessage = input.message;
267
+ return Effect.succeed(undefined);
276
268
  });
277
269
 
278
- const invoker = OperationInvoker.make(() =>
279
- Effect.succeed([computeHandler, halveComputeHandler, showUndoHandler]),
270
+ const invoker = OperationInvoker.make(
271
+ () => Effect.succeed([computeHandler, halveComputeHandler, showUndoHandler]),
272
+ testRuntime,
280
273
  );
281
274
  const undoRegistry = UndoRegistry.make(() => [undoMapping]);
282
275
  const tracker = HistoryTracker.make(invoker, undoRegistry);
@@ -295,7 +288,7 @@ describe('HistoryTracker', () => {
295
288
  yield* waitUntil(() => showUndoWasCalled);
296
289
  expect(showUndoWasCalled).toBe(true);
297
290
  // Compute 2 * 2 = 4, so message should be 'computed 2 to 4'.
298
- expect(showUndoMessage).toEqual(['computed 2 to 4', { ns: 'test' }]);
291
+ expect(showUndoMessage).toEqual(['computed-2-to-4', { ns: 'test' }]);
299
292
  }),
300
293
  );
301
294
 
@@ -314,7 +307,7 @@ describe('HistoryTracker', () => {
314
307
  },
315
308
  });
316
309
 
317
- const invoker = OperationInvoker.make(() => Effect.succeed([computeHandler, halveComputeHandler]));
310
+ const invoker = OperationInvoker.make(() => Effect.succeed([computeHandler, halveComputeHandler]), testRuntime);
318
311
  const undoRegistry = UndoRegistry.make(() => [undoMapping]);
319
312
  const tracker = HistoryTracker.make(invoker, undoRegistry);
320
313
  const collector = yield* createEventCollector(invoker);
@@ -352,7 +345,7 @@ describe('HistoryTracker', () => {
352
345
  },
353
346
  });
354
347
 
355
- const invoker = OperationInvoker.make(() => Effect.succeed([computeHandler, halveComputeHandler]));
348
+ const invoker = OperationInvoker.make(() => Effect.succeed([computeHandler, halveComputeHandler]), testRuntime);
356
349
  const undoRegistry = UndoRegistry.make(() => [undoMapping]);
357
350
  const tracker = HistoryTracker.make(invoker, undoRegistry);
358
351
  const collector = yield* createEventCollector(invoker);
@@ -10,7 +10,6 @@ import { log } from '@dxos/log';
10
10
  import { type OperationInvoker } from '@dxos/operation';
11
11
 
12
12
  import { UndoOperation } from '../../common';
13
-
14
13
  import { EmptyHistoryError } from './errors';
15
14
  import type { HistoryEntry } from './types';
16
15
  import { resolveMessage } from './undo-mapping';
@@ -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
  */
@@ -5,7 +5,6 @@
5
5
  import { describe, test } from 'vitest';
6
6
 
7
7
  import { Compute, HalveCompute } from '../testing';
8
-
9
8
  import * as UndoMapping from './undo-mapping';
10
9
  import * as UndoRegistry from './undo-registry';
11
10
 
@@ -52,18 +51,18 @@ describe('resolveMessage', () => {
52
51
  });
53
52
 
54
53
  test('returns static label as-is', ({ expect }) => {
55
- const staticMessage: [string, { ns: string }] = ['test message', { ns: 'test' }];
54
+ const staticMessage: [string, { ns: string }] = ['test.message', { ns: 'test' }];
56
55
  const result = UndoMapping.resolveMessage(staticMessage, { value: 1 }, { value: 2 });
57
56
  expect(result).toEqual(staticMessage);
58
57
  });
59
58
 
60
59
  test('calls function message with input and output', ({ expect }) => {
61
60
  const messageFunc = (input: { value: number }, output: { value: number }): [string, { ns: string }] => [
62
- `input: ${input.value}, output: ${output.value}`,
61
+ `input-${input.value}-output-${output.value}`,
63
62
  { ns: 'test' },
64
63
  ];
65
64
  const result = UndoMapping.resolveMessage(messageFunc, { value: 5 }, { value: 10 });
66
- expect(result).toEqual(['input: 5, output: 10', { ns: 'test' }]);
65
+ expect(result).toEqual(['input-5-output-10', { ns: 'test' }]);
67
66
  });
68
67
 
69
68
  test('returns string label as-is', ({ expect }) => {
@@ -4,9 +4,9 @@
4
4
 
5
5
  import * as Effect from 'effect/Effect';
6
6
 
7
- import { OperationInvoker } from '@dxos/operation';
7
+ import { OperationHandlerSet, OperationInvoker } from '@dxos/operation';
8
8
 
9
- import * as Common from '../common';
9
+ import { ActivationEvents, Capabilities } from '../common';
10
10
  import { Capability, Plugin } from '../core';
11
11
 
12
12
  //
@@ -20,21 +20,35 @@ export default Capability.makeModule(
20
20
  const pluginManager = yield* Plugin.Service;
21
21
 
22
22
  // Get the ManagedRuntime capability (should be available since we activate after ManagedRuntimeReady).
23
- const managedRuntimes = yield* Capability.getAll(Common.Capability.ManagedRuntime);
24
- const managedRuntime = managedRuntimes.length > 0 ? managedRuntimes[0] : undefined;
23
+ const managedRuntime = yield* Capability.get(Capabilities.ManagedRuntime);
24
+
25
+ // Cache the merged handler promise to prevent concurrent module loading.
26
+ // Multiple Effects can invoke getHandlers simultaneously; without caching each
27
+ // creates a new merge() which triggers parallel dynamic imports that race in
28
+ // WebKit's module evaluator, causing TDZ errors on export default bindings.
29
+ let cachedSets: readonly OperationHandlerSet.OperationHandlerSet[] | undefined;
30
+ let cachedHandlers: ReturnType<OperationHandlerSet.OperationHandlerSet['getHandlers']> | undefined;
25
31
 
26
32
  const invoker = OperationInvoker.make(
27
33
  () =>
28
34
  Effect.gen(function* () {
29
- yield* Plugin.activate(Common.ActivationEvent.SetupOperationResolver);
30
- return (yield* Capability.getAll(Common.Capability.OperationResolver)).flat();
35
+ yield* Plugin.activate(ActivationEvents.SetupOperationHandler);
36
+ const sets = yield* Capability.getAll(Capabilities.OperationHandler);
37
+
38
+ if (sets !== cachedSets) {
39
+ cachedSets = sets;
40
+ cachedHandlers = OperationHandlerSet.merge(...sets).getHandlers();
41
+ }
42
+
43
+ return yield* Effect.promise(() => cachedHandlers!);
31
44
  }).pipe(
32
45
  Effect.provideService(Capability.Service, capabilityManager),
33
46
  Effect.provideService(Plugin.Service, pluginManager),
47
+ Effect.orDie,
34
48
  ),
35
49
  managedRuntime,
36
50
  );
37
51
 
38
- return Capability.contributes(Common.Capability.OperationInvoker, invoker);
52
+ return Capability.contributes(Capabilities.OperationInvoker, invoker);
39
53
  }),
40
54
  );
@@ -5,7 +5,7 @@
5
5
  import { type Plugin } from '../core';
6
6
 
7
7
  export const meta: Plugin.Meta = {
8
- id: 'dxos.org/plugin/operation',
8
+ id: 'org.dxos.plugin.operation',
9
9
  name: 'Operation Plugin',
10
10
  description: 'Provides operation invocation, undo registry, and history tracking.',
11
11
  };