@dxos/app-framework 0.8.4-main.f9ba587 → 0.8.4-main.fd6878d
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/.swc/plugins/v7_linux_x86_64_13.0.0/c614d7475354583212fbd7669acbae95b9832c305bf51bdaabe2e6de05abb6bf +0 -0
- package/dist/lib/browser/{app-graph-builder-BGGXLD6T.mjs → app-graph-builder-MOVKFH3J.mjs} +3 -3
- package/dist/lib/browser/app-graph-builder-MOVKFH3J.mjs.map +7 -0
- package/dist/lib/browser/{chunk-2636QSIK.mjs → chunk-NKCIDYDI.mjs} +304 -224
- package/dist/lib/browser/chunk-NKCIDYDI.mjs.map +7 -0
- package/dist/lib/browser/{chunk-DHZB7HG7.mjs → chunk-OSBZFKMO.mjs} +38 -23
- package/dist/lib/browser/chunk-OSBZFKMO.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +5 -5
- package/dist/lib/browser/index.mjs.map +2 -2
- package/dist/lib/browser/{intent-dispatcher-TWKB22NI.mjs → intent-dispatcher-FTTJLVGN.mjs} +2 -2
- package/dist/lib/browser/{intent-resolver-O67UANYP.mjs → intent-resolver-ZCGEAG3E.mjs} +2 -2
- package/dist/lib/browser/intent-resolver-ZCGEAG3E.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/{store-LFKDWHUQ.mjs → store-3QB6Q2BC.mjs} +2 -2
- package/dist/lib/browser/{store-LFKDWHUQ.mjs.map → store-3QB6Q2BC.mjs.map} +1 -1
- package/dist/lib/browser/testing/index.mjs +2 -2
- package/dist/lib/browser/testing/index.mjs.map +2 -2
- package/dist/lib/browser/worker.mjs +1 -1
- package/dist/lib/node-esm/{app-graph-builder-QHIJUYYW.mjs → app-graph-builder-ODE4B5GT.mjs} +3 -3
- package/dist/lib/node-esm/app-graph-builder-ODE4B5GT.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-NJAFK626.mjs → chunk-WU3QN5B6.mjs} +38 -23
- package/dist/lib/node-esm/chunk-WU3QN5B6.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-VSKRV3NW.mjs → chunk-YEN7NKTF.mjs} +304 -224
- package/dist/lib/node-esm/chunk-YEN7NKTF.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +5 -5
- package/dist/lib/node-esm/index.mjs.map +2 -2
- package/dist/lib/node-esm/{intent-dispatcher-5PRM3KGH.mjs → intent-dispatcher-YQIQ55LJ.mjs} +2 -2
- package/dist/lib/node-esm/{intent-resolver-K3D4BXQQ.mjs → intent-resolver-KG27L7EQ.mjs} +2 -2
- package/dist/lib/node-esm/intent-resolver-KG27L7EQ.mjs.map +7 -0
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/{store-53XDUBMD.mjs → store-TIJAVO3D.mjs} +2 -2
- package/dist/lib/node-esm/{store-53XDUBMD.mjs.map → store-TIJAVO3D.mjs.map} +1 -1
- package/dist/lib/node-esm/testing/index.mjs +2 -2
- package/dist/lib/node-esm/testing/index.mjs.map +2 -2
- package/dist/lib/node-esm/worker.mjs +1 -1
- package/dist/types/src/App.d.ts +1 -1
- package/dist/types/src/App.d.ts.map +1 -1
- package/dist/types/src/common/capabilities.d.ts +82 -7
- package/dist/types/src/common/capabilities.d.ts.map +1 -1
- package/dist/types/src/common/events.d.ts.map +1 -1
- package/dist/types/src/common/surface.d.ts +1 -1
- package/dist/types/src/common/surface.d.ts.map +1 -1
- package/dist/types/src/core/capabilities.d.ts.map +1 -1
- package/dist/types/src/core/manager.d.ts +6 -2
- package/dist/types/src/core/manager.d.ts.map +1 -1
- package/dist/types/src/playground/generator/Toolbar.d.ts.map +1 -1
- package/dist/types/src/playground/generator/generator.d.ts.map +1 -1
- package/dist/types/src/playground/logger/Toolbar.d.ts.map +1 -1
- package/dist/types/src/playground/logger/plugin.d.ts.map +1 -1
- package/dist/types/src/playground/playground.stories.d.ts.map +1 -1
- package/dist/types/src/plugin-intent/IntentPlugin.d.ts.map +1 -1
- package/dist/types/src/plugin-intent/intent-dispatcher.d.ts +2 -2
- package/dist/types/src/plugin-intent/intent-dispatcher.d.ts.map +1 -1
- package/dist/types/src/plugin-settings/SettingsPlugin.d.ts.map +1 -1
- package/dist/types/src/plugin-settings/app-graph-builder.d.ts.map +1 -1
- package/dist/types/src/plugin-settings/intent-resolver.d.ts.map +1 -1
- package/dist/types/src/plugin-settings/store.d.ts.map +1 -1
- package/dist/types/src/react/ErrorBoundary.d.ts +13 -14
- 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.map +1 -1
- package/dist/types/src/react/Surface.stories.d.ts.map +1 -1
- package/dist/types/src/react/common.d.ts.map +1 -1
- package/dist/types/src/react/useCapabilities.d.ts.map +1 -1
- package/dist/types/src/testing/withPluginManager.d.ts +2 -0
- 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 +28 -24
- package/src/App.tsx +12 -4
- package/src/common/capabilities.ts +103 -10
- package/src/common/events.ts +3 -1
- package/src/common/surface.ts +1 -1
- package/src/core/capabilities.test.ts +1 -1
- package/src/core/capabilities.ts +1 -0
- package/src/core/manager.test.ts +4 -3
- package/src/core/manager.ts +132 -54
- package/src/helpers.test.ts +1 -1
- package/src/playground/generator/Toolbar.tsx +2 -1
- package/src/playground/generator/generator.ts +2 -2
- package/src/playground/layout/plugin.ts +1 -1
- package/src/playground/logger/Toolbar.tsx +2 -1
- package/src/playground/logger/plugin.ts +3 -2
- package/src/playground/playground.stories.tsx +4 -3
- package/src/plugin-intent/IntentPlugin.ts +2 -1
- package/src/plugin-intent/intent-dispatcher.test.ts +1 -1
- package/src/plugin-intent/intent-dispatcher.ts +6 -5
- package/src/plugin-settings/SettingsPlugin.ts +3 -2
- package/src/plugin-settings/app-graph-builder.ts +4 -3
- package/src/plugin-settings/intent-resolver.ts +3 -2
- package/src/plugin-settings/store.ts +1 -1
- package/src/react/ErrorBoundary.tsx +24 -15
- package/src/react/IntentContext.tsx +3 -2
- package/src/react/Surface.stories.tsx +3 -2
- package/src/react/Surface.tsx +4 -3
- package/src/react/common.ts +2 -1
- package/src/react/useCapabilities.ts +2 -1
- package/src/testing/withPluginManager.stories.tsx +3 -2
- package/src/testing/withPluginManager.tsx +8 -5
- package/tsconfig.json +4 -1
- package/.eslintrc.cjs +0 -9
- package/.swc/plugins/v7_linux_x86_64_13.0.0/f45bdff002284d9e8f9ef3f0be909de12da36c049cbcf261ac78fc00abb09a2d +0 -0
- package/dist/lib/browser/app-graph-builder-BGGXLD6T.mjs.map +0 -7
- package/dist/lib/browser/chunk-2636QSIK.mjs.map +0 -7
- package/dist/lib/browser/chunk-DHZB7HG7.mjs.map +0 -7
- package/dist/lib/browser/intent-resolver-O67UANYP.mjs.map +0 -7
- package/dist/lib/node-esm/app-graph-builder-QHIJUYYW.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-NJAFK626.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-VSKRV3NW.mjs.map +0 -7
- package/dist/lib/node-esm/intent-resolver-K3D4BXQQ.mjs.map +0 -7
- package/typedoc/.nojekyll +0 -1
- package/typedoc/assets/hierarchy.js +0 -1
- package/typedoc/assets/highlight.css +0 -106
- package/typedoc/assets/icons.js +0 -18
- package/typedoc/assets/icons.svg +0 -1
- package/typedoc/assets/main.js +0 -60
- package/typedoc/assets/navigation.js +0 -1
- package/typedoc/assets/search.js +0 -1
- package/typedoc/assets/style.css +0 -1640
- package/typedoc/classes/CollaborationActions.InsertContent.html +0 -421
- package/typedoc/classes/ErrorBoundary.html +0 -125
- package/typedoc/classes/IntentAction.ShowUndo.html +0 -227
- package/typedoc/classes/IntentAction.Track.html +0 -266
- package/typedoc/classes/LayoutAction.AddToast.html +0 -265
- package/typedoc/classes/LayoutAction.Close.html +0 -382
- package/typedoc/classes/LayoutAction.Expose.html +0 -265
- package/typedoc/classes/LayoutAction.Open.html +0 -1123
- package/typedoc/classes/LayoutAction.RevertWorkspace.html +0 -343
- package/typedoc/classes/LayoutAction.ScrollIntoView.html +0 -460
- package/typedoc/classes/LayoutAction.Set.html +0 -460
- package/typedoc/classes/LayoutAction.SetLayoutMode.html +0 -499
- package/typedoc/classes/LayoutAction.SwitchWorkspace.html +0 -265
- package/typedoc/classes/LayoutAction.UpdateComplementary.html +0 -616
- package/typedoc/classes/LayoutAction.UpdateDialog.html +0 -1123
- package/typedoc/classes/LayoutAction.UpdateLayout.html +0 -461
- package/typedoc/classes/LayoutAction.UpdatePopover.html +0 -1435
- package/typedoc/classes/LayoutAction.UpdateSidebar.html +0 -616
- package/typedoc/classes/Plugin.html +0 -6
- package/typedoc/classes/PluginContext.html +0 -38
- package/typedoc/classes/PluginManager.html +0 -43
- package/typedoc/classes/PluginModule.html +0 -18
- package/typedoc/classes/SettingsAction.Open.html +0 -226
- package/typedoc/classes/SettingsAction.OpenPluginRegistry.html +0 -265
- package/typedoc/functions/Events.createStateEvent.html +0 -2
- package/typedoc/functions/IntentPlugin.html +0 -1
- package/typedoc/functions/SettingsPlugin.html +0 -1
- package/typedoc/functions/allOf.html +0 -2
- package/typedoc/functions/chain.html +0 -3
- package/typedoc/functions/contributes.html +0 -2
- package/typedoc/functions/createDispatcher.html +0 -3
- package/typedoc/functions/createIntent.html +0 -6
- package/typedoc/functions/createResolver.html +0 -2
- package/typedoc/functions/createSurface.html +0 -2
- package/typedoc/functions/defineCapability.html +0 -2
- package/typedoc/functions/defineEvent.html +0 -2
- package/typedoc/functions/defineModule.html +0 -2
- package/typedoc/functions/definePlugin.html +0 -2
- package/typedoc/functions/eventKey.html +0 -2
- package/typedoc/functions/getEvents.html +0 -2
- package/typedoc/functions/isAllOf.html +0 -2
- package/typedoc/functions/isOneOf.html +0 -2
- package/typedoc/functions/isSurfaceAvailable.html +0 -2
- package/typedoc/functions/lazy.html +0 -2
- package/typedoc/functions/oneOf.html +0 -2
- package/typedoc/functions/useApp.html +0 -6
- package/typedoc/functions/useAppGraph.html +0 -1
- package/typedoc/functions/useCapabilities.html +0 -3
- package/typedoc/functions/useCapability.html +0 -4
- package/typedoc/functions/useIntentDispatcher.html +0 -1
- package/typedoc/functions/useIntentResolver.html +0 -1
- package/typedoc/functions/useLayout.html +0 -1
- package/typedoc/functions/usePluginManager.html +0 -2
- package/typedoc/hierarchy.html +0 -1
- package/typedoc/index.html +0 -12
- package/typedoc/interfaces/LayoutAction.Toast.html +0 -10
- package/typedoc/media/LICENSE +0 -8
- package/typedoc/modules/Capabilities.html +0 -1
- package/typedoc/modules/CollaborationActions.html +0 -1
- package/typedoc/modules/Events.html +0 -1
- package/typedoc/modules/IntentAction.html +0 -1
- package/typedoc/modules/LayoutAction.html +0 -2
- package/typedoc/modules/SettingsAction.html +0 -1
- package/typedoc/modules.html +0 -1
- package/typedoc/types/ActivationEvent.html +0 -8
- package/typedoc/types/ActivationEvents.html +0 -2
- package/typedoc/types/AnyCapability.html +0 -1
- package/typedoc/types/AnyIntent.html +0 -1
- package/typedoc/types/AnyIntentChain.html +0 -1
- package/typedoc/types/AnyIntentEffectResult.html +0 -1
- package/typedoc/types/AnyIntentResolver.html +0 -1
- package/typedoc/types/AnyIntentResult.html +0 -1
- package/typedoc/types/Capabilities.FileUploader.html +0 -1
- package/typedoc/types/Capabilities.IntentResolver.html +0 -1
- package/typedoc/types/Capabilities.Layout.html +0 -1
- package/typedoc/types/Capabilities.Metadata.html +0 -1
- package/typedoc/types/Capabilities.ReactContext.html +0 -1
- package/typedoc/types/Capabilities.ReactRoot.html +0 -1
- package/typedoc/types/Capabilities.ReactSurface.html +0 -1
- package/typedoc/types/Capabilities.Settings.html +0 -4
- package/typedoc/types/Capability.html +0 -9
- package/typedoc/types/CreateAppOptions.html +0 -10
- package/typedoc/types/FileInfo.html +0 -1
- package/typedoc/types/Intent.html +0 -10
- package/typedoc/types/IntentChain.html +0 -6
- package/typedoc/types/IntentContext.html +0 -5
- package/typedoc/types/IntentData.html +0 -1
- package/typedoc/types/IntentDispatcher.html +0 -2
- package/typedoc/types/IntentDispatcherResult.html +0 -2
- package/typedoc/types/IntentEffectDefinition.html +0 -2
- package/typedoc/types/IntentEffectResult.html +0 -15
- package/typedoc/types/IntentParams.html +0 -3
- package/typedoc/types/IntentResolver.html +0 -2
- package/typedoc/types/IntentResultData.html +0 -1
- package/typedoc/types/IntentSchema.html +0 -1
- package/typedoc/types/IntentUndo.html +0 -2
- package/typedoc/types/InterfaceDef.html +0 -4
- package/typedoc/types/Label.html +0 -1
- package/typedoc/types/NodeSerializer.html +0 -8
- package/typedoc/types/PluginManagerOptions.html +0 -6
- package/typedoc/types/PluginMeta.html +0 -21
- package/typedoc/types/PromiseIntentDispatcher.html +0 -2
- package/typedoc/types/PromiseIntentUndo.html +0 -2
- package/typedoc/types/Resource.html +0 -1
- package/typedoc/types/ResourceKey.html +0 -1
- package/typedoc/types/ResourceLanguage.html +0 -1
- package/typedoc/types/SerializedNode.html +0 -4
- package/typedoc/types/SurfaceComponent.html +0 -2
- package/typedoc/types/SurfaceDefinition.html +0 -2
- package/typedoc/types/SurfaceProps.html +0 -4
- package/typedoc/variables/Capabilities.AnchorSort.html +0 -1
- package/typedoc/variables/Capabilities.AppGraph.html +0 -1
- package/typedoc/variables/Capabilities.AppGraphBuilder.html +0 -1
- package/typedoc/variables/Capabilities.AppGraphSerializer.html +0 -1
- package/typedoc/variables/Capabilities.ArtifactDefinition.html +0 -1
- package/typedoc/variables/Capabilities.FileUploader.html +0 -1
- package/typedoc/variables/Capabilities.IntentDispatcher.html +0 -1
- package/typedoc/variables/Capabilities.IntentResolver.html +0 -1
- package/typedoc/variables/Capabilities.Layout.html +0 -1
- package/typedoc/variables/Capabilities.Metadata.html +0 -1
- package/typedoc/variables/Capabilities.Null.html +0 -1
- package/typedoc/variables/Capabilities.PluginManager.html +0 -1
- package/typedoc/variables/Capabilities.ReactContext.html +0 -1
- package/typedoc/variables/Capabilities.ReactRoot.html +0 -1
- package/typedoc/variables/Capabilities.ReactSurface.html +0 -1
- package/typedoc/variables/Capabilities.RxRegistry.html +0 -1
- package/typedoc/variables/Capabilities.Settings.html +0 -1
- package/typedoc/variables/Capabilities.SettingsStore.html +0 -1
- package/typedoc/variables/Capabilities.Tools.html +0 -1
- package/typedoc/variables/Capabilities.Translations.html +0 -1
- package/typedoc/variables/Events.AppGraphReady.html +0 -2
- package/typedoc/variables/Events.DispatcherReady.html +0 -2
- package/typedoc/variables/Events.LayoutReady.html +0 -1
- package/typedoc/variables/Events.SettingsReady.html +0 -2
- package/typedoc/variables/Events.SetupAppGraph.html +0 -2
- package/typedoc/variables/Events.SetupArtifactDefinition.html +0 -2
- package/typedoc/variables/Events.SetupIntentResolver.html +0 -2
- package/typedoc/variables/Events.SetupMetadata.html +0 -2
- package/typedoc/variables/Events.SetupReactSurface.html +0 -2
- package/typedoc/variables/Events.SetupSettings.html +0 -2
- package/typedoc/variables/Events.SetupTranslations.html +0 -2
- package/typedoc/variables/Events.Startup.html +0 -2
- package/typedoc/variables/FileInfoSchema.html +0 -1
- package/typedoc/variables/INTENT_ACTION.html +0 -1
- package/typedoc/variables/INTENT_PLUGIN.html +0 -1
- package/typedoc/variables/LAYOUT_ACTION.html +0 -1
- package/typedoc/variables/LAYOUT_PLUGIN.html +0 -1
- package/typedoc/variables/Label.html +0 -1
- package/typedoc/variables/LayoutAction.Toast.html +0 -1
- package/typedoc/variables/LayoutAction.UPDATE_LAYOUT.html +0 -1
- package/typedoc/variables/PluginManagerProvider.html +0 -2
- package/typedoc/variables/Resource.html +0 -2
- package/typedoc/variables/ResourceKey.html +0 -1
- package/typedoc/variables/ResourceLanguage.html +0 -1
- package/typedoc/variables/SETTINGS_ACTION.html +0 -1
- package/typedoc/variables/SETTINGS_ID.html +0 -1
- package/typedoc/variables/SETTINGS_KEY.html +0 -1
- package/typedoc/variables/SETTINGS_PLUGIN.html +0 -1
- package/typedoc/variables/Surface.html +0 -2
- package/typedoc/variables/defaultFileTypes.html +0 -1
- /package/dist/lib/browser/{intent-dispatcher-TWKB22NI.mjs.map → intent-dispatcher-FTTJLVGN.mjs.map} +0 -0
- /package/dist/lib/node-esm/{intent-dispatcher-5PRM3KGH.mjs.map → intent-dispatcher-YQIQ55LJ.mjs.map} +0 -0
package/src/core/manager.ts
CHANGED
|
@@ -4,16 +4,16 @@
|
|
|
4
4
|
|
|
5
5
|
import { Registry } from '@effect-rx/rx-react';
|
|
6
6
|
import { untracked } from '@preact/signals-core';
|
|
7
|
-
import { Array
|
|
7
|
+
import { Array, Duration, Effect, Fiber, HashSet, Match, Ref, pipe } from 'effect';
|
|
8
8
|
|
|
9
9
|
import { Event } from '@dxos/async';
|
|
10
|
-
import {
|
|
10
|
+
import { type Live, live } from '@dxos/live-object';
|
|
11
11
|
import { log } from '@dxos/log';
|
|
12
12
|
import { type MaybePromise } from '@dxos/util';
|
|
13
13
|
|
|
14
14
|
import { type AnyCapability, PluginContext } from './capabilities';
|
|
15
15
|
import { type ActivationEvent, eventKey, getEvents, isAllOf } from './events';
|
|
16
|
-
import { type
|
|
16
|
+
import { type Plugin, type PluginModule } from './plugin';
|
|
17
17
|
|
|
18
18
|
// TODO(wittjosiah): Factor out?
|
|
19
19
|
const isPromise = (value: unknown): value is Promise<unknown> => {
|
|
@@ -52,6 +52,9 @@ export class PluginManager {
|
|
|
52
52
|
private readonly _state: Live<PluginManagerState>;
|
|
53
53
|
private readonly _pluginLoader: PluginManagerOptions['pluginLoader'];
|
|
54
54
|
private readonly _capabilities = new Map<string, AnyCapability[]>();
|
|
55
|
+
private readonly _moduleMemoMap = new Map<PluginModule['id'], Promise<AnyCapability[]>>();
|
|
56
|
+
private readonly _activatingEvents = Effect.runSync(Ref.make<string[]>([]));
|
|
57
|
+
private readonly _activatingModules = Effect.runSync(Ref.make<string[]>([]));
|
|
55
58
|
|
|
56
59
|
constructor({
|
|
57
60
|
pluginLoader,
|
|
@@ -74,8 +77,8 @@ export class PluginManager {
|
|
|
74
77
|
enabled,
|
|
75
78
|
modules: [],
|
|
76
79
|
active: [],
|
|
77
|
-
pendingReset: [],
|
|
78
80
|
eventsFired: [],
|
|
81
|
+
pendingReset: [],
|
|
79
82
|
});
|
|
80
83
|
plugins.forEach((plugin) => this._addPlugin(plugin));
|
|
81
84
|
core.forEach((id) => this.enable(id));
|
|
@@ -268,6 +271,7 @@ export class PluginManager {
|
|
|
268
271
|
private _addPlugin(plugin: Plugin): void {
|
|
269
272
|
untracked(() => {
|
|
270
273
|
log('add plugin', { id: plugin.meta.id });
|
|
274
|
+
// TODO(wittjosiah): Find a way to add a warning for duplicate plugins that doesn't cause log spam.
|
|
271
275
|
if (!this._state.plugins.includes(plugin)) {
|
|
272
276
|
this._state.plugins.push(plugin);
|
|
273
277
|
}
|
|
@@ -287,6 +291,7 @@ export class PluginManager {
|
|
|
287
291
|
private _addModule(module: PluginModule): void {
|
|
288
292
|
untracked(() => {
|
|
289
293
|
log('add module', { id: module.id });
|
|
294
|
+
// TODO(wittjosiah): Find a way to add a warning for duplicate modules that doesn't cause log spam.
|
|
290
295
|
if (!this._state.modules.includes(module)) {
|
|
291
296
|
this._state.modules.push(module);
|
|
292
297
|
}
|
|
@@ -329,7 +334,7 @@ export class PluginManager {
|
|
|
329
334
|
.map(eventKey)
|
|
330
335
|
.filter((key) => this._state.eventsFired.includes(key));
|
|
331
336
|
|
|
332
|
-
const pendingReset = Array.
|
|
337
|
+
const pendingReset = Array.fromIterable(new Set(activationEvents)).filter(
|
|
333
338
|
(event) => !this._state.pendingReset.includes(event),
|
|
334
339
|
);
|
|
335
340
|
if (pendingReset.length > 0) {
|
|
@@ -343,24 +348,42 @@ export class PluginManager {
|
|
|
343
348
|
* @internal
|
|
344
349
|
*/
|
|
345
350
|
// TODO(wittjosiah): Improve error typing.
|
|
346
|
-
_activate(
|
|
351
|
+
_activate(
|
|
352
|
+
event: ActivationEvent | string,
|
|
353
|
+
params?: { before?: string; after?: string },
|
|
354
|
+
): Effect.Effect<boolean, Error> {
|
|
347
355
|
return Effect.gen(this, function* () {
|
|
348
356
|
const key = typeof event === 'string' ? event : eventKey(event);
|
|
349
|
-
log('activating', { key });
|
|
357
|
+
log('activating', { key, ...params });
|
|
358
|
+
yield* Ref.update(this._activatingEvents, (activating) => Array.append(activating, key));
|
|
350
359
|
const pendingIndex = this._state.pendingReset.findIndex((event) => event === key);
|
|
351
360
|
if (pendingIndex !== -1) {
|
|
352
361
|
this._state.pendingReset.splice(pendingIndex, 1);
|
|
353
362
|
}
|
|
354
363
|
|
|
364
|
+
const activatingEvents = yield* this._activatingEvents;
|
|
365
|
+
const activatingModules = yield* this._activatingModules;
|
|
355
366
|
const modules = this._getInactiveModulesByEvent(key).filter((module) => {
|
|
356
367
|
const allOf = isAllOf(module.activatesOn);
|
|
357
368
|
if (!allOf) {
|
|
358
369
|
return true;
|
|
359
370
|
}
|
|
360
371
|
|
|
372
|
+
// Check to see if all of the events in the `allOf` have been fired.
|
|
373
|
+
// An event can be considered "fired" if it is in the `eventsFired` list or if it is currently being activated.
|
|
361
374
|
const events = module.activatesOn.events.filter((event) => eventKey(event) !== key);
|
|
362
|
-
return
|
|
375
|
+
return (
|
|
376
|
+
events.every(
|
|
377
|
+
(event) => this._state.eventsFired.includes(eventKey(event)) || activatingEvents.includes(eventKey(event)),
|
|
378
|
+
) && !activatingModules.includes(module.id)
|
|
379
|
+
);
|
|
363
380
|
});
|
|
381
|
+
yield* Ref.update(this._activatingModules, (activating) =>
|
|
382
|
+
Array.appendAll(
|
|
383
|
+
activating,
|
|
384
|
+
modules.map((module) => module.id),
|
|
385
|
+
),
|
|
386
|
+
);
|
|
364
387
|
if (modules.length === 0) {
|
|
365
388
|
log('no modules to activate', { key });
|
|
366
389
|
if (!this._state.eventsFired.includes(key)) {
|
|
@@ -372,31 +395,53 @@ export class PluginManager {
|
|
|
372
395
|
log('activating modules', { key, modules: modules.map((module) => module.id) });
|
|
373
396
|
this.activation.emit({ event: key, state: 'activating' });
|
|
374
397
|
|
|
398
|
+
// Fire activatesBefore events.
|
|
399
|
+
yield* pipe(
|
|
400
|
+
modules,
|
|
401
|
+
Array.flatMap((module) => module.activatesBefore ?? []),
|
|
402
|
+
HashSet.fromIterable,
|
|
403
|
+
HashSet.toValues,
|
|
404
|
+
Array.filter((event) => !activatingEvents.includes(eventKey(event))),
|
|
405
|
+
Array.map((event) => this._activate(event, { before: key })),
|
|
406
|
+
Effect.allWith({ concurrency: 'unbounded' }),
|
|
407
|
+
);
|
|
408
|
+
|
|
375
409
|
// Concurrently triggers loading of lazy capabilities.
|
|
376
|
-
const getCapabilities = yield*
|
|
377
|
-
modules
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
})
|
|
382
|
-
|
|
383
|
-
|
|
410
|
+
const getCapabilities = yield* pipe(
|
|
411
|
+
modules,
|
|
412
|
+
Array.map((mod) => this._loadModule(mod)),
|
|
413
|
+
Effect.allWith({ concurrency: 'unbounded' }),
|
|
414
|
+
Effect.catchAll((error) => {
|
|
415
|
+
this.activation.emit({ event: key, state: 'error', error });
|
|
416
|
+
return Effect.fail(error);
|
|
417
|
+
}),
|
|
384
418
|
);
|
|
385
419
|
|
|
386
|
-
|
|
420
|
+
// Contribute the capabilities from the activated modules.
|
|
421
|
+
yield* pipe(
|
|
387
422
|
modules,
|
|
388
|
-
|
|
389
|
-
|
|
423
|
+
Array.zip(getCapabilities),
|
|
424
|
+
Array.map(([module, capabilities]) => this._contributeCapabilities(module, capabilities)),
|
|
390
425
|
// TODO(wittjosiah): This currently can't be run in parallel.
|
|
391
426
|
// Running this with concurrency causes races with `allOf` activation events.
|
|
392
427
|
Effect.all,
|
|
393
|
-
Effect.either,
|
|
394
428
|
);
|
|
395
429
|
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
430
|
+
// Fire activatesAfter events.
|
|
431
|
+
yield* pipe(
|
|
432
|
+
modules,
|
|
433
|
+
Array.flatMap((module) => module.activatesAfter ?? []),
|
|
434
|
+
HashSet.fromIterable,
|
|
435
|
+
HashSet.toValues,
|
|
436
|
+
Array.filter((event) => !activatingEvents.includes(eventKey(event))),
|
|
437
|
+
Array.map((event) => this._activate(event, { after: key })),
|
|
438
|
+
Effect.allWith({ concurrency: 'unbounded' }),
|
|
439
|
+
);
|
|
440
|
+
|
|
441
|
+
yield* Ref.update(this._activatingEvents, (activating) => Array.filter(activating, (event) => event !== key));
|
|
442
|
+
yield* Ref.update(this._activatingModules, (activating) =>
|
|
443
|
+
Array.filter(activating, (module) => !modules.map((module) => module.id).includes(module)),
|
|
444
|
+
);
|
|
400
445
|
|
|
401
446
|
if (!this._state.eventsFired.includes(key)) {
|
|
402
447
|
this._state.eventsFired.push(key);
|
|
@@ -409,43 +454,60 @@ export class PluginManager {
|
|
|
409
454
|
});
|
|
410
455
|
}
|
|
411
456
|
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
457
|
+
// Memoized with _moduleMemoMap
|
|
458
|
+
private _loadModule = (mod: PluginModule): Effect.Effect<AnyCapability[], Error> =>
|
|
459
|
+
Effect.tryPromise({
|
|
460
|
+
try: async () => {
|
|
461
|
+
const entry = this._moduleMemoMap.get(mod.id);
|
|
462
|
+
if (entry) {
|
|
463
|
+
return entry;
|
|
464
|
+
}
|
|
420
465
|
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
466
|
+
const promise = (async () => {
|
|
467
|
+
const start = performance.now();
|
|
468
|
+
let failed = false;
|
|
469
|
+
try {
|
|
470
|
+
log('loading module', { module: mod.id });
|
|
471
|
+
// TODO(wittjosiah): Support activation with an effect.
|
|
472
|
+
let activationResult = await mod.activate(this.context);
|
|
473
|
+
if (typeof activationResult === 'function') {
|
|
474
|
+
activationResult = await activationResult();
|
|
475
|
+
}
|
|
476
|
+
return Array.isArray(activationResult) ? activationResult : [activationResult];
|
|
477
|
+
} catch (error) {
|
|
478
|
+
failed = true;
|
|
479
|
+
throw error;
|
|
480
|
+
} finally {
|
|
481
|
+
performance.measure('activate-module', {
|
|
482
|
+
start,
|
|
483
|
+
end: performance.now(),
|
|
484
|
+
detail: {
|
|
485
|
+
module: mod.id,
|
|
486
|
+
},
|
|
487
|
+
});
|
|
488
|
+
log('loaded module', { module: mod.id, elapsed: performance.now() - start, failed });
|
|
489
|
+
}
|
|
490
|
+
})();
|
|
491
|
+
this._moduleMemoMap.set(mod.id, promise);
|
|
492
|
+
return promise;
|
|
493
|
+
},
|
|
494
|
+
catch: (error) => error as Error,
|
|
495
|
+
}).pipe(
|
|
496
|
+
Effect.withSpan('PluginManager._loadModule'),
|
|
497
|
+
together(
|
|
498
|
+
Effect.sleep(Duration.seconds(10)).pipe(
|
|
499
|
+
Effect.andThen(Effect.sync(() => log.warn(`module is taking a long time to activate`, { module: mod.id }))),
|
|
432
500
|
),
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
);
|
|
501
|
+
),
|
|
502
|
+
);
|
|
503
|
+
|
|
504
|
+
private _contributeCapabilities(module: PluginModule, capabilities: AnyCapability[]): Effect.Effect<void, Error> {
|
|
505
|
+
return Effect.gen(this, function* () {
|
|
439
506
|
capabilities.forEach((capability) => {
|
|
440
507
|
this.context.contributeCapability({ module: module.id, ...capability });
|
|
441
508
|
});
|
|
442
509
|
this._state.active.push(module.id);
|
|
443
510
|
this._capabilities.set(module.id, capabilities);
|
|
444
|
-
log('activated module', { module: module.id });
|
|
445
|
-
|
|
446
|
-
yield* Effect.all(module.activatesAfter?.map((event) => this._activate(event)) ?? [], {
|
|
447
|
-
concurrency: 'unbounded',
|
|
448
|
-
});
|
|
449
511
|
});
|
|
450
512
|
}
|
|
451
513
|
|
|
@@ -469,6 +531,7 @@ export class PluginManager {
|
|
|
469
531
|
return Effect.gen(this, function* () {
|
|
470
532
|
const id = module.id;
|
|
471
533
|
log('deactivating', { id });
|
|
534
|
+
this._moduleMemoMap.delete(id);
|
|
472
535
|
|
|
473
536
|
const capabilities = this._capabilities.get(id);
|
|
474
537
|
if (capabilities) {
|
|
@@ -517,3 +580,18 @@ export class PluginManager {
|
|
|
517
580
|
});
|
|
518
581
|
}
|
|
519
582
|
}
|
|
583
|
+
|
|
584
|
+
/**
|
|
585
|
+
* Runs an effect concurrently with another effect.
|
|
586
|
+
* If the first effect completes, the second effect is interrupted.
|
|
587
|
+
*/
|
|
588
|
+
// TODO(dmaretskyi): Effect.race > Effect.asVoid
|
|
589
|
+
const together =
|
|
590
|
+
<R1>(togetherEffect: Effect.Effect<void, never, R1>) =>
|
|
591
|
+
<A, E, R2>(effect: Effect.Effect<A, E, R2>): Effect.Effect<A, E, R1 | R2> =>
|
|
592
|
+
Effect.gen(function* () {
|
|
593
|
+
const togetherFiber = yield* Effect.fork(togetherEffect);
|
|
594
|
+
const result = yield* effect;
|
|
595
|
+
yield* Fiber.interrupt(togetherFiber);
|
|
596
|
+
return result;
|
|
597
|
+
});
|
package/src/helpers.test.ts
CHANGED
|
@@ -6,12 +6,13 @@ import React, { useCallback } from 'react';
|
|
|
6
6
|
|
|
7
7
|
import { Button } from '@dxos/react-ui';
|
|
8
8
|
|
|
9
|
-
import { createGeneratorIntent, createPluginId, Number } from './generator';
|
|
10
9
|
import { Capabilities } from '../../common';
|
|
11
10
|
import { contributes } from '../../core';
|
|
12
11
|
import { createIntent } from '../../plugin-intent';
|
|
13
12
|
import { useCapabilities, useIntentDispatcher, usePluginManager } from '../../react';
|
|
14
13
|
|
|
14
|
+
import { Number, createGeneratorIntent, createPluginId } from './generator';
|
|
15
|
+
|
|
15
16
|
export const Toolbar = () => {
|
|
16
17
|
const manager = usePluginManager();
|
|
17
18
|
const { dispatchPromise: dispatch } = useIntentDispatcher();
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
import { Schema } from 'effect';
|
|
6
6
|
|
|
7
7
|
import { Capabilities, Events } from '../../common';
|
|
8
|
-
import { contributes,
|
|
9
|
-
import {
|
|
8
|
+
import { contributes, defineCapability, defineEvent, defineModule, definePlugin } from '../../core';
|
|
9
|
+
import { type IntentSchema, createResolver } from '../../plugin-intent';
|
|
10
10
|
|
|
11
11
|
export const Number = defineCapability<number>('dxos.org/test/generator/number');
|
|
12
12
|
|
|
@@ -6,12 +6,13 @@ import React, { useCallback } from 'react';
|
|
|
6
6
|
|
|
7
7
|
import { Button } from '@dxos/react-ui';
|
|
8
8
|
|
|
9
|
-
import { Log } from './schema';
|
|
10
9
|
import { Capabilities, createSurface } from '../../common';
|
|
11
10
|
import { contributes } from '../../core';
|
|
12
11
|
import { createIntent } from '../../plugin-intent';
|
|
13
12
|
import { useIntentDispatcher } from '../../react';
|
|
14
13
|
|
|
14
|
+
import { Log } from './schema';
|
|
15
|
+
|
|
15
16
|
export const Logger = () => {
|
|
16
17
|
const { dispatchPromise } = useIntentDispatcher();
|
|
17
18
|
const handleClick = useCallback(() => dispatchPromise(createIntent(Log, { message: 'Hello, world!' })), []);
|
|
@@ -4,11 +4,12 @@
|
|
|
4
4
|
|
|
5
5
|
import { log } from '@dxos/log';
|
|
6
6
|
|
|
7
|
-
import { Log } from './schema';
|
|
8
7
|
import { Capabilities, Events } from '../../common';
|
|
9
|
-
import { contributes, defineModule,
|
|
8
|
+
import { contributes, defineModule, definePlugin, lazy } from '../../core';
|
|
10
9
|
import { createResolver } from '../../plugin-intent';
|
|
11
10
|
|
|
11
|
+
import { Log } from './schema';
|
|
12
|
+
|
|
12
13
|
const Toolbar = lazy(() => import('./Toolbar'));
|
|
13
14
|
|
|
14
15
|
export const LoggerPlugin = () =>
|
|
@@ -8,12 +8,13 @@ import React from 'react';
|
|
|
8
8
|
|
|
9
9
|
import { withLayout, withTheme } from '@dxos/storybook-utils';
|
|
10
10
|
|
|
11
|
+
import { useApp } from '../App';
|
|
12
|
+
import { IntentPlugin } from '../plugin-intent';
|
|
13
|
+
|
|
11
14
|
import { DebugPlugin } from './debug';
|
|
12
|
-
import {
|
|
15
|
+
import { GeneratorPlugin, createNumberPlugin } from './generator';
|
|
13
16
|
import { LayoutPlugin } from './layout';
|
|
14
17
|
import { LoggerPlugin } from './logger';
|
|
15
|
-
import { useApp } from '../App';
|
|
16
|
-
import { IntentPlugin } from '../plugin-intent';
|
|
17
18
|
|
|
18
19
|
const plugins = [IntentPlugin(), LayoutPlugin(), DebugPlugin(), LoggerPlugin(), GeneratorPlugin()];
|
|
19
20
|
|
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { INTENT_PLUGIN } from './actions';
|
|
6
5
|
import { Events } from '../common';
|
|
7
6
|
import { defineModule, definePlugin, lazy } from '../core';
|
|
8
7
|
|
|
8
|
+
import { INTENT_PLUGIN } from './actions';
|
|
9
|
+
|
|
9
10
|
export const IntentPlugin = () =>
|
|
10
11
|
definePlugin({ id: INTENT_PLUGIN, name: 'Intent' }, [
|
|
11
12
|
defineModule({
|
|
@@ -2,17 +2,19 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { Effect, Option,
|
|
5
|
+
import { Effect, Option, Ref, pipe } from 'effect';
|
|
6
6
|
import { type Simplify } from 'effect/Types';
|
|
7
7
|
|
|
8
8
|
import { live } from '@dxos/live-object';
|
|
9
9
|
import { log } from '@dxos/log';
|
|
10
|
-
import {
|
|
10
|
+
import { type GuardedType, type MaybePromise, type Position, byPosition } from '@dxos/util';
|
|
11
|
+
|
|
12
|
+
import { Capabilities, Events } from '../common';
|
|
13
|
+
import { type PluginContext, contributes } from '../core';
|
|
11
14
|
|
|
12
15
|
import { IntentAction } from './actions';
|
|
13
16
|
import { CycleDetectedError, NoResolversError } from './errors';
|
|
14
17
|
import {
|
|
15
|
-
createIntent,
|
|
16
18
|
type AnyIntent,
|
|
17
19
|
type AnyIntentChain,
|
|
18
20
|
type Intent,
|
|
@@ -22,9 +24,8 @@ import {
|
|
|
22
24
|
type IntentResultData,
|
|
23
25
|
type IntentSchema,
|
|
24
26
|
type Label,
|
|
27
|
+
createIntent,
|
|
25
28
|
} from './intent';
|
|
26
|
-
import { Events, Capabilities } from '../common';
|
|
27
|
-
import { contributes, type PluginContext } from '../core';
|
|
28
29
|
|
|
29
30
|
const EXECUTION_LIMIT = 100;
|
|
30
31
|
const HISTORY_LIMIT = 100;
|
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { SETTINGS_PLUGIN } from './actions';
|
|
6
|
-
import { translations } from './translations';
|
|
7
5
|
import { Capabilities, Events } from '../common';
|
|
8
6
|
import { contributes, defineModule, definePlugin, lazy } from '../core';
|
|
9
7
|
|
|
8
|
+
import { SETTINGS_PLUGIN } from './actions';
|
|
9
|
+
import { translations } from './translations';
|
|
10
|
+
|
|
10
11
|
// TODO(wittjosiah): Add options to exclude some modules.
|
|
11
12
|
export const SettingsPlugin = () =>
|
|
12
13
|
definePlugin({ id: SETTINGS_PLUGIN, name: 'Settings' }, [
|
|
@@ -5,15 +5,16 @@
|
|
|
5
5
|
import { Rx } from '@effect-rx/rx-react';
|
|
6
6
|
import { Option, pipe } from 'effect';
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import { ROOT_ID, createExtension } from '@dxos/app-graph';
|
|
9
9
|
import { type SettingsStore, type SettingsValue } from '@dxos/local-storage';
|
|
10
10
|
import { isNonNullable } from '@dxos/util';
|
|
11
11
|
|
|
12
|
-
import { SETTINGS_ID, SETTINGS_KEY, SETTINGS_PLUGIN, SettingsAction } from './actions';
|
|
13
12
|
import { Capabilities } from '../common';
|
|
14
|
-
import {
|
|
13
|
+
import { type PluginContext, type PluginMeta, contributes } from '../core';
|
|
15
14
|
import { createIntent } from '../plugin-intent';
|
|
16
15
|
|
|
16
|
+
import { SETTINGS_ID, SETTINGS_KEY, SETTINGS_PLUGIN, SettingsAction } from './actions';
|
|
17
|
+
|
|
17
18
|
export default (context: PluginContext) =>
|
|
18
19
|
contributes(Capabilities.AppGraphBuilder, [
|
|
19
20
|
createExtension({
|
|
@@ -4,10 +4,11 @@
|
|
|
4
4
|
|
|
5
5
|
import { pipe } from 'effect';
|
|
6
6
|
|
|
7
|
-
import { SETTINGS_ID, SETTINGS_KEY, SettingsAction } from './actions';
|
|
8
7
|
import { Capabilities, LayoutAction } from '../common';
|
|
9
8
|
import { contributes } from '../core';
|
|
10
|
-
import {
|
|
9
|
+
import { chain, createIntent, createResolver } from '../plugin-intent';
|
|
10
|
+
|
|
11
|
+
import { SETTINGS_ID, SETTINGS_KEY, SettingsAction } from './actions';
|
|
11
12
|
|
|
12
13
|
export default () =>
|
|
13
14
|
contributes(
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { RootSettingsStore } from '@dxos/local-storage';
|
|
6
6
|
|
|
7
7
|
import { Capabilities } from '../common';
|
|
8
|
-
import {
|
|
8
|
+
import { type PluginContext, contributes } from '../core';
|
|
9
9
|
|
|
10
10
|
export default (context: PluginContext) => {
|
|
11
11
|
// TODO(wittjosiah): Replace with rx?
|
|
@@ -2,38 +2,40 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import React, { Component, type FC, type PropsWithChildren } from 'react';
|
|
5
|
+
import React, { Component, type FC, type JSX, type PropsWithChildren, type ReactNode } from 'react';
|
|
6
6
|
|
|
7
|
-
type
|
|
8
|
-
|
|
7
|
+
type State = {
|
|
8
|
+
error: Error | undefined;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export type ErrorBoundaryProps = PropsWithChildren<{
|
|
12
|
+
data?: any;
|
|
13
|
+
fallback?: FC<{ data?: any; error: Error }>;
|
|
14
|
+
}>;
|
|
9
15
|
|
|
10
16
|
/**
|
|
11
17
|
* Surface error boundary.
|
|
12
|
-
*
|
|
13
18
|
* For basic usage prefer providing a fallback component to `Surface`.
|
|
14
19
|
*
|
|
15
|
-
*
|
|
16
|
-
* https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary
|
|
20
|
+
* Ref: https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary
|
|
17
21
|
*/
|
|
18
|
-
export class ErrorBoundary extends Component<
|
|
19
|
-
constructor(props: Props) {
|
|
20
|
-
super(props);
|
|
21
|
-
this.state = { error: undefined };
|
|
22
|
-
}
|
|
23
|
-
|
|
22
|
+
export class ErrorBoundary extends Component<ErrorBoundaryProps, State> {
|
|
24
23
|
static getDerivedStateFromError(error: Error): { error: Error } {
|
|
25
24
|
return { error };
|
|
26
25
|
}
|
|
27
26
|
|
|
28
|
-
override
|
|
27
|
+
override state = { error: undefined };
|
|
28
|
+
|
|
29
|
+
override componentDidUpdate(prevProps: ErrorBoundaryProps): void {
|
|
29
30
|
if (prevProps.data !== this.props.data) {
|
|
30
31
|
this.resetError();
|
|
31
32
|
}
|
|
32
33
|
}
|
|
33
34
|
|
|
34
|
-
override render(): string | number | boolean |
|
|
35
|
+
override render(): string | number | boolean | JSX.Element | Iterable<ReactNode> | null | undefined {
|
|
35
36
|
if (this.state.error) {
|
|
36
|
-
|
|
37
|
+
const Fallback = this.props.fallback ?? DefaultFallback;
|
|
38
|
+
return <Fallback data={this.props.data} error={this.state.error} />;
|
|
37
39
|
}
|
|
38
40
|
|
|
39
41
|
return this.props.children;
|
|
@@ -43,3 +45,10 @@ export class ErrorBoundary extends Component<Props, State> {
|
|
|
43
45
|
this.setState({ error: undefined });
|
|
44
46
|
}
|
|
45
47
|
}
|
|
48
|
+
|
|
49
|
+
const DefaultFallback: NonNullable<ErrorBoundaryProps['fallback']> = ({ data, error }) => (
|
|
50
|
+
<div className='flex flex-col gap-2 overflow-hidden border border-red-500 rounded-sm'>
|
|
51
|
+
<pre className='whitespace-pre-wrap font-sm text-xs p-2'>ERROR: {error.message}</pre>
|
|
52
|
+
<pre className='whitespace-pre-wrap font-sm text-xs p-2 text-subdued'>{JSON.stringify(data, null, 2)}</pre>
|
|
53
|
+
</div>
|
|
54
|
+
);
|
|
@@ -2,15 +2,16 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { type Context, createContext, useContext,
|
|
5
|
+
import { type Context, type Provider, createContext, useContext, useEffect } from 'react';
|
|
6
6
|
|
|
7
7
|
import { raise } from '@dxos/debug';
|
|
8
8
|
import { pick } from '@dxos/util';
|
|
9
9
|
|
|
10
|
-
import { usePluginManager } from './PluginManagerProvider';
|
|
11
10
|
import { Capabilities } from '../common';
|
|
12
11
|
import { type AnyIntentResolver, type IntentContext } from '../plugin-intent';
|
|
13
12
|
|
|
13
|
+
import { usePluginManager } from './PluginManagerProvider';
|
|
14
|
+
|
|
14
15
|
const IntentContext: Context<IntentContext | undefined> = createContext<IntentContext | undefined>(undefined);
|
|
15
16
|
|
|
16
17
|
export const useIntentDispatcher = (): Pick<IntentContext, 'dispatch' | 'dispatchPromise'> => {
|
|
@@ -10,12 +10,13 @@ import { faker } from '@dxos/random';
|
|
|
10
10
|
import { Button, List, ListItem } from '@dxos/react-ui';
|
|
11
11
|
import { withLayout, withTheme } from '@dxos/storybook-utils';
|
|
12
12
|
|
|
13
|
-
import { PluginManagerProvider, usePluginManager } from './PluginManagerProvider';
|
|
14
|
-
import { Surface, useSurfaces } from './Surface';
|
|
15
13
|
import { Capabilities, createSurface } from '../common';
|
|
16
14
|
import { type PluginManager } from '../core';
|
|
17
15
|
import { setupPluginManager } from '../testing';
|
|
18
16
|
|
|
17
|
+
import { PluginManagerProvider, usePluginManager } from './PluginManagerProvider';
|
|
18
|
+
import { Surface, useSurfaces } from './Surface';
|
|
19
|
+
|
|
19
20
|
const randomColor = (): string => {
|
|
20
21
|
const hue = faker.number.int({ min: 0, max: 360 });
|
|
21
22
|
const saturation = faker.number.int({ min: 50, max: 90 });
|
package/src/react/Surface.tsx
CHANGED
|
@@ -2,16 +2,17 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import React, {
|
|
5
|
+
import React, { Fragment, Suspense, forwardRef, memo, useMemo } from 'react';
|
|
6
6
|
|
|
7
7
|
import { useDefaultValue } from '@dxos/react-hooks';
|
|
8
8
|
import { byPosition } from '@dxos/util';
|
|
9
9
|
|
|
10
|
-
import { ErrorBoundary } from './ErrorBoundary';
|
|
11
|
-
import { useCapabilities } from './useCapabilities';
|
|
12
10
|
import { Capabilities, type SurfaceDefinition, type SurfaceProps } from '../common';
|
|
13
11
|
import { type PluginContext } from '../core';
|
|
14
12
|
|
|
13
|
+
import { ErrorBoundary } from './ErrorBoundary';
|
|
14
|
+
import { useCapabilities } from './useCapabilities';
|
|
15
|
+
|
|
15
16
|
const DEFAULT_PLACEHOLDER = <Fragment />;
|
|
16
17
|
|
|
17
18
|
/**
|
package/src/react/common.ts
CHANGED
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { useCapability } from './useCapabilities';
|
|
6
5
|
import { Capabilities } from '../common';
|
|
7
6
|
|
|
7
|
+
import { useCapability } from './useCapabilities';
|
|
8
|
+
|
|
8
9
|
export const useIntentDispatcher = () => useCapability(Capabilities.IntentDispatcher);
|
|
9
10
|
|
|
10
11
|
export const useAppGraph = () => useCapability(Capabilities.AppGraph);
|