@dxos/app-framework 0.8.2-staging.7ac8446 → 0.8.2
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/dist/lib/browser/{app-graph-builder-576BHZC7.mjs → app-graph-builder-DYEAGZPS.mjs} +23 -23
- package/dist/lib/browser/app-graph-builder-DYEAGZPS.mjs.map +7 -0
- package/dist/lib/browser/{chunk-6AVTZPMT.mjs → chunk-5GE2ERNU.mjs} +340 -275
- package/dist/lib/browser/chunk-5GE2ERNU.mjs.map +7 -0
- package/dist/lib/browser/{chunk-SFPT4Z2C.mjs → chunk-WWEJRWFX.mjs} +10 -10
- package/dist/lib/browser/chunk-WWEJRWFX.mjs.map +7 -0
- package/dist/lib/browser/{chunk-PPIBZ5N4.mjs → chunk-ZMXJV64L.mjs} +123 -63
- package/dist/lib/browser/chunk-ZMXJV64L.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +12 -10
- package/dist/lib/browser/index.mjs.map +1 -1
- package/dist/lib/browser/{intent-dispatcher-3Q67MHZZ.mjs → intent-dispatcher-ELZN5EM7.mjs} +2 -2
- package/dist/lib/browser/{intent-resolver-O763LCLG.mjs → intent-resolver-SGWLINTO.mjs} +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/{store-URSN7DZI.mjs → store-YIU6IPZ2.mjs} +7 -6
- package/dist/lib/browser/store-YIU6IPZ2.mjs.map +7 -0
- package/dist/lib/browser/testing/index.mjs +30 -14
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/browser/worker.mjs +5 -3
- package/dist/lib/node/app-graph-builder-GBLISL7L.cjs +146 -0
- package/dist/lib/node/app-graph-builder-GBLISL7L.cjs.map +7 -0
- package/dist/lib/node/{chunk-JUSEAFDU.cjs → chunk-G774ASXO.cjs} +5 -5
- package/dist/lib/node/chunk-G774ASXO.cjs.map +7 -0
- package/dist/lib/node/{chunk-YIFTVCOR.cjs → chunk-HIVITTZD.cjs} +319 -255
- package/dist/lib/node/chunk-HIVITTZD.cjs.map +7 -0
- package/dist/lib/node/{chunk-YNTKVTVX.cjs → chunk-Z2PMVDJ5.cjs} +155 -95
- package/dist/lib/node/chunk-Z2PMVDJ5.cjs.map +7 -0
- package/dist/lib/node/index.cjs +82 -80
- package/dist/lib/node/index.cjs.map +1 -1
- package/dist/lib/node/{intent-dispatcher-H334XLFD.cjs → intent-dispatcher-LFXZJTAS.cjs} +8 -8
- package/dist/lib/node/{intent-dispatcher-H334XLFD.cjs.map → intent-dispatcher-LFXZJTAS.cjs.map} +2 -2
- package/dist/lib/node/{intent-resolver-3F4POWAM.cjs → intent-resolver-EPSFTHL6.cjs} +12 -12
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/{store-OFDHTDCB.cjs → store-CVVRXUTH.cjs} +10 -9
- package/dist/lib/node/store-CVVRXUTH.cjs.map +7 -0
- package/dist/lib/node/testing/index.cjs +34 -17
- package/dist/lib/node/testing/index.cjs.map +3 -3
- package/dist/lib/node/worker.cjs +40 -38
- package/dist/lib/node/worker.cjs.map +2 -2
- package/dist/lib/node-esm/{app-graph-builder-VYKLSMSZ.mjs → app-graph-builder-LUBDEIT6.mjs} +23 -23
- package/dist/lib/node-esm/app-graph-builder-LUBDEIT6.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-R6A7Z4LU.mjs → chunk-6IKYKERU.mjs} +123 -63
- package/dist/lib/node-esm/chunk-6IKYKERU.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-PHOUQACM.mjs → chunk-I6BVZMAH.mjs} +10 -10
- package/dist/lib/node-esm/chunk-I6BVZMAH.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-AHKIPS2L.mjs → chunk-Z2ZHH4HN.mjs} +340 -275
- package/dist/lib/node-esm/chunk-Z2ZHH4HN.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +12 -10
- package/dist/lib/node-esm/index.mjs.map +1 -1
- package/dist/lib/node-esm/{intent-dispatcher-YDE2ONZA.mjs → intent-dispatcher-A2JCMWRD.mjs} +2 -2
- package/dist/lib/node-esm/{intent-resolver-LAGJ7LXM.mjs → intent-resolver-5C4O43GK.mjs} +3 -3
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/{store-EYSUVNCS.mjs → store-HRZXZ2D2.mjs} +7 -6
- package/dist/lib/node-esm/store-HRZXZ2D2.mjs.map +7 -0
- package/dist/lib/node-esm/testing/index.mjs +30 -14
- package/dist/lib/node-esm/testing/index.mjs.map +3 -3
- package/dist/lib/node-esm/worker.mjs +5 -3
- package/dist/types/src/App.d.ts +3 -1
- package/dist/types/src/App.d.ts.map +1 -1
- package/dist/types/src/common/capabilities.d.ts +40 -222
- package/dist/types/src/common/capabilities.d.ts.map +1 -1
- package/dist/types/src/common/collaboration.d.ts +19 -0
- package/dist/types/src/common/collaboration.d.ts.map +1 -0
- package/dist/types/src/common/events.d.ts.map +1 -1
- package/dist/types/src/common/file.d.ts +7 -7
- package/dist/types/src/common/file.d.ts.map +1 -1
- package/dist/types/src/common/index.d.ts +1 -0
- package/dist/types/src/common/index.d.ts.map +1 -1
- package/dist/types/src/common/layout.d.ts +166 -158
- package/dist/types/src/common/layout.d.ts.map +1 -1
- package/dist/types/src/common/surface.d.ts.map +1 -1
- package/dist/types/src/common/translations.d.ts +7 -7
- package/dist/types/src/common/translations.d.ts.map +1 -1
- package/dist/types/src/core/capabilities.d.ts +33 -15
- package/dist/types/src/core/capabilities.d.ts.map +1 -1
- package/dist/types/src/core/events.d.ts +4 -1
- package/dist/types/src/core/events.d.ts.map +1 -1
- package/dist/types/src/core/manager.d.ts +14 -11
- package/dist/types/src/core/manager.d.ts.map +1 -1
- package/dist/types/src/core/plugin.d.ts +4 -3
- package/dist/types/src/core/plugin.d.ts.map +1 -1
- package/dist/types/src/helpers.d.ts.map +1 -1
- package/dist/types/src/playground/generator/generator.d.ts.map +1 -1
- package/dist/types/src/playground/logger/schema.d.ts +6 -6
- package/dist/types/src/playground/logger/schema.d.ts.map +1 -1
- package/dist/types/src/playground/playground.stories.d.ts.map +1 -1
- package/dist/types/src/plugin-intent/actions.d.ts +14 -14
- package/dist/types/src/plugin-intent/actions.d.ts.map +1 -1
- package/dist/types/src/plugin-intent/intent-dispatcher.d.ts +29 -3
- package/dist/types/src/plugin-intent/intent-dispatcher.d.ts.map +1 -1
- package/dist/types/src/plugin-intent/intent.d.ts +14 -20
- package/dist/types/src/plugin-intent/intent.d.ts.map +1 -1
- package/dist/types/src/plugin-settings/actions.d.ts +10 -10
- package/dist/types/src/plugin-settings/actions.d.ts.map +1 -1
- package/dist/types/src/plugin-settings/app-graph-builder.d.ts +2 -195
- package/dist/types/src/plugin-settings/app-graph-builder.d.ts.map +1 -1
- package/dist/types/src/plugin-settings/store.d.ts +2 -2
- package/dist/types/src/plugin-settings/store.d.ts.map +1 -1
- package/dist/types/src/react/ErrorBoundary.d.ts +1 -1
- package/dist/types/src/react/ErrorBoundary.d.ts.map +1 -1
- package/dist/types/src/react/IntentContext.d.ts.map +1 -1
- package/dist/types/src/react/Surface.d.ts +2 -2
- package/dist/types/src/react/Surface.d.ts.map +1 -1
- package/dist/types/src/react/useCapabilities.d.ts +2 -2
- package/dist/types/src/react/useCapabilities.d.ts.map +1 -1
- package/dist/types/src/react/useIntentResolver.d.ts.map +1 -1
- package/dist/types/src/testing/withPluginManager.d.ts +6 -2
- 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/tsconfig.tsbuildinfo +1 -1
- package/package.json +32 -21
- package/project.json +2 -1
- package/src/App.tsx +98 -48
- package/src/common/capabilities.ts +18 -7
- package/src/common/collaboration.ts +21 -0
- package/src/common/file.ts +7 -7
- package/src/common/index.ts +1 -0
- package/src/common/layout.ts +167 -128
- package/src/common/translations.ts +7 -7
- package/src/core/capabilities.test.ts +55 -36
- package/src/core/capabilities.ts +84 -60
- package/src/core/events.ts +4 -1
- package/src/core/manager.test.ts +22 -22
- package/src/core/manager.ts +34 -26
- package/src/core/plugin.ts +4 -3
- package/src/playground/generator/generator.ts +4 -4
- package/src/playground/logger/schema.ts +5 -5
- package/src/playground/playground.stories.tsx +13 -9
- package/src/plugin-intent/actions.ts +9 -9
- package/src/plugin-intent/intent-dispatcher.test.ts +23 -42
- package/src/plugin-intent/intent-dispatcher.ts +25 -13
- package/src/plugin-intent/intent.ts +22 -20
- package/src/plugin-settings/actions.ts +8 -8
- package/src/plugin-settings/app-graph-builder.ts +129 -94
- package/src/plugin-settings/store.ts +20 -17
- package/src/react/ErrorBoundary.tsx +3 -3
- package/src/react/Surface.stories.tsx +1 -1
- package/src/react/Surface.tsx +3 -3
- package/src/react/useCapabilities.ts +9 -19
- package/src/testing/withPluginManager.stories.tsx +0 -1
- package/src/testing/withPluginManager.tsx +35 -16
- package/tsconfig.json +1 -53
- package/typedoc/.nojekyll +1 -0
- package/typedoc/assets/hierarchy.js +1 -0
- package/typedoc/assets/highlight.css +106 -0
- package/typedoc/assets/icons.js +18 -0
- package/typedoc/assets/icons.svg +1 -0
- package/typedoc/assets/main.js +60 -0
- package/typedoc/assets/navigation.js +1 -0
- package/typedoc/assets/search.js +1 -0
- package/typedoc/assets/style.css +1640 -0
- package/typedoc/classes/CollaborationActions.InsertContent.html +421 -0
- package/typedoc/classes/ErrorBoundary.html +125 -0
- package/typedoc/classes/IntentAction.ShowUndo.html +227 -0
- package/typedoc/classes/IntentAction.Track.html +266 -0
- package/typedoc/classes/LayoutAction.AddToast.html +265 -0
- package/typedoc/classes/LayoutAction.Close.html +382 -0
- package/typedoc/classes/LayoutAction.Expose.html +265 -0
- package/typedoc/classes/LayoutAction.Open.html +1123 -0
- package/typedoc/classes/LayoutAction.RevertWorkspace.html +343 -0
- package/typedoc/classes/LayoutAction.ScrollIntoView.html +460 -0
- package/typedoc/classes/LayoutAction.Set.html +460 -0
- package/typedoc/classes/LayoutAction.SetLayoutMode.html +499 -0
- package/typedoc/classes/LayoutAction.SwitchWorkspace.html +265 -0
- package/typedoc/classes/LayoutAction.UpdateComplementary.html +616 -0
- package/typedoc/classes/LayoutAction.UpdateDialog.html +1123 -0
- package/typedoc/classes/LayoutAction.UpdateLayout.html +461 -0
- package/typedoc/classes/LayoutAction.UpdatePopover.html +1435 -0
- package/typedoc/classes/LayoutAction.UpdateSidebar.html +616 -0
- package/typedoc/classes/Plugin.html +6 -0
- package/typedoc/classes/PluginContext.html +38 -0
- package/typedoc/classes/PluginManager.html +43 -0
- package/typedoc/classes/PluginModule.html +18 -0
- package/typedoc/classes/SettingsAction.Open.html +226 -0
- package/typedoc/classes/SettingsAction.OpenPluginRegistry.html +265 -0
- package/typedoc/functions/Events.createStateEvent.html +2 -0
- package/typedoc/functions/IntentPlugin.html +1 -0
- package/typedoc/functions/SettingsPlugin.html +1 -0
- package/typedoc/functions/allOf.html +2 -0
- package/typedoc/functions/chain.html +3 -0
- package/typedoc/functions/contributes.html +2 -0
- package/typedoc/functions/createDispatcher.html +3 -0
- package/typedoc/functions/createIntent.html +6 -0
- package/typedoc/functions/createResolver.html +2 -0
- package/typedoc/functions/createSurface.html +2 -0
- package/typedoc/functions/defineCapability.html +2 -0
- package/typedoc/functions/defineEvent.html +2 -0
- package/typedoc/functions/defineModule.html +2 -0
- package/typedoc/functions/definePlugin.html +2 -0
- package/typedoc/functions/eventKey.html +2 -0
- package/typedoc/functions/getEvents.html +2 -0
- package/typedoc/functions/isAllOf.html +2 -0
- package/typedoc/functions/isOneOf.html +2 -0
- package/typedoc/functions/isSurfaceAvailable.html +2 -0
- package/typedoc/functions/lazy.html +2 -0
- package/typedoc/functions/oneOf.html +2 -0
- package/typedoc/functions/useApp.html +6 -0
- package/typedoc/functions/useAppGraph.html +1 -0
- package/typedoc/functions/useCapabilities.html +3 -0
- package/typedoc/functions/useCapability.html +4 -0
- package/typedoc/functions/useIntentDispatcher.html +1 -0
- package/typedoc/functions/useIntentResolver.html +1 -0
- package/typedoc/functions/useLayout.html +1 -0
- package/typedoc/functions/usePluginManager.html +2 -0
- package/typedoc/hierarchy.html +1 -0
- package/typedoc/index.html +16 -0
- package/typedoc/interfaces/LayoutAction.Toast.html +10 -0
- package/typedoc/media/LICENSE +8 -0
- package/typedoc/modules/Capabilities.html +1 -0
- package/typedoc/modules/CollaborationActions.html +1 -0
- package/typedoc/modules/Events.html +1 -0
- package/typedoc/modules/IntentAction.html +1 -0
- package/typedoc/modules/LayoutAction.html +2 -0
- package/typedoc/modules/SettingsAction.html +1 -0
- package/typedoc/modules.html +1 -0
- package/typedoc/types/ActivationEvent.html +8 -0
- package/typedoc/types/ActivationEvents.html +2 -0
- package/typedoc/types/AnyCapability.html +1 -0
- package/typedoc/types/AnyIntent.html +1 -0
- package/typedoc/types/AnyIntentChain.html +1 -0
- package/typedoc/types/AnyIntentEffectResult.html +1 -0
- package/typedoc/types/AnyIntentResolver.html +1 -0
- package/typedoc/types/AnyIntentResult.html +1 -0
- package/typedoc/types/Capabilities.FileUploader.html +1 -0
- package/typedoc/types/Capabilities.IntentResolver.html +1 -0
- package/typedoc/types/Capabilities.Layout.html +1 -0
- package/typedoc/types/Capabilities.Metadata.html +1 -0
- package/typedoc/types/Capabilities.ReactContext.html +1 -0
- package/typedoc/types/Capabilities.ReactRoot.html +1 -0
- package/typedoc/types/Capabilities.ReactSurface.html +1 -0
- package/typedoc/types/Capabilities.Settings.html +4 -0
- package/typedoc/types/Capability.html +9 -0
- package/typedoc/types/CreateAppOptions.html +10 -0
- package/typedoc/types/FileInfo.html +1 -0
- package/typedoc/types/Intent.html +10 -0
- package/typedoc/types/IntentChain.html +6 -0
- package/typedoc/types/IntentContext.html +5 -0
- package/typedoc/types/IntentData.html +1 -0
- package/typedoc/types/IntentDispatcher.html +2 -0
- package/typedoc/types/IntentDispatcherResult.html +2 -0
- package/typedoc/types/IntentEffectDefinition.html +2 -0
- package/typedoc/types/IntentEffectResult.html +15 -0
- package/typedoc/types/IntentParams.html +3 -0
- package/typedoc/types/IntentResolver.html +2 -0
- package/typedoc/types/IntentResultData.html +1 -0
- package/typedoc/types/IntentSchema.html +1 -0
- package/typedoc/types/IntentUndo.html +2 -0
- package/typedoc/types/InterfaceDef.html +4 -0
- package/typedoc/types/Label.html +1 -0
- package/typedoc/types/NodeSerializer.html +8 -0
- package/typedoc/types/PluginManagerOptions.html +6 -0
- package/typedoc/types/PluginMeta.html +21 -0
- package/typedoc/types/PromiseIntentDispatcher.html +2 -0
- package/typedoc/types/PromiseIntentUndo.html +2 -0
- package/typedoc/types/Resource.html +1 -0
- package/typedoc/types/ResourceKey.html +1 -0
- package/typedoc/types/ResourceLanguage.html +1 -0
- package/typedoc/types/SerializedNode.html +4 -0
- package/typedoc/types/SurfaceComponent.html +2 -0
- package/typedoc/types/SurfaceDefinition.html +2 -0
- package/typedoc/types/SurfaceProps.html +4 -0
- package/typedoc/variables/Capabilities.AnchorSort.html +1 -0
- package/typedoc/variables/Capabilities.AppGraph.html +1 -0
- package/typedoc/variables/Capabilities.AppGraphBuilder.html +1 -0
- package/typedoc/variables/Capabilities.AppGraphSerializer.html +1 -0
- package/typedoc/variables/Capabilities.ArtifactDefinition.html +1 -0
- package/typedoc/variables/Capabilities.FileUploader.html +1 -0
- package/typedoc/variables/Capabilities.IntentDispatcher.html +1 -0
- package/typedoc/variables/Capabilities.IntentResolver.html +1 -0
- package/typedoc/variables/Capabilities.Layout.html +1 -0
- package/typedoc/variables/Capabilities.Metadata.html +1 -0
- package/typedoc/variables/Capabilities.Null.html +1 -0
- package/typedoc/variables/Capabilities.PluginManager.html +1 -0
- package/typedoc/variables/Capabilities.ReactContext.html +1 -0
- package/typedoc/variables/Capabilities.ReactRoot.html +1 -0
- package/typedoc/variables/Capabilities.ReactSurface.html +1 -0
- package/typedoc/variables/Capabilities.RxRegistry.html +1 -0
- package/typedoc/variables/Capabilities.Settings.html +1 -0
- package/typedoc/variables/Capabilities.SettingsStore.html +1 -0
- package/typedoc/variables/Capabilities.Tools.html +1 -0
- package/typedoc/variables/Capabilities.Translations.html +1 -0
- package/typedoc/variables/Events.AppGraphReady.html +2 -0
- package/typedoc/variables/Events.DispatcherReady.html +2 -0
- package/typedoc/variables/Events.LayoutReady.html +1 -0
- package/typedoc/variables/Events.SettingsReady.html +2 -0
- package/typedoc/variables/Events.SetupAppGraph.html +2 -0
- package/typedoc/variables/Events.SetupArtifactDefinition.html +2 -0
- package/typedoc/variables/Events.SetupIntentResolver.html +2 -0
- package/typedoc/variables/Events.SetupMetadata.html +2 -0
- package/typedoc/variables/Events.SetupReactSurface.html +2 -0
- package/typedoc/variables/Events.SetupSettings.html +2 -0
- package/typedoc/variables/Events.SetupTranslations.html +2 -0
- package/typedoc/variables/Events.Startup.html +2 -0
- package/typedoc/variables/FileInfoSchema.html +1 -0
- package/typedoc/variables/INTENT_ACTION.html +1 -0
- package/typedoc/variables/INTENT_PLUGIN.html +1 -0
- package/typedoc/variables/LAYOUT_ACTION.html +1 -0
- package/typedoc/variables/LAYOUT_PLUGIN.html +1 -0
- package/typedoc/variables/Label.html +1 -0
- package/typedoc/variables/LayoutAction.Toast.html +1 -0
- package/typedoc/variables/LayoutAction.UPDATE_LAYOUT.html +1 -0
- package/typedoc/variables/PluginManagerProvider.html +2 -0
- package/typedoc/variables/Resource.html +2 -0
- package/typedoc/variables/ResourceKey.html +1 -0
- package/typedoc/variables/ResourceLanguage.html +1 -0
- package/typedoc/variables/SETTINGS_ACTION.html +1 -0
- package/typedoc/variables/SETTINGS_ID.html +1 -0
- package/typedoc/variables/SETTINGS_KEY.html +1 -0
- package/typedoc/variables/SETTINGS_PLUGIN.html +1 -0
- package/typedoc/variables/Surface.html +2 -0
- package/typedoc/variables/defaultFileTypes.html +1 -0
- package/dist/lib/browser/app-graph-builder-576BHZC7.mjs.map +0 -7
- package/dist/lib/browser/chunk-6AVTZPMT.mjs.map +0 -7
- package/dist/lib/browser/chunk-PPIBZ5N4.mjs.map +0 -7
- package/dist/lib/browser/chunk-SFPT4Z2C.mjs.map +0 -7
- package/dist/lib/browser/store-URSN7DZI.mjs.map +0 -7
- package/dist/lib/node/app-graph-builder-JZCSKYPY.cjs +0 -146
- package/dist/lib/node/app-graph-builder-JZCSKYPY.cjs.map +0 -7
- package/dist/lib/node/chunk-JUSEAFDU.cjs.map +0 -7
- package/dist/lib/node/chunk-YIFTVCOR.cjs.map +0 -7
- package/dist/lib/node/chunk-YNTKVTVX.cjs.map +0 -7
- package/dist/lib/node/store-OFDHTDCB.cjs.map +0 -7
- package/dist/lib/node-esm/app-graph-builder-VYKLSMSZ.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-AHKIPS2L.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-PHOUQACM.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-R6A7Z4LU.mjs.map +0 -7
- package/dist/lib/node-esm/store-EYSUVNCS.mjs.map +0 -7
- /package/dist/lib/browser/{intent-dispatcher-3Q67MHZZ.mjs.map → intent-dispatcher-ELZN5EM7.mjs.map} +0 -0
- /package/dist/lib/browser/{intent-resolver-O763LCLG.mjs.map → intent-resolver-SGWLINTO.mjs.map} +0 -0
- /package/dist/lib/node/{intent-resolver-3F4POWAM.cjs.map → intent-resolver-EPSFTHL6.cjs.map} +0 -0
- /package/dist/lib/node-esm/{intent-dispatcher-YDE2ONZA.mjs.map → intent-dispatcher-A2JCMWRD.mjs.map} +0 -0
- /package/dist/lib/node-esm/{intent-resolver-LAGJ7LXM.mjs.map → intent-resolver-5C4O43GK.mjs.map} +0 -0
package/src/core/manager.ts
CHANGED
|
@@ -2,15 +2,16 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import { Registry } from '@effect-rx/rx-react';
|
|
5
6
|
import { untracked } from '@preact/signals-core';
|
|
6
7
|
import { Array as A, Effect, Either, Match, pipe } from 'effect';
|
|
7
8
|
|
|
8
9
|
import { Event } from '@dxos/async';
|
|
9
|
-
import {
|
|
10
|
+
import { live, type Live } from '@dxos/live-object';
|
|
10
11
|
import { log } from '@dxos/log';
|
|
11
12
|
import { type MaybePromise } from '@dxos/util';
|
|
12
13
|
|
|
13
|
-
import { type AnyCapability,
|
|
14
|
+
import { type AnyCapability, PluginContext } from './capabilities';
|
|
14
15
|
import { type ActivationEvent, eventKey, getEvents, isAllOf } from './events';
|
|
15
16
|
import { type PluginModule, type Plugin } from './plugin';
|
|
16
17
|
|
|
@@ -24,6 +25,7 @@ export type PluginManagerOptions = {
|
|
|
24
25
|
plugins?: Plugin[];
|
|
25
26
|
core?: string[];
|
|
26
27
|
enabled?: string[];
|
|
28
|
+
registry?: Registry.Registry;
|
|
27
29
|
};
|
|
28
30
|
|
|
29
31
|
type PluginManagerState = {
|
|
@@ -43,13 +45,11 @@ type PluginManagerState = {
|
|
|
43
45
|
|
|
44
46
|
export class PluginManager {
|
|
45
47
|
readonly activation = new Event<{ event: string; state: 'activating' | 'activated' | 'error'; error?: any }>();
|
|
48
|
+
readonly context: PluginContext;
|
|
49
|
+
readonly registry: Registry.Registry;
|
|
46
50
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
reset: (id) => this._reset(id),
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
private readonly _state: ReactiveObject<PluginManagerState>;
|
|
51
|
+
// TODO(wittjosiah): Replace with Rx.
|
|
52
|
+
private readonly _state: Live<PluginManagerState>;
|
|
53
53
|
private readonly _pluginLoader: PluginManagerOptions['pluginLoader'];
|
|
54
54
|
private readonly _capabilities = new Map<string, AnyCapability[]>();
|
|
55
55
|
|
|
@@ -58,9 +58,17 @@ export class PluginManager {
|
|
|
58
58
|
plugins = [],
|
|
59
59
|
core = plugins.map(({ meta }) => meta.id),
|
|
60
60
|
enabled = [],
|
|
61
|
+
registry,
|
|
61
62
|
}: PluginManagerOptions) {
|
|
63
|
+
this.registry = registry ?? Registry.make();
|
|
64
|
+
this.context = new PluginContext({
|
|
65
|
+
registry: this.registry,
|
|
66
|
+
activate: (event) => this._activate(event),
|
|
67
|
+
reset: (id) => this._reset(id),
|
|
68
|
+
});
|
|
69
|
+
|
|
62
70
|
this._pluginLoader = pluginLoader;
|
|
63
|
-
this._state =
|
|
71
|
+
this._state = live({
|
|
64
72
|
plugins,
|
|
65
73
|
core,
|
|
66
74
|
enabled,
|
|
@@ -79,7 +87,7 @@ export class PluginManager {
|
|
|
79
87
|
*
|
|
80
88
|
* @reactive
|
|
81
89
|
*/
|
|
82
|
-
get plugins():
|
|
90
|
+
get plugins(): Live<readonly Plugin[]> {
|
|
83
91
|
return this._state.plugins;
|
|
84
92
|
}
|
|
85
93
|
|
|
@@ -88,7 +96,7 @@ export class PluginManager {
|
|
|
88
96
|
*
|
|
89
97
|
* @reactive
|
|
90
98
|
*/
|
|
91
|
-
get core():
|
|
99
|
+
get core(): Live<readonly string[]> {
|
|
92
100
|
return this._state.core;
|
|
93
101
|
}
|
|
94
102
|
|
|
@@ -97,7 +105,7 @@ export class PluginManager {
|
|
|
97
105
|
*
|
|
98
106
|
* @reactive
|
|
99
107
|
*/
|
|
100
|
-
get enabled():
|
|
108
|
+
get enabled(): Live<readonly string[]> {
|
|
101
109
|
return this._state.enabled;
|
|
102
110
|
}
|
|
103
111
|
|
|
@@ -106,7 +114,7 @@ export class PluginManager {
|
|
|
106
114
|
*
|
|
107
115
|
* @reactive
|
|
108
116
|
*/
|
|
109
|
-
get modules():
|
|
117
|
+
get modules(): Live<readonly PluginModule[]> {
|
|
110
118
|
return this._state.modules;
|
|
111
119
|
}
|
|
112
120
|
|
|
@@ -115,7 +123,7 @@ export class PluginManager {
|
|
|
115
123
|
*
|
|
116
124
|
* @reactive
|
|
117
125
|
*/
|
|
118
|
-
get active():
|
|
126
|
+
get active(): Live<readonly string[]> {
|
|
119
127
|
return this._state.active;
|
|
120
128
|
}
|
|
121
129
|
|
|
@@ -124,7 +132,7 @@ export class PluginManager {
|
|
|
124
132
|
*
|
|
125
133
|
* @reactive
|
|
126
134
|
*/
|
|
127
|
-
get eventsFired():
|
|
135
|
+
get eventsFired(): Live<readonly string[]> {
|
|
128
136
|
return this._state.eventsFired;
|
|
129
137
|
}
|
|
130
138
|
|
|
@@ -133,7 +141,7 @@ export class PluginManager {
|
|
|
133
141
|
*
|
|
134
142
|
* @reactive
|
|
135
143
|
*/
|
|
136
|
-
get pendingReset():
|
|
144
|
+
get pendingReset(): Live<readonly string[]> {
|
|
137
145
|
return this._state.pendingReset;
|
|
138
146
|
}
|
|
139
147
|
|
|
@@ -257,7 +265,7 @@ export class PluginManager {
|
|
|
257
265
|
return untracked(() => Effect.runPromise(this._reset(event)));
|
|
258
266
|
}
|
|
259
267
|
|
|
260
|
-
private _addPlugin(plugin: Plugin) {
|
|
268
|
+
private _addPlugin(plugin: Plugin): void {
|
|
261
269
|
untracked(() => {
|
|
262
270
|
log('add plugin', { id: plugin.meta.id });
|
|
263
271
|
if (!this._state.plugins.includes(plugin)) {
|
|
@@ -266,7 +274,7 @@ export class PluginManager {
|
|
|
266
274
|
});
|
|
267
275
|
}
|
|
268
276
|
|
|
269
|
-
private _removePlugin(id: string) {
|
|
277
|
+
private _removePlugin(id: string): void {
|
|
270
278
|
untracked(() => {
|
|
271
279
|
log('remove plugin', { id });
|
|
272
280
|
const pluginIndex = this._state.plugins.findIndex((plugin) => plugin.meta.id === id);
|
|
@@ -276,7 +284,7 @@ export class PluginManager {
|
|
|
276
284
|
});
|
|
277
285
|
}
|
|
278
286
|
|
|
279
|
-
private _addModule(module: PluginModule) {
|
|
287
|
+
private _addModule(module: PluginModule): void {
|
|
280
288
|
untracked(() => {
|
|
281
289
|
log('add module', { id: module.id });
|
|
282
290
|
if (!this._state.modules.includes(module)) {
|
|
@@ -285,7 +293,7 @@ export class PluginManager {
|
|
|
285
293
|
});
|
|
286
294
|
}
|
|
287
295
|
|
|
288
|
-
private _removeModule(id: string) {
|
|
296
|
+
private _removeModule(id: string): void {
|
|
289
297
|
untracked(() => {
|
|
290
298
|
log('remove module', { id });
|
|
291
299
|
const moduleIndex = this._state.modules.findIndex((module) => module.id === id);
|
|
@@ -295,27 +303,27 @@ export class PluginManager {
|
|
|
295
303
|
});
|
|
296
304
|
}
|
|
297
305
|
|
|
298
|
-
private _getPlugin(id: string) {
|
|
306
|
+
private _getPlugin(id: string): Plugin | undefined {
|
|
299
307
|
return this._state.plugins.find((plugin) => plugin.meta.id === id);
|
|
300
308
|
}
|
|
301
309
|
|
|
302
|
-
private _getActiveModules() {
|
|
310
|
+
private _getActiveModules(): PluginModule[] {
|
|
303
311
|
return this._state.modules.filter((module) => this._state.active.includes(module.id));
|
|
304
312
|
}
|
|
305
313
|
|
|
306
|
-
private _getInactiveModules() {
|
|
314
|
+
private _getInactiveModules(): PluginModule[] {
|
|
307
315
|
return this._state.modules.filter((module) => !this._state.active.includes(module.id));
|
|
308
316
|
}
|
|
309
317
|
|
|
310
|
-
private _getActiveModulesByEvent(key: string) {
|
|
318
|
+
private _getActiveModulesByEvent(key: string): PluginModule[] {
|
|
311
319
|
return this._getActiveModules().filter((module) => getEvents(module.activatesOn).map(eventKey).includes(key));
|
|
312
320
|
}
|
|
313
321
|
|
|
314
|
-
private _getInactiveModulesByEvent(key: string) {
|
|
322
|
+
private _getInactiveModulesByEvent(key: string): PluginModule[] {
|
|
315
323
|
return this._getInactiveModules().filter((module) => getEvents(module.activatesOn).map(eventKey).includes(key));
|
|
316
324
|
}
|
|
317
325
|
|
|
318
|
-
private _setPendingResetByModule(module: PluginModule) {
|
|
326
|
+
private _setPendingResetByModule(module: PluginModule): void {
|
|
319
327
|
return untracked(() => {
|
|
320
328
|
const activationEvents = getEvents(module.activatesOn)
|
|
321
329
|
.map(eventKey)
|
package/src/core/plugin.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { type MaybePromise } from '@dxos/util';
|
|
6
6
|
|
|
7
|
-
import { type AnyCapability, type
|
|
7
|
+
import { type AnyCapability, type PluginContext } from './capabilities';
|
|
8
8
|
import { type ActivationEvent, type ActivationEvents } from './events';
|
|
9
9
|
|
|
10
10
|
interface PluginModuleInterface {
|
|
@@ -36,13 +36,13 @@ interface PluginModuleInterface {
|
|
|
36
36
|
* @returns The capabilities of the module.
|
|
37
37
|
*/
|
|
38
38
|
activate: (
|
|
39
|
-
context:
|
|
39
|
+
context: PluginContext,
|
|
40
40
|
) => MaybePromise<AnyCapability | AnyCapability[]> | Promise<() => Promise<AnyCapability | AnyCapability[]>>;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
/**
|
|
44
44
|
* A unit of containment of modular functionality that can be provided to an application.
|
|
45
|
-
*
|
|
45
|
+
* Activation of a module is async allowing for code to split and loaded lazily.
|
|
46
46
|
*/
|
|
47
47
|
// NOTE: This is implemented as a class to prevent it from being proxied by PluginManager state.
|
|
48
48
|
export class PluginModule implements PluginModuleInterface {
|
|
@@ -114,6 +114,7 @@ export type PluginMeta = {
|
|
|
114
114
|
|
|
115
115
|
/**
|
|
116
116
|
* A collection of modules that are be enabled/disabled as a unit.
|
|
117
|
+
* Plugins provide things such as components, state, actions, etc. to the application.
|
|
117
118
|
*/
|
|
118
119
|
// NOTE: This is implemented as a class to prevent it from being proxied by PluginManager state.
|
|
119
120
|
export class Plugin {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { Schema
|
|
5
|
+
import { Schema } from 'effect';
|
|
6
6
|
|
|
7
7
|
import { Capabilities, Events } from '../../common';
|
|
8
8
|
import { contributes, defineEvent, defineCapability, defineModule, definePlugin } from '../../core';
|
|
@@ -15,9 +15,9 @@ export const CountEvent = defineEvent('dxos.org/test/generator/count');
|
|
|
15
15
|
export const createPluginId = (id: string) => `dxos.org/test/generator/${id}`;
|
|
16
16
|
|
|
17
17
|
export const createGeneratorIntent = (id: string) => {
|
|
18
|
-
class Alert extends
|
|
19
|
-
input:
|
|
20
|
-
output:
|
|
18
|
+
class Alert extends Schema.TaggedClass<Alert>()(`${createPluginId(id)}/action/alert`, {
|
|
19
|
+
input: Schema.Void,
|
|
20
|
+
output: Schema.Void,
|
|
21
21
|
}) {}
|
|
22
22
|
|
|
23
23
|
return Alert as unknown as IntentSchema<any, any>;
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { Schema
|
|
5
|
+
import { Schema } from 'effect';
|
|
6
6
|
|
|
7
|
-
export class Log extends
|
|
8
|
-
input:
|
|
9
|
-
message:
|
|
7
|
+
export class Log extends Schema.TaggedClass<Log>()('dxos.org/test/logger/log', {
|
|
8
|
+
input: Schema.Struct({
|
|
9
|
+
message: Schema.String,
|
|
10
10
|
}),
|
|
11
|
-
output:
|
|
11
|
+
output: Schema.Void,
|
|
12
12
|
}) {}
|
|
@@ -12,7 +12,7 @@ import { DebugPlugin } from './debug';
|
|
|
12
12
|
import { createNumberPlugin, GeneratorPlugin } from './generator';
|
|
13
13
|
import { LayoutPlugin } from './layout';
|
|
14
14
|
import { LoggerPlugin } from './logger';
|
|
15
|
-
import {
|
|
15
|
+
import { useApp } from '../App';
|
|
16
16
|
import { IntentPlugin } from '../plugin-intent';
|
|
17
17
|
|
|
18
18
|
const plugins = [IntentPlugin(), LayoutPlugin(), DebugPlugin(), LoggerPlugin(), GeneratorPlugin()];
|
|
@@ -21,18 +21,22 @@ const Placeholder = () => {
|
|
|
21
21
|
return <div>Loading...</div>;
|
|
22
22
|
};
|
|
23
23
|
|
|
24
|
-
const Story =
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
24
|
+
const Story = () => {
|
|
25
|
+
const App = useApp({
|
|
26
|
+
pluginLoader: (id) => createNumberPlugin(id),
|
|
27
|
+
plugins,
|
|
28
|
+
core: plugins.map((plugin) => plugin.meta.id),
|
|
29
|
+
// Having a non-empty placeholder makes it clear if it's taking a while to load.
|
|
30
|
+
placeholder: Placeholder,
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
return <App />;
|
|
34
|
+
};
|
|
31
35
|
|
|
32
36
|
export const Playground = {};
|
|
33
37
|
|
|
34
38
|
export default {
|
|
35
39
|
title: 'sdk/app-framework/playground',
|
|
36
40
|
render: Story,
|
|
37
|
-
decorators: [withTheme, withLayout(
|
|
41
|
+
decorators: [withTheme, withLayout()],
|
|
38
42
|
};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { Schema
|
|
5
|
+
import { Schema } from 'effect';
|
|
6
6
|
|
|
7
7
|
import { Label } from './intent';
|
|
8
8
|
|
|
@@ -13,21 +13,21 @@ export namespace IntentAction {
|
|
|
13
13
|
/**
|
|
14
14
|
* Log an intent.
|
|
15
15
|
*/
|
|
16
|
-
export class Track extends
|
|
17
|
-
input:
|
|
18
|
-
intents:
|
|
19
|
-
error:
|
|
16
|
+
export class Track extends Schema.TaggedClass<Track>()(`${INTENT_ACTION}/track`, {
|
|
17
|
+
input: Schema.Struct({
|
|
18
|
+
intents: Schema.Array(Schema.String),
|
|
19
|
+
error: Schema.optional(Schema.String),
|
|
20
20
|
}),
|
|
21
|
-
output:
|
|
21
|
+
output: Schema.Void,
|
|
22
22
|
}) {}
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
25
|
* Fired after an intent is dispatched if the intent is undoable.
|
|
26
26
|
*/
|
|
27
|
-
export class ShowUndo extends
|
|
28
|
-
input:
|
|
27
|
+
export class ShowUndo extends Schema.TaggedClass<ShowUndo>()(`${INTENT_ACTION}/show-undo`, {
|
|
28
|
+
input: Schema.Struct({
|
|
29
29
|
message: Label,
|
|
30
30
|
}),
|
|
31
|
-
output:
|
|
31
|
+
output: Schema.Void,
|
|
32
32
|
}) {}
|
|
33
33
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { Schema
|
|
5
|
+
import { Schema, Effect, Fiber, pipe } from 'effect';
|
|
6
6
|
import { describe, expect, test } from 'vitest';
|
|
7
7
|
|
|
8
8
|
import { chain, createIntent } from './intent';
|
|
@@ -134,25 +134,6 @@ describe('Intent dispatcher', () => {
|
|
|
134
134
|
await Effect.runPromise(program);
|
|
135
135
|
});
|
|
136
136
|
|
|
137
|
-
test('filter resolvers by plugin', async () => {
|
|
138
|
-
const otherComputeResolver = createResolver({
|
|
139
|
-
intent: Compute,
|
|
140
|
-
resolve: async (data) => ({ data: { value: data?.value * 3 } }),
|
|
141
|
-
});
|
|
142
|
-
const { dispatch } = createDispatcher((module) => (module === 'test' ? [computeResolver] : [otherComputeResolver]));
|
|
143
|
-
const program = Effect.gen(function* () {
|
|
144
|
-
const a = yield* dispatch(createIntent(Compute, { value: 1 }));
|
|
145
|
-
|
|
146
|
-
expect(a.value).toBe(3);
|
|
147
|
-
|
|
148
|
-
const b = yield* dispatch(createIntent(Compute, { value: 1 }, { module: 'test' }));
|
|
149
|
-
|
|
150
|
-
expect(b.value).toBe(2);
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
await Effect.runPromise(program);
|
|
154
|
-
});
|
|
155
|
-
|
|
156
137
|
test('filter resolvers by predicate', async () => {
|
|
157
138
|
const conditionalComputeResolver = createResolver({
|
|
158
139
|
intent: Compute,
|
|
@@ -224,12 +205,12 @@ describe('Intent dispatcher', () => {
|
|
|
224
205
|
test.todo('follow up intents');
|
|
225
206
|
});
|
|
226
207
|
|
|
227
|
-
class ToString extends
|
|
228
|
-
input:
|
|
229
|
-
value:
|
|
208
|
+
class ToString extends Schema.TaggedClass<ToString>()('ToString', {
|
|
209
|
+
input: Schema.Struct({
|
|
210
|
+
value: Schema.Number,
|
|
230
211
|
}),
|
|
231
|
-
output:
|
|
232
|
-
string:
|
|
212
|
+
output: Schema.Struct({
|
|
213
|
+
string: Schema.String,
|
|
233
214
|
}),
|
|
234
215
|
}) {}
|
|
235
216
|
|
|
@@ -238,12 +219,12 @@ const toStringResolver = createResolver({
|
|
|
238
219
|
resolve: async (data) => ({ data: { string: data.value.toString() } }),
|
|
239
220
|
});
|
|
240
221
|
|
|
241
|
-
class Compute extends
|
|
242
|
-
input:
|
|
243
|
-
value:
|
|
222
|
+
class Compute extends Schema.TaggedClass<Compute>()('Compute', {
|
|
223
|
+
input: Schema.Struct({
|
|
224
|
+
value: Schema.Number,
|
|
244
225
|
}),
|
|
245
|
-
output:
|
|
246
|
-
value:
|
|
226
|
+
output: Schema.Struct({
|
|
227
|
+
value: Schema.Number,
|
|
247
228
|
}),
|
|
248
229
|
}) {}
|
|
249
230
|
|
|
@@ -262,13 +243,13 @@ const computeResolver = createResolver({
|
|
|
262
243
|
},
|
|
263
244
|
});
|
|
264
245
|
|
|
265
|
-
class Concat extends
|
|
266
|
-
input:
|
|
267
|
-
string:
|
|
268
|
-
plus:
|
|
246
|
+
class Concat extends Schema.TaggedClass<Concat>()('Concat', {
|
|
247
|
+
input: Schema.Struct({
|
|
248
|
+
string: Schema.String,
|
|
249
|
+
plus: Schema.String,
|
|
269
250
|
}),
|
|
270
|
-
output:
|
|
271
|
-
string:
|
|
251
|
+
output: Schema.Struct({
|
|
252
|
+
string: Schema.String,
|
|
272
253
|
}),
|
|
273
254
|
}) {}
|
|
274
255
|
|
|
@@ -277,9 +258,9 @@ const concatResolver = createResolver({
|
|
|
277
258
|
resolve: async (data) => ({ data: { string: data.string + data.plus } }),
|
|
278
259
|
});
|
|
279
260
|
|
|
280
|
-
class Add extends
|
|
281
|
-
input:
|
|
282
|
-
output:
|
|
261
|
+
class Add extends Schema.TaggedClass<Add>()('Add', {
|
|
262
|
+
input: Schema.Tuple(Schema.Number, Schema.Number),
|
|
263
|
+
output: Schema.Number,
|
|
283
264
|
}) {}
|
|
284
265
|
|
|
285
266
|
const addResolver = createResolver({
|
|
@@ -287,9 +268,9 @@ const addResolver = createResolver({
|
|
|
287
268
|
resolve: async (data) => ({ data: data[0] + data[1] }),
|
|
288
269
|
});
|
|
289
270
|
|
|
290
|
-
class SideEffect extends
|
|
291
|
-
input:
|
|
292
|
-
output:
|
|
271
|
+
class SideEffect extends Schema.TaggedClass<SideEffect>()('SideEffect', {
|
|
272
|
+
input: Schema.Void,
|
|
273
|
+
output: Schema.Void,
|
|
293
274
|
}) {}
|
|
294
275
|
|
|
295
276
|
const sideEffectResolver = createResolver({
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { Effect, Option, pipe, Ref } from 'effect';
|
|
6
6
|
import { type Simplify } from 'effect/Types';
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import { live } from '@dxos/live-object';
|
|
9
9
|
import { log } from '@dxos/log';
|
|
10
10
|
import { byPosition, type MaybePromise, type Position, type GuardedType } from '@dxos/util';
|
|
11
11
|
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
type Label,
|
|
25
25
|
} from './intent';
|
|
26
26
|
import { Events, Capabilities } from '../common';
|
|
27
|
-
import { contributes, type
|
|
27
|
+
import { contributes, type PluginContext } from '../core';
|
|
28
28
|
|
|
29
29
|
const EXECUTION_LIMIT = 100;
|
|
30
30
|
const HISTORY_LIMIT = 100;
|
|
@@ -91,9 +91,25 @@ export type IntentEffectDefinition<Input, Output> = (
|
|
|
91
91
|
* Intent resolver to match intents to their effects.
|
|
92
92
|
*/
|
|
93
93
|
export type IntentResolver<Tag extends string, Fields extends IntentParams, Data = IntentData<Fields>> = Readonly<{
|
|
94
|
+
/**
|
|
95
|
+
* The schema of the intent to be resolved.
|
|
96
|
+
*/
|
|
94
97
|
intent: IntentSchema<Tag, Fields>;
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Hint to determine the order the resolvers are processed if multiple resolvers are defined for the same intent.
|
|
101
|
+
* Only one resolver will be used.
|
|
102
|
+
*/
|
|
95
103
|
position?: Position;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Optional filter to determine if the resolver should be used.
|
|
107
|
+
*/
|
|
96
108
|
filter?: (data: IntentData<Fields>) => data is Data;
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* The effect to be performed when the intent is resolved.
|
|
112
|
+
*/
|
|
97
113
|
resolve: IntentEffectDefinition<GuardedType<IntentResolver<Tag, Fields, Data>['filter']>, IntentResultData<Fields>>;
|
|
98
114
|
}>;
|
|
99
115
|
|
|
@@ -168,14 +184,14 @@ export type IntentContext = {
|
|
|
168
184
|
* @param params.executionLimit The maximum recursion depth of intent chains.
|
|
169
185
|
*/
|
|
170
186
|
export const createDispatcher = (
|
|
171
|
-
getResolvers: (
|
|
187
|
+
getResolvers: () => AnyIntentResolver[],
|
|
172
188
|
{ executionLimit = EXECUTION_LIMIT, historyLimit = HISTORY_LIMIT } = {},
|
|
173
189
|
): IntentContext => {
|
|
174
190
|
const historyRef = Effect.runSync(Ref.make<AnyIntentResult[][]>([]));
|
|
175
191
|
|
|
176
192
|
const handleIntent = (intent: AnyIntent) =>
|
|
177
193
|
Effect.gen(function* () {
|
|
178
|
-
const candidates = getResolvers(
|
|
194
|
+
const candidates = getResolvers()
|
|
179
195
|
.filter((resolver) => resolver.intent._tag === intent.id)
|
|
180
196
|
.filter((resolver) => !resolver.filter || resolver.filter(intent.data))
|
|
181
197
|
.toSorted(byPosition);
|
|
@@ -286,8 +302,8 @@ export const createDispatcher = (
|
|
|
286
302
|
const defaultEffect = () => Effect.fail(new Error('Intent runtime not ready'));
|
|
287
303
|
const defaultPromise = () => Effect.runPromise(defaultEffect());
|
|
288
304
|
|
|
289
|
-
export default (context:
|
|
290
|
-
const state =
|
|
305
|
+
export default (context: PluginContext) => {
|
|
306
|
+
const state = live<IntentContext>({
|
|
291
307
|
dispatch: defaultEffect,
|
|
292
308
|
dispatchPromise: defaultPromise,
|
|
293
309
|
undo: defaultEffect,
|
|
@@ -295,15 +311,11 @@ export default (context: PluginsContext) => {
|
|
|
295
311
|
});
|
|
296
312
|
|
|
297
313
|
// TODO(wittjosiah): Make getResolver callback async and allow resolvers to be requested on demand.
|
|
298
|
-
const { dispatch, dispatchPromise, undo, undoPromise } = createDispatcher((
|
|
299
|
-
context
|
|
300
|
-
.requestCapabilities(Capabilities.IntentResolver, (c, moduleId): c is AnyIntentResolver => {
|
|
301
|
-
return module ? moduleId === module : true;
|
|
302
|
-
})
|
|
303
|
-
.flat(),
|
|
314
|
+
const { dispatch, dispatchPromise, undo, undoPromise } = createDispatcher(() =>
|
|
315
|
+
context.getCapabilities(Capabilities.IntentResolver).flat(),
|
|
304
316
|
);
|
|
305
317
|
|
|
306
|
-
const manager = context.
|
|
318
|
+
const manager = context.getCapability(Capabilities.PluginManager);
|
|
307
319
|
state.dispatch = (intentChain, depth) => {
|
|
308
320
|
return Effect.gen(function* () {
|
|
309
321
|
yield* manager._activate(Events.SetupIntentResolver);
|
|
@@ -2,20 +2,24 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { Schema
|
|
5
|
+
import { Schema } from 'effect';
|
|
6
6
|
|
|
7
7
|
export type IntentParams = {
|
|
8
|
-
readonly input:
|
|
9
|
-
readonly output:
|
|
8
|
+
readonly input: Schema.Schema.All;
|
|
9
|
+
readonly output: Schema.Schema.All;
|
|
10
10
|
};
|
|
11
11
|
|
|
12
12
|
export type IntentData<Fields extends IntentParams> =
|
|
13
|
-
|
|
13
|
+
Schema.Schema.Type<Schema.Struct<Fields>> extends { readonly input: any }
|
|
14
|
+
? Schema.Schema.Type<Schema.Struct<Fields>>['input']
|
|
15
|
+
: any;
|
|
14
16
|
|
|
15
17
|
export type IntentResultData<Fields extends IntentParams> =
|
|
16
|
-
|
|
18
|
+
Schema.Schema.Type<Schema.Struct<Fields>> extends { readonly output: any }
|
|
19
|
+
? Schema.Schema.Type<Schema.Struct<Fields>>['output']
|
|
20
|
+
: any;
|
|
17
21
|
|
|
18
|
-
export type IntentSchema<Tag extends string, Fields extends IntentParams> =
|
|
22
|
+
export type IntentSchema<Tag extends string, Fields extends IntentParams> = Schema.TaggedClass<any, Tag, Fields>;
|
|
19
23
|
|
|
20
24
|
/**
|
|
21
25
|
* An intent is an abstract description of an operation to be performed.
|
|
@@ -34,13 +38,6 @@ export type Intent<Tag extends string, Fields extends IntentParams> = {
|
|
|
34
38
|
*/
|
|
35
39
|
data: IntentData<Fields>;
|
|
36
40
|
|
|
37
|
-
/**
|
|
38
|
-
* Module ID.
|
|
39
|
-
* If specified, the intent will be sent explicitly to the plugin module.
|
|
40
|
-
* Otherwise, the intent will be sent to all plugins, in order and the first to resolve a non-null value will be used.
|
|
41
|
-
*/
|
|
42
|
-
module?: string;
|
|
43
|
-
|
|
44
41
|
/**
|
|
45
42
|
* Whether or not the intent is being undone.
|
|
46
43
|
*/
|
|
@@ -76,11 +73,11 @@ export type AnyIntentChain = IntentChain<any, any, any, any>;
|
|
|
76
73
|
export const createIntent = <Tag extends string, Fields extends IntentParams>(
|
|
77
74
|
schema: IntentSchema<Tag, Fields>,
|
|
78
75
|
data: IntentData<Fields> = {},
|
|
79
|
-
params: Pick<AnyIntent, '
|
|
76
|
+
params: Pick<AnyIntent, 'undo'> = {},
|
|
80
77
|
): IntentChain<Tag, Tag, Fields, Fields> => {
|
|
81
78
|
// The output of validateSync breaks proxy objects so this is just used for validation.
|
|
82
79
|
// TODO(wittjosiah): Is there a better way to make theses types align?
|
|
83
|
-
const _ =
|
|
80
|
+
const _ = Schema.validateSync(schema.fields.input as Schema.Schema<any, any, unknown>)(data);
|
|
84
81
|
const intent = {
|
|
85
82
|
...params,
|
|
86
83
|
_schema: schema,
|
|
@@ -112,7 +109,7 @@ export const chain =
|
|
|
112
109
|
>(
|
|
113
110
|
schema: IntentSchema<NextTag, NextFields>,
|
|
114
111
|
data: Omit<IntentData<NextFields>, keyof IntentResultData<LastFields>> = {},
|
|
115
|
-
params: Pick<AnyIntent, '
|
|
112
|
+
params: Pick<AnyIntent, 'undo'> = {},
|
|
116
113
|
) =>
|
|
117
114
|
(
|
|
118
115
|
intent: IntentChain<FirstTag, any, FirstFields, LastFields>,
|
|
@@ -139,8 +136,13 @@ export const chain =
|
|
|
139
136
|
|
|
140
137
|
// NOTE: Should maintain compatibility with `i18next` (and @dxos/react-ui).
|
|
141
138
|
// TODO(wittjosiah): Making this immutable breaks type compatibility.
|
|
142
|
-
export const Label =
|
|
143
|
-
|
|
144
|
-
|
|
139
|
+
export const Label = Schema.Union(
|
|
140
|
+
Schema.String,
|
|
141
|
+
Schema.mutable(
|
|
142
|
+
Schema.Tuple(
|
|
143
|
+
Schema.String,
|
|
144
|
+
Schema.mutable(Schema.Struct({ ns: Schema.String, count: Schema.optional(Schema.Number) })),
|
|
145
|
+
),
|
|
146
|
+
),
|
|
145
147
|
);
|
|
146
|
-
export type Label =
|
|
148
|
+
export type Label = Schema.Schema.Type<typeof Label>;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { Schema
|
|
5
|
+
import { Schema } from 'effect';
|
|
6
6
|
|
|
7
7
|
export const SETTINGS_PLUGIN = 'dxos.org/plugin/settings';
|
|
8
8
|
export const SETTINGS_ACTION = `${SETTINGS_PLUGIN}/action`;
|
|
@@ -12,18 +12,18 @@ export const SETTINGS_ID = '!dxos:settings';
|
|
|
12
12
|
export const SETTINGS_KEY = 'settings';
|
|
13
13
|
|
|
14
14
|
export namespace SettingsAction {
|
|
15
|
-
export class Open extends
|
|
16
|
-
input:
|
|
17
|
-
plugin:
|
|
15
|
+
export class Open extends Schema.TaggedClass<Open>()(`${SETTINGS_ACTION}/open`, {
|
|
16
|
+
input: Schema.Struct({
|
|
17
|
+
plugin: Schema.optional(Schema.String),
|
|
18
18
|
}),
|
|
19
|
-
output:
|
|
19
|
+
output: Schema.Void,
|
|
20
20
|
}) {}
|
|
21
21
|
|
|
22
|
-
export class OpenPluginRegistry extends
|
|
22
|
+
export class OpenPluginRegistry extends Schema.TaggedClass<OpenPluginRegistry>()(
|
|
23
23
|
`${SETTINGS_ACTION}/open-plugin-registry`,
|
|
24
24
|
{
|
|
25
|
-
input:
|
|
26
|
-
output:
|
|
25
|
+
input: Schema.Void,
|
|
26
|
+
output: Schema.Void,
|
|
27
27
|
},
|
|
28
28
|
) {}
|
|
29
29
|
}
|