@dxos/app-framework 0.8.4-main.fd6878d → 0.8.4-staging.60fe92afc8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.storybook/main.mts +9 -0
- package/.storybook/preview.mts +8 -0
- package/LICENSE +102 -5
- package/README.md +1 -1
- package/dist/lib/browser/capability-BOPAKKWG.mjs +35 -0
- package/dist/lib/browser/capability-BOPAKKWG.mjs.map +7 -0
- package/dist/lib/browser/chunk-5GY3YOEL.mjs +28 -0
- package/dist/lib/browser/chunk-5GY3YOEL.mjs.map +7 -0
- package/dist/lib/browser/chunk-66IXTIVK.mjs +48 -0
- package/dist/lib/browser/chunk-66IXTIVK.mjs.map +7 -0
- package/dist/lib/browser/chunk-CO3XLNUX.mjs +95 -0
- package/dist/lib/browser/chunk-CO3XLNUX.mjs.map +7 -0
- package/dist/lib/browser/chunk-DC3WRPBV.mjs +227 -0
- package/dist/lib/browser/chunk-DC3WRPBV.mjs.map +7 -0
- package/dist/lib/browser/chunk-FJ4765WW.mjs +8 -0
- package/dist/lib/browser/chunk-FJ4765WW.mjs.map +7 -0
- package/dist/lib/browser/chunk-FO3IYSLV.mjs +68 -0
- package/dist/lib/browser/chunk-FO3IYSLV.mjs.map +7 -0
- package/dist/lib/browser/chunk-HFLKXMT7.mjs +587 -0
- package/dist/lib/browser/chunk-HFLKXMT7.mjs.map +7 -0
- package/dist/lib/browser/chunk-IW44C7UL.mjs +83 -0
- package/dist/lib/browser/chunk-IW44C7UL.mjs.map +7 -0
- package/dist/lib/browser/chunk-J5LGTIGS.mjs +10 -0
- package/dist/lib/browser/chunk-KZUDO43J.mjs +422 -0
- package/dist/lib/browser/chunk-KZUDO43J.mjs.map +7 -0
- package/dist/lib/browser/chunk-Q2GLJTVV.mjs +12 -0
- package/dist/lib/browser/chunk-Q2GLJTVV.mjs.map +7 -0
- package/dist/lib/browser/chunk-SYXIYT6T.mjs +143 -0
- package/dist/lib/browser/chunk-SYXIYT6T.mjs.map +7 -0
- package/dist/lib/browser/chunk-XHS5KDNX.mjs +1471 -0
- package/dist/lib/browser/chunk-XHS5KDNX.mjs.map +7 -0
- package/dist/lib/browser/chunk-Y66ELD4U.mjs +476 -0
- package/dist/lib/browser/chunk-Y66ELD4U.mjs.map +7 -0
- package/dist/lib/browser/cli/index.mjs +74 -0
- package/dist/lib/browser/cli/index.mjs.map +7 -0
- package/dist/lib/browser/common/activation-events.mjs +20 -0
- package/dist/lib/browser/common/capabilities.mjs +56 -0
- package/dist/lib/browser/core/activation-event.mjs +20 -0
- package/dist/lib/browser/core/capability.mjs +32 -0
- package/dist/lib/browser/core/capability.mjs.map +7 -0
- package/dist/lib/browser/core/plugin-manager.mjs +19 -0
- package/dist/lib/browser/core/plugin-manager.mjs.map +7 -0
- package/dist/lib/browser/core/plugin.mjs +41 -0
- package/dist/lib/browser/core/plugin.mjs.map +7 -0
- package/dist/lib/browser/core/url-loader.mjs +24 -0
- package/dist/lib/browser/core/url-loader.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +85 -157
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/process-manager-capability-GXNUO7AR.mjs +132 -0
- package/dist/lib/browser/process-manager-capability-GXNUO7AR.mjs.map +7 -0
- package/dist/lib/browser/testing/index.mjs +321 -56
- package/dist/lib/browser/testing/index.mjs.map +4 -4
- package/dist/lib/browser/testing/react.mjs +78 -0
- package/dist/lib/browser/testing/react.mjs.map +7 -0
- package/dist/lib/browser/ui/index.mjs +52 -0
- package/dist/lib/browser/ui/index.mjs.map +7 -0
- package/dist/lib/node-esm/capability-KZWRTX7R.mjs +36 -0
- package/dist/lib/node-esm/capability-KZWRTX7R.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-37Z53PXZ.mjs +10 -0
- package/dist/lib/node-esm/chunk-37Z53PXZ.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-A5CHGAZE.mjs +588 -0
- package/dist/lib/node-esm/chunk-A5CHGAZE.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-COHOWGGJ.mjs +144 -0
- package/dist/lib/node-esm/chunk-COHOWGGJ.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-CTKEZHKF.mjs +84 -0
- package/dist/lib/node-esm/chunk-CTKEZHKF.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-FPW45EZH.mjs +14 -0
- package/dist/lib/node-esm/chunk-FPW45EZH.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-FSVGKTF6.mjs +477 -0
- package/dist/lib/node-esm/chunk-FSVGKTF6.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +11 -0
- package/dist/lib/node-esm/chunk-HSLMI22Q.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-KFZEB6BV.mjs +29 -0
- package/dist/lib/node-esm/chunk-KFZEB6BV.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-NULBHQYS.mjs +96 -0
- package/dist/lib/node-esm/chunk-NULBHQYS.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-SX5NVETP.mjs +1472 -0
- package/dist/lib/node-esm/chunk-SX5NVETP.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-WK7OIQKI.mjs +70 -0
- package/dist/lib/node-esm/chunk-WK7OIQKI.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-XGBUKRCK.mjs +423 -0
- package/dist/lib/node-esm/chunk-XGBUKRCK.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-XIGPWXCQ.mjs +228 -0
- package/dist/lib/node-esm/chunk-XIGPWXCQ.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-XOCUANHO.mjs +49 -0
- package/dist/lib/node-esm/chunk-XOCUANHO.mjs.map +7 -0
- package/dist/lib/node-esm/cli/index.mjs +75 -0
- package/dist/lib/node-esm/cli/index.mjs.map +7 -0
- package/dist/lib/node-esm/common/activation-events.mjs +21 -0
- package/dist/lib/node-esm/common/activation-events.mjs.map +7 -0
- package/dist/lib/node-esm/common/capabilities.mjs +57 -0
- package/dist/lib/node-esm/common/capabilities.mjs.map +7 -0
- package/dist/lib/node-esm/core/activation-event.mjs +21 -0
- package/dist/lib/node-esm/core/activation-event.mjs.map +7 -0
- package/dist/lib/node-esm/core/capability.mjs +33 -0
- package/dist/lib/node-esm/core/capability.mjs.map +7 -0
- package/dist/lib/node-esm/core/plugin-manager.mjs +20 -0
- package/dist/lib/node-esm/core/plugin-manager.mjs.map +7 -0
- package/dist/lib/node-esm/core/plugin.mjs +42 -0
- package/dist/lib/node-esm/core/plugin.mjs.map +7 -0
- package/dist/lib/node-esm/core/url-loader.mjs +25 -0
- package/dist/lib/node-esm/core/url-loader.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +85 -157
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/process-manager-capability-TX5TA6YN.mjs +133 -0
- package/dist/lib/node-esm/process-manager-capability-TX5TA6YN.mjs.map +7 -0
- package/dist/lib/node-esm/testing/index.mjs +321 -56
- package/dist/lib/node-esm/testing/index.mjs.map +4 -4
- package/dist/lib/node-esm/testing/react.mjs +79 -0
- package/dist/lib/node-esm/testing/react.mjs.map +7 -0
- package/dist/lib/node-esm/ui/index.mjs +53 -0
- package/dist/lib/node-esm/ui/index.mjs.map +7 -0
- package/dist/plugin/node-esm/index.mjs +977 -0
- package/dist/plugin/node-esm/index.mjs.map +7 -0
- package/dist/plugin/node-esm/meta.json +1 -0
- package/dist/types/src/cli/cli.d.ts +37 -0
- package/dist/types/src/cli/cli.d.ts.map +1 -0
- package/dist/types/src/cli/index.d.ts +2 -0
- package/dist/types/src/cli/index.d.ts.map +1 -0
- package/dist/types/src/common/activation-events.d.ts +24 -0
- package/dist/types/src/common/activation-events.d.ts.map +1 -0
- package/dist/types/src/common/annotations.d.ts +1 -0
- package/dist/types/src/common/annotations.d.ts.map +1 -0
- package/dist/types/src/common/capabilities.d.ts +214 -195
- package/dist/types/src/common/capabilities.d.ts.map +1 -1
- package/dist/types/src/common/index.d.ts +3 -8
- package/dist/types/src/common/index.d.ts.map +1 -1
- package/dist/types/src/common/translations.d.ts +8 -8
- package/dist/types/src/common/translations.d.ts.map +1 -1
- package/dist/types/src/context.d.ts +5 -0
- package/dist/types/src/context.d.ts.map +1 -0
- package/dist/types/src/core/{events.d.ts → activation-event.d.ts} +11 -11
- package/dist/types/src/core/activation-event.d.ts.map +1 -0
- package/dist/types/src/core/capability-manager.d.ts +52 -0
- package/dist/types/src/core/capability-manager.d.ts.map +1 -0
- package/dist/types/src/core/capability-manager.test.d.ts +2 -0
- package/dist/types/src/core/capability-manager.test.d.ts.map +1 -0
- package/dist/types/src/core/capability.d.ts +161 -0
- package/dist/types/src/core/capability.d.ts.map +1 -0
- package/dist/types/src/core/edge-registry-plugin-provider.d.ts +30 -0
- package/dist/types/src/core/edge-registry-plugin-provider.d.ts.map +1 -0
- package/dist/types/src/core/index.d.ts +11 -4
- package/dist/types/src/core/index.d.ts.map +1 -1
- package/dist/types/src/core/plugin-asset-cache.d.ts +71 -0
- package/dist/types/src/core/plugin-asset-cache.d.ts.map +1 -0
- package/dist/types/src/core/plugin-manager.d.ts +297 -0
- package/dist/types/src/core/plugin-manager.d.ts.map +1 -0
- package/dist/types/src/core/plugin-manager.test.d.ts +2 -0
- package/dist/types/src/core/plugin-manager.test.d.ts.map +1 -0
- package/dist/types/src/core/plugin-manifest.d.ts +101 -0
- package/dist/types/src/core/plugin-manifest.d.ts.map +1 -0
- package/dist/types/src/core/plugin-manifest.test.d.ts +2 -0
- package/dist/types/src/core/plugin-manifest.test.d.ts.map +1 -0
- package/dist/types/src/core/plugin.d.ts +308 -41
- package/dist/types/src/core/plugin.d.ts.map +1 -1
- package/dist/types/src/core/registry.d.ts +107 -0
- package/dist/types/src/core/registry.d.ts.map +1 -0
- package/dist/types/src/core/url-loader.d.ts +127 -0
- package/dist/types/src/core/url-loader.d.ts.map +1 -0
- package/dist/types/src/core/url-loader.test.d.ts +2 -0
- package/dist/types/src/core/url-loader.test.d.ts.map +1 -0
- package/dist/types/src/helpers.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +2 -4
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/plugin-process-manager/ProcessManagerPlugin.d.ts +3 -0
- package/dist/types/src/plugin-process-manager/ProcessManagerPlugin.d.ts.map +1 -0
- package/dist/types/src/plugin-process-manager/history/capability.d.ts +7 -0
- package/dist/types/src/plugin-process-manager/history/capability.d.ts.map +1 -0
- package/dist/types/src/plugin-process-manager/history/errors.d.ts +32 -0
- package/dist/types/src/plugin-process-manager/history/errors.d.ts.map +1 -0
- package/dist/types/src/plugin-process-manager/history/history-tracker.d.ts +32 -0
- package/dist/types/src/plugin-process-manager/history/history-tracker.d.ts.map +1 -0
- package/dist/types/src/plugin-process-manager/history/history-tracker.test.d.ts +2 -0
- package/dist/types/src/plugin-process-manager/history/history-tracker.test.d.ts.map +1 -0
- package/dist/types/src/plugin-process-manager/history/index.d.ts +6 -0
- package/dist/types/src/plugin-process-manager/history/index.d.ts.map +1 -0
- package/dist/types/src/plugin-process-manager/history/types.d.ts +13 -0
- package/dist/types/src/plugin-process-manager/history/types.d.ts.map +1 -0
- package/dist/types/src/plugin-process-manager/history/undo-mapping.d.ts +101 -0
- package/dist/types/src/plugin-process-manager/history/undo-mapping.d.ts.map +1 -0
- package/dist/types/src/plugin-process-manager/history/undo-registry.d.ts +23 -0
- package/dist/types/src/plugin-process-manager/history/undo-registry.d.ts.map +1 -0
- package/dist/types/src/plugin-process-manager/history/undo-registry.test.d.ts +2 -0
- package/dist/types/src/plugin-process-manager/history/undo-registry.test.d.ts.map +1 -0
- package/dist/types/src/plugin-process-manager/idb-key-value-store.d.ts +10 -0
- package/dist/types/src/plugin-process-manager/idb-key-value-store.d.ts.map +1 -0
- package/dist/types/src/plugin-process-manager/index.d.ts +3 -0
- package/dist/types/src/plugin-process-manager/index.d.ts.map +1 -0
- package/dist/types/src/plugin-process-manager/meta.d.ts +3 -0
- package/dist/types/src/plugin-process-manager/meta.d.ts.map +1 -0
- package/dist/types/src/plugin-process-manager/process-manager-capability.d.ts +8 -0
- package/dist/types/src/plugin-process-manager/process-manager-capability.d.ts.map +1 -0
- package/dist/types/src/plugin-process-manager/testing.d.ts +59 -0
- package/dist/types/src/plugin-process-manager/testing.d.ts.map +1 -0
- package/dist/types/src/testing/harness.d.ts +79 -0
- package/dist/types/src/testing/harness.d.ts.map +1 -0
- package/dist/types/src/testing/index.d.ts +3 -0
- package/dist/types/src/testing/index.d.ts.map +1 -1
- package/dist/types/src/testing/operationCapture.d.ts +64 -0
- package/dist/types/src/testing/operationCapture.d.ts.map +1 -0
- package/dist/types/src/testing/react.d.ts +27 -0
- package/dist/types/src/testing/react.d.ts.map +1 -0
- package/dist/types/src/testing/react.test.d.ts +2 -0
- package/dist/types/src/testing/react.test.d.ts.map +1 -0
- package/dist/types/src/testing/service.d.ts +8 -0
- package/dist/types/src/testing/service.d.ts.map +1 -0
- package/dist/types/src/testing/withPluginManager.d.ts +9 -10
- package/dist/types/src/testing/withPluginManager.d.ts.map +1 -1
- package/dist/types/src/testing/withPluginManager.stories.d.ts +9 -3
- package/dist/types/src/testing/withPluginManager.stories.d.ts.map +1 -1
- package/dist/types/src/ui/components/App/App.d.ts +41 -0
- package/dist/types/src/ui/components/App/App.d.ts.map +1 -0
- package/dist/types/src/ui/components/App/App.stories.d.ts +19 -0
- package/dist/types/src/ui/components/App/App.stories.d.ts.map +1 -0
- package/dist/types/src/ui/components/App/index.d.ts +2 -0
- package/dist/types/src/ui/components/App/index.d.ts.map +1 -0
- package/dist/types/src/ui/components/PluginManager/PluginManagerContext.stories.d.ts +13 -0
- package/dist/types/src/ui/components/PluginManager/PluginManagerContext.stories.d.ts.map +1 -0
- package/dist/types/src/ui/components/PluginManager/PluginManagerProvider.d.ts +10 -0
- package/dist/types/src/ui/components/PluginManager/PluginManagerProvider.d.ts.map +1 -0
- package/dist/types/src/ui/components/PluginManager/index.d.ts +2 -0
- package/dist/types/src/ui/components/PluginManager/index.d.ts.map +1 -0
- package/dist/types/src/ui/components/Surface/SurfaceComponent.d.ts +24 -0
- package/dist/types/src/ui/components/Surface/SurfaceComponent.d.ts.map +1 -0
- package/dist/types/src/ui/components/Surface/SurfaceComponent.stories.d.ts +14 -0
- package/dist/types/src/ui/components/Surface/SurfaceComponent.stories.d.ts.map +1 -0
- package/dist/types/src/ui/components/Surface/SurfaceInfo.d.ts +11 -0
- package/dist/types/src/ui/components/Surface/SurfaceInfo.d.ts.map +1 -0
- package/dist/types/src/ui/components/Surface/SurfaceProfilerContext.d.ts +48 -0
- package/dist/types/src/ui/components/Surface/SurfaceProfilerContext.d.ts.map +1 -0
- package/dist/types/src/ui/components/Surface/context.d.ts +5 -0
- package/dist/types/src/ui/components/Surface/context.d.ts.map +1 -0
- package/dist/types/src/ui/components/Surface/index.d.ts +36 -0
- package/dist/types/src/ui/components/Surface/index.d.ts.map +1 -0
- package/dist/types/src/ui/components/Surface/types.d.ts +197 -0
- package/dist/types/src/ui/components/Surface/types.d.ts.map +1 -0
- package/dist/types/src/ui/components/Surface/types.test.d.ts +2 -0
- package/dist/types/src/ui/components/Surface/types.test.d.ts.map +1 -0
- package/dist/types/src/ui/components/index.d.ts +4 -0
- package/dist/types/src/ui/components/index.d.ts.map +1 -0
- package/dist/types/src/ui/hooks/index.d.ts +7 -0
- package/dist/types/src/ui/hooks/index.d.ts.map +1 -0
- package/dist/types/src/ui/hooks/useApp.d.ts +80 -0
- package/dist/types/src/ui/hooks/useApp.d.ts.map +1 -0
- package/dist/types/src/ui/hooks/useApp.test.d.ts +2 -0
- package/dist/types/src/ui/hooks/useApp.test.d.ts.map +1 -0
- package/dist/types/src/ui/hooks/useCapabilities.d.ts +31 -0
- package/dist/types/src/ui/hooks/useCapabilities.d.ts.map +1 -0
- package/dist/types/src/ui/hooks/useLoading.d.ts +18 -0
- package/dist/types/src/ui/hooks/useLoading.d.ts.map +1 -0
- package/dist/types/src/ui/hooks/useProcessManagerRuntime.d.ts +30 -0
- package/dist/types/src/ui/hooks/useProcessManagerRuntime.d.ts.map +1 -0
- package/dist/types/src/ui/hooks/useSettingsState.d.ts +10 -0
- package/dist/types/src/ui/hooks/useSettingsState.d.ts.map +1 -0
- package/dist/types/src/ui/hooks/useSurface.d.ts +3 -0
- package/dist/types/src/ui/hooks/useSurface.d.ts.map +1 -0
- package/dist/types/src/ui/index.d.ts +3 -0
- package/dist/types/src/ui/index.d.ts.map +1 -0
- package/dist/types/src/vite-plugin/boot-loader/index.d.ts +2 -0
- package/dist/types/src/vite-plugin/boot-loader/index.d.ts.map +1 -0
- package/dist/types/src/vite-plugin/boot-loader/loader.d.ts +59 -0
- package/dist/types/src/vite-plugin/boot-loader/loader.d.ts.map +1 -0
- package/dist/types/src/vite-plugin/composer/index.d.ts +34 -0
- package/dist/types/src/vite-plugin/composer/index.d.ts.map +1 -0
- package/dist/types/src/vite-plugin/import-map/index.d.ts +28 -0
- package/dist/types/src/vite-plugin/import-map/index.d.ts.map +1 -0
- package/dist/types/src/vite-plugin/index.d.ts +5 -0
- package/dist/types/src/vite-plugin/index.d.ts.map +1 -0
- package/dist/types/src/vite-plugin/manifest.d.ts +41 -0
- package/dist/types/src/vite-plugin/manifest.d.ts.map +1 -0
- package/dist/types/src/vite-plugin/manifest.test.d.ts +2 -0
- package/dist/types/src/vite-plugin/manifest.test.d.ts.map +1 -0
- package/dist/types/src/vite-plugin/packages.d.ts +13 -0
- package/dist/types/src/vite-plugin/packages.d.ts.map +1 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/moon.yml +26 -3
- package/package.json +125 -55
- package/src/cli/cli.ts +102 -0
- package/src/{playground/layout → cli}/index.ts +1 -1
- package/src/common/activation-events.ts +39 -0
- package/src/{playground/debug/index.ts → common/annotations.ts} +0 -2
- package/src/common/capabilities.ts +287 -184
- package/src/common/index.ts +3 -8
- package/src/common/translations.ts +18 -10
- package/src/context.ts +9 -0
- package/src/core/{events.ts → activation-event.ts} +10 -7
- package/src/core/capability-manager.test.ts +154 -0
- package/src/core/capability-manager.ts +213 -0
- package/src/core/capability.ts +254 -0
- package/src/core/edge-registry-plugin-provider.ts +92 -0
- package/src/core/index.ts +11 -4
- package/src/core/plugin-asset-cache.ts +60 -0
- package/src/core/plugin-manager.test.ts +1929 -0
- package/src/core/plugin-manager.ts +1696 -0
- package/src/core/plugin-manifest.test.ts +75 -0
- package/src/core/plugin-manifest.ts +134 -0
- package/src/core/plugin.ts +458 -46
- package/src/core/registry.ts +163 -0
- package/src/core/url-loader.test.ts +222 -0
- package/src/core/url-loader.ts +388 -0
- package/src/index.ts +2 -4
- package/src/plugin-process-manager/ProcessManagerPlugin.ts +24 -0
- package/src/plugin-process-manager/history/capability.ts +36 -0
- package/src/plugin-process-manager/history/errors.ts +7 -0
- package/src/plugin-process-manager/history/history-tracker.test.ts +353 -0
- package/src/plugin-process-manager/history/history-tracker.ts +144 -0
- package/src/plugin-process-manager/history/index.ts +9 -0
- package/src/plugin-process-manager/history/types.ts +17 -0
- package/src/plugin-process-manager/history/undo-mapping.ts +135 -0
- package/src/plugin-process-manager/history/undo-registry.test.ts +74 -0
- package/src/plugin-process-manager/history/undo-registry.ts +54 -0
- package/src/plugin-process-manager/idb-key-value-store.ts +64 -0
- package/src/plugin-process-manager/index.ts +6 -0
- package/src/plugin-process-manager/meta.ts +16 -0
- package/src/plugin-process-manager/process-manager-capability.ts +178 -0
- package/src/plugin-process-manager/testing.ts +156 -0
- package/src/testing/harness.ts +247 -0
- package/src/testing/index.ts +3 -0
- package/src/testing/operationCapture.ts +144 -0
- package/src/testing/react.test.tsx +50 -0
- package/src/testing/react.tsx +113 -0
- package/src/testing/service.ts +52 -0
- package/src/testing/withPluginManager.stories.tsx +15 -13
- package/src/testing/withPluginManager.tsx +81 -56
- package/src/ui/components/App/App.stories.tsx +84 -0
- package/src/ui/components/App/App.tsx +144 -0
- package/src/{playground/logger → ui/components/App}/index.ts +1 -1
- package/src/ui/components/PluginManager/PluginManagerContext.stories.tsx +179 -0
- package/src/{react → ui/components/PluginManager}/PluginManagerProvider.ts +3 -3
- package/src/ui/components/PluginManager/index.ts +5 -0
- package/src/ui/components/Surface/SurfaceComponent.stories.tsx +144 -0
- package/src/ui/components/Surface/SurfaceComponent.tsx +303 -0
- package/src/ui/components/Surface/SurfaceInfo.tsx +106 -0
- package/src/ui/components/Surface/SurfaceProfilerContext.tsx +207 -0
- package/src/ui/components/Surface/context.ts +12 -0
- package/src/ui/components/Surface/index.ts +54 -0
- package/src/ui/components/Surface/types.test.ts +126 -0
- package/src/ui/components/Surface/types.ts +290 -0
- package/src/ui/components/index.ts +7 -0
- package/src/ui/hooks/index.ts +10 -0
- package/src/ui/hooks/useApp.test.tsx +161 -0
- package/src/ui/hooks/useApp.tsx +404 -0
- package/src/ui/hooks/useCapabilities.ts +68 -0
- package/src/ui/hooks/useLoading.tsx +76 -0
- package/src/ui/hooks/useProcessManagerRuntime.ts +78 -0
- package/src/ui/hooks/useSettingsState.ts +26 -0
- package/src/ui/hooks/useSurface.ts +13 -0
- package/src/ui/index.ts +6 -0
- package/src/vite-plugin/boot-loader/BootLoader.solid-stories.tsx +198 -0
- package/src/vite-plugin/boot-loader/index.ts +5 -0
- package/src/vite-plugin/boot-loader/loader-app/Loader.tsx +166 -0
- package/src/vite-plugin/boot-loader/loader-app/boot-loader.css +311 -0
- package/src/vite-plugin/boot-loader/loader-app/bridge.ts +25 -0
- package/src/vite-plugin/boot-loader/loader-app/entry.tsx +21 -0
- package/src/vite-plugin/boot-loader/loader-app/mount.tsx +70 -0
- package/src/vite-plugin/boot-loader/loader-app/store.test.ts +137 -0
- package/src/vite-plugin/boot-loader/loader-app/store.ts +149 -0
- package/src/vite-plugin/boot-loader/loader-app/tsconfig.json +11 -0
- package/src/vite-plugin/boot-loader/loader-app/types.ts +78 -0
- package/src/vite-plugin/boot-loader/loader.ts +204 -0
- package/src/vite-plugin/composer/index.ts +306 -0
- package/src/vite-plugin/import-map/index.ts +527 -0
- package/src/vite-plugin/index.ts +10 -0
- package/src/vite-plugin/manifest.test.ts +55 -0
- package/src/vite-plugin/manifest.ts +63 -0
- package/src/vite-plugin/packages.ts +187 -0
- package/tsconfig.json +31 -24
- package/tsconfig.node.json +2 -4
- package/typedoc.json +2 -4
- package/vitest.config.ts +8 -6
- package/.swc/plugins/v7_linux_x86_64_13.0.0/c614d7475354583212fbd7669acbae95b9832c305bf51bdaabe2e6de05abb6bf +0 -0
- package/.swc/plugins/v7_linux_x86_64_13.0.0/fce1bdb8e20a094e4af08bad09cc81497ed0e2e7c51223b07d371063cca18429 +0 -0
- package/dist/lib/browser/app-graph-builder-MOVKFH3J.mjs +0 -137
- package/dist/lib/browser/app-graph-builder-MOVKFH3J.mjs.map +0 -7
- package/dist/lib/browser/chunk-NKCIDYDI.mjs +0 -1598
- package/dist/lib/browser/chunk-NKCIDYDI.mjs.map +0 -7
- package/dist/lib/browser/chunk-ORWHM7CO.mjs +0 -32
- package/dist/lib/browser/chunk-ORWHM7CO.mjs.map +0 -7
- package/dist/lib/browser/chunk-OSBZFKMO.mjs +0 -428
- package/dist/lib/browser/chunk-OSBZFKMO.mjs.map +0 -7
- package/dist/lib/browser/intent-dispatcher-FTTJLVGN.mjs +0 -11
- package/dist/lib/browser/intent-resolver-ZCGEAG3E.mjs +0 -39
- package/dist/lib/browser/intent-resolver-ZCGEAG3E.mjs.map +0 -7
- package/dist/lib/browser/store-3QB6Q2BC.mjs +0 -30
- package/dist/lib/browser/store-3QB6Q2BC.mjs.map +0 -7
- package/dist/lib/browser/worker.mjs +0 -79
- package/dist/lib/node-esm/app-graph-builder-ODE4B5GT.mjs +0 -138
- package/dist/lib/node-esm/app-graph-builder-ODE4B5GT.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-UMZQERLE.mjs +0 -34
- package/dist/lib/node-esm/chunk-UMZQERLE.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-WU3QN5B6.mjs +0 -429
- package/dist/lib/node-esm/chunk-WU3QN5B6.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-YEN7NKTF.mjs +0 -1600
- package/dist/lib/node-esm/chunk-YEN7NKTF.mjs.map +0 -7
- package/dist/lib/node-esm/intent-dispatcher-YQIQ55LJ.mjs +0 -12
- package/dist/lib/node-esm/intent-resolver-KG27L7EQ.mjs +0 -40
- package/dist/lib/node-esm/intent-resolver-KG27L7EQ.mjs.map +0 -7
- package/dist/lib/node-esm/store-TIJAVO3D.mjs +0 -31
- package/dist/lib/node-esm/store-TIJAVO3D.mjs.map +0 -7
- package/dist/lib/node-esm/worker.mjs +0 -80
- package/dist/types/src/App.d.ts +0 -43
- package/dist/types/src/App.d.ts.map +0 -1
- package/dist/types/src/common/collaboration.d.ts +0 -19
- package/dist/types/src/common/collaboration.d.ts.map +0 -1
- package/dist/types/src/common/events.d.ts +0 -52
- package/dist/types/src/common/events.d.ts.map +0 -1
- package/dist/types/src/common/file.d.ts +0 -14
- package/dist/types/src/common/file.d.ts.map +0 -1
- package/dist/types/src/common/graph.d.ts +0 -21
- package/dist/types/src/common/graph.d.ts.map +0 -1
- package/dist/types/src/common/layout.d.ts +0 -281
- package/dist/types/src/common/layout.d.ts.map +0 -1
- package/dist/types/src/common/surface.d.ts +0 -65
- package/dist/types/src/common/surface.d.ts.map +0 -1
- package/dist/types/src/core/capabilities.d.ts +0 -114
- package/dist/types/src/core/capabilities.d.ts.map +0 -1
- package/dist/types/src/core/capabilities.test.d.ts +0 -2
- package/dist/types/src/core/capabilities.test.d.ts.map +0 -1
- package/dist/types/src/core/events.d.ts.map +0 -1
- package/dist/types/src/core/manager.d.ts +0 -126
- package/dist/types/src/core/manager.d.ts.map +0 -1
- package/dist/types/src/core/manager.test.d.ts +0 -2
- package/dist/types/src/core/manager.test.d.ts.map +0 -1
- package/dist/types/src/playground/debug/Debug.d.ts +0 -6
- package/dist/types/src/playground/debug/Debug.d.ts.map +0 -1
- package/dist/types/src/playground/debug/index.d.ts +0 -2
- package/dist/types/src/playground/debug/index.d.ts.map +0 -1
- package/dist/types/src/playground/debug/plugin.d.ts +0 -2
- package/dist/types/src/playground/debug/plugin.d.ts.map +0 -1
- package/dist/types/src/playground/generator/Main.d.ts +0 -6
- package/dist/types/src/playground/generator/Main.d.ts.map +0 -1
- package/dist/types/src/playground/generator/Toolbar.d.ts +0 -6
- package/dist/types/src/playground/generator/Toolbar.d.ts.map +0 -1
- package/dist/types/src/playground/generator/generator.d.ts +0 -7
- package/dist/types/src/playground/generator/generator.d.ts.map +0 -1
- package/dist/types/src/playground/generator/index.d.ts +0 -3
- package/dist/types/src/playground/generator/index.d.ts.map +0 -1
- package/dist/types/src/playground/generator/plugin.d.ts +0 -2
- package/dist/types/src/playground/generator/plugin.d.ts.map +0 -1
- package/dist/types/src/playground/layout/Layout.d.ts +0 -8
- package/dist/types/src/playground/layout/Layout.d.ts.map +0 -1
- package/dist/types/src/playground/layout/index.d.ts +0 -2
- package/dist/types/src/playground/layout/index.d.ts.map +0 -1
- package/dist/types/src/playground/layout/plugin.d.ts +0 -2
- package/dist/types/src/playground/layout/plugin.d.ts.map +0 -1
- package/dist/types/src/playground/logger/Toolbar.d.ts +0 -6
- package/dist/types/src/playground/logger/Toolbar.d.ts.map +0 -1
- package/dist/types/src/playground/logger/index.d.ts +0 -2
- package/dist/types/src/playground/logger/index.d.ts.map +0 -1
- package/dist/types/src/playground/logger/plugin.d.ts +0 -2
- package/dist/types/src/playground/logger/plugin.d.ts.map +0 -1
- package/dist/types/src/playground/logger/schema.d.ts +0 -13
- package/dist/types/src/playground/logger/schema.d.ts.map +0 -1
- package/dist/types/src/playground/playground.stories.d.ts +0 -10
- package/dist/types/src/playground/playground.stories.d.ts.map +0 -1
- package/dist/types/src/plugin-intent/IntentPlugin.d.ts +0 -2
- package/dist/types/src/plugin-intent/IntentPlugin.d.ts.map +0 -1
- package/dist/types/src/plugin-intent/actions.d.ts +0 -38
- package/dist/types/src/plugin-intent/actions.d.ts.map +0 -1
- package/dist/types/src/plugin-intent/errors.d.ts +0 -16
- package/dist/types/src/plugin-intent/errors.d.ts.map +0 -1
- package/dist/types/src/plugin-intent/index.d.ts +0 -5
- package/dist/types/src/plugin-intent/index.d.ts.map +0 -1
- package/dist/types/src/plugin-intent/intent-dispatcher.d.ts +0 -139
- package/dist/types/src/plugin-intent/intent-dispatcher.d.ts.map +0 -1
- package/dist/types/src/plugin-intent/intent-dispatcher.test.d.ts +0 -2
- package/dist/types/src/plugin-intent/intent-dispatcher.test.d.ts.map +0 -1
- package/dist/types/src/plugin-intent/intent.d.ts +0 -63
- package/dist/types/src/plugin-intent/intent.d.ts.map +0 -1
- package/dist/types/src/plugin-settings/SettingsPlugin.d.ts +0 -2
- package/dist/types/src/plugin-settings/SettingsPlugin.d.ts.map +0 -1
- package/dist/types/src/plugin-settings/actions.d.ts +0 -27
- package/dist/types/src/plugin-settings/actions.d.ts.map +0 -1
- package/dist/types/src/plugin-settings/app-graph-builder.d.ts +0 -4
- package/dist/types/src/plugin-settings/app-graph-builder.d.ts.map +0 -1
- package/dist/types/src/plugin-settings/index.d.ts +0 -3
- package/dist/types/src/plugin-settings/index.d.ts.map +0 -1
- package/dist/types/src/plugin-settings/intent-resolver.d.ts +0 -4
- package/dist/types/src/plugin-settings/intent-resolver.d.ts.map +0 -1
- package/dist/types/src/plugin-settings/store.d.ts +0 -5
- package/dist/types/src/plugin-settings/store.d.ts.map +0 -1
- package/dist/types/src/plugin-settings/translations.d.ts +0 -10
- package/dist/types/src/plugin-settings/translations.d.ts.map +0 -1
- package/dist/types/src/react/ErrorBoundary.d.ts +0 -30
- package/dist/types/src/react/ErrorBoundary.d.ts.map +0 -1
- package/dist/types/src/react/IntentContext.d.ts +0 -8
- package/dist/types/src/react/IntentContext.d.ts.map +0 -1
- package/dist/types/src/react/PluginManagerProvider.d.ts +0 -10
- package/dist/types/src/react/PluginManagerProvider.d.ts.map +0 -1
- package/dist/types/src/react/Surface.d.ts +0 -12
- package/dist/types/src/react/Surface.d.ts.map +0 -1
- package/dist/types/src/react/Surface.stories.d.ts +0 -16
- package/dist/types/src/react/Surface.stories.d.ts.map +0 -1
- package/dist/types/src/react/common.d.ts +0 -13
- package/dist/types/src/react/common.d.ts.map +0 -1
- package/dist/types/src/react/index.d.ts +0 -7
- package/dist/types/src/react/index.d.ts.map +0 -1
- package/dist/types/src/react/useCapabilities.d.ts +0 -13
- package/dist/types/src/react/useCapabilities.d.ts.map +0 -1
- package/dist/types/src/react/useIntentResolver.d.ts +0 -3
- package/dist/types/src/react/useIntentResolver.d.ts.map +0 -1
- package/dist/types/src/worker.d.ts +0 -4
- package/dist/types/src/worker.d.ts.map +0 -1
- package/src/App.tsx +0 -284
- package/src/common/collaboration.ts +0 -21
- package/src/common/events.ts +0 -79
- package/src/common/file.ts +0 -22
- package/src/common/graph.ts +0 -30
- package/src/common/layout.ts +0 -278
- package/src/common/surface.ts +0 -86
- package/src/core/capabilities.test.ts +0 -136
- package/src/core/capabilities.ts +0 -255
- package/src/core/manager.test.ts +0 -516
- package/src/core/manager.ts +0 -597
- package/src/playground/debug/Debug.tsx +0 -39
- package/src/playground/debug/plugin.ts +0 -17
- package/src/playground/generator/Main.tsx +0 -71
- package/src/playground/generator/Toolbar.tsx +0 -47
- package/src/playground/generator/generator.ts +0 -48
- package/src/playground/generator/index.ts +0 -6
- package/src/playground/generator/plugin.ts +0 -23
- package/src/playground/layout/Layout.tsx +0 -33
- package/src/playground/layout/plugin.ts +0 -17
- package/src/playground/logger/Toolbar.tsx +0 -30
- package/src/playground/logger/plugin.ts +0 -37
- package/src/playground/logger/schema.ts +0 -12
- package/src/playground/playground.stories.tsx +0 -43
- package/src/plugin-intent/IntentPlugin.ts +0 -21
- package/src/plugin-intent/actions.ts +0 -33
- package/src/plugin-intent/errors.ts +0 -39
- package/src/plugin-intent/index.ts +0 -8
- package/src/plugin-intent/intent-dispatcher.test.ts +0 -279
- package/src/plugin-intent/intent-dispatcher.ts +0 -334
- package/src/plugin-intent/intent.ts +0 -154
- package/src/plugin-settings/SettingsPlugin.ts +0 -36
- package/src/plugin-settings/actions.ts +0 -29
- package/src/plugin-settings/app-graph-builder.ts +0 -158
- package/src/plugin-settings/index.ts +0 -6
- package/src/plugin-settings/intent-resolver.ts +0 -35
- package/src/plugin-settings/store.ts +0 -33
- package/src/plugin-settings/translations.ts +0 -19
- package/src/react/ErrorBoundary.tsx +0 -54
- package/src/react/IntentContext.tsx +0 -35
- package/src/react/Surface.stories.tsx +0 -97
- package/src/react/Surface.tsx +0 -78
- package/src/react/common.ts +0 -13
- package/src/react/index.ts +0 -10
- package/src/react/useCapabilities.ts +0 -31
- package/src/react/useIntentResolver.ts +0 -22
- package/src/worker.ts +0 -11
- /package/dist/lib/browser/{intent-dispatcher-FTTJLVGN.mjs.map → chunk-J5LGTIGS.mjs.map} +0 -0
- /package/dist/lib/browser/{worker.mjs.map → common/activation-events.mjs.map} +0 -0
- /package/dist/lib/{node-esm/intent-dispatcher-YQIQ55LJ.mjs.map → browser/common/capabilities.mjs.map} +0 -0
- /package/dist/lib/{node-esm/worker.mjs.map → browser/core/activation-event.mjs.map} +0 -0
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type Registry } from '@effect-atom/atom-react';
|
|
6
|
+
import * as Duration from 'effect/Duration';
|
|
7
|
+
import * as Effect from 'effect/Effect';
|
|
8
|
+
import * as PubSub from 'effect/PubSub';
|
|
9
|
+
import * as Queue from 'effect/Queue';
|
|
10
|
+
|
|
11
|
+
import { type Operation } from '@dxos/compute';
|
|
12
|
+
import { EffectEx } from '@dxos/effect';
|
|
13
|
+
import { invariant } from '@dxos/invariant';
|
|
14
|
+
|
|
15
|
+
import { ActivationEvents, Capabilities } from '../common';
|
|
16
|
+
import { ActivationEvent, type Capability, type CapabilityManager, type Plugin, PluginManager } from '../core';
|
|
17
|
+
|
|
18
|
+
export type TestAppOptions = {
|
|
19
|
+
/**
|
|
20
|
+
* Plugins to register. Plugins whose `meta.tags` includes `'system'` are treated as core
|
|
21
|
+
* (force-enabled). For test convenience, plugins without a `'system'` tag are enabled by
|
|
22
|
+
* default unless `enabled` is provided.
|
|
23
|
+
*/
|
|
24
|
+
plugins: Plugin.Plugin[];
|
|
25
|
+
/** Plugin ids that are enabled by default in addition to core. Defaults to all non-system plugin ids. */
|
|
26
|
+
enabled?: string[];
|
|
27
|
+
/** Additional activation events fired alongside SetupReactSurface. */
|
|
28
|
+
setupEvents?: ActivationEvent.ActivationEvent[];
|
|
29
|
+
/**
|
|
30
|
+
* Whether to automatically fire SetupReactSurface + Startup during setup.
|
|
31
|
+
* Defaults to true.
|
|
32
|
+
*/
|
|
33
|
+
autoStart?: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Whether to register the PluginManager + AtomRegistry framework capabilities.
|
|
36
|
+
* Defaults to true.
|
|
37
|
+
*/
|
|
38
|
+
registerFrameworkCapabilities?: boolean;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* A running plugin manager plus helpers for driving it in tests.
|
|
43
|
+
*/
|
|
44
|
+
export interface TestHarness {
|
|
45
|
+
readonly manager: PluginManager.PluginManager;
|
|
46
|
+
readonly capabilities: CapabilityManager.CapabilityManager;
|
|
47
|
+
readonly registry: Registry.Registry;
|
|
48
|
+
|
|
49
|
+
/** Activate the given event. Equivalent to `manager.activate(event)`. */
|
|
50
|
+
fire(event: ActivationEvent.ActivationEvent | string): Promise<boolean>;
|
|
51
|
+
/** Re-activate all modules that were activated by the given event. */
|
|
52
|
+
reset(event: ActivationEvent.ActivationEvent | string): Promise<boolean>;
|
|
53
|
+
|
|
54
|
+
/** Returns the first contributed capability for the given interface. Throws if none are present. */
|
|
55
|
+
get<T>(iface: Capability.InterfaceDef<T>): T;
|
|
56
|
+
/** Returns all contributed capabilities for the given interface. */
|
|
57
|
+
getAll<T>(iface: Capability.InterfaceDef<T>): T[];
|
|
58
|
+
/** Waits until at least one capability is contributed for the given interface. */
|
|
59
|
+
waitForCapability<T>(iface: Capability.InterfaceDef<T>, opts?: { timeout?: number }): Promise<T>;
|
|
60
|
+
/** Waits until the given activation event has completed. */
|
|
61
|
+
waitForEvent(event: ActivationEvent.ActivationEvent | string, opts?: { timeout?: number }): Promise<void>;
|
|
62
|
+
|
|
63
|
+
/** Invokes an operation through the `Capabilities.OperationInvoker` capability. */
|
|
64
|
+
invoke<I, O>(op: Operation.Definition<I, O>, ...args: void extends I ? [input?: I] : [input: I]): Promise<O>;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Waits for `Capabilities.ProcessManagerRuntime` and runs the given effect on it.
|
|
68
|
+
* Convenience around `waitForCapability(ProcessManagerRuntime).runPromise(effect)`.
|
|
69
|
+
*/
|
|
70
|
+
runPromise<A, E>(
|
|
71
|
+
effect: Effect.Effect<A, E, Capabilities.ProcessManagerRuntimeServices>,
|
|
72
|
+
options?: { readonly timeout?: number; readonly signal?: AbortSignal },
|
|
73
|
+
): Promise<A>;
|
|
74
|
+
|
|
75
|
+
enable(id: string): Promise<boolean>;
|
|
76
|
+
disable(id: string): Promise<boolean>;
|
|
77
|
+
|
|
78
|
+
/** Shuts down the underlying plugin manager. */
|
|
79
|
+
dispose(): Promise<void>;
|
|
80
|
+
|
|
81
|
+
/** Async-disposable support so tests can use `await using harness = ...`. */
|
|
82
|
+
[Symbol.asyncDispose](): Promise<void>;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const DEFAULT_TIMEOUT_MS = 5_000;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Creates a TestHarness with the same bootstrap sequence that `useApp` performs,
|
|
89
|
+
* minus the React provider tree.
|
|
90
|
+
*
|
|
91
|
+
* For Node-only tests, this is enough to fire activation events, read
|
|
92
|
+
* capabilities, and invoke operations.
|
|
93
|
+
*
|
|
94
|
+
* For React tests, pass the returned harness to `render` or `renderSurface`
|
|
95
|
+
* from `@dxos/app-framework/testing-react`.
|
|
96
|
+
*/
|
|
97
|
+
export const createTestApp = async (opts: TestAppOptions): Promise<TestHarness> => {
|
|
98
|
+
const {
|
|
99
|
+
plugins,
|
|
100
|
+
enabled = plugins.filter(({ meta }) => !meta.tags?.includes('system')).map((plugin) => plugin.meta.id),
|
|
101
|
+
setupEvents = [],
|
|
102
|
+
autoStart = true,
|
|
103
|
+
registerFrameworkCapabilities = true,
|
|
104
|
+
} = opts;
|
|
105
|
+
|
|
106
|
+
const pluginLoader = (id: string) =>
|
|
107
|
+
Effect.sync(() => {
|
|
108
|
+
const plugin = plugins.find((plugin) => plugin.meta.id === id);
|
|
109
|
+
invariant(plugin, `Plugin not found: ${id}`);
|
|
110
|
+
return { plugin };
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
const manager = PluginManager.make({ pluginLoader, plugins, enabled });
|
|
114
|
+
|
|
115
|
+
if (registerFrameworkCapabilities) {
|
|
116
|
+
manager.capabilities.contribute({
|
|
117
|
+
interface: Capabilities.PluginManager,
|
|
118
|
+
implementation: manager,
|
|
119
|
+
module: 'org.dxos.app-framework.plugin-manager',
|
|
120
|
+
});
|
|
121
|
+
manager.capabilities.contribute({
|
|
122
|
+
interface: Capabilities.AtomRegistry,
|
|
123
|
+
implementation: manager.registry,
|
|
124
|
+
module: 'org.dxos.app-framework.atom-registry',
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (autoStart) {
|
|
129
|
+
try {
|
|
130
|
+
await EffectEx.runAndForwardErrors(
|
|
131
|
+
Effect.all([
|
|
132
|
+
...setupEvents.map((event) => manager.activate(event)),
|
|
133
|
+
manager.activate(ActivationEvents.SetupReactSurface),
|
|
134
|
+
manager.activate(ActivationEvents.Startup),
|
|
135
|
+
]),
|
|
136
|
+
);
|
|
137
|
+
} catch (err) {
|
|
138
|
+
await EffectEx.runAndForwardErrors(manager.shutdown()).catch(() => undefined);
|
|
139
|
+
throw err;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return new TestHarnessImpl(manager);
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
class TestHarnessImpl implements TestHarness {
|
|
147
|
+
constructor(readonly manager: PluginManager.PluginManager) {}
|
|
148
|
+
|
|
149
|
+
get capabilities(): CapabilityManager.CapabilityManager {
|
|
150
|
+
return this.manager.capabilities;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
get registry(): Registry.Registry {
|
|
154
|
+
return this.manager.registry;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
fire(event: ActivationEvent.ActivationEvent | string): Promise<boolean> {
|
|
158
|
+
return EffectEx.runAndForwardErrors(this.manager.activate(event));
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
reset(event: ActivationEvent.ActivationEvent | string): Promise<boolean> {
|
|
162
|
+
return EffectEx.runAndForwardErrors(this.manager.reset(event));
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
get<T>(iface: Capability.InterfaceDef<T>): T {
|
|
166
|
+
return this.manager.capabilities.get(iface);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
getAll<T>(iface: Capability.InterfaceDef<T>): T[] {
|
|
170
|
+
return this.manager.capabilities.getAll(iface);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
waitForCapability<T>(iface: Capability.InterfaceDef<T>, opts?: { timeout?: number }): Promise<T> {
|
|
174
|
+
const timeout = opts?.timeout ?? DEFAULT_TIMEOUT_MS;
|
|
175
|
+
return EffectEx.runAndForwardErrors(
|
|
176
|
+
this.manager.capabilities.waitFor(iface).pipe(
|
|
177
|
+
Effect.timeoutFail({
|
|
178
|
+
duration: Duration.millis(timeout),
|
|
179
|
+
onTimeout: () => timeoutError(iface.identifier),
|
|
180
|
+
}),
|
|
181
|
+
),
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
waitForEvent(event: ActivationEvent.ActivationEvent | string, opts?: { timeout?: number }): Promise<void> {
|
|
186
|
+
const key = typeof event === 'string' ? event : ActivationEvent.eventKey(event);
|
|
187
|
+
const timeout = opts?.timeout ?? DEFAULT_TIMEOUT_MS;
|
|
188
|
+
|
|
189
|
+
const program = Effect.gen(this, function* () {
|
|
190
|
+
const queue = yield* PubSub.subscribe(this.manager.activation);
|
|
191
|
+
// Re-check after subscribing to avoid a race where the event fires
|
|
192
|
+
// between the caller invoking this and the subscription being installed.
|
|
193
|
+
if (this.manager.getEventsFired().includes(key)) {
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
while (true) {
|
|
197
|
+
const message = yield* Queue.take(queue);
|
|
198
|
+
if (message.event === key && message.state === 'activated') {
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}).pipe(
|
|
203
|
+
Effect.scoped,
|
|
204
|
+
Effect.timeoutFail({
|
|
205
|
+
duration: Duration.millis(timeout),
|
|
206
|
+
onTimeout: () => timeoutError(key),
|
|
207
|
+
}),
|
|
208
|
+
);
|
|
209
|
+
|
|
210
|
+
return EffectEx.runAndForwardErrors(program);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
async invoke<I, O>(op: Operation.Definition<I, O>, ...args: [input?: I]): Promise<O> {
|
|
214
|
+
const invoker = await this.waitForCapability(Capabilities.OperationInvoker);
|
|
215
|
+
const result = await invoker.invokePromise(op as any, ...(args as [any]));
|
|
216
|
+
if (result.error) {
|
|
217
|
+
throw result.error;
|
|
218
|
+
}
|
|
219
|
+
return result.data as O;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
async runPromise<A, E>(
|
|
223
|
+
effect: Effect.Effect<A, E, Capabilities.ProcessManagerRuntimeServices>,
|
|
224
|
+
options?: { readonly timeout?: number; readonly signal?: AbortSignal },
|
|
225
|
+
): Promise<A> {
|
|
226
|
+
const runtime = await this.waitForCapability(Capabilities.ProcessManagerRuntime, { timeout: options?.timeout });
|
|
227
|
+
return runtime.runPromise(effect, options?.signal ? { signal: options.signal } : undefined);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
enable(id: string): Promise<boolean> {
|
|
231
|
+
return EffectEx.runAndForwardErrors(this.manager.enable(id));
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
disable(id: string): Promise<boolean> {
|
|
235
|
+
return EffectEx.runAndForwardErrors(this.manager.disable(id));
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
async dispose(): Promise<void> {
|
|
239
|
+
await EffectEx.runAndForwardErrors(this.manager.shutdown());
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
[Symbol.asyncDispose](): Promise<void> {
|
|
243
|
+
return this.dispose();
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
const timeoutError = (id: string) => new Error(`Timed out waiting for ${id}`);
|
package/src/testing/index.ts
CHANGED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import * as Effect from 'effect/Effect';
|
|
6
|
+
|
|
7
|
+
import { type Operation } from '@dxos/compute';
|
|
8
|
+
|
|
9
|
+
import { Capabilities } from '../common';
|
|
10
|
+
import { Capability } from '../core';
|
|
11
|
+
|
|
12
|
+
export type CapturedCall<I = unknown> = {
|
|
13
|
+
/** The DXN key string of the invoked operation. */
|
|
14
|
+
operationKey: string;
|
|
15
|
+
/** The input passed to the operation. */
|
|
16
|
+
input: I;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
type CapabilityManagerLike = {
|
|
20
|
+
get: (cap: Capability.InterfaceDef<Capabilities.OperationInvoker>) => Capabilities.OperationInvoker;
|
|
21
|
+
getAll: (cap: Capability.InterfaceDef<Capabilities.OperationInvoker>) => Capabilities.OperationInvoker[];
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export type OperationCapture = {
|
|
25
|
+
/**
|
|
26
|
+
* Wraps the real OperationInvoker from the given manager. Pass to
|
|
27
|
+
* `withPluginManager({ capabilities: (m) => capture.wrap(m) })`.
|
|
28
|
+
*/
|
|
29
|
+
wrap(manager: CapabilityManagerLike): Capability.Any[];
|
|
30
|
+
/** Returns all recorded calls (mocked or real) for the given operation. */
|
|
31
|
+
getCalls<I, O>(op: Operation.Definition<I, O>): CapturedCall<I>[];
|
|
32
|
+
/** Clears all recorded calls (useful between play function steps). */
|
|
33
|
+
reset(): void;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Creates a capture that wraps the real `Capabilities.OperationInvoker`:
|
|
38
|
+
*
|
|
39
|
+
* - **Mocked operations** (declared in `mockedOperations`) are intercepted: the call is recorded
|
|
40
|
+
* and returns `{ data: undefined }` without executing. Use this for side-effecting operations
|
|
41
|
+
* you don't want to run in tests, such as `LayoutOperation.Open` (navigation).
|
|
42
|
+
*
|
|
43
|
+
* - **All other operations** are forwarded to the real invoker and still execute normally. The
|
|
44
|
+
* call is still recorded so you can assert it was triggered even though it ran for real.
|
|
45
|
+
*
|
|
46
|
+
* Pass a `spyFn` wrapper (e.g. `fn` from `storybook/test`) to get Storybook Actions panel
|
|
47
|
+
* integration and vi-style matchers on the recording.
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```ts
|
|
51
|
+
* import { fn } from 'storybook/test';
|
|
52
|
+
*
|
|
53
|
+
* const capture = makeOperationCapture(
|
|
54
|
+
* // These ops are mocked: captured but not executed.
|
|
55
|
+
* [AssistantOperation.RunPromptInNewChat, LayoutOperation.Open],
|
|
56
|
+
* fn,
|
|
57
|
+
* );
|
|
58
|
+
*
|
|
59
|
+
* // Wire into withPluginManager:
|
|
60
|
+
* capabilities: (manager) => capture.wrap(manager)
|
|
61
|
+
*
|
|
62
|
+
* // Assert in a play function:
|
|
63
|
+
* const calls = capture.getCalls(AssistantOperation.RunPromptInNewChat);
|
|
64
|
+
* expect(calls).toHaveLength(1);
|
|
65
|
+
* expect(calls[0].input.prompt).toBe('Draft a new document');
|
|
66
|
+
* ```
|
|
67
|
+
*
|
|
68
|
+
* @idiom org.dxos.app-framework.testing.operationCapture
|
|
69
|
+
* applies: Storybook play-function tests for components that call plugin operations
|
|
70
|
+
* instead-of: Loading every plugin whose operations the component triggers
|
|
71
|
+
* uses: {@link makeOperationCapture}, {@link withPluginManager}
|
|
72
|
+
*/
|
|
73
|
+
export const makeOperationCapture = (
|
|
74
|
+
mockedOperations: readonly Operation.Definition.Any[],
|
|
75
|
+
spyFn?: (impl: (...args: any[]) => any) => any,
|
|
76
|
+
): OperationCapture => {
|
|
77
|
+
const calls: CapturedCall[] = [];
|
|
78
|
+
|
|
79
|
+
const mockedKeys = new Set(mockedOperations.map((op) => String(op.meta.key)));
|
|
80
|
+
|
|
81
|
+
const record = (op: Operation.Definition<any, any>, input?: unknown) => {
|
|
82
|
+
calls.push({ operationKey: String(op.meta.key), input: input ?? {} });
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const recordFn = spyFn ? spyFn(record) : record;
|
|
86
|
+
|
|
87
|
+
return {
|
|
88
|
+
wrap(manager) {
|
|
89
|
+
// Use getAll to find the real invoker that was registered before our wrapper. manager.get
|
|
90
|
+
// returns the last contribution (ours, once added), but getAll returns them all in order.
|
|
91
|
+
// On first invocation (when activation is complete) we find the non-wrapper contribution.
|
|
92
|
+
let real: Capabilities.OperationInvoker | undefined;
|
|
93
|
+
const delegate = () => {
|
|
94
|
+
if (!real) {
|
|
95
|
+
const all = manager.getAll(Capabilities.OperationInvoker);
|
|
96
|
+
real = all.find((inv) => inv !== wrapped);
|
|
97
|
+
}
|
|
98
|
+
return real;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
const wrapped: Capabilities.OperationInvoker = {
|
|
102
|
+
get invocations() {
|
|
103
|
+
return delegate()!.invocations;
|
|
104
|
+
},
|
|
105
|
+
get pendingFollowups() {
|
|
106
|
+
return delegate()!.pendingFollowups;
|
|
107
|
+
},
|
|
108
|
+
get awaitFollowups() {
|
|
109
|
+
return delegate()!.awaitFollowups;
|
|
110
|
+
},
|
|
111
|
+
invoke: (op: Operation.Definition<any, any>, input?: unknown, ...rest: any[]) => {
|
|
112
|
+
recordFn(op, input);
|
|
113
|
+
if (mockedKeys.has(String(op.meta.key))) {
|
|
114
|
+
return Effect.succeed(undefined as any);
|
|
115
|
+
}
|
|
116
|
+
return (delegate()!.invoke as any)(op, input, ...rest);
|
|
117
|
+
},
|
|
118
|
+
invokePromise: async (op: Operation.Definition<any, any>, input?: unknown, ...rest: any[]) => {
|
|
119
|
+
recordFn(op, input);
|
|
120
|
+
if (mockedKeys.has(String(op.meta.key))) {
|
|
121
|
+
return { data: undefined };
|
|
122
|
+
}
|
|
123
|
+
return (delegate()!.invokePromise as any)(op, input, ...rest);
|
|
124
|
+
},
|
|
125
|
+
schedule: (op: Operation.Definition<any, any>, input?: unknown, ...rest: any[]) => {
|
|
126
|
+
recordFn(op, input);
|
|
127
|
+
if (mockedKeys.has(String(op.meta.key))) {
|
|
128
|
+
return Effect.succeed(undefined);
|
|
129
|
+
}
|
|
130
|
+
return (delegate()!.schedule as any)(op, input, ...rest);
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
return [Capability.contributes(Capabilities.OperationInvoker, wrapped)];
|
|
135
|
+
},
|
|
136
|
+
getCalls<I, O>(op: Operation.Definition<I, O>): CapturedCall<I>[] {
|
|
137
|
+
const key = String(op.meta.key);
|
|
138
|
+
return calls.filter((c) => c.operationKey === key) as CapturedCall<I>[];
|
|
139
|
+
},
|
|
140
|
+
reset() {
|
|
141
|
+
calls.length = 0;
|
|
142
|
+
},
|
|
143
|
+
};
|
|
144
|
+
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import * as Effect from 'effect/Effect';
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import { describe, test } from 'vitest';
|
|
8
|
+
|
|
9
|
+
import { DXN } from '@dxos/keys';
|
|
10
|
+
|
|
11
|
+
import { ActivationEvents, Capabilities } from '../common';
|
|
12
|
+
import { Capability, Plugin } from '../core';
|
|
13
|
+
import { Surface } from '../ui';
|
|
14
|
+
import { createTestApp } from './harness';
|
|
15
|
+
import { render, renderSurface } from './react';
|
|
16
|
+
|
|
17
|
+
const testMeta = Plugin.makeMeta({ key: DXN.make('org.dxos.plugin.test.reactHarness'), name: 'ReactHarnessTest' });
|
|
18
|
+
|
|
19
|
+
const TestPlugin = Plugin.define(testMeta).pipe(
|
|
20
|
+
Plugin.addModule({
|
|
21
|
+
id: 'surfaces',
|
|
22
|
+
activatesOn: ActivationEvents.SetupReactSurface,
|
|
23
|
+
activate: () =>
|
|
24
|
+
Effect.succeed(
|
|
25
|
+
Capability.contributes(Capabilities.ReactSurface, [
|
|
26
|
+
Surface.create<{ message: string }>({
|
|
27
|
+
id: 'greeting',
|
|
28
|
+
role: 'greeting',
|
|
29
|
+
component: ({ data }) => <span data-testid='greeting'>hello {data.message}</span>,
|
|
30
|
+
}),
|
|
31
|
+
]),
|
|
32
|
+
),
|
|
33
|
+
}),
|
|
34
|
+
Plugin.make,
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
describe('testing/react', () => {
|
|
38
|
+
test('render wraps ui in the harness provider tree', async ({ expect }) => {
|
|
39
|
+
await using harness = await createTestApp({ plugins: [TestPlugin()] });
|
|
40
|
+
const view = render(harness, <span data-testid='hello'>world</span>);
|
|
41
|
+
expect(view.getByTestId('hello').textContent).toBe('world');
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
test('renderSurface mounts a surface registered by a plugin', async ({ expect }) => {
|
|
45
|
+
await using harness = await createTestApp({ plugins: [TestPlugin()] });
|
|
46
|
+
const view = renderSurface(harness, { role: 'greeting', data: { message: 'plugins' } });
|
|
47
|
+
const node = await view.findByTestId('greeting');
|
|
48
|
+
expect(node.textContent).toBe('hello plugins');
|
|
49
|
+
});
|
|
50
|
+
});
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { RegistryContext } from '@effect-atom/atom-react';
|
|
6
|
+
import { render as rtlRender, type RenderOptions, type RenderResult } from '@testing-library/react';
|
|
7
|
+
import React, { type FC, Fragment, type PropsWithChildren, type ReactNode } from 'react';
|
|
8
|
+
|
|
9
|
+
import { ContextProtocolProvider } from '@dxos/web-context-react';
|
|
10
|
+
|
|
11
|
+
import { Capabilities } from '../common';
|
|
12
|
+
import { PluginManagerContext } from '../context';
|
|
13
|
+
import { topologicalSort } from '../helpers';
|
|
14
|
+
import { PluginManagerProvider } from '../ui/components/PluginManager/PluginManagerProvider';
|
|
15
|
+
import { SurfaceComponent } from '../ui/components/Surface/SurfaceComponent';
|
|
16
|
+
import { type TestHarness } from './harness';
|
|
17
|
+
|
|
18
|
+
export type HarnessRenderOptions = Omit<RenderOptions, 'wrapper'> & {
|
|
19
|
+
/** Additional providers to wrap around the harness tree (applied innermost first). */
|
|
20
|
+
reactContexts?: FC<PropsWithChildren>[];
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Renders `ui` wrapped in the same provider tree as `useApp` plus every contributed
|
|
25
|
+
* `Capabilities.ReactContext`.
|
|
26
|
+
*/
|
|
27
|
+
export const render = (harness: TestHarness, ui: ReactNode, options?: HarnessRenderOptions): RenderResult => {
|
|
28
|
+
const { reactContexts = [], ...rest } = options ?? {};
|
|
29
|
+
const Wrapper = ({ children }: PropsWithChildren) => (
|
|
30
|
+
<HarnessProviders harness={harness} extra={reactContexts}>
|
|
31
|
+
{children}
|
|
32
|
+
</HarnessProviders>
|
|
33
|
+
);
|
|
34
|
+
return rtlRender(<>{ui}</>, { ...rest, wrapper: Wrapper });
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export type RenderSurfaceProps = {
|
|
38
|
+
role: string;
|
|
39
|
+
data?: unknown;
|
|
40
|
+
limit?: number;
|
|
41
|
+
fallback?: FC<{ error: Error; data?: any }>;
|
|
42
|
+
placeholder?: ReactNode;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Renders a `Surface` with the given role/data inside the harness provider tree.
|
|
47
|
+
*/
|
|
48
|
+
export const renderSurface = (
|
|
49
|
+
harness: TestHarness,
|
|
50
|
+
props: RenderSurfaceProps,
|
|
51
|
+
options?: HarnessRenderOptions,
|
|
52
|
+
): RenderResult => {
|
|
53
|
+
const { role, data, limit, fallback, placeholder } = props;
|
|
54
|
+
return render(
|
|
55
|
+
harness,
|
|
56
|
+
<SurfaceComponent role={role} data={data as any} limit={limit} fallback={fallback} placeholder={placeholder} />,
|
|
57
|
+
options,
|
|
58
|
+
);
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
type HarnessProvidersProps = PropsWithChildren<{
|
|
62
|
+
harness: TestHarness;
|
|
63
|
+
extra: FC<PropsWithChildren>[];
|
|
64
|
+
}>;
|
|
65
|
+
|
|
66
|
+
const HarnessProviders = ({ harness, extra, children }: HarnessProvidersProps) => {
|
|
67
|
+
const contributed = harness.getAll(Capabilities.ReactContext);
|
|
68
|
+
const ContributedContext = composeContexts(contributed);
|
|
69
|
+
const ExtraContext = composeExtra(extra);
|
|
70
|
+
return (
|
|
71
|
+
<PluginManagerProvider value={harness.manager}>
|
|
72
|
+
<ContextProtocolProvider value={harness.manager} context={PluginManagerContext}>
|
|
73
|
+
<RegistryContext.Provider value={harness.registry}>
|
|
74
|
+
<ContributedContext>
|
|
75
|
+
<ExtraContext>{children}</ExtraContext>
|
|
76
|
+
</ContributedContext>
|
|
77
|
+
</RegistryContext.Provider>
|
|
78
|
+
</ContextProtocolProvider>
|
|
79
|
+
</PluginManagerProvider>
|
|
80
|
+
);
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const composeContexts = (contexts: Capabilities.ReactContext[]): FC<PropsWithChildren> => {
|
|
84
|
+
if (contexts.length === 0) {
|
|
85
|
+
return Passthrough;
|
|
86
|
+
}
|
|
87
|
+
return topologicalSort(contexts)
|
|
88
|
+
.map(({ context }) => context)
|
|
89
|
+
.reduce((Acc, Next) => ({ children }: PropsWithChildren) => (
|
|
90
|
+
<Acc>
|
|
91
|
+
<Next>{children}</Next>
|
|
92
|
+
</Acc>
|
|
93
|
+
));
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
// Composes in innermost-first order: the first context in the array wraps
|
|
97
|
+
// `children` directly; subsequent contexts wrap the accumulator.
|
|
98
|
+
const composeExtra = (contexts: FC<PropsWithChildren>[]): FC<PropsWithChildren> => {
|
|
99
|
+
if (contexts.length === 0) {
|
|
100
|
+
return Passthrough;
|
|
101
|
+
}
|
|
102
|
+
return contexts.reduce<FC<PropsWithChildren>>(
|
|
103
|
+
(Acc, Next) =>
|
|
104
|
+
({ children }: PropsWithChildren) => (
|
|
105
|
+
<Next>
|
|
106
|
+
<Acc>{children}</Acc>
|
|
107
|
+
</Next>
|
|
108
|
+
),
|
|
109
|
+
Passthrough,
|
|
110
|
+
);
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
const Passthrough: FC<PropsWithChildren> = ({ children }) => <Fragment>{children}</Fragment>;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import * as Effect from 'effect/Effect';
|
|
6
|
+
import * as Layer from 'effect/Layer';
|
|
7
|
+
|
|
8
|
+
import { invariant } from '@dxos/invariant';
|
|
9
|
+
|
|
10
|
+
import { ActivationEvents, Capabilities } from '../common';
|
|
11
|
+
import { Plugin, PluginManager } from '../core';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Creates a Plugin.Service layer from a list of plugins.
|
|
15
|
+
* This is primarily used for testing.
|
|
16
|
+
*/
|
|
17
|
+
export const fromPlugins = (plugins: Plugin.Plugin[]) =>
|
|
18
|
+
Layer.effect(
|
|
19
|
+
Plugin.Service,
|
|
20
|
+
Effect.gen(function* () {
|
|
21
|
+
// TODO(wittjosiah): Try to dedupe logic between here, createCliApp and useApp.
|
|
22
|
+
|
|
23
|
+
const pluginLoader = (id: string) =>
|
|
24
|
+
Effect.sync(() => {
|
|
25
|
+
const plugin = plugins.find((plugin) => plugin.meta.id === id);
|
|
26
|
+
invariant(plugin, `Plugin not found: ${id}`);
|
|
27
|
+
return { plugin };
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
const manager = PluginManager.make({
|
|
31
|
+
pluginLoader,
|
|
32
|
+
plugins,
|
|
33
|
+
enabled: plugins.map((plugin) => plugin.meta.id),
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
manager.capabilities.contribute({
|
|
37
|
+
interface: Capabilities.PluginManager,
|
|
38
|
+
implementation: manager,
|
|
39
|
+
module: 'org.dxos.app-framework.plugin-manager',
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
manager.capabilities.contribute({
|
|
43
|
+
interface: Capabilities.AtomRegistry,
|
|
44
|
+
implementation: manager.registry,
|
|
45
|
+
module: 'org.dxos.app-framework.atom-registry',
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
yield* manager.activate(ActivationEvents.Startup);
|
|
49
|
+
|
|
50
|
+
return manager;
|
|
51
|
+
}),
|
|
52
|
+
);
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
5
6
|
import React from 'react';
|
|
6
7
|
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
import { Capabilities, createSurface } from '../common';
|
|
10
|
-
import { contributes } from '../core';
|
|
11
|
-
import { Surface } from '../react';
|
|
8
|
+
import { withTheme } from '@dxos/react-ui/testing';
|
|
12
9
|
|
|
10
|
+
import { Capabilities } from '../common';
|
|
11
|
+
import { Capability } from '../core';
|
|
12
|
+
import { Surface } from '../ui';
|
|
13
13
|
import { withPluginManager } from './withPluginManager';
|
|
14
14
|
|
|
15
15
|
const DefaultStory = () => {
|
|
@@ -17,21 +17,21 @@ const DefaultStory = () => {
|
|
|
17
17
|
return (
|
|
18
18
|
<div>
|
|
19
19
|
<div>Hello</div>
|
|
20
|
-
<Surface role='main' />
|
|
20
|
+
<Surface.Surface role='main' />
|
|
21
21
|
</div>
|
|
22
22
|
);
|
|
23
23
|
};
|
|
24
24
|
|
|
25
|
-
const meta
|
|
26
|
-
title: 'sdk/app-framework/withPluginManager',
|
|
25
|
+
const meta = {
|
|
26
|
+
title: 'sdk/app-framework/testing/withPluginManager',
|
|
27
27
|
render: DefaultStory,
|
|
28
28
|
decorators: [
|
|
29
|
-
withTheme,
|
|
29
|
+
withTheme(),
|
|
30
30
|
withPluginManager({
|
|
31
31
|
capabilities: [
|
|
32
|
-
contributes(
|
|
32
|
+
Capability.contributes(
|
|
33
33
|
Capabilities.ReactSurface,
|
|
34
|
-
|
|
34
|
+
Surface.create({
|
|
35
35
|
id: 'test',
|
|
36
36
|
role: 'main',
|
|
37
37
|
component: ({ role }) => <span>{JSON.stringify({ role })}</span>,
|
|
@@ -40,8 +40,10 @@ const meta: Meta = {
|
|
|
40
40
|
],
|
|
41
41
|
}),
|
|
42
42
|
],
|
|
43
|
-
}
|
|
43
|
+
} satisfies Meta<typeof DefaultStory>;
|
|
44
44
|
|
|
45
45
|
export default meta;
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
type Story = StoryObj<typeof meta>;
|
|
48
|
+
|
|
49
|
+
export const Default: Story = {};
|