@dxos/app-framework 0.8.4-main.40e3dcdf1b → 0.8.4-main.43cb759274
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/LICENSE +102 -5
- package/README.md +1 -1
- package/dist/lib/browser/{capability-LF3OXSCV.mjs → capability-JCUNWZ66.mjs} +12 -11
- package/dist/lib/browser/capability-JCUNWZ66.mjs.map +7 -0
- package/dist/lib/browser/{chunk-WEBSGU5L.mjs → chunk-2ZIYRDAF.mjs} +20 -5
- package/dist/lib/browser/chunk-2ZIYRDAF.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-272IPLHQ.mjs → chunk-66IXTIVK.mjs} +3 -2
- package/dist/lib/browser/chunk-66IXTIVK.mjs.map +7 -0
- package/dist/lib/browser/chunk-7MBI66M7.mjs +587 -0
- package/dist/lib/browser/chunk-7MBI66M7.mjs.map +7 -0
- package/dist/lib/browser/chunk-BMLCIFZW.mjs +1467 -0
- package/dist/lib/browser/chunk-BMLCIFZW.mjs.map +7 -0
- package/dist/lib/browser/{chunk-7M4467QR.mjs → chunk-DC3WRPBV.mjs} +100 -18
- package/dist/lib/browser/chunk-DC3WRPBV.mjs.map +7 -0
- package/dist/lib/browser/{chunk-JGWCBVKJ.mjs → chunk-E5DTDNDY.mjs} +28 -55
- package/dist/lib/browser/chunk-E5DTDNDY.mjs.map +7 -0
- package/dist/lib/browser/{chunk-TGX63LTL.mjs → chunk-FJ4765WW.mjs} +1 -1
- package/dist/lib/browser/{chunk-TGX63LTL.mjs.map → chunk-FJ4765WW.mjs.map} +2 -2
- package/dist/lib/browser/chunk-FO3IYSLV.mjs +68 -0
- package/dist/lib/browser/chunk-FO3IYSLV.mjs.map +7 -0
- package/dist/lib/browser/{chunk-YNFPIQGB.mjs → chunk-IW44C7UL.mjs} +9 -2
- package/dist/lib/browser/chunk-IW44C7UL.mjs.map +7 -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-VBG5F5UF.mjs +476 -0
- package/dist/lib/browser/chunk-VBG5F5UF.mjs.map +7 -0
- package/dist/lib/browser/cli/index.mjs +15 -30
- package/dist/lib/browser/cli/index.mjs.map +3 -3
- package/dist/lib/browser/common/activation-events.mjs +11 -14
- package/dist/lib/browser/common/capabilities.mjs +19 -8
- package/dist/lib/browser/core/activation-event.mjs +1 -1
- package/dist/lib/browser/core/capability.mjs +5 -1
- package/dist/lib/browser/core/plugin-manager.mjs +8 -4
- package/dist/lib/browser/core/plugin.mjs +18 -4
- package/dist/lib/browser/core/url-loader.mjs +24 -0
- package/dist/lib/browser/index.mjs +51 -54
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/process-manager-capability-4FUA4TRP.mjs +89 -0
- package/dist/lib/browser/process-manager-capability-4FUA4TRP.mjs.map +7 -0
- package/dist/lib/browser/testing/index.mjs +198 -54
- 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 +22 -15
- package/dist/lib/node-esm/{capability-SA6LPYGL.mjs → capability-7TCQK7ZP.mjs} +12 -11
- package/dist/lib/node-esm/capability-7TCQK7ZP.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-FKE4Z3D6.mjs → chunk-37Z53PXZ.mjs} +1 -1
- package/dist/lib/node-esm/{chunk-FKE4Z3D6.mjs.map → chunk-37Z53PXZ.mjs.map} +2 -2
- package/dist/lib/node-esm/chunk-4BX2AE47.mjs +1468 -0
- package/dist/lib/node-esm/chunk-4BX2AE47.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-SB5ODNPX.mjs → chunk-CTKEZHKF.mjs} +9 -2
- 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-GEWHMHM7.mjs +588 -0
- package/dist/lib/node-esm/chunk-GEWHMHM7.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-3D66SZHP.mjs → chunk-KSH4OVMY.mjs} +28 -55
- package/dist/lib/node-esm/chunk-KSH4OVMY.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-SQICGJBW.mjs → chunk-QBUGLR4H.mjs} +20 -5
- package/dist/lib/node-esm/chunk-QBUGLR4H.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-JHFY3HTS.mjs → chunk-XIGPWXCQ.mjs} +100 -18
- package/dist/lib/node-esm/chunk-XIGPWXCQ.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-6REV5DE7.mjs → chunk-XOCUANHO.mjs} +3 -2
- package/dist/lib/node-esm/chunk-XOCUANHO.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-Y7JKXNDU.mjs +477 -0
- package/dist/lib/node-esm/chunk-Y7JKXNDU.mjs.map +7 -0
- package/dist/lib/node-esm/cli/index.mjs +15 -30
- package/dist/lib/node-esm/cli/index.mjs.map +3 -3
- package/dist/lib/node-esm/common/activation-events.mjs +11 -14
- package/dist/lib/node-esm/common/capabilities.mjs +19 -8
- package/dist/lib/node-esm/core/activation-event.mjs +1 -1
- package/dist/lib/node-esm/core/capability.mjs +5 -1
- package/dist/lib/node-esm/core/plugin-manager.mjs +8 -4
- package/dist/lib/node-esm/core/plugin.mjs +18 -4
- package/dist/lib/node-esm/core/url-loader.mjs +25 -0
- package/dist/lib/node-esm/index.mjs +51 -54
- 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-F23D62RN.mjs +90 -0
- package/dist/lib/node-esm/process-manager-capability-F23D62RN.mjs.map +7 -0
- package/dist/lib/node-esm/testing/index.mjs +198 -54
- 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 +22 -15
- package/dist/plugin/node-esm/index.mjs +971 -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 +1 -3
- package/dist/types/src/cli/cli.d.ts.map +1 -1
- package/dist/types/src/common/activation-events.d.ts +10 -13
- package/dist/types/src/common/activation-events.d.ts.map +1 -1
- 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 +113 -12
- package/dist/types/src/common/capabilities.d.ts.map +1 -1
- package/dist/types/src/common/index.d.ts +0 -1
- package/dist/types/src/common/index.d.ts.map +1 -1
- package/dist/types/src/common/translations.d.ts +1 -1
- package/dist/types/src/core/activation-event.d.ts +4 -4
- package/dist/types/src/core/activation-event.d.ts.map +1 -1
- package/dist/types/src/core/capability-manager.d.ts +9 -0
- package/dist/types/src/core/capability-manager.d.ts.map +1 -1
- package/dist/types/src/core/capability.d.ts +13 -2
- package/dist/types/src/core/capability.d.ts.map +1 -1
- 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 +6 -0
- 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 +238 -7
- package/dist/types/src/core/plugin-manager.d.ts.map +1 -1
- 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 +213 -11
- 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 +1 -2
- 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.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.map +1 -0
- package/dist/types/src/plugin-process-manager/history/index.d.ts.map +1 -0
- package/dist/types/src/{plugin-operation → plugin-process-manager}/history/types.d.ts +1 -1
- package/dist/types/src/plugin-process-manager/history/types.d.ts.map +1 -0
- package/dist/types/src/{plugin-operation → plugin-process-manager}/history/undo-mapping.d.ts +2 -2
- package/dist/types/src/plugin-process-manager/history/undo-mapping.d.ts.map +1 -0
- package/dist/types/src/{plugin-operation → plugin-process-manager}/history/undo-registry.d.ts +1 -1
- 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.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 +1 -0
- package/dist/types/src/testing/index.d.ts.map +1 -1
- 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.map +1 -1
- package/dist/types/src/testing/withPluginManager.d.ts.map +1 -1
- package/dist/types/src/testing/withPluginManager.stories.d.ts.map +1 -1
- package/dist/types/src/ui/components/App/App.d.ts +36 -3
- package/dist/types/src/ui/components/App/App.d.ts.map +1 -1
- package/dist/types/src/ui/components/App/App.stories.d.ts +2 -2
- package/dist/types/src/ui/components/App/App.stories.d.ts.map +1 -1
- package/dist/types/src/ui/components/PluginManager/PluginManagerContext.stories.d.ts.map +1 -1
- package/dist/types/src/ui/components/Surface/SurfaceComponent.d.ts +16 -4
- package/dist/types/src/ui/components/Surface/SurfaceComponent.d.ts.map +1 -1
- package/dist/types/src/ui/components/Surface/SurfaceComponent.stories.d.ts.map +1 -1
- package/dist/types/src/ui/components/Surface/SurfaceInfo.d.ts.map +1 -1
- 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/index.d.ts +22 -6
- package/dist/types/src/ui/components/Surface/index.d.ts.map +1 -1
- package/dist/types/src/ui/components/Surface/types.d.ts +110 -9
- package/dist/types/src/ui/components/Surface/types.d.ts.map +1 -1
- 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/hooks/index.d.ts +1 -1
- package/dist/types/src/ui/hooks/index.d.ts.map +1 -1
- package/dist/types/src/ui/hooks/useApp.d.ts +42 -12
- package/dist/types/src/ui/hooks/useApp.d.ts.map +1 -1
- 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.map +1 -1
- package/dist/types/src/ui/hooks/useLoading.d.ts.map +1 -1
- 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.map +1 -1
- 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 +54 -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 +15 -0
- package/package.json +61 -57
- package/src/cli/cli.ts +2 -7
- package/src/common/activation-events.ts +10 -15
- package/src/common/annotations.ts +3 -0
- package/src/common/capabilities.ts +147 -16
- package/src/common/index.ts +0 -1
- package/src/common/translations.ts +1 -1
- package/src/core/activation-event.ts +4 -1
- package/src/core/capability-manager.test.ts +4 -1
- package/src/core/capability-manager.ts +44 -2
- package/src/core/capability.ts +20 -2
- package/src/core/edge-registry-plugin-provider.ts +92 -0
- package/src/core/index.ts +6 -0
- package/src/core/plugin-asset-cache.ts +60 -0
- package/src/core/plugin-manager.test.ts +1103 -19
- package/src/core/plugin-manager.ts +1176 -199
- package/src/core/plugin-manifest.test.ts +75 -0
- package/src/core/plugin-manifest.ts +134 -0
- package/src/core/plugin.ts +235 -17
- 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 +1 -2
- package/src/plugin-process-manager/ProcessManagerPlugin.ts +24 -0
- package/src/{plugin-operation → plugin-process-manager}/history/capability.ts +1 -2
- package/src/plugin-process-manager/history/errors.ts +7 -0
- package/src/{plugin-operation → plugin-process-manager}/history/history-tracker.test.ts +61 -88
- package/src/{plugin-operation → plugin-process-manager}/history/history-tracker.ts +33 -18
- package/src/{plugin-operation → plugin-process-manager}/history/types.ts +1 -1
- package/src/{plugin-operation → plugin-process-manager}/history/undo-mapping.ts +2 -2
- package/src/{plugin-operation → plugin-process-manager}/history/undo-registry.test.ts +6 -5
- package/src/{plugin-operation → plugin-process-manager}/history/undo-registry.ts +1 -1
- package/src/{plugin-operation → plugin-process-manager}/index.ts +1 -1
- package/src/plugin-process-manager/meta.ts +16 -0
- package/src/plugin-process-manager/process-manager-capability.ts +178 -0
- package/src/{plugin-operation → plugin-process-manager}/testing.ts +32 -50
- package/src/testing/harness.ts +247 -0
- package/src/testing/index.ts +1 -0
- package/src/testing/react.test.tsx +50 -0
- package/src/testing/react.tsx +113 -0
- package/src/testing/service.ts +2 -2
- package/src/testing/withPluginManager.stories.tsx +1 -2
- package/src/testing/withPluginManager.tsx +47 -21
- package/src/ui/components/App/App.stories.tsx +12 -20
- package/src/ui/components/App/App.tsx +97 -10
- package/src/ui/components/PluginManager/PluginManagerContext.stories.tsx +13 -17
- package/src/ui/components/Surface/SurfaceComponent.stories.tsx +17 -16
- package/src/ui/components/Surface/SurfaceComponent.tsx +111 -55
- package/src/ui/components/Surface/SurfaceInfo.tsx +0 -1
- package/src/ui/components/Surface/SurfaceProfilerContext.tsx +207 -0
- package/src/ui/components/Surface/index.ts +35 -1
- package/src/ui/components/Surface/types.test.ts +126 -0
- package/src/ui/components/Surface/types.ts +185 -12
- package/src/ui/hooks/index.ts +1 -1
- package/src/ui/hooks/useApp.test.tsx +161 -0
- package/src/ui/hooks/useApp.tsx +215 -24
- package/src/ui/hooks/useCapabilities.ts +1 -0
- package/src/ui/hooks/useLoading.tsx +14 -6
- package/src/ui/hooks/useProcessManagerRuntime.ts +78 -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 +193 -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 +26 -3
- package/tsconfig.node.json +1 -1
- package/vitest.config.ts +1 -1
- package/.swc/plugins/linux_x86_64_19.0.0/727453fb3a62f7f1d952a41e051ca8a6f88cadc45cee43c6a4d1aa45f9b75665.wasmer-v7 +0 -0
- package/dist/lib/browser/capability-6YMUBS54.mjs +0 -37
- package/dist/lib/browser/capability-6YMUBS54.mjs.map +0 -7
- package/dist/lib/browser/capability-LF3OXSCV.mjs.map +0 -7
- package/dist/lib/browser/chunk-272IPLHQ.mjs.map +0 -7
- package/dist/lib/browser/chunk-2UI6ACB5.mjs +0 -824
- package/dist/lib/browser/chunk-2UI6ACB5.mjs.map +0 -7
- package/dist/lib/browser/chunk-7M4467QR.mjs.map +0 -7
- package/dist/lib/browser/chunk-JGWCBVKJ.mjs.map +0 -7
- package/dist/lib/browser/chunk-M5IC326L.mjs +0 -34
- package/dist/lib/browser/chunk-M5IC326L.mjs.map +0 -7
- package/dist/lib/browser/chunk-NQPYE365.mjs +0 -703
- package/dist/lib/browser/chunk-NQPYE365.mjs.map +0 -7
- package/dist/lib/browser/chunk-TIEBZMTF.mjs +0 -44
- package/dist/lib/browser/chunk-TIEBZMTF.mjs.map +0 -7
- package/dist/lib/browser/chunk-WEBSGU5L.mjs.map +0 -7
- package/dist/lib/browser/chunk-YAFEA4GV.mjs +0 -1
- package/dist/lib/browser/chunk-YNFPIQGB.mjs.map +0 -7
- package/dist/lib/browser/invoker-capability-4AUGUMM5.mjs +0 -36
- package/dist/lib/browser/invoker-capability-4AUGUMM5.mjs.map +0 -7
- package/dist/lib/node-esm/capability-R5O2OYX4.mjs +0 -38
- package/dist/lib/node-esm/capability-R5O2OYX4.mjs.map +0 -7
- package/dist/lib/node-esm/capability-SA6LPYGL.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-3D66SZHP.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-6REV5DE7.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-FHWPWQRJ.mjs +0 -704
- package/dist/lib/node-esm/chunk-FHWPWQRJ.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-JHFY3HTS.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-JIVXIJ2T.mjs +0 -825
- package/dist/lib/node-esm/chunk-JIVXIJ2T.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-NHXBSAQR.mjs +0 -35
- package/dist/lib/node-esm/chunk-NHXBSAQR.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-SB5ODNPX.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-SCDGIGGU.mjs +0 -45
- package/dist/lib/node-esm/chunk-SCDGIGGU.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-SQICGJBW.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-Z4TJPSMP.mjs +0 -2
- package/dist/lib/node-esm/invoker-capability-3YDIVDWV.mjs +0 -37
- package/dist/lib/node-esm/invoker-capability-3YDIVDWV.mjs.map +0 -7
- package/dist/types/src/common/operations.d.ts +0 -33
- package/dist/types/src/common/operations.d.ts.map +0 -1
- package/dist/types/src/plugin-operation/OperationPlugin.d.ts +0 -3
- package/dist/types/src/plugin-operation/OperationPlugin.d.ts.map +0 -1
- package/dist/types/src/plugin-operation/history/capability.d.ts.map +0 -1
- package/dist/types/src/plugin-operation/history/errors.d.ts +0 -5
- package/dist/types/src/plugin-operation/history/errors.d.ts.map +0 -1
- package/dist/types/src/plugin-operation/history/history-tracker.d.ts +0 -18
- package/dist/types/src/plugin-operation/history/history-tracker.d.ts.map +0 -1
- package/dist/types/src/plugin-operation/history/history-tracker.test.d.ts.map +0 -1
- package/dist/types/src/plugin-operation/history/index.d.ts.map +0 -1
- package/dist/types/src/plugin-operation/history/types.d.ts.map +0 -1
- package/dist/types/src/plugin-operation/history/undo-mapping.d.ts.map +0 -1
- package/dist/types/src/plugin-operation/history/undo-registry.d.ts.map +0 -1
- package/dist/types/src/plugin-operation/history/undo-registry.test.d.ts.map +0 -1
- package/dist/types/src/plugin-operation/index.d.ts +0 -3
- package/dist/types/src/plugin-operation/index.d.ts.map +0 -1
- package/dist/types/src/plugin-operation/invoker-capability.d.ts +0 -6
- package/dist/types/src/plugin-operation/invoker-capability.d.ts.map +0 -1
- package/dist/types/src/plugin-operation/meta.d.ts +0 -3
- package/dist/types/src/plugin-operation/meta.d.ts.map +0 -1
- package/dist/types/src/plugin-operation/testing.d.ts +0 -109
- package/dist/types/src/plugin-operation/testing.d.ts.map +0 -1
- package/dist/types/src/plugin-runtime/RuntimePlugin.d.ts +0 -3
- package/dist/types/src/plugin-runtime/RuntimePlugin.d.ts.map +0 -1
- package/dist/types/src/plugin-runtime/capability.d.ts +0 -6
- package/dist/types/src/plugin-runtime/capability.d.ts.map +0 -1
- package/dist/types/src/plugin-runtime/index.d.ts +0 -2
- package/dist/types/src/plugin-runtime/index.d.ts.map +0 -1
- package/dist/types/src/plugin-runtime/meta.d.ts +0 -3
- package/dist/types/src/plugin-runtime/meta.d.ts.map +0 -1
- package/dist/types/src/ui/hooks/useOperationResolver.d.ts +0 -19
- package/dist/types/src/ui/hooks/useOperationResolver.d.ts.map +0 -1
- package/src/common/operations.ts +0 -38
- package/src/plugin-operation/OperationPlugin.ts +0 -25
- package/src/plugin-operation/history/errors.ts +0 -11
- package/src/plugin-operation/invoker-capability.ts +0 -40
- package/src/plugin-operation/meta.ts +0 -11
- package/src/plugin-runtime/RuntimePlugin.ts +0 -20
- package/src/plugin-runtime/capability.ts +0 -53
- package/src/plugin-runtime/index.ts +0 -5
- package/src/plugin-runtime/meta.ts +0 -11
- package/src/ui/hooks/useOperationResolver.ts +0 -40
- /package/dist/lib/browser/{chunk-YAFEA4GV.mjs.map → core/url-loader.mjs.map} +0 -0
- /package/dist/lib/node-esm/{chunk-Z4TJPSMP.mjs.map → core/url-loader.mjs.map} +0 -0
- /package/dist/types/src/{plugin-operation → plugin-process-manager}/history/capability.d.ts +0 -0
- /package/dist/types/src/{plugin-operation → plugin-process-manager}/history/history-tracker.test.d.ts +0 -0
- /package/dist/types/src/{plugin-operation → plugin-process-manager}/history/index.d.ts +0 -0
- /package/dist/types/src/{plugin-operation → plugin-process-manager}/history/undo-registry.test.d.ts +0 -0
- /package/src/{plugin-operation → plugin-process-manager}/history/index.ts +0 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { describe, test } from 'vitest';
|
|
6
|
+
|
|
7
|
+
import * as PluginManifest from './plugin-manifest';
|
|
8
|
+
|
|
9
|
+
describe('PluginManifest', () => {
|
|
10
|
+
describe('parse', () => {
|
|
11
|
+
test('resolves entry and assets relative to manifest URL', ({ expect }) => {
|
|
12
|
+
const resolved = PluginManifest.parse('https://example.com/plugins/foo/manifest.json', {
|
|
13
|
+
id: 'com.example.foo',
|
|
14
|
+
name: 'Foo',
|
|
15
|
+
version: '1.0.0',
|
|
16
|
+
assets: ['index.mjs', 'style.css', 'chunks/lib-abc.js'],
|
|
17
|
+
});
|
|
18
|
+
expect(resolved.id).toBe('com.example.foo');
|
|
19
|
+
expect(resolved.dev).toBe(false);
|
|
20
|
+
expect(resolved.entryUrl).toBe('https://example.com/plugins/foo/index.mjs');
|
|
21
|
+
expect(resolved.assetUrls).toEqual([
|
|
22
|
+
'https://example.com/plugins/foo/index.mjs',
|
|
23
|
+
'https://example.com/plugins/foo/style.css',
|
|
24
|
+
'https://example.com/plugins/foo/chunks/lib-abc.js',
|
|
25
|
+
]);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test('throws if the canonical entry filename is not listed in assets', ({ expect }) => {
|
|
29
|
+
expect(() =>
|
|
30
|
+
PluginManifest.parse('https://example.com/manifest.json', {
|
|
31
|
+
id: 'a',
|
|
32
|
+
name: 'A',
|
|
33
|
+
version: '0.0.1',
|
|
34
|
+
assets: ['style.css'],
|
|
35
|
+
}),
|
|
36
|
+
).toThrow();
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
test('throws on missing required fields', ({ expect }) => {
|
|
40
|
+
expect(() =>
|
|
41
|
+
PluginManifest.parse('https://example.com/manifest.json', {
|
|
42
|
+
name: 'A',
|
|
43
|
+
version: '0.0.1',
|
|
44
|
+
assets: ['index.mjs'],
|
|
45
|
+
}),
|
|
46
|
+
).toThrow();
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
test('devEntry flips dev mode and resolves the entry against the manifest URL', ({ expect }) => {
|
|
50
|
+
const resolved = PluginManifest.parse('http://localhost:3967/manifest.json', {
|
|
51
|
+
id: 'com.example.foo',
|
|
52
|
+
name: 'Foo',
|
|
53
|
+
version: '0.0.0-dev',
|
|
54
|
+
assets: [],
|
|
55
|
+
devEntry: 'src/plugin.tsx',
|
|
56
|
+
});
|
|
57
|
+
expect(resolved.dev).toBe(true);
|
|
58
|
+
expect(resolved.entryUrl).toBe('http://localhost:3967/src/plugin.tsx');
|
|
59
|
+
expect(resolved.assetUrls).toEqual([]);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
test('devEntry waives the canonical-entry-in-assets requirement', ({ expect }) => {
|
|
63
|
+
// No `index.mjs` in assets — would throw without devEntry.
|
|
64
|
+
expect(() =>
|
|
65
|
+
PluginManifest.parse('http://localhost:3967/manifest.json', {
|
|
66
|
+
id: 'a',
|
|
67
|
+
name: 'A',
|
|
68
|
+
version: '0.0.0-dev',
|
|
69
|
+
assets: [],
|
|
70
|
+
devEntry: 'src/plugin.tsx',
|
|
71
|
+
}),
|
|
72
|
+
).not.toThrow();
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
});
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import * as FetchHttpClient from '@effect/platform/FetchHttpClient';
|
|
6
|
+
import * as HttpClient from '@effect/platform/HttpClient';
|
|
7
|
+
import * as HttpClientRequest from '@effect/platform/HttpClientRequest';
|
|
8
|
+
import * as HttpClientResponse from '@effect/platform/HttpClientResponse';
|
|
9
|
+
import * as Effect from 'effect/Effect';
|
|
10
|
+
import * as Schema from 'effect/Schema';
|
|
11
|
+
|
|
12
|
+
import { BaseError } from '@dxos/errors';
|
|
13
|
+
import { PLUGIN_ENTRY_FILENAME } from '@dxos/protocols';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Default port the Vite plugin (`composerPlugin`) binds the dev server to.
|
|
17
|
+
*
|
|
18
|
+
* Shared single source of truth — `composerPlugin` reads it as the default
|
|
19
|
+
* port, and the host's "Load Dev Plugin" affordance pre-fills the manifest URL
|
|
20
|
+
* with `http://localhost:${PLUGIN_DEV_SERVER_PORT}/manifest.json`. Lives in
|
|
21
|
+
* app-framework rather than `@dxos/protocols` because the constant is a
|
|
22
|
+
* client-side convention (host loader + Vite plugin) rather than a wire-level
|
|
23
|
+
* protocol.
|
|
24
|
+
*/
|
|
25
|
+
export const PLUGIN_DEV_SERVER_PORT = 3967;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Tagged error for manifest fetch / parse failures. Construction sites set
|
|
29
|
+
* `context.manifestUrl` and `context.reason` (one of `'fetch-failed' |
|
|
30
|
+
* 'http-error' | 'parse-failed' | 'invalid'`) so handlers can route on the
|
|
31
|
+
* specific failure mode.
|
|
32
|
+
*/
|
|
33
|
+
export class PluginManifestError extends BaseError.extend('PluginManifestError', 'Plugin manifest is invalid') {}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Schema for a third-party plugin manifest.
|
|
37
|
+
*
|
|
38
|
+
* Production manifests are published as a sibling of the plugin's entry module
|
|
39
|
+
* ({@link PLUGIN_ENTRY_FILENAME}) and advertise every file the plugin needs at
|
|
40
|
+
* runtime so the host can eagerly cache them for offline use.
|
|
41
|
+
*
|
|
42
|
+
* Dev manifests (served by `vite dev` via {@link composerPlugin}) set `devEntry`
|
|
43
|
+
* to point at the unbundled source entry. The host's loader treats the presence
|
|
44
|
+
* of `devEntry` as the dev-mode signal: it imports the entry directly from the
|
|
45
|
+
* dev server, skips eager asset caching, and skips static stylesheet injection
|
|
46
|
+
* (Vite handles CSS via runtime `<style>` injection during HMR). `assets` is not
|
|
47
|
+
* required to enumerate every file in dev mode — chunks and styles flow through
|
|
48
|
+
* the dev server on demand.
|
|
49
|
+
*/
|
|
50
|
+
export const Manifest = Schema.Struct({
|
|
51
|
+
id: Schema.String,
|
|
52
|
+
name: Schema.String,
|
|
53
|
+
version: Schema.String,
|
|
54
|
+
assets: Schema.Array(Schema.String),
|
|
55
|
+
devEntry: Schema.String.pipe(Schema.optional),
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
export type Manifest = Schema.Schema.Type<typeof Manifest>;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Resolved manifest with all asset paths converted to absolute URLs.
|
|
62
|
+
*
|
|
63
|
+
* `dev` reflects whether the source manifest declared a `devEntry`. Loaders branch
|
|
64
|
+
* on this to skip offline caching and stylesheet injection — both are no-ops (or
|
|
65
|
+
* actively wrong) when the plugin is being served by a Vite dev server.
|
|
66
|
+
*/
|
|
67
|
+
export type ResolvedManifest = {
|
|
68
|
+
id: string;
|
|
69
|
+
name: string;
|
|
70
|
+
version: string;
|
|
71
|
+
entryUrl: string;
|
|
72
|
+
assetUrls: readonly string[];
|
|
73
|
+
dev: boolean;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Resolves a parsed manifest's relative asset paths against the manifest's URL.
|
|
78
|
+
* In dev mode the entry comes from `devEntry`; otherwise it's the canonical
|
|
79
|
+
* {@link PLUGIN_ENTRY_FILENAME} sitting next to the manifest.
|
|
80
|
+
*/
|
|
81
|
+
const resolve = (manifestUrl: string, manifest: Manifest): ResolvedManifest => {
|
|
82
|
+
const dev = manifest.devEntry !== undefined;
|
|
83
|
+
return {
|
|
84
|
+
id: manifest.id,
|
|
85
|
+
name: manifest.name,
|
|
86
|
+
version: manifest.version,
|
|
87
|
+
entryUrl: new URL(dev ? manifest.devEntry! : PLUGIN_ENTRY_FILENAME, manifestUrl).toString(),
|
|
88
|
+
assetUrls: manifest.assets.map((asset) => new URL(asset, manifestUrl).toString()),
|
|
89
|
+
dev,
|
|
90
|
+
};
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Synchronous decode + validate + resolve for an in-memory manifest payload. Used
|
|
95
|
+
* by tests and tooling that have the manifest body already loaded; the runtime
|
|
96
|
+
* path goes through {@link fetchManifest}.
|
|
97
|
+
*/
|
|
98
|
+
export const parse = (manifestUrl: string, payload: unknown): ResolvedManifest => {
|
|
99
|
+
const manifest = Schema.decodeUnknownSync(Manifest)(payload);
|
|
100
|
+
if (manifest.devEntry === undefined && !manifest.assets.includes(PLUGIN_ENTRY_FILENAME)) {
|
|
101
|
+
throw new Error(`Manifest at ${manifestUrl} does not list ${PLUGIN_ENTRY_FILENAME} in assets.`);
|
|
102
|
+
}
|
|
103
|
+
return resolve(manifestUrl, manifest);
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Fetches and parses a manifest from the given URL via Effect's HTTP client and
|
|
108
|
+
* Schema-driven JSON decoding. All failure modes surface as a single tagged
|
|
109
|
+
* {@link PluginManifestError}; callers route on `error.context.reason`.
|
|
110
|
+
*/
|
|
111
|
+
export const fetchManifest = (manifestUrl: string): Effect.Effect<ResolvedManifest, PluginManifestError> =>
|
|
112
|
+
Effect.gen(function* () {
|
|
113
|
+
const response = yield* HttpClientRequest.get(manifestUrl).pipe(
|
|
114
|
+
HttpClient.execute,
|
|
115
|
+
Effect.mapError((cause) => new PluginManifestError({ context: { manifestUrl, reason: 'fetch-failed' }, cause })),
|
|
116
|
+
);
|
|
117
|
+
if (response.status >= 400) {
|
|
118
|
+
return yield* Effect.fail(
|
|
119
|
+
new PluginManifestError({ context: { manifestUrl, reason: 'http-error', status: response.status } }),
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
const manifest = yield* HttpClientResponse.schemaBodyJson(Manifest)(response).pipe(
|
|
123
|
+
Effect.mapError((cause) => new PluginManifestError({ context: { manifestUrl, reason: 'parse-failed' }, cause })),
|
|
124
|
+
);
|
|
125
|
+
if (manifest.devEntry === undefined && !manifest.assets.includes(PLUGIN_ENTRY_FILENAME)) {
|
|
126
|
+
return yield* Effect.fail(
|
|
127
|
+
new PluginManifestError({
|
|
128
|
+
context: { manifestUrl, reason: 'invalid' },
|
|
129
|
+
cause: `assets does not include ${PLUGIN_ENTRY_FILENAME}`,
|
|
130
|
+
}),
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
return resolve(manifestUrl, manifest);
|
|
134
|
+
}).pipe(Effect.scoped, Effect.provide(FetchHttpClient.layer));
|
package/src/core/plugin.ts
CHANGED
|
@@ -7,7 +7,9 @@ import * as Effect from 'effect/Effect';
|
|
|
7
7
|
import * as Option from 'effect/Option';
|
|
8
8
|
import * as Pipeable from 'effect/Pipeable';
|
|
9
9
|
|
|
10
|
+
import { BaseError } from '@dxos/errors';
|
|
10
11
|
import { invariant } from '@dxos/invariant';
|
|
12
|
+
import { DXN } from '@dxos/keys';
|
|
11
13
|
|
|
12
14
|
import type * as ActivationEvent from './activation-event';
|
|
13
15
|
import * as Capability from './capability';
|
|
@@ -45,6 +47,13 @@ export const activate = (event: ActivationEvent.ActivationEvent): Effect.Effect<
|
|
|
45
47
|
export const reset = (event: ActivationEvent.ActivationEvent): Effect.Effect<boolean, Error, Service> =>
|
|
46
48
|
Effect.flatMap(Service, (manager) => manager.reset(event));
|
|
47
49
|
|
|
50
|
+
/**
|
|
51
|
+
* Shuts down the plugin manager, deactivating all active modules and clearing lifecycle state.
|
|
52
|
+
* Accesses the PluginManager via the Effect layer system.
|
|
53
|
+
*/
|
|
54
|
+
export const shutdown = (): Effect.Effect<boolean, Error, Service> =>
|
|
55
|
+
Effect.flatMap(Service, (manager) => manager.shutdown());
|
|
56
|
+
|
|
48
57
|
/**
|
|
49
58
|
* Computes a module ID from plugin ID and export name.
|
|
50
59
|
*/
|
|
@@ -82,16 +91,33 @@ export interface PluginModule {
|
|
|
82
91
|
activatesOn: ActivationEvent.Events;
|
|
83
92
|
|
|
84
93
|
/**
|
|
85
|
-
* Events
|
|
86
|
-
*
|
|
87
|
-
*
|
|
94
|
+
* Events that this module fires *before* its own activation runs.
|
|
95
|
+
*
|
|
96
|
+
* When this module is asked to activate (via {@link activatesOn}), the
|
|
97
|
+
* plugin manager first activates every event listed here, ensuring any
|
|
98
|
+
* other modules that contribute to those events have completed before
|
|
99
|
+
* this module's {@link activate} body executes. These events are fired
|
|
100
|
+
* by the framework on this module's behalf — the module does not need
|
|
101
|
+
* to wait for some other code to fire them.
|
|
102
|
+
*
|
|
103
|
+
* The module is marked as needing reset if a module activated by one
|
|
104
|
+
* of these events is later removed.
|
|
105
|
+
*
|
|
106
|
+
* Read as: "this module fires these events before [its] activation".
|
|
88
107
|
*/
|
|
89
|
-
|
|
108
|
+
firesBeforeActivation?: ActivationEvent.ActivationEvent[];
|
|
90
109
|
|
|
91
110
|
/**
|
|
92
|
-
* Events
|
|
111
|
+
* Events that this module fires *after* its own activation completes.
|
|
112
|
+
*
|
|
113
|
+
* Once this module's {@link activate} body has finished executing, the
|
|
114
|
+
* plugin manager activates every event listed here, causing any modules
|
|
115
|
+
* listening on those events to run. These events are fired by the
|
|
116
|
+
* framework on this module's behalf as part of this module's lifecycle.
|
|
117
|
+
*
|
|
118
|
+
* Read as: "this module fires these events after [its] activation".
|
|
93
119
|
*/
|
|
94
|
-
|
|
120
|
+
firesAfterActivation?: ActivationEvent.ActivationEvent[];
|
|
95
121
|
|
|
96
122
|
/**
|
|
97
123
|
* Called when the module is activated.
|
|
@@ -109,39 +135,60 @@ class PluginModuleImpl implements PluginModule {
|
|
|
109
135
|
readonly [PluginModuleTypeId]: PluginModuleTypeId = PluginModuleTypeId;
|
|
110
136
|
readonly id: PluginModule['id'];
|
|
111
137
|
readonly activatesOn: PluginModule['activatesOn'];
|
|
112
|
-
readonly
|
|
113
|
-
readonly
|
|
138
|
+
readonly firesBeforeActivation?: PluginModule['firesBeforeActivation'];
|
|
139
|
+
readonly firesAfterActivation?: PluginModule['firesAfterActivation'];
|
|
114
140
|
readonly activate: PluginModule['activate'];
|
|
115
141
|
|
|
116
142
|
constructor(options: Omit<PluginModule, typeof PluginModuleTypeId>) {
|
|
117
143
|
this.id = options.id;
|
|
118
144
|
this.activatesOn = options.activatesOn;
|
|
119
|
-
this.
|
|
120
|
-
this.
|
|
145
|
+
this.firesBeforeActivation = options.firesBeforeActivation;
|
|
146
|
+
this.firesAfterActivation = options.firesAfterActivation;
|
|
121
147
|
this.activate = options.activate;
|
|
122
148
|
}
|
|
123
149
|
}
|
|
124
150
|
|
|
125
151
|
export type Meta = {
|
|
126
152
|
/**
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
* @example org.dxos.plugin.example
|
|
153
|
+
* Bare NSID (the name portion of {@link key}, e.g. `org.dxos.plugin.example`).
|
|
154
|
+
* Stable across versions; used for module-id namespacing, i18n namespaces,
|
|
155
|
+
* enable/disable, and registry lookups. Derived from `key` by {@link makeMeta} —
|
|
156
|
+
* do not set directly.
|
|
132
157
|
*/
|
|
133
158
|
id: string;
|
|
134
159
|
|
|
160
|
+
/**
|
|
161
|
+
* Canonical identity DXN, including version when published
|
|
162
|
+
* (e.g. `dxn:org.dxos.plugin.example:0.8.3`). The validated source of truth
|
|
163
|
+
* from which {@link id} and {@link version} are derived.
|
|
164
|
+
*
|
|
165
|
+
* @example DXN.make('org.dxos.plugin.example', '0.8.3')
|
|
166
|
+
*/
|
|
167
|
+
key: DXN.DXN;
|
|
168
|
+
|
|
135
169
|
/**
|
|
136
170
|
* Human-readable name.
|
|
137
171
|
*/
|
|
138
172
|
name: string;
|
|
139
173
|
|
|
174
|
+
/**
|
|
175
|
+
* Semver version string of the plugin, typically the publishing package's
|
|
176
|
+
* `package.json` version. Derived from the version segment of {@link key} by
|
|
177
|
+
* {@link makeMeta} — do not set directly.
|
|
178
|
+
*/
|
|
179
|
+
version?: string;
|
|
180
|
+
|
|
140
181
|
/**
|
|
141
182
|
* Short description of plugin functionality.
|
|
142
183
|
*/
|
|
143
184
|
description?: string;
|
|
144
185
|
|
|
186
|
+
/**
|
|
187
|
+
* Name of the author or organization that created the plugin.
|
|
188
|
+
*/
|
|
189
|
+
// TODO(burdon): DID or domain name?
|
|
190
|
+
author?: string;
|
|
191
|
+
|
|
145
192
|
/**
|
|
146
193
|
* URL of home page.
|
|
147
194
|
*/
|
|
@@ -152,6 +199,14 @@ export type Meta = {
|
|
|
152
199
|
*/
|
|
153
200
|
source?: string;
|
|
154
201
|
|
|
202
|
+
/**
|
|
203
|
+
* Relative path (inside the published package) to the plugin's bundled MDL
|
|
204
|
+
* specification file — e.g. `'PLUGIN.mdl'` or `'docs/PLUGIN.mdl'`. The file
|
|
205
|
+
* is shipped via the package's `files` entry and resolved by registry
|
|
206
|
+
* surfaces to render an in-app viewer and/or external link.
|
|
207
|
+
*/
|
|
208
|
+
spec?: string;
|
|
209
|
+
|
|
155
210
|
/**
|
|
156
211
|
* URL of screenshot.
|
|
157
212
|
*/
|
|
@@ -171,8 +226,48 @@ export type Meta = {
|
|
|
171
226
|
* Icon hue (ChromaticPalette).
|
|
172
227
|
*/
|
|
173
228
|
iconHue?: string;
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* IDs of plugins this plugin functionally depends on.
|
|
232
|
+
*
|
|
233
|
+
* Treated as a convenience by the default `PluginManager` flow:
|
|
234
|
+
* - Enabling this plugin auto-enables the transitive closure of `dependsOn`
|
|
235
|
+
* (installing missing entries from the plugin registry when possible).
|
|
236
|
+
* - Disabling a depended-upon plugin surfaces dependents to the caller; the
|
|
237
|
+
* `PluginManager.disable` API supports an opt-in cascade.
|
|
238
|
+
*
|
|
239
|
+
* Not an invariant: low-level `PluginManager` APIs accept opt-outs
|
|
240
|
+
* (`resolveDependencies: false`, `ignoreDependents: true`) so a caller may
|
|
241
|
+
* substitute an alternative implementation that satisfies the dependent's
|
|
242
|
+
* capability needs in its own way.
|
|
243
|
+
*/
|
|
244
|
+
dependsOn?: string[];
|
|
174
245
|
};
|
|
175
246
|
|
|
247
|
+
/**
|
|
248
|
+
* Options for {@link makeMeta}: a {@link Meta} minus the fields derived from `key`.
|
|
249
|
+
* Identity and version are specified solely through the `key` DXN — `id` and
|
|
250
|
+
* `version` cannot be passed directly.
|
|
251
|
+
*/
|
|
252
|
+
export type MakeMetaOptions = Omit<Meta, 'id' | 'version'>;
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Constructs a plugin {@link Meta} from a single canonical DXN. The `key` DXN is
|
|
256
|
+
* the one source of truth; `id` (bare NSID) and `version` (semver) are derived
|
|
257
|
+
* from it so each datum has exactly one home and cannot drift out of sync.
|
|
258
|
+
*
|
|
259
|
+
* @example
|
|
260
|
+
* export const meta = Plugin.makeMeta({
|
|
261
|
+
* key: DXN.make('org.dxos.plugin.example', '0.8.3'),
|
|
262
|
+
* name: 'Example',
|
|
263
|
+
* });
|
|
264
|
+
*/
|
|
265
|
+
export const makeMeta = (options: MakeMetaOptions): Meta => ({
|
|
266
|
+
...options,
|
|
267
|
+
id: DXN.getName(options.key),
|
|
268
|
+
version: DXN.getVersion(options.key),
|
|
269
|
+
});
|
|
270
|
+
|
|
176
271
|
/**
|
|
177
272
|
* Identifier denoting a Plugin.
|
|
178
273
|
*/
|
|
@@ -294,14 +389,15 @@ const resolveModule = (
|
|
|
294
389
|
options?: any,
|
|
295
390
|
): PluginModuleImpl => {
|
|
296
391
|
const moduleOptions = typeof module === 'function' ? module(options) : module;
|
|
392
|
+
const pluginName = meta.id;
|
|
297
393
|
const id = Option.fromNullable(moduleOptions.id).pipe(
|
|
298
394
|
Option.match({
|
|
299
395
|
onNone: () => {
|
|
300
396
|
const exportName = Capability.getModuleTag(moduleOptions.activate);
|
|
301
397
|
invariant(exportName, `Plugin module missing name. Plugin: ${meta.id}`);
|
|
302
|
-
return computeModuleId(
|
|
398
|
+
return computeModuleId(pluginName, exportName);
|
|
303
399
|
},
|
|
304
|
-
onSome: (id) => computeModuleId(
|
|
400
|
+
onSome: (id) => computeModuleId(pluginName, id),
|
|
305
401
|
}),
|
|
306
402
|
);
|
|
307
403
|
return new PluginModuleImpl({ ...moduleOptions, id });
|
|
@@ -316,6 +412,8 @@ const resolveModule = (
|
|
|
316
412
|
export function make<T>(builder: PluginBuilder<T>): PluginFactory<T>;
|
|
317
413
|
export function make<T>(builder: PluginBuilder<T>): PluginFactory<T> {
|
|
318
414
|
const meta = builder.meta;
|
|
415
|
+
// `dependsOn` entries and `id` are both bare NSIDs, so compare directly.
|
|
416
|
+
invariant(!meta.dependsOn?.includes(meta.id), `Plugin ${meta.id} declares itself as a dependency.`);
|
|
319
417
|
|
|
320
418
|
const factory = (options: T) => {
|
|
321
419
|
const modules = builder.modules.map((module) => resolveModule(meta, module, options));
|
|
@@ -324,3 +422,123 @@ export function make<T>(builder: PluginBuilder<T>): PluginFactory<T> {
|
|
|
324
422
|
|
|
325
423
|
return Object.assign(factory, { meta });
|
|
326
424
|
}
|
|
425
|
+
|
|
426
|
+
//
|
|
427
|
+
// Lazy plugin loading
|
|
428
|
+
//
|
|
429
|
+
|
|
430
|
+
/**
|
|
431
|
+
* Symbol used to tag lazy plugin stubs with their loader closure.
|
|
432
|
+
* Hidden from enumeration so plugin manager iteration / serialization paths
|
|
433
|
+
* don't trip over it.
|
|
434
|
+
*/
|
|
435
|
+
const LazyTag: unique symbol = Symbol.for('@dxos/app-framework/Plugin/Lazy');
|
|
436
|
+
|
|
437
|
+
/**
|
|
438
|
+
* Async loader for a lazy plugin's real implementation.
|
|
439
|
+
* The default export of the loaded module must be a `PluginFactory<T>` —
|
|
440
|
+
* i.e. the same shape `Plugin.make` produces.
|
|
441
|
+
*/
|
|
442
|
+
export type LazyLoader<T = void> = () => Promise<{ default: PluginFactory<T> }>;
|
|
443
|
+
|
|
444
|
+
/** Internal: payload carried on a lazy stub. */
|
|
445
|
+
type LazyPayload = { loader: LazyLoader<any>; options: unknown };
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* Defines a lazy plugin whose body is loaded on first enable.
|
|
449
|
+
*
|
|
450
|
+
* The returned factory produces a stub `Plugin` that exposes `meta`
|
|
451
|
+
* synchronously (so callers can read `Plugin.meta.id` for free) but defers
|
|
452
|
+
* loading the real plugin's modules until the manager calls
|
|
453
|
+
* `Plugin.resolveLazy`. This lets the plugin's main entry point ship as a
|
|
454
|
+
* tiny meta-only chunk — the heavy capabilities, schema, React surfaces,
|
|
455
|
+
* etc. live behind the dynamic `import()` and become a separate Rollup
|
|
456
|
+
* chunk that is only fetched when the plugin is enabled.
|
|
457
|
+
*
|
|
458
|
+
* @example
|
|
459
|
+
* ```ts
|
|
460
|
+
* // plugin-markdown/src/index.ts
|
|
461
|
+
* import { Plugin } from '@dxos/app-framework';
|
|
462
|
+
* import { meta } from './meta';
|
|
463
|
+
*
|
|
464
|
+
* export const MarkdownPlugin = Plugin.lazy(meta, () => import('./MarkdownPlugin'));
|
|
465
|
+
*
|
|
466
|
+
* // plugin-markdown/src/MarkdownPlugin.tsx
|
|
467
|
+
* export const MarkdownPlugin = Plugin.define(meta).pipe(...heavy modules..., Plugin.make);
|
|
468
|
+
* export default MarkdownPlugin;
|
|
469
|
+
* ```
|
|
470
|
+
*/
|
|
471
|
+
export const lazy = <T = void>(meta: Meta, loader: LazyLoader<T>): PluginFactory<T> => {
|
|
472
|
+
const factory = (options: T): Plugin => {
|
|
473
|
+
const stub = new PluginImpl(meta, []);
|
|
474
|
+
Object.defineProperty(stub, LazyTag, {
|
|
475
|
+
value: { loader, options } satisfies LazyPayload,
|
|
476
|
+
enumerable: false,
|
|
477
|
+
});
|
|
478
|
+
return stub;
|
|
479
|
+
};
|
|
480
|
+
return Object.assign(factory, { meta });
|
|
481
|
+
};
|
|
482
|
+
|
|
483
|
+
/**
|
|
484
|
+
* Type guard for lazy plugin stubs produced by {@link lazy}.
|
|
485
|
+
*/
|
|
486
|
+
export const isLazy = (plugin: Plugin): boolean => LazyTag in plugin;
|
|
487
|
+
|
|
488
|
+
/**
|
|
489
|
+
* Tagged error for failures during lazy plugin resolution. `context.id` is
|
|
490
|
+
* the lazy plugin's `meta.id`; `context.reason` discriminates the failure
|
|
491
|
+
* mode (`'load-failed' | 'missing-default' | 'invalid-plugin' |
|
|
492
|
+
* 'meta-mismatch'`) so callers can route on it.
|
|
493
|
+
*/
|
|
494
|
+
export class LazyPluginError extends BaseError.extend('LazyPluginError', 'Failed to resolve lazy plugin') {}
|
|
495
|
+
|
|
496
|
+
/**
|
|
497
|
+
* Tagged error for plugin-level dependency resolution failures.
|
|
498
|
+
*
|
|
499
|
+
* `context.id` is the plugin id the manager was acting on. `context.reason`
|
|
500
|
+
* discriminates the failure mode:
|
|
501
|
+
* - `'missing'` — declared dep is neither registered nor in the catalog.
|
|
502
|
+
* `context.missing` lists offending ids.
|
|
503
|
+
* - `'install-failed'` — dep was found in the catalog but `add()` failed.
|
|
504
|
+
* `cause` carries the original error.
|
|
505
|
+
* - `'cycle'` — closure walk detected a cycle. `context.path` is the cycle path.
|
|
506
|
+
* - `'core-dependent'` — cascade-disable would have to disable a core plugin.
|
|
507
|
+
* `context.coreDependent` is the blocking id.
|
|
508
|
+
*/
|
|
509
|
+
export class PluginDependencyError extends BaseError.extend(
|
|
510
|
+
'PluginDependencyError',
|
|
511
|
+
'Plugin dependency resolution failed',
|
|
512
|
+
) {}
|
|
513
|
+
|
|
514
|
+
/**
|
|
515
|
+
* Resolves a lazy plugin stub to its real plugin.
|
|
516
|
+
* Returns the plugin unchanged if it is not lazy. Failures surface as
|
|
517
|
+
* {@link LazyPluginError} with `context.reason` indicating the failure mode
|
|
518
|
+
* and (for loader failures) `cause` set to the original error.
|
|
519
|
+
*/
|
|
520
|
+
export const resolveLazy = (plugin: Plugin): Effect.Effect<Plugin, LazyPluginError> =>
|
|
521
|
+
Effect.gen(function* () {
|
|
522
|
+
if (!isLazy(plugin)) {
|
|
523
|
+
return plugin;
|
|
524
|
+
}
|
|
525
|
+
const id = plugin.meta.id;
|
|
526
|
+
const { loader, options } = (plugin as unknown as { [LazyTag]: LazyPayload })[LazyTag];
|
|
527
|
+
const mod = yield* Effect.tryPromise({
|
|
528
|
+
try: loader,
|
|
529
|
+
catch: (error) => new LazyPluginError({ context: { id, reason: 'load-failed' }, cause: error }),
|
|
530
|
+
});
|
|
531
|
+
if (!mod || typeof mod.default !== 'function') {
|
|
532
|
+
return yield* Effect.fail(new LazyPluginError({ context: { id, reason: 'missing-default' } }));
|
|
533
|
+
}
|
|
534
|
+
const result = mod.default(options);
|
|
535
|
+
if (!isPlugin(result)) {
|
|
536
|
+
return yield* Effect.fail(new LazyPluginError({ context: { id, reason: 'invalid-plugin' } }));
|
|
537
|
+
}
|
|
538
|
+
if (result.meta.id !== id) {
|
|
539
|
+
return yield* Effect.fail(
|
|
540
|
+
new LazyPluginError({ context: { id, reason: 'meta-mismatch', returnedId: result.meta.id } }),
|
|
541
|
+
);
|
|
542
|
+
}
|
|
543
|
+
return result;
|
|
544
|
+
});
|