@dxos/app-framework 0.8.4-main.bc674ce → 0.8.4-main.bcb3aa67d6
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 +1 -3
- package/dist/lib/browser/{capability-7PCNSWBT.mjs → capability-4NSF2SOO.mjs} +16 -11
- package/dist/lib/browser/capability-4NSF2SOO.mjs.map +7 -0
- package/dist/lib/browser/capability-EB3UKSKA.mjs +35 -0
- package/dist/lib/browser/capability-EB3UKSKA.mjs.map +7 -0
- package/dist/lib/browser/{chunk-FMZN33N4.mjs → chunk-27FZETIA.mjs} +324 -181
- package/dist/lib/browser/chunk-27FZETIA.mjs.map +7 -0
- package/dist/lib/browser/chunk-CV7I2AAB.mjs +80 -0
- package/dist/lib/browser/chunk-CV7I2AAB.mjs.map +7 -0
- package/dist/lib/browser/{chunk-6Y7PZV72.mjs → chunk-FL2XTEJH.mjs} +3 -4
- package/dist/lib/browser/chunk-FL2XTEJH.mjs.map +7 -0
- package/dist/lib/browser/chunk-H7OMDDGW.mjs +42 -0
- package/dist/lib/browser/chunk-H7OMDDGW.mjs.map +7 -0
- package/dist/lib/browser/chunk-HDQXX5DC.mjs +157 -0
- package/dist/lib/browser/chunk-HDQXX5DC.mjs.map +7 -0
- package/dist/lib/browser/chunk-I34GF4NG.mjs +34 -0
- package/dist/lib/browser/chunk-I34GF4NG.mjs.map +7 -0
- package/dist/lib/browser/chunk-KNBRTZVK.mjs +892 -0
- package/dist/lib/browser/chunk-KNBRTZVK.mjs.map +7 -0
- package/dist/lib/browser/{chunk-7IQHKD4U.mjs → chunk-NO7R7QHA.mjs} +4 -7
- package/dist/lib/browser/chunk-NO7R7QHA.mjs.map +7 -0
- package/dist/lib/browser/{chunk-TCLLRCS3.mjs → chunk-P2E7VMRF.mjs} +10 -7
- package/dist/lib/browser/chunk-P2E7VMRF.mjs.map +7 -0
- package/dist/lib/browser/{chunk-PKQT6C53.mjs → chunk-QSXYHXCE.mjs} +3 -2
- package/dist/lib/browser/chunk-QSXYHXCE.mjs.map +7 -0
- package/dist/lib/browser/chunk-RFSO3JRG.mjs +1 -0
- package/dist/lib/browser/chunk-TGX63LTL.mjs +8 -0
- package/dist/lib/browser/{chunk-FHQTHCX7.mjs.map → chunk-TGX63LTL.mjs.map} +1 -1
- package/dist/lib/browser/cli/index.mjs +90 -0
- package/dist/lib/browser/cli/index.mjs.map +7 -0
- package/dist/lib/browser/common/activation-events.mjs +24 -0
- package/dist/lib/browser/common/capabilities.mjs +46 -0
- package/dist/lib/browser/core/activation-event.mjs +1 -1
- package/dist/lib/browser/core/capability.mjs +1 -1
- package/dist/lib/browser/core/plugin-manager.mjs +4 -4
- package/dist/lib/browser/core/plugin.mjs +6 -4
- package/dist/lib/browser/core/url-loader.mjs +12 -0
- package/dist/lib/browser/index.mjs +40 -131
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/invoker-capability-P7KPBTP3.mjs +43 -0
- package/dist/lib/browser/invoker-capability-P7KPBTP3.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +56 -34
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/browser/{react → ui}/index.mjs +19 -21
- package/dist/lib/browser/ui/index.mjs.map +7 -0
- package/dist/lib/node-esm/{capability-CFLQ2QQU.mjs → capability-CB3MNEI3.mjs} +16 -11
- package/dist/lib/node-esm/capability-CB3MNEI3.mjs.map +7 -0
- package/dist/lib/node-esm/capability-CMROGK7R.mjs +36 -0
- package/dist/lib/node-esm/capability-CMROGK7R.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-STMXUEPO.mjs → chunk-37NG7SIN.mjs} +3 -4
- package/dist/lib/node-esm/chunk-37NG7SIN.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-7JPKC7OM.mjs +893 -0
- package/dist/lib/node-esm/chunk-7JPKC7OM.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-7PPVTBYR.mjs +81 -0
- package/dist/lib/node-esm/chunk-7PPVTBYR.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-BQ56U4QX.mjs +43 -0
- package/dist/lib/node-esm/chunk-BQ56U4QX.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-GT6OKM5I.mjs → chunk-CG6UBBZZ.mjs} +10 -7
- package/dist/lib/node-esm/chunk-CG6UBBZZ.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-EL3R25OQ.mjs +2 -0
- package/dist/lib/node-esm/chunk-EL3R25OQ.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-663A54LQ.mjs → chunk-EXYTXQ47.mjs} +4 -7
- package/dist/lib/node-esm/chunk-EXYTXQ47.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-UEWJDI2L.mjs → chunk-FKE4Z3D6.mjs} +2 -2
- package/dist/lib/node-esm/{chunk-UEWJDI2L.mjs.map → chunk-FKE4Z3D6.mjs.map} +1 -1
- package/dist/lib/node-esm/chunk-OXXXRCQX.mjs +158 -0
- package/dist/lib/node-esm/chunk-OXXXRCQX.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-WZCSOX5Q.mjs +35 -0
- package/dist/lib/node-esm/chunk-WZCSOX5Q.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-XYQTBFPA.mjs → chunk-YH44RHP6.mjs} +324 -181
- package/dist/lib/node-esm/chunk-YH44RHP6.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-7OWSHPYK.mjs → chunk-ZZ7CKK6W.mjs} +3 -2
- package/dist/lib/node-esm/chunk-ZZ7CKK6W.mjs.map +7 -0
- package/dist/lib/node-esm/cli/index.mjs +91 -0
- package/dist/lib/node-esm/cli/index.mjs.map +7 -0
- package/dist/lib/node-esm/common/activation-events.mjs +25 -0
- package/dist/lib/node-esm/common/activation-events.mjs.map +7 -0
- package/dist/lib/node-esm/common/capabilities.mjs +47 -0
- package/dist/lib/node-esm/common/capabilities.mjs.map +7 -0
- package/dist/lib/node-esm/core/activation-event.mjs +1 -1
- package/dist/lib/node-esm/core/capability.mjs +1 -1
- package/dist/lib/node-esm/core/plugin-manager.mjs +4 -4
- package/dist/lib/node-esm/core/plugin.mjs +6 -4
- package/dist/lib/node-esm/core/url-loader.mjs +13 -0
- package/dist/lib/node-esm/core/url-loader.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +40 -131
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/invoker-capability-3C5H46ZY.mjs +44 -0
- package/dist/lib/node-esm/invoker-capability-3C5H46ZY.mjs.map +7 -0
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/testing/index.mjs +56 -34
- package/dist/lib/node-esm/testing/index.mjs.map +3 -3
- package/dist/lib/node-esm/{react → ui}/index.mjs +19 -21
- package/dist/lib/node-esm/ui/index.mjs.map +7 -0
- package/dist/plugin/node-esm/index.mjs +384 -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.d.ts → cli/cli.d.ts} +2 -2
- 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 +27 -0
- package/dist/types/src/common/activation-events.d.ts.map +1 -0
- package/dist/types/src/common/capabilities.d.ts +110 -0
- package/dist/types/src/common/capabilities.d.ts.map +1 -0
- package/dist/types/src/common/index.d.ts +4 -9
- package/dist/types/src/common/index.d.ts.map +1 -1
- package/dist/types/src/common/operations.d.ts +8 -369
- package/dist/types/src/common/operations.d.ts.map +1 -1
- package/dist/types/src/common/translations.d.ts +0 -9
- package/dist/types/src/common/translations.d.ts.map +1 -1
- package/dist/types/src/core/activation-event.d.ts +1 -1
- package/dist/types/src/core/activation-event.d.ts.map +1 -1
- package/dist/types/src/core/capability.d.ts +7 -7
- package/dist/types/src/core/capability.d.ts.map +1 -1
- package/dist/types/src/core/index.d.ts +1 -0
- package/dist/types/src/core/index.d.ts.map +1 -1
- package/dist/types/src/core/plugin-manager.d.ts +9 -2
- package/dist/types/src/core/plugin-manager.d.ts.map +1 -1
- package/dist/types/src/core/plugin.d.ts +6 -1
- package/dist/types/src/core/plugin.d.ts.map +1 -1
- package/dist/types/src/core/url-loader.d.ts +25 -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/index.d.ts +1 -3
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/plugin-operation/history/capability.d.ts +1 -1
- package/dist/types/src/plugin-operation/history/errors.d.ts +30 -3
- package/dist/types/src/plugin-operation/history/errors.d.ts.map +1 -1
- package/dist/types/src/plugin-operation/history/undo-mapping.d.ts +11 -3
- package/dist/types/src/plugin-operation/history/undo-mapping.d.ts.map +1 -1
- package/dist/types/src/plugin-operation/invoker-capability.d.ts +1 -1
- package/dist/types/src/plugin-operation/invoker-capability.d.ts.map +1 -1
- package/dist/types/src/plugin-operation/testing.d.ts +26 -77
- package/dist/types/src/plugin-operation/testing.d.ts.map +1 -1
- package/dist/types/src/plugin-runtime/capability.d.ts +2 -2
- package/dist/types/src/plugin-runtime/capability.d.ts.map +1 -1
- package/dist/types/src/testing/withPluginManager.d.ts +1 -1
- package/dist/types/src/testing/withPluginManager.d.ts.map +1 -1
- package/dist/types/src/{react → ui/components/App}/App.d.ts +3 -2
- package/dist/types/src/ui/components/App/App.d.ts.map +1 -0
- package/dist/types/src/{react/Surface.stories.d.ts → ui/components/App/App.stories.d.ts} +7 -2
- 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.map +1 -0
- package/dist/types/src/{react → ui/components/PluginManager}/PluginManagerProvider.d.ts +1 -1
- 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 +12 -0
- package/dist/types/src/ui/components/Surface/SurfaceComponent.d.ts.map +1 -0
- package/dist/types/src/{react/App.stories.d.ts → ui/components/Surface/SurfaceComponent.stories.d.ts} +1 -1
- package/dist/types/src/ui/components/Surface/SurfaceComponent.stories.d.ts.map +1 -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 +26 -0
- package/dist/types/src/ui/components/Surface/index.d.ts.map +1 -0
- package/dist/types/src/{common/surface.d.ts → ui/components/Surface/types.d.ts} +20 -18
- package/dist/types/src/ui/components/Surface/types.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 +6 -0
- package/dist/types/src/ui/hooks/index.d.ts.map +1 -0
- package/dist/types/src/{react → ui/hooks}/useApp.d.ts +26 -9
- 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/{react → ui/hooks}/useCapabilities.d.ts +6 -1
- package/dist/types/src/ui/hooks/useCapabilities.d.ts.map +1 -0
- package/dist/types/src/ui/hooks/useLoading.d.ts.map +1 -0
- package/dist/types/src/{react/common.d.ts → ui/hooks/useSettingsState.d.ts} +1 -5
- 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/composer-plugin.d.ts +18 -0
- package/dist/types/src/vite-plugin/composer-plugin.d.ts.map +1 -0
- package/dist/types/src/vite-plugin/import-map-plugin.d.ts +16 -0
- package/dist/types/src/vite-plugin/import-map-plugin.d.ts.map +1 -0
- package/dist/types/src/vite-plugin/index.d.ts +3 -0
- package/dist/types/src/vite-plugin/index.d.ts.map +1 -0
- package/dist/types/src/vite-plugin/packages.d.ts +7 -0
- package/dist/types/src/vite-plugin/packages.d.ts.map +1 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/moon.yml +20 -6
- package/package.json +91 -64
- package/src/{cli.ts → cli/cli.ts} +10 -10
- package/src/{playground/debug → cli}/index.ts +1 -1
- package/src/common/activation-events.ts +44 -0
- package/src/common/capabilities.ts +172 -0
- package/src/common/index.ts +4 -9
- package/src/common/operations.ts +6 -382
- package/src/common/translations.ts +0 -12
- package/src/context.ts +1 -1
- package/src/core/activation-event.ts +5 -2
- package/src/core/capability-manager.ts +1 -1
- package/src/core/capability.ts +11 -10
- package/src/core/index.ts +1 -0
- package/src/core/plugin-manager.test.ts +313 -44
- package/src/core/plugin-manager.ts +344 -157
- package/src/core/plugin.ts +10 -2
- package/src/core/url-loader.test.ts +79 -0
- package/src/core/url-loader.ts +148 -0
- package/src/index.ts +1 -3
- package/src/plugin-operation/OperationPlugin.ts +5 -5
- package/src/plugin-operation/history/capability.ts +5 -5
- package/src/plugin-operation/history/errors.ts +2 -6
- package/src/plugin-operation/history/history-tracker.test.ts +36 -42
- package/src/plugin-operation/history/undo-mapping.ts +6 -3
- package/src/plugin-operation/history/undo-registry.test.ts +3 -3
- package/src/plugin-operation/invoker-capability.ts +21 -7
- package/src/plugin-operation/meta.ts +1 -1
- package/src/plugin-operation/testing.ts +25 -45
- package/src/plugin-runtime/RuntimePlugin.ts +4 -4
- package/src/plugin-runtime/capability.ts +5 -5
- package/src/plugin-runtime/meta.ts +1 -1
- package/src/testing/service.ts +6 -6
- package/src/testing/withPluginManager.stories.tsx +6 -6
- package/src/testing/withPluginManager.tsx +46 -19
- package/src/ui/components/App/App.stories.tsx +92 -0
- package/src/{react → ui/components/App}/App.tsx +9 -11
- package/src/{playground/layout → ui/components/App}/index.ts +1 -1
- package/src/{react → ui/components/PluginManager}/PluginManagerContext.stories.tsx +13 -14
- package/src/{react → ui/components/PluginManager}/PluginManagerProvider.ts +1 -1
- package/src/ui/components/PluginManager/index.ts +5 -0
- package/src/{react/Surface.stories.tsx → ui/components/Surface/SurfaceComponent.stories.tsx} +28 -24
- package/src/{react/Surface.tsx → ui/components/Surface/SurfaceComponent.tsx} +48 -58
- package/src/{react → ui/components/Surface}/SurfaceInfo.tsx +2 -2
- 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 +35 -0
- package/src/{common/surface.ts → ui/components/Surface/types.ts} +22 -25
- package/src/ui/components/index.ts +7 -0
- package/src/ui/hooks/index.ts +9 -0
- package/src/ui/hooks/useApp.test.tsx +159 -0
- package/src/{react → ui/hooks}/useApp.tsx +110 -30
- package/src/{react → ui/hooks}/useCapabilities.ts +9 -5
- package/src/{react/common.ts → ui/hooks/useSettingsState.ts} +0 -11
- package/src/ui/hooks/useSurface.ts +13 -0
- package/src/ui/index.ts +6 -0
- package/src/vite-plugin/composer-plugin.ts +128 -0
- package/src/vite-plugin/import-map-plugin.ts +315 -0
- package/src/vite-plugin/index.ts +6 -0
- package/src/vite-plugin/packages.ts +29 -0
- package/tsconfig.json +4 -28
- package/tsconfig.node.json +2 -4
- package/typedoc.json +2 -4
- package/vitest.config.ts +1 -1
- package/dist/lib/browser/app-graph-builder-M2VPYQC6.mjs +0 -149
- package/dist/lib/browser/app-graph-builder-M2VPYQC6.mjs.map +0 -7
- package/dist/lib/browser/capability-7PCNSWBT.mjs.map +0 -7
- package/dist/lib/browser/capability-KP3PFEXD.mjs +0 -31
- package/dist/lib/browser/capability-KP3PFEXD.mjs.map +0 -7
- package/dist/lib/browser/chunk-6Y7PZV72.mjs.map +0 -7
- package/dist/lib/browser/chunk-7IQHKD4U.mjs.map +0 -7
- package/dist/lib/browser/chunk-BLQJSGL3.mjs +0 -732
- package/dist/lib/browser/chunk-BLQJSGL3.mjs.map +0 -7
- package/dist/lib/browser/chunk-FHQTHCX7.mjs +0 -8
- package/dist/lib/browser/chunk-FMZN33N4.mjs.map +0 -7
- package/dist/lib/browser/chunk-H4WPA7U7.mjs +0 -77
- package/dist/lib/browser/chunk-H4WPA7U7.mjs.map +0 -7
- package/dist/lib/browser/chunk-PKQT6C53.mjs.map +0 -7
- package/dist/lib/browser/chunk-TCLLRCS3.mjs.map +0 -7
- package/dist/lib/browser/chunk-XYNO72GQ.mjs +0 -746
- package/dist/lib/browser/chunk-XYNO72GQ.mjs.map +0 -7
- package/dist/lib/browser/common/index.mjs +0 -38
- package/dist/lib/browser/invoker-capability-SZRSTHEH.mjs +0 -32
- package/dist/lib/browser/invoker-capability-SZRSTHEH.mjs.map +0 -7
- package/dist/lib/browser/operation-resolver-6MP2MYOY.mjs +0 -64
- package/dist/lib/browser/operation-resolver-6MP2MYOY.mjs.map +0 -7
- package/dist/lib/node-esm/app-graph-builder-LROHGJEM.mjs +0 -150
- package/dist/lib/node-esm/app-graph-builder-LROHGJEM.mjs.map +0 -7
- package/dist/lib/node-esm/capability-CFLQ2QQU.mjs.map +0 -7
- package/dist/lib/node-esm/capability-RCUNM2M7.mjs +0 -32
- package/dist/lib/node-esm/capability-RCUNM2M7.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-663A54LQ.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-6WXBT3EC.mjs +0 -747
- package/dist/lib/node-esm/chunk-6WXBT3EC.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-7OWSHPYK.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-GQEBIGKD.mjs +0 -733
- package/dist/lib/node-esm/chunk-GQEBIGKD.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-GT6OKM5I.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-STMXUEPO.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-XR6NMKEP.mjs +0 -78
- package/dist/lib/node-esm/chunk-XR6NMKEP.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-XYQTBFPA.mjs.map +0 -7
- package/dist/lib/node-esm/common/index.mjs +0 -39
- package/dist/lib/node-esm/invoker-capability-PNMA5JOS.mjs +0 -33
- package/dist/lib/node-esm/invoker-capability-PNMA5JOS.mjs.map +0 -7
- package/dist/lib/node-esm/operation-resolver-7YWDMTNU.mjs +0 -65
- package/dist/lib/node-esm/operation-resolver-7YWDMTNU.mjs.map +0 -7
- package/dist/types/src/cli.d.ts.map +0 -1
- package/dist/types/src/common/activation-event.d.ts +0 -66
- package/dist/types/src/common/activation-event.d.ts.map +0 -1
- package/dist/types/src/common/capability.d.ts +0 -265
- package/dist/types/src/common/capability.d.ts.map +0 -1
- package/dist/types/src/common/collaboration.d.ts +0 -26
- package/dist/types/src/common/collaboration.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/plugin.d.ts +0 -201
- package/dist/types/src/common/plugin.d.ts.map +0 -1
- package/dist/types/src/common/surface.d.ts.map +0 -1
- package/dist/types/src/playground/debug/Debug.d.ts +0 -8
- 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 -3
- package/dist/types/src/playground/debug/plugin.d.ts.map +0 -1
- package/dist/types/src/playground/generator/Main.d.ts +0 -8
- package/dist/types/src/playground/generator/Main.d.ts.map +0 -1
- package/dist/types/src/playground/generator/Toolbar.d.ts +0 -8
- package/dist/types/src/playground/generator/Toolbar.d.ts.map +0 -1
- package/dist/types/src/playground/generator/generator.d.ts +0 -19
- 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 -3
- package/dist/types/src/playground/generator/plugin.d.ts.map +0 -1
- package/dist/types/src/playground/layout/Layout.d.ts +0 -10
- 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 -3
- package/dist/types/src/playground/layout/plugin.d.ts.map +0 -1
- package/dist/types/src/playground/logger/Toolbar.d.ts +0 -8
- 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 -3
- package/dist/types/src/playground/logger/plugin.d.ts.map +0 -1
- package/dist/types/src/playground/logger/schema.d.ts +0 -27
- package/dist/types/src/playground/logger/schema.d.ts.map +0 -1
- package/dist/types/src/playground/playground.stories.d.ts +0 -11
- package/dist/types/src/playground/playground.stories.d.ts.map +0 -1
- package/dist/types/src/plugin-settings/SettingsPlugin.d.ts +0 -3
- package/dist/types/src/plugin-settings/SettingsPlugin.d.ts.map +0 -1
- package/dist/types/src/plugin-settings/actions.d.ts +0 -61
- package/dist/types/src/plugin-settings/actions.d.ts.map +0 -1
- package/dist/types/src/plugin-settings/app-graph-builder.d.ts +0 -6
- 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/meta.d.ts +0 -3
- package/dist/types/src/plugin-settings/meta.d.ts.map +0 -1
- package/dist/types/src/plugin-settings/operation-resolver.d.ts +0 -6
- package/dist/types/src/plugin-settings/operation-resolver.d.ts.map +0 -1
- package/dist/types/src/plugin-settings/translations.d.ts +0 -11
- package/dist/types/src/plugin-settings/translations.d.ts.map +0 -1
- package/dist/types/src/react/App.d.ts.map +0 -1
- package/dist/types/src/react/App.stories.d.ts.map +0 -1
- package/dist/types/src/react/DefaultFallback.d.ts +0 -8
- package/dist/types/src/react/DefaultFallback.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/PluginManagerContext.stories.d.ts.map +0 -1
- package/dist/types/src/react/PluginManagerProvider.d.ts.map +0 -1
- package/dist/types/src/react/Surface.d.ts +0 -14
- package/dist/types/src/react/Surface.d.ts.map +0 -1
- package/dist/types/src/react/Surface.stories.d.ts.map +0 -1
- package/dist/types/src/react/SurfaceInfo.d.ts.map +0 -1
- package/dist/types/src/react/common.d.ts.map +0 -1
- package/dist/types/src/react/index.d.ts +0 -9
- package/dist/types/src/react/index.d.ts.map +0 -1
- package/dist/types/src/react/types.d.ts +0 -12
- package/dist/types/src/react/types.d.ts.map +0 -1
- package/dist/types/src/react/useApp.d.ts.map +0 -1
- package/dist/types/src/react/useCapabilities.d.ts.map +0 -1
- package/dist/types/src/react/useLoading.d.ts.map +0 -1
- package/dist/types/src/react/useOperationResolver.d.ts +0 -19
- package/dist/types/src/react/useOperationResolver.d.ts.map +0 -1
- package/src/common/activation-event.ts +0 -99
- package/src/common/capability.ts +0 -343
- package/src/common/collaboration.ts +0 -31
- package/src/common/file.ts +0 -22
- package/src/common/graph.ts +0 -30
- package/src/common/plugin.ts +0 -364
- package/src/playground/debug/Debug.tsx +0 -49
- package/src/playground/debug/plugin.ts +0 -16
- package/src/playground/generator/Main.tsx +0 -80
- package/src/playground/generator/Toolbar.tsx +0 -57
- package/src/playground/generator/generator.ts +0 -48
- package/src/playground/generator/index.ts +0 -6
- package/src/playground/generator/plugin.ts +0 -21
- package/src/playground/layout/Layout.tsx +0 -37
- package/src/playground/layout/plugin.ts +0 -18
- package/src/playground/logger/Toolbar.tsx +0 -33
- package/src/playground/logger/index.ts +0 -5
- package/src/playground/logger/plugin.ts +0 -42
- package/src/playground/logger/schema.ts +0 -22
- package/src/playground/playground.stories.tsx +0 -54
- package/src/plugin-settings/SettingsPlugin.ts +0 -19
- package/src/plugin-settings/actions.ts +0 -64
- package/src/plugin-settings/app-graph-builder.ts +0 -140
- package/src/plugin-settings/index.ts +0 -6
- package/src/plugin-settings/meta.ts +0 -10
- package/src/plugin-settings/operation-resolver.ts +0 -55
- package/src/plugin-settings/translations.ts +0 -19
- package/src/react/App.stories.tsx +0 -63
- package/src/react/DefaultFallback.tsx +0 -26
- package/src/react/ErrorBoundary.tsx +0 -56
- package/src/react/index.ts +0 -14
- package/src/react/types.ts +0 -27
- package/src/react/useOperationResolver.ts +0 -40
- /package/dist/lib/{node-esm/react/index.mjs.map → browser/chunk-RFSO3JRG.mjs.map} +0 -0
- /package/dist/lib/{node-esm/common/index.mjs.map → browser/common/activation-events.mjs.map} +0 -0
- /package/dist/lib/browser/{react/index.mjs.map → common/capabilities.mjs.map} +0 -0
- /package/dist/lib/browser/{common/index.mjs.map → core/url-loader.mjs.map} +0 -0
- /package/dist/types/src/{react → ui/components/PluginManager}/PluginManagerContext.stories.d.ts +0 -0
- /package/dist/types/src/{react → ui/components/Surface}/SurfaceInfo.d.ts +0 -0
- /package/dist/types/src/{react → ui/hooks}/useLoading.d.ts +0 -0
- /package/src/{react → ui/hooks}/useLoading.tsx +0 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { assert, describe, it } from '@effect/vitest';
|
|
6
|
+
import * as Effect from 'effect/Effect';
|
|
7
|
+
|
|
8
|
+
import * as Plugin from './plugin';
|
|
9
|
+
import * as UrlLoader from './url-loader';
|
|
10
|
+
|
|
11
|
+
const testMeta = { id: 'org.dxos.plugin.test', name: 'Test' };
|
|
12
|
+
|
|
13
|
+
describe('UrlLoader', () => {
|
|
14
|
+
describe('make', () => {
|
|
15
|
+
it.effect('resolves built-in plugins by meta.id', () =>
|
|
16
|
+
Effect.gen(function* () {
|
|
17
|
+
const testPlugin = Plugin.make(Plugin.define(testMeta))();
|
|
18
|
+
const loader = UrlLoader.make([testPlugin]);
|
|
19
|
+
const result = yield* loader(testMeta.id);
|
|
20
|
+
assert.strictEqual(result.meta.id, testMeta.id);
|
|
21
|
+
}),
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
it.effect('fails for unknown non-URL locator', () =>
|
|
25
|
+
Effect.gen(function* () {
|
|
26
|
+
const loader = UrlLoader.make([]);
|
|
27
|
+
const exit = yield* Effect.exit(loader('not-a-url'));
|
|
28
|
+
assert.isTrue(exit._tag === 'Failure');
|
|
29
|
+
}),
|
|
30
|
+
);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
describe('preload', () => {
|
|
34
|
+
it('returns empty array when storage has no entries', async ({ expect }) => {
|
|
35
|
+
const storage: UrlLoader.Storage = {
|
|
36
|
+
get: () => null,
|
|
37
|
+
set: () => {},
|
|
38
|
+
};
|
|
39
|
+
const result = await UrlLoader.preload({ storage });
|
|
40
|
+
expect(result).toEqual([]);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('returns empty array when storage has invalid JSON', async ({ expect }) => {
|
|
44
|
+
const storage: UrlLoader.Storage = {
|
|
45
|
+
get: () => '{{invalid json',
|
|
46
|
+
set: () => {},
|
|
47
|
+
};
|
|
48
|
+
const result = await UrlLoader.preload({ storage });
|
|
49
|
+
expect(result).toEqual([]);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('returns empty array when storage contains null', async ({ expect }) => {
|
|
53
|
+
const storage: UrlLoader.Storage = {
|
|
54
|
+
get: () => 'null',
|
|
55
|
+
set: () => {},
|
|
56
|
+
};
|
|
57
|
+
const result = await UrlLoader.preload({ storage });
|
|
58
|
+
expect(result).toEqual([]);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('returns empty array when storage contains an object', async ({ expect }) => {
|
|
62
|
+
const storage: UrlLoader.Storage = {
|
|
63
|
+
get: () => '{}',
|
|
64
|
+
set: () => {},
|
|
65
|
+
};
|
|
66
|
+
const result = await UrlLoader.preload({ storage });
|
|
67
|
+
expect(result).toEqual([]);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('returns empty array when entries are missing required fields', async ({ expect }) => {
|
|
71
|
+
const storage: UrlLoader.Storage = {
|
|
72
|
+
get: () => '[{"title":"no url"}]',
|
|
73
|
+
set: () => {},
|
|
74
|
+
};
|
|
75
|
+
const result = await UrlLoader.preload({ storage });
|
|
76
|
+
expect(result).toEqual([]);
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
});
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import * as Effect from 'effect/Effect';
|
|
6
|
+
|
|
7
|
+
import { log } from '@dxos/log';
|
|
8
|
+
|
|
9
|
+
import * as Plugin from './plugin';
|
|
10
|
+
|
|
11
|
+
const DEFAULT_KEY = 'org.dxos.composer.remote-plugins';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Abstraction over key-value storage (defaults to localStorage).
|
|
15
|
+
*/
|
|
16
|
+
export type Storage = {
|
|
17
|
+
get(key: string): string | null;
|
|
18
|
+
set(key: string, value: string): void;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Options for configuring the URL loader.
|
|
23
|
+
*/
|
|
24
|
+
export type Options = {
|
|
25
|
+
storage?: Storage;
|
|
26
|
+
key?: string;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
type RemotePluginEntry = { id: string; url: string };
|
|
30
|
+
|
|
31
|
+
const defaultStorage = (): Storage => ({
|
|
32
|
+
get: (key) => localStorage.getItem(key),
|
|
33
|
+
set: (key, value) => localStorage.setItem(key, value),
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const getPersistedRemotePlugins = (storage: Storage, key: string): RemotePluginEntry[] => {
|
|
37
|
+
try {
|
|
38
|
+
const parsed: unknown = JSON.parse(storage.get(key) ?? '[]');
|
|
39
|
+
if (!Array.isArray(parsed)) {
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
return parsed.filter(
|
|
43
|
+
(entry): entry is RemotePluginEntry =>
|
|
44
|
+
typeof entry === 'object' && entry !== null && typeof entry.id === 'string' && typeof entry.url === 'string',
|
|
45
|
+
);
|
|
46
|
+
} catch {
|
|
47
|
+
return [];
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const persistRemotePlugin = (storage: Storage, key: string, entry: RemotePluginEntry): void => {
|
|
52
|
+
try {
|
|
53
|
+
const entries = getPersistedRemotePlugins(storage, key).filter((existing) => existing.id !== entry.id);
|
|
54
|
+
entries.push(entry);
|
|
55
|
+
storage.set(key, JSON.stringify(entries));
|
|
56
|
+
} catch (error) {
|
|
57
|
+
log.warn('failed to persist remote plugin entry', { entry, error });
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const isUrl = (locator: string): boolean => {
|
|
62
|
+
try {
|
|
63
|
+
const url = new URL(locator);
|
|
64
|
+
return url.protocol === 'http:' || url.protocol === 'https:';
|
|
65
|
+
} catch {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const normalizePluginExport = (mod: Record<string, unknown>): Plugin.Plugin => {
|
|
71
|
+
const exported = mod.default;
|
|
72
|
+
if (Plugin.isPlugin(exported)) {
|
|
73
|
+
return exported;
|
|
74
|
+
}
|
|
75
|
+
if (typeof exported === 'function') {
|
|
76
|
+
const result = (exported as () => unknown)();
|
|
77
|
+
if (Plugin.isPlugin(result)) {
|
|
78
|
+
return result;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
throw new Error('Remote module default export is not a Plugin or a zero-arg plugin factory.');
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const loadRemotePlugin = async (url: string): Promise<Plugin.Plugin> => {
|
|
85
|
+
log.info('loading remote plugin', { url });
|
|
86
|
+
const mod = await import(/* @vite-ignore */ url);
|
|
87
|
+
const plugin = normalizePluginExport(mod);
|
|
88
|
+
if (!plugin.meta.id || !plugin.meta.name) {
|
|
89
|
+
throw new Error(`Remote plugin at ${url} is missing required meta.id or meta.name.`);
|
|
90
|
+
}
|
|
91
|
+
return plugin;
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Preloads previously persisted remote plugins from storage.
|
|
96
|
+
*/
|
|
97
|
+
export const preload = async (options: Options = {}): Promise<Plugin.Plugin[]> => {
|
|
98
|
+
const storage = options.storage ?? defaultStorage();
|
|
99
|
+
const key = options.key ?? DEFAULT_KEY;
|
|
100
|
+
|
|
101
|
+
const entries = getPersistedRemotePlugins(storage, key);
|
|
102
|
+
if (entries.length === 0) {
|
|
103
|
+
return [];
|
|
104
|
+
}
|
|
105
|
+
log.info('preloading remote plugins', { count: entries.length });
|
|
106
|
+
const results = await Promise.allSettled(entries.map((entry) => loadRemotePlugin(entry.url)));
|
|
107
|
+
const plugins: Plugin.Plugin[] = [];
|
|
108
|
+
for (let index = 0; index < results.length; index++) {
|
|
109
|
+
const result = results[index];
|
|
110
|
+
if (result.status === 'fulfilled') {
|
|
111
|
+
plugins.push(result.value);
|
|
112
|
+
} else {
|
|
113
|
+
log.warn('failed to preload remote plugin', { entry: entries[index], error: result.reason });
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return plugins;
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Creates a plugin loader that resolves built-in plugins by ID or loads remote plugins from URLs.
|
|
121
|
+
*/
|
|
122
|
+
export const make = (builtinPlugins: Plugin.Plugin[], options: Options = {}) => {
|
|
123
|
+
const storage = options.storage ?? defaultStorage();
|
|
124
|
+
const key = options.key ?? DEFAULT_KEY;
|
|
125
|
+
|
|
126
|
+
return (locator: string): Effect.Effect<Plugin.Plugin, Error> =>
|
|
127
|
+
Effect.gen(function* () {
|
|
128
|
+
const builtin = builtinPlugins.find((plugin) => plugin.meta.id === locator);
|
|
129
|
+
if (builtin) {
|
|
130
|
+
return builtin;
|
|
131
|
+
}
|
|
132
|
+
if (!isUrl(locator)) {
|
|
133
|
+
return yield* Effect.fail(new Error(`Plugin not found and locator is not a URL: ${locator}`));
|
|
134
|
+
}
|
|
135
|
+
const plugin = yield* Effect.tryPromise({
|
|
136
|
+
try: () => loadRemotePlugin(locator),
|
|
137
|
+
catch: (error) => new Error(`Failed to load remote plugin from ${locator}: ${error}`),
|
|
138
|
+
});
|
|
139
|
+
const duplicate = builtinPlugins.find((existing) => existing.meta.id === plugin.meta.id);
|
|
140
|
+
if (duplicate) {
|
|
141
|
+
return yield* Effect.fail(
|
|
142
|
+
new Error(`Remote plugin ${plugin.meta.id} conflicts with built-in plugin of the same id.`),
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
persistRemotePlugin(storage, key, { id: plugin.meta.id, url: locator });
|
|
146
|
+
return plugin;
|
|
147
|
+
});
|
|
148
|
+
};
|
package/src/index.ts
CHANGED
|
@@ -2,10 +2,8 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
export * from './
|
|
6
|
-
export * as Common from './common';
|
|
5
|
+
export * from './common';
|
|
7
6
|
export * from './context';
|
|
8
7
|
export * from './core';
|
|
9
8
|
export * from './plugin-operation';
|
|
10
9
|
export * from './plugin-runtime';
|
|
11
|
-
export * from './plugin-settings';
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import { ActivationEvents } from '../common';
|
|
6
6
|
import { Capability, Plugin } from '../core';
|
|
7
7
|
|
|
8
8
|
import { meta } from './meta';
|
|
@@ -12,13 +12,13 @@ const HistoryCapabilities = Capability.lazy('HistoryCapabilities', () => import(
|
|
|
12
12
|
|
|
13
13
|
export const OperationPlugin = Plugin.define(meta).pipe(
|
|
14
14
|
Plugin.addModule({
|
|
15
|
-
activatesOn:
|
|
16
|
-
activatesBefore: [
|
|
17
|
-
activatesAfter: [
|
|
15
|
+
activatesOn: ActivationEvents.ManagedRuntimeReady,
|
|
16
|
+
activatesBefore: [ActivationEvents.SetupOperationHandler],
|
|
17
|
+
activatesAfter: [ActivationEvents.OperationInvokerReady],
|
|
18
18
|
activate: OperationInvoker,
|
|
19
19
|
}),
|
|
20
20
|
Plugin.addModule({
|
|
21
|
-
activatesOn:
|
|
21
|
+
activatesOn: ActivationEvents.OperationInvokerReady,
|
|
22
22
|
activate: HistoryCapabilities,
|
|
23
23
|
}),
|
|
24
24
|
Plugin.make,
|
|
@@ -6,7 +6,7 @@ import * as Effect from 'effect/Effect';
|
|
|
6
6
|
|
|
7
7
|
import { type OperationInvoker } from '@dxos/operation';
|
|
8
8
|
|
|
9
|
-
import
|
|
9
|
+
import { Capabilities } from '../../common';
|
|
10
10
|
import { Capability } from '../../core';
|
|
11
11
|
|
|
12
12
|
import * as HistoryTracker from './history-tracker';
|
|
@@ -22,16 +22,16 @@ export default Capability.makeModule(
|
|
|
22
22
|
const capabilities = yield* Capability.Service;
|
|
23
23
|
|
|
24
24
|
// Create UndoRegistry.
|
|
25
|
-
const undoRegistry = UndoRegistry.make(() => capabilities.getAll(
|
|
25
|
+
const undoRegistry = UndoRegistry.make(() => capabilities.getAll(Capabilities.UndoMapping).flat());
|
|
26
26
|
|
|
27
27
|
// Create HistoryTracker (depends on UndoRegistry and OperationInvoker).
|
|
28
|
-
const invoker = yield* Capability.get(
|
|
28
|
+
const invoker = yield* Capability.get(Capabilities.OperationInvoker);
|
|
29
29
|
// Cast to internal type - the factory always returns OperationInvokerInternal.
|
|
30
30
|
const historyTracker = HistoryTracker.make(invoker as OperationInvoker.OperationInvokerInternal, undoRegistry);
|
|
31
31
|
|
|
32
32
|
return [
|
|
33
|
-
Capability.contributes(
|
|
34
|
-
Capability.contributes(
|
|
33
|
+
Capability.contributes(Capabilities.UndoRegistry, undoRegistry),
|
|
34
|
+
Capability.contributes(Capabilities.HistoryTracker, historyTracker),
|
|
35
35
|
];
|
|
36
36
|
}),
|
|
37
37
|
);
|
|
@@ -2,10 +2,6 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { BaseError } from '@dxos/errors';
|
|
6
6
|
|
|
7
|
-
export class EmptyHistoryError extends
|
|
8
|
-
constructor() {
|
|
9
|
-
super('EMPTY_HISTORY', 'Cannot undo: history is empty.');
|
|
10
|
-
}
|
|
11
|
-
}
|
|
7
|
+
export class EmptyHistoryError extends BaseError.extend('EmptyHistoryError', 'Cannot undo: history is empty.') {}
|
|
@@ -5,10 +5,14 @@
|
|
|
5
5
|
import { it } from '@effect/vitest';
|
|
6
6
|
import * as Effect from 'effect/Effect';
|
|
7
7
|
import * as Fiber from 'effect/Fiber';
|
|
8
|
+
import * as Layer from 'effect/Layer';
|
|
9
|
+
import * as ManagedRuntime from 'effect/ManagedRuntime';
|
|
8
10
|
import * as TestClock from 'effect/TestClock';
|
|
9
11
|
import { describe, expect } from 'vitest';
|
|
10
12
|
|
|
11
|
-
import {
|
|
13
|
+
import { Operation, OperationInvoker } from '@dxos/operation';
|
|
14
|
+
|
|
15
|
+
const testRuntime = ManagedRuntime.make(Layer.empty) as unknown as ManagedRuntime.ManagedRuntime<any, any>;
|
|
12
16
|
|
|
13
17
|
import { UndoOperation } from '../../common';
|
|
14
18
|
import {
|
|
@@ -35,7 +39,7 @@ describe('HistoryTracker', () => {
|
|
|
35
39
|
deriveContext: (_input, output) => ({ value: output.value }),
|
|
36
40
|
});
|
|
37
41
|
|
|
38
|
-
const invoker = OperationInvoker.make(() => Effect.succeed([computeHandler, halveComputeHandler]));
|
|
42
|
+
const invoker = OperationInvoker.make(() => Effect.succeed([computeHandler, halveComputeHandler]), testRuntime);
|
|
39
43
|
const undoRegistry = UndoRegistry.make(() => [undoMapping]);
|
|
40
44
|
const tracker = HistoryTracker.make(invoker, undoRegistry);
|
|
41
45
|
|
|
@@ -55,7 +59,7 @@ describe('HistoryTracker', () => {
|
|
|
55
59
|
|
|
56
60
|
it.effect('does not track operations without undo mapping', () =>
|
|
57
61
|
Effect.gen(function* () {
|
|
58
|
-
const invoker = OperationInvoker.make(() => Effect.succeed([toStringHandler]));
|
|
62
|
+
const invoker = OperationInvoker.make(() => Effect.succeed([toStringHandler]), testRuntime);
|
|
59
63
|
const undoRegistry = UndoRegistry.make(() => []);
|
|
60
64
|
const tracker = HistoryTracker.make(invoker, undoRegistry);
|
|
61
65
|
const collector = yield* createEventCollector(invoker);
|
|
@@ -81,15 +85,12 @@ describe('HistoryTracker', () => {
|
|
|
81
85
|
});
|
|
82
86
|
|
|
83
87
|
let halveWasCalled = false;
|
|
84
|
-
const trackingHalveHandler =
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
halveWasCalled = true;
|
|
88
|
-
return Effect.succeed({ value: data.value / 2 });
|
|
89
|
-
},
|
|
88
|
+
const trackingHalveHandler = Operation.withHandler(HalveCompute, (data) => {
|
|
89
|
+
halveWasCalled = true;
|
|
90
|
+
return Effect.succeed({ value: data.value / 2 });
|
|
90
91
|
});
|
|
91
92
|
|
|
92
|
-
const invoker = OperationInvoker.make(() => Effect.succeed([computeHandler, trackingHalveHandler]));
|
|
93
|
+
const invoker = OperationInvoker.make(() => Effect.succeed([computeHandler, trackingHalveHandler]), testRuntime);
|
|
93
94
|
const undoRegistry = UndoRegistry.make(() => [undoMapping]);
|
|
94
95
|
const tracker = HistoryTracker.make(invoker, undoRegistry);
|
|
95
96
|
|
|
@@ -117,7 +118,7 @@ describe('HistoryTracker', () => {
|
|
|
117
118
|
deriveContext: (_input, output) => ({ value: output.value }),
|
|
118
119
|
});
|
|
119
120
|
|
|
120
|
-
const invoker = OperationInvoker.make(() => Effect.succeed([computeHandler, halveComputeHandler]));
|
|
121
|
+
const invoker = OperationInvoker.make(() => Effect.succeed([computeHandler, halveComputeHandler]), testRuntime);
|
|
121
122
|
const undoRegistry = UndoRegistry.make(() => [undoMapping]);
|
|
122
123
|
const tracker = HistoryTracker.make(invoker, undoRegistry);
|
|
123
124
|
const collector = yield* createEventCollector(invoker);
|
|
@@ -152,15 +153,12 @@ describe('HistoryTracker', () => {
|
|
|
152
153
|
});
|
|
153
154
|
|
|
154
155
|
const halveInputs: number[] = [];
|
|
155
|
-
const trackingHalveHandler =
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
halveInputs.push(data.value);
|
|
159
|
-
return Effect.succeed({ value: data.value / 2 });
|
|
160
|
-
},
|
|
156
|
+
const trackingHalveHandler = Operation.withHandler(HalveCompute, (data) => {
|
|
157
|
+
halveInputs.push(data.value);
|
|
158
|
+
return Effect.succeed({ value: data.value / 2 });
|
|
161
159
|
});
|
|
162
160
|
|
|
163
|
-
const invoker = OperationInvoker.make(() => Effect.succeed([computeHandler, trackingHalveHandler]));
|
|
161
|
+
const invoker = OperationInvoker.make(() => Effect.succeed([computeHandler, trackingHalveHandler]), testRuntime);
|
|
164
162
|
const undoRegistry = UndoRegistry.make(() => [undoMapping]);
|
|
165
163
|
const tracker = HistoryTracker.make(invoker, undoRegistry);
|
|
166
164
|
const collector = yield* createEventCollector(invoker);
|
|
@@ -194,7 +192,7 @@ describe('HistoryTracker', () => {
|
|
|
194
192
|
|
|
195
193
|
it.effect('undo on empty history returns error', () =>
|
|
196
194
|
Effect.gen(function* () {
|
|
197
|
-
const invoker = OperationInvoker.make(() => Effect.succeed([]));
|
|
195
|
+
const invoker = OperationInvoker.make(() => Effect.succeed([]), testRuntime);
|
|
198
196
|
const undoRegistry = UndoRegistry.make(() => []);
|
|
199
197
|
const tracker = HistoryTracker.make(invoker, undoRegistry);
|
|
200
198
|
|
|
@@ -208,7 +206,7 @@ describe('HistoryTracker', () => {
|
|
|
208
206
|
|
|
209
207
|
it.effect('fires ShowUndo operation when undoable operation is tracked', () =>
|
|
210
208
|
Effect.gen(function* () {
|
|
211
|
-
const testMessage: [string, { ns: string }] = ['test
|
|
209
|
+
const testMessage: [string, { ns: string }] = ['test-undo.message', { ns: 'test' }];
|
|
212
210
|
const undoMapping = UndoMapping.make({
|
|
213
211
|
operation: Compute,
|
|
214
212
|
inverse: HalveCompute,
|
|
@@ -218,17 +216,15 @@ describe('HistoryTracker', () => {
|
|
|
218
216
|
|
|
219
217
|
let showUndoWasCalled = false;
|
|
220
218
|
let showUndoMessage: unknown = undefined;
|
|
221
|
-
const showUndoHandler =
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
showUndoMessage = input.message;
|
|
226
|
-
return Effect.succeed(undefined);
|
|
227
|
-
},
|
|
219
|
+
const showUndoHandler = Operation.withHandler(UndoOperation.ShowUndo, (input) => {
|
|
220
|
+
showUndoWasCalled = true;
|
|
221
|
+
showUndoMessage = input.message;
|
|
222
|
+
return Effect.succeed(undefined);
|
|
228
223
|
});
|
|
229
224
|
|
|
230
|
-
const invoker = OperationInvoker.make(
|
|
231
|
-
Effect.succeed([computeHandler, halveComputeHandler, showUndoHandler]),
|
|
225
|
+
const invoker = OperationInvoker.make(
|
|
226
|
+
() => Effect.succeed([computeHandler, halveComputeHandler, showUndoHandler]),
|
|
227
|
+
testRuntime,
|
|
232
228
|
);
|
|
233
229
|
const undoRegistry = UndoRegistry.make(() => [undoMapping]);
|
|
234
230
|
const tracker = HistoryTracker.make(invoker, undoRegistry);
|
|
@@ -254,7 +250,7 @@ describe('HistoryTracker', () => {
|
|
|
254
250
|
Effect.gen(function* () {
|
|
255
251
|
// Dynamic message that depends on input/output.
|
|
256
252
|
const dynamicMessage = (input: { value: number }, output: { value: number }): [string, { ns: string }] => [
|
|
257
|
-
`computed
|
|
253
|
+
`computed-${input.value}-to-${output.value}`,
|
|
258
254
|
{ ns: 'test' },
|
|
259
255
|
];
|
|
260
256
|
const undoMapping = UndoMapping.make({
|
|
@@ -266,17 +262,15 @@ describe('HistoryTracker', () => {
|
|
|
266
262
|
|
|
267
263
|
let showUndoWasCalled = false;
|
|
268
264
|
let showUndoMessage: unknown = undefined;
|
|
269
|
-
const showUndoHandler =
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
showUndoMessage = input.message;
|
|
274
|
-
return Effect.succeed(undefined);
|
|
275
|
-
},
|
|
265
|
+
const showUndoHandler = Operation.withHandler(UndoOperation.ShowUndo, (input) => {
|
|
266
|
+
showUndoWasCalled = true;
|
|
267
|
+
showUndoMessage = input.message;
|
|
268
|
+
return Effect.succeed(undefined);
|
|
276
269
|
});
|
|
277
270
|
|
|
278
|
-
const invoker = OperationInvoker.make(
|
|
279
|
-
Effect.succeed([computeHandler, halveComputeHandler, showUndoHandler]),
|
|
271
|
+
const invoker = OperationInvoker.make(
|
|
272
|
+
() => Effect.succeed([computeHandler, halveComputeHandler, showUndoHandler]),
|
|
273
|
+
testRuntime,
|
|
280
274
|
);
|
|
281
275
|
const undoRegistry = UndoRegistry.make(() => [undoMapping]);
|
|
282
276
|
const tracker = HistoryTracker.make(invoker, undoRegistry);
|
|
@@ -295,7 +289,7 @@ describe('HistoryTracker', () => {
|
|
|
295
289
|
yield* waitUntil(() => showUndoWasCalled);
|
|
296
290
|
expect(showUndoWasCalled).toBe(true);
|
|
297
291
|
// Compute 2 * 2 = 4, so message should be 'computed 2 to 4'.
|
|
298
|
-
expect(showUndoMessage).toEqual(['computed
|
|
292
|
+
expect(showUndoMessage).toEqual(['computed-2-to-4', { ns: 'test' }]);
|
|
299
293
|
}),
|
|
300
294
|
);
|
|
301
295
|
|
|
@@ -314,7 +308,7 @@ describe('HistoryTracker', () => {
|
|
|
314
308
|
},
|
|
315
309
|
});
|
|
316
310
|
|
|
317
|
-
const invoker = OperationInvoker.make(() => Effect.succeed([computeHandler, halveComputeHandler]));
|
|
311
|
+
const invoker = OperationInvoker.make(() => Effect.succeed([computeHandler, halveComputeHandler]), testRuntime);
|
|
318
312
|
const undoRegistry = UndoRegistry.make(() => [undoMapping]);
|
|
319
313
|
const tracker = HistoryTracker.make(invoker, undoRegistry);
|
|
320
314
|
const collector = yield* createEventCollector(invoker);
|
|
@@ -352,7 +346,7 @@ describe('HistoryTracker', () => {
|
|
|
352
346
|
},
|
|
353
347
|
});
|
|
354
348
|
|
|
355
|
-
const invoker = OperationInvoker.make(() => Effect.succeed([computeHandler, halveComputeHandler]));
|
|
349
|
+
const invoker = OperationInvoker.make(() => Effect.succeed([computeHandler, halveComputeHandler]), testRuntime);
|
|
356
350
|
const undoRegistry = UndoRegistry.make(() => [undoMapping]);
|
|
357
351
|
const tracker = HistoryTracker.make(invoker, undoRegistry);
|
|
358
352
|
const collector = yield* createEventCollector(invoker);
|
|
@@ -4,7 +4,10 @@
|
|
|
4
4
|
|
|
5
5
|
import type { Operation } from '@dxos/operation';
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Label type for translatable text (canonical definition in @dxos/app-toolkit).
|
|
9
|
+
*/
|
|
10
|
+
type Label = string | [string, { ns: string; count?: number; defaultValue?: string }];
|
|
8
11
|
|
|
9
12
|
/**
|
|
10
13
|
* Extract the input type from an OperationDefinition.
|
|
@@ -95,7 +98,7 @@ export interface UndoMappingProps<
|
|
|
95
98
|
* thread: output.thread,
|
|
96
99
|
* anchor: output.anchor,
|
|
97
100
|
* }),
|
|
98
|
-
* message: ['thread deleted label', { ns: 'plugin-thread' }],
|
|
101
|
+
* message: ['thread deleted label', { ns: '@dxos/plugin-thread' }],
|
|
99
102
|
* });
|
|
100
103
|
*
|
|
101
104
|
* // Dynamic message based on input/output
|
|
@@ -106,7 +109,7 @@ export interface UndoMappingProps<
|
|
|
106
109
|
* message: (input, _output) =>
|
|
107
110
|
* input.objects.length === 1
|
|
108
111
|
* ? ['object deleted label', { ns: getTypename(input.objects[0]) }]
|
|
109
|
-
* : ['objects deleted label', { ns: 'plugin-space' }],
|
|
112
|
+
* : ['objects deleted label', { ns: '@dxos/plugin-space' }],
|
|
110
113
|
* });
|
|
111
114
|
* ```
|
|
112
115
|
*/
|
|
@@ -52,18 +52,18 @@ describe('resolveMessage', () => {
|
|
|
52
52
|
});
|
|
53
53
|
|
|
54
54
|
test('returns static label as-is', ({ expect }) => {
|
|
55
|
-
const staticMessage: [string, { ns: string }] = ['test
|
|
55
|
+
const staticMessage: [string, { ns: string }] = ['test.message', { ns: 'test' }];
|
|
56
56
|
const result = UndoMapping.resolveMessage(staticMessage, { value: 1 }, { value: 2 });
|
|
57
57
|
expect(result).toEqual(staticMessage);
|
|
58
58
|
});
|
|
59
59
|
|
|
60
60
|
test('calls function message with input and output', ({ expect }) => {
|
|
61
61
|
const messageFunc = (input: { value: number }, output: { value: number }): [string, { ns: string }] => [
|
|
62
|
-
`input
|
|
62
|
+
`input-${input.value}-output-${output.value}`,
|
|
63
63
|
{ ns: 'test' },
|
|
64
64
|
];
|
|
65
65
|
const result = UndoMapping.resolveMessage(messageFunc, { value: 5 }, { value: 10 });
|
|
66
|
-
expect(result).toEqual(['input
|
|
66
|
+
expect(result).toEqual(['input-5-output-10', { ns: 'test' }]);
|
|
67
67
|
});
|
|
68
68
|
|
|
69
69
|
test('returns string label as-is', ({ expect }) => {
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
import * as Effect from 'effect/Effect';
|
|
6
6
|
|
|
7
|
-
import { OperationInvoker } from '@dxos/operation';
|
|
7
|
+
import { OperationHandlerSet, OperationInvoker } from '@dxos/operation';
|
|
8
8
|
|
|
9
|
-
import
|
|
9
|
+
import { ActivationEvents, Capabilities } from '../common';
|
|
10
10
|
import { Capability, Plugin } from '../core';
|
|
11
11
|
|
|
12
12
|
//
|
|
@@ -20,21 +20,35 @@ export default Capability.makeModule(
|
|
|
20
20
|
const pluginManager = yield* Plugin.Service;
|
|
21
21
|
|
|
22
22
|
// Get the ManagedRuntime capability (should be available since we activate after ManagedRuntimeReady).
|
|
23
|
-
const
|
|
24
|
-
|
|
23
|
+
const managedRuntime = yield* Capability.get(Capabilities.ManagedRuntime);
|
|
24
|
+
|
|
25
|
+
// Cache the merged handler promise to prevent concurrent module loading.
|
|
26
|
+
// Multiple Effects can invoke getHandlers simultaneously; without caching each
|
|
27
|
+
// creates a new merge() which triggers parallel dynamic imports that race in
|
|
28
|
+
// WebKit's module evaluator, causing TDZ errors on export default bindings.
|
|
29
|
+
let cachedSets: readonly OperationHandlerSet.OperationHandlerSet[] | undefined;
|
|
30
|
+
let cachedHandlers: ReturnType<OperationHandlerSet.OperationHandlerSet['getHandlers']> | undefined;
|
|
25
31
|
|
|
26
32
|
const invoker = OperationInvoker.make(
|
|
27
33
|
() =>
|
|
28
34
|
Effect.gen(function* () {
|
|
29
|
-
yield* Plugin.activate(
|
|
30
|
-
|
|
35
|
+
yield* Plugin.activate(ActivationEvents.SetupOperationHandler);
|
|
36
|
+
const sets = yield* Capability.getAll(Capabilities.OperationHandler);
|
|
37
|
+
|
|
38
|
+
if (sets !== cachedSets) {
|
|
39
|
+
cachedSets = sets;
|
|
40
|
+
cachedHandlers = OperationHandlerSet.merge(...sets).getHandlers();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return yield* Effect.promise(() => cachedHandlers!);
|
|
31
44
|
}).pipe(
|
|
32
45
|
Effect.provideService(Capability.Service, capabilityManager),
|
|
33
46
|
Effect.provideService(Plugin.Service, pluginManager),
|
|
47
|
+
Effect.orDie,
|
|
34
48
|
),
|
|
35
49
|
managedRuntime,
|
|
36
50
|
);
|
|
37
51
|
|
|
38
|
-
return Capability.contributes(
|
|
52
|
+
return Capability.contributes(Capabilities.OperationInvoker, invoker);
|
|
39
53
|
}),
|
|
40
54
|
);
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { type Plugin } from '../core';
|
|
6
6
|
|
|
7
7
|
export const meta: Plugin.Meta = {
|
|
8
|
-
id: 'dxos.
|
|
8
|
+
id: 'org.dxos.plugin.operation',
|
|
9
9
|
name: 'Operation Plugin',
|
|
10
10
|
description: 'Provides operation invocation, undo registry, and history tracking.',
|
|
11
11
|
};
|