@dxos/app-framework 0.8.4-main.b97322e → 0.8.4-main.dedc0f3
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/linux_x86_64_19.0.0/727453fb3a62f7f1d952a41e051ca8a6f88cadc45cee43c6a4d1aa45f9b75665.wasmer-v7 +0 -0
- package/.swc/plugins/{v7_linux_x86_64_13.0.0/fce1bdb8e20a094e4af08bad09cc81497ed0e2e7c51223b07d371063cca18429 → linux_x86_64_19.0.0/fce1bdb8e20a094e4af08bad09cc81497ed0e2e7c51223b07d371063cca18429.wasmer-v7} +0 -0
- package/dist/lib/browser/{app-graph-builder-LYF7EKNN.mjs → app-graph-builder-AFFC6VB2.mjs} +3 -3
- package/dist/lib/browser/app-graph-builder-AFFC6VB2.mjs.map +7 -0
- package/dist/lib/browser/{chunk-FMN65HSW.mjs → chunk-OZY7HV2A.mjs} +376 -252
- package/dist/lib/browser/chunk-OZY7HV2A.mjs.map +7 -0
- package/dist/lib/browser/{chunk-FO2PH7M3.mjs → chunk-T6M7JB7M.mjs} +186 -130
- package/dist/lib/browser/chunk-T6M7JB7M.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +11 -5
- package/dist/lib/browser/index.mjs.map +2 -2
- package/dist/lib/browser/{intent-dispatcher-LSYQZSEB.mjs → intent-dispatcher-QG7UPGQX.mjs} +2 -2
- package/dist/lib/browser/{intent-resolver-ZTNOSO3A.mjs → intent-resolver-4S4PSTM5.mjs} +2 -2
- package/dist/lib/browser/intent-resolver-4S4PSTM5.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/{store-KML2R4IE.mjs → store-6E33KLGK.mjs} +2 -2
- package/dist/lib/browser/{store-KML2R4IE.mjs.map → store-6E33KLGK.mjs.map} +1 -1
- package/dist/lib/browser/testing/index.mjs +5 -7
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/browser/worker.mjs +7 -1
- package/dist/lib/node-esm/{app-graph-builder-SAOWGJDK.mjs → app-graph-builder-S4OAULX5.mjs} +3 -3
- package/dist/lib/node-esm/app-graph-builder-S4OAULX5.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-ZEZ4FVEU.mjs → chunk-F63ZRXMK.mjs} +376 -252
- package/dist/lib/node-esm/chunk-F63ZRXMK.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-73HGSHKE.mjs → chunk-HJFU7QOR.mjs} +186 -130
- package/dist/lib/node-esm/chunk-HJFU7QOR.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +11 -5
- package/dist/lib/node-esm/index.mjs.map +2 -2
- package/dist/lib/node-esm/{intent-dispatcher-6CYNGPSW.mjs → intent-dispatcher-NXBGPJOX.mjs} +2 -2
- package/dist/lib/node-esm/{intent-resolver-W7Z7WFFM.mjs → intent-resolver-2ZKXI5ET.mjs} +2 -2
- package/dist/lib/node-esm/intent-resolver-2ZKXI5ET.mjs.map +7 -0
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/{store-QEXGXLWZ.mjs → store-QQUTQHHT.mjs} +2 -2
- package/dist/lib/node-esm/{store-QEXGXLWZ.mjs.map → store-QQUTQHHT.mjs.map} +1 -1
- package/dist/lib/node-esm/testing/index.mjs +5 -7
- package/dist/lib/node-esm/testing/index.mjs.map +3 -3
- package/dist/lib/node-esm/worker.mjs +7 -1
- package/dist/types/src/common/capabilities.d.ts +75 -8
- package/dist/types/src/common/capabilities.d.ts.map +1 -1
- package/dist/types/src/common/collaboration.d.ts +9 -8
- package/dist/types/src/common/collaboration.d.ts.map +1 -1
- package/dist/types/src/common/events.d.ts.map +1 -1
- package/dist/types/src/common/index.d.ts +1 -1
- package/dist/types/src/common/index.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/components/App.d.ts +10 -0
- package/dist/types/src/components/App.d.ts.map +1 -0
- package/dist/types/src/components/App.stories.d.ts +15 -0
- package/dist/types/src/components/App.stories.d.ts.map +1 -0
- package/dist/types/src/components/DefaultFallback.d.ts +8 -0
- package/dist/types/src/components/DefaultFallback.d.ts.map +1 -0
- package/dist/types/src/components/index.d.ts +2 -0
- package/dist/types/src/components/index.d.ts.map +1 -0
- package/dist/types/src/{App.d.ts → components/useApp.d.ts} +7 -6
- package/dist/types/src/components/useApp.d.ts.map +1 -0
- package/dist/types/src/components/useLoading.d.ts +19 -0
- package/dist/types/src/components/useLoading.d.ts.map +1 -0
- package/dist/types/src/core/capabilities.d.ts +4 -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/index.d.ts +1 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/playground/debug/Debug.d.ts +1 -1
- package/dist/types/src/playground/generator/Main.d.ts +1 -1
- package/dist/types/src/playground/generator/Toolbar.d.ts +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/layout/Layout.d.ts +2 -2
- package/dist/types/src/playground/logger/Toolbar.d.ts +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 +5 -3
- 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/index.d.ts +1 -0
- package/dist/types/src/plugin-intent/index.d.ts.map +1 -1
- package/dist/types/src/plugin-intent/intent-dispatcher.d.ts +3 -3
- 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 +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 +1 -1
- package/dist/types/src/plugin-settings/intent-resolver.d.ts.map +1 -1
- package/dist/types/src/plugin-settings/store.d.ts +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 +6 -4
- 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 +4 -2
- package/dist/types/src/testing/withPluginManager.d.ts.map +1 -1
- package/dist/types/src/testing/withPluginManager.stories.d.ts +9 -3
- package/dist/types/src/testing/withPluginManager.stories.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +28 -24
- package/src/common/capabilities.ts +91 -10
- package/src/common/collaboration.ts +5 -8
- package/src/common/events.ts +3 -1
- package/src/common/index.ts +1 -1
- package/src/common/surface.ts +1 -1
- package/src/components/App.stories.tsx +35 -0
- package/src/components/App.tsx +59 -0
- package/src/components/DefaultFallback.tsx +26 -0
- package/src/components/index.ts +5 -0
- package/src/{App.tsx → components/useApp.tsx} +20 -130
- package/src/components/useLoading.tsx +70 -0
- package/src/core/capabilities.test.ts +1 -1
- package/src/core/capabilities.ts +11 -6
- package/src/core/manager.test.ts +4 -3
- package/src/core/manager.ts +132 -54
- package/src/helpers.test.ts +1 -1
- package/src/index.ts +1 -1
- package/src/playground/debug/Debug.tsx +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 +15 -10
- package/src/plugin-intent/IntentPlugin.ts +2 -1
- package/src/plugin-intent/index.ts +1 -0
- package/src/plugin-intent/intent-dispatcher.test.ts +1 -1
- package/src/plugin-intent/intent-dispatcher.ts +10 -8
- 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 +21 -13
- 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 +9 -5
- package/src/testing/withPluginManager.tsx +13 -13
- package/tsconfig.json +1 -8
- package/.swc/plugins/v7_linux_x86_64_13.0.0/f45bdff002284d9e8f9ef3f0be909de12da36c049cbcf261ac78fc00abb09a2d +0 -0
- package/dist/lib/browser/app-graph-builder-LYF7EKNN.mjs.map +0 -7
- package/dist/lib/browser/chunk-FMN65HSW.mjs.map +0 -7
- package/dist/lib/browser/chunk-FO2PH7M3.mjs.map +0 -7
- package/dist/lib/browser/intent-resolver-ZTNOSO3A.mjs.map +0 -7
- package/dist/lib/node-esm/app-graph-builder-SAOWGJDK.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-73HGSHKE.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-ZEZ4FVEU.mjs.map +0 -7
- package/dist/lib/node-esm/intent-resolver-W7Z7WFFM.mjs.map +0 -7
- package/dist/types/src/App.d.ts.map +0 -1
- /package/dist/lib/browser/{intent-dispatcher-LSYQZSEB.mjs.map → intent-dispatcher-QG7UPGQX.mjs.map} +0 -0
- /package/dist/lib/node-esm/{intent-dispatcher-6CYNGPSW.mjs.map → intent-dispatcher-NXBGPJOX.mjs.map} +0 -0
|
@@ -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;
|
|
@@ -196,7 +197,8 @@ export const createDispatcher = (
|
|
|
196
197
|
.filter((resolver) => !resolver.filter || resolver.filter(intent.data))
|
|
197
198
|
.toSorted(byPosition);
|
|
198
199
|
if (candidates.length === 0) {
|
|
199
|
-
|
|
200
|
+
log.info('no resolvers found', { intent: intent.id });
|
|
201
|
+
return yield* Effect.fail(new NoResolversError(intent.id));
|
|
200
202
|
}
|
|
201
203
|
|
|
202
204
|
const effect = candidates[0].resolve(intent.data, intent.undo ?? false);
|
|
@@ -207,7 +209,7 @@ export const createDispatcher = (
|
|
|
207
209
|
const dispatch: IntentDispatcher = (intentChain, depth = 0) => {
|
|
208
210
|
return Effect.gen(function* () {
|
|
209
211
|
if (depth > executionLimit) {
|
|
210
|
-
yield* Effect.fail(new CycleDetectedError());
|
|
212
|
+
return yield* Effect.fail(new CycleDetectedError());
|
|
211
213
|
}
|
|
212
214
|
|
|
213
215
|
const resultsRef = yield* Ref.make<AnyIntentResult[]>([]);
|
|
@@ -230,7 +232,7 @@ export const createDispatcher = (
|
|
|
230
232
|
// error: result.error.message,
|
|
231
233
|
// }),
|
|
232
234
|
// );
|
|
233
|
-
yield* Effect.fail(result.error);
|
|
235
|
+
return yield* Effect.fail(result.error);
|
|
234
236
|
}
|
|
235
237
|
}
|
|
236
238
|
|
|
@@ -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'> => {
|
|
@@ -4,18 +4,20 @@
|
|
|
4
4
|
|
|
5
5
|
import '@dxos-theme';
|
|
6
6
|
|
|
7
|
+
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
7
8
|
import React, { useCallback, useState } from 'react';
|
|
8
9
|
|
|
9
10
|
import { faker } from '@dxos/random';
|
|
10
11
|
import { Button, List, ListItem } from '@dxos/react-ui';
|
|
11
12
|
import { withLayout, withTheme } from '@dxos/storybook-utils';
|
|
12
13
|
|
|
13
|
-
import { PluginManagerProvider, usePluginManager } from './PluginManagerProvider';
|
|
14
|
-
import { Surface, useSurfaces } from './Surface';
|
|
15
14
|
import { Capabilities, createSurface } from '../common';
|
|
16
15
|
import { type PluginManager } from '../core';
|
|
17
16
|
import { setupPluginManager } from '../testing';
|
|
18
17
|
|
|
18
|
+
import { PluginManagerProvider, usePluginManager } from './PluginManagerProvider';
|
|
19
|
+
import { Surface, useSurfaces } from './Surface';
|
|
20
|
+
|
|
19
21
|
const randomColor = (): string => {
|
|
20
22
|
const hue = faker.number.int({ min: 0, max: 360 });
|
|
21
23
|
const saturation = faker.number.int({ min: 50, max: 90 });
|
|
@@ -23,7 +25,7 @@ const randomColor = (): string => {
|
|
|
23
25
|
return `hsl(${hue}, ${saturation}%, ${lightness}%)`;
|
|
24
26
|
};
|
|
25
27
|
|
|
26
|
-
const
|
|
28
|
+
const Component = () => {
|
|
27
29
|
const manager = usePluginManager();
|
|
28
30
|
const surfaces = useSurfaces();
|
|
29
31
|
const [picked, setPicked] = useState('test');
|
|
@@ -77,20 +79,26 @@ const Story = () => {
|
|
|
77
79
|
);
|
|
78
80
|
};
|
|
79
81
|
|
|
80
|
-
|
|
82
|
+
const DefaultStory = (props: { manager: PluginManager }) => {
|
|
83
|
+
return (
|
|
84
|
+
<PluginManagerProvider value={props.manager}>
|
|
85
|
+
<Component />
|
|
86
|
+
</PluginManagerProvider>
|
|
87
|
+
);
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const meta = {
|
|
81
91
|
title: 'sdk/app-framework/Surface',
|
|
82
|
-
render:
|
|
83
|
-
return (
|
|
84
|
-
<PluginManagerProvider value={manager}>
|
|
85
|
-
<Story />
|
|
86
|
-
</PluginManagerProvider>
|
|
87
|
-
);
|
|
88
|
-
},
|
|
92
|
+
render: DefaultStory,
|
|
89
93
|
// NOTE: Intentionally not using withPluginManager to try to reduce surface area of the story.
|
|
90
94
|
decorators: [withTheme, withLayout()],
|
|
91
95
|
args: {
|
|
92
96
|
manager: setupPluginManager(),
|
|
93
97
|
},
|
|
94
|
-
}
|
|
98
|
+
} satisfies Meta<typeof DefaultStory>;
|
|
99
|
+
|
|
100
|
+
export default meta;
|
|
101
|
+
|
|
102
|
+
type Story = StoryObj<typeof meta>;
|
|
95
103
|
|
|
96
|
-
export const Default = {};
|
|
104
|
+
export const Default: Story = {};
|
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);
|
|
@@ -6,9 +6,10 @@ import { useRxValue } from '@effect-rx/rx-react';
|
|
|
6
6
|
|
|
7
7
|
import { invariant } from '@dxos/invariant';
|
|
8
8
|
|
|
9
|
-
import { usePluginManager } from './PluginManagerProvider';
|
|
10
9
|
import { type InterfaceDef } from '../core';
|
|
11
10
|
|
|
11
|
+
import { usePluginManager } from './PluginManagerProvider';
|
|
12
|
+
|
|
12
13
|
/**
|
|
13
14
|
* Hook to request capabilities from the plugin context.
|
|
14
15
|
* @returns An array of capabilities.
|
|
@@ -2,15 +2,17 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
5
6
|
import React from 'react';
|
|
6
7
|
|
|
7
|
-
import { withTheme
|
|
8
|
+
import { withTheme } from '@dxos/storybook-utils';
|
|
8
9
|
|
|
9
|
-
import { withPluginManager } from './withPluginManager';
|
|
10
10
|
import { Capabilities, createSurface } from '../common';
|
|
11
11
|
import { contributes } from '../core';
|
|
12
12
|
import { Surface } from '../react';
|
|
13
13
|
|
|
14
|
+
import { withPluginManager } from './withPluginManager';
|
|
15
|
+
|
|
14
16
|
const DefaultStory = () => {
|
|
15
17
|
console.log('Render');
|
|
16
18
|
return (
|
|
@@ -21,7 +23,7 @@ const DefaultStory = () => {
|
|
|
21
23
|
);
|
|
22
24
|
};
|
|
23
25
|
|
|
24
|
-
const meta
|
|
26
|
+
const meta = {
|
|
25
27
|
title: 'sdk/app-framework/withPluginManager',
|
|
26
28
|
render: DefaultStory,
|
|
27
29
|
decorators: [
|
|
@@ -39,8 +41,10 @@ const meta: Meta = {
|
|
|
39
41
|
],
|
|
40
42
|
}),
|
|
41
43
|
],
|
|
42
|
-
}
|
|
44
|
+
} satisfies Meta<typeof DefaultStory>;
|
|
43
45
|
|
|
44
46
|
export default meta;
|
|
45
47
|
|
|
46
|
-
|
|
48
|
+
type Story = StoryObj<typeof meta>;
|
|
49
|
+
|
|
50
|
+
export const Default: Story = {};
|
|
@@ -6,22 +6,24 @@ import { type Decorator } from '@storybook/react';
|
|
|
6
6
|
import React, { useEffect, useMemo } from 'react';
|
|
7
7
|
|
|
8
8
|
import { raise } from '@dxos/debug';
|
|
9
|
+
import { useAsyncEffect } from '@dxos/react-hooks';
|
|
9
10
|
|
|
10
|
-
import { useApp, type CreateAppOptions } from '../App';
|
|
11
11
|
import { Capabilities, Events } from '../common';
|
|
12
|
+
import { type UseAppOptions, useApp } from '../components';
|
|
12
13
|
import {
|
|
13
|
-
contributes,
|
|
14
|
-
defineModule,
|
|
15
|
-
definePlugin,
|
|
16
14
|
type ActivationEvent,
|
|
17
15
|
type AnyCapability,
|
|
18
|
-
PluginManager,
|
|
19
16
|
type PluginContext,
|
|
17
|
+
PluginManager,
|
|
18
|
+
contributes,
|
|
19
|
+
defineModule,
|
|
20
|
+
definePlugin,
|
|
20
21
|
} from '../core';
|
|
21
22
|
|
|
22
23
|
// TODO(burdon): Factor out (use consistently in plugin framework?)
|
|
23
24
|
export type Provider<C, R> = (context: C) => R;
|
|
24
25
|
export type ProviderOrValue<C, R> = Provider<C, R> | R;
|
|
26
|
+
|
|
25
27
|
export const getValue = <C, R>(providerOrValue: ProviderOrValue<C, R>, context: C): R => {
|
|
26
28
|
return typeof providerOrValue === 'function' ? (providerOrValue as Provider<C, R>)(context) : providerOrValue;
|
|
27
29
|
};
|
|
@@ -34,7 +36,7 @@ export const setupPluginManager = ({
|
|
|
34
36
|
plugins = [],
|
|
35
37
|
core = plugins.map(({ meta }) => meta.id),
|
|
36
38
|
...options
|
|
37
|
-
}:
|
|
39
|
+
}: UseAppOptions & Pick<WithPluginManagerOptions, 'capabilities'> = {}) => {
|
|
38
40
|
const pluginManager = new PluginManager({
|
|
39
41
|
pluginLoader: () => raise(new Error('Not implemented')),
|
|
40
42
|
plugins: [storyPlugin(), ...plugins],
|
|
@@ -55,8 +57,10 @@ export const setupPluginManager = ({
|
|
|
55
57
|
return pluginManager;
|
|
56
58
|
};
|
|
57
59
|
|
|
58
|
-
export type WithPluginManagerOptions =
|
|
60
|
+
export type WithPluginManagerOptions = UseAppOptions & {
|
|
61
|
+
/** @deprecated */
|
|
59
62
|
capabilities?: ProviderOrValue<PluginContext, AnyCapability[]>;
|
|
63
|
+
/** @deprecated */
|
|
60
64
|
fireEvents?: (ActivationEvent | string)[];
|
|
61
65
|
};
|
|
62
66
|
|
|
@@ -86,12 +90,8 @@ export const withPluginManager = (options: WithPluginManagerOptions = {}): Decor
|
|
|
86
90
|
}, [pluginManager, context]);
|
|
87
91
|
|
|
88
92
|
// Fire events.
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
await Promise.all(options.fireEvents?.map((event) => pluginManager.activate(event)) ?? []);
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
return () => clearTimeout(timeout);
|
|
93
|
+
useAsyncEffect(async () => {
|
|
94
|
+
await Promise.all(options.fireEvents?.map((event) => pluginManager.activate(event)) ?? []);
|
|
95
95
|
}, [pluginManager]);
|
|
96
96
|
|
|
97
97
|
// Create app.
|
package/tsconfig.json
CHANGED
|
Binary file
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/plugin-settings/app-graph-builder.ts"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport { Rx } from '@effect-rx/rx-react';\nimport { Option, pipe } from 'effect';\n\nimport { createExtension, ROOT_ID } from '@dxos/app-graph';\nimport { type SettingsStore, type SettingsValue } from '@dxos/local-storage';\nimport { isNonNullable } from '@dxos/util';\n\nimport { SETTINGS_ID, SETTINGS_KEY, SETTINGS_PLUGIN, SettingsAction } from './actions';\nimport { Capabilities } from '../common';\nimport { contributes, type PluginMeta, type PluginContext } from '../core';\nimport { createIntent } from '../plugin-intent';\n\nexport default (context: PluginContext) =>\n contributes(Capabilities.AppGraphBuilder, [\n createExtension({\n id: `${SETTINGS_PLUGIN}/action`,\n actions: (node) =>\n Rx.make((get) =>\n pipe(\n get(node),\n Option.flatMap((node) => (node.id === ROOT_ID ? Option.some(node) : Option.none())),\n Option.map(() => [\n {\n id: SETTINGS_PLUGIN,\n data: async () => {\n const { dispatchPromise: dispatch } = context.getCapability(Capabilities.IntentDispatcher);\n await dispatch(createIntent(SettingsAction.Open));\n },\n properties: {\n label: ['open settings label', { ns: SETTINGS_PLUGIN }],\n icon: 'ph--gear--regular',\n disposition: 'menu',\n keyBinding: {\n macos: 'meta+,',\n windows: 'alt+,',\n },\n },\n },\n ]),\n Option.getOrElse(() => []),\n ),\n ),\n }),\n createExtension({\n id: `${SETTINGS_PLUGIN}/core`,\n connector: (node) =>\n Rx.make((get) =>\n pipe(\n get(node),\n Option.flatMap((node) => (node.id === ROOT_ID ? Option.some(node) : Option.none())),\n Option.map(() => [\n {\n id: SETTINGS_ID,\n type: SETTINGS_PLUGIN,\n properties: {\n label: ['app settings label', { ns: SETTINGS_PLUGIN }],\n icon: 'ph--gear--regular',\n disposition: 'pin-end',\n position: 'hoist',\n testId: 'treeView.appSettings',\n },\n },\n ]),\n Option.getOrElse(() => []),\n ),\n ),\n }),\n createExtension({\n id: `${SETTINGS_PLUGIN}/core-plugins`,\n connector: (node) =>\n Rx.make((get) =>\n pipe(\n get(node),\n Option.flatMap((node) => (node.id !== SETTINGS_ID ? Option.none() : Option.some(node))),\n Option.map(() => {\n const manager = get(context.capability(Capabilities.PluginManager));\n const [settingsStore] = get(context.capabilities(Capabilities.SettingsStore));\n return [\n ...manager.plugins\n .filter((plugin) => manager.core.includes(plugin.meta.id))\n .map((plugin): [PluginMeta, SettingsStore<SettingsValue>] | null => {\n const settings = settingsStore?.getStore(plugin.meta.id);\n if (!settings) {\n return null;\n }\n\n return [plugin.meta, settings];\n })\n .filter(isNonNullable)\n .map(([meta, settings]) => ({\n id: `${SETTINGS_KEY}:${meta.id.replaceAll('/', ':')}`,\n type: 'category',\n data: settings,\n properties: {\n label: meta.name ?? meta.id,\n icon: meta.icon ?? 'ph--circle--regular',\n },\n })),\n\n {\n id: `${SETTINGS_KEY}:custom-plugins`,\n type: 'category',\n properties: {\n label: ['custom plugins label', { ns: SETTINGS_PLUGIN }],\n icon: 'ph--squares-four--regular',\n role: 'branch',\n disposition: 'collection',\n },\n },\n ];\n }),\n Option.getOrElse(() => []),\n ),\n ),\n }),\n createExtension({\n id: `${SETTINGS_PLUGIN}/custom-plugins`,\n connector: (node) =>\n Rx.make((get) =>\n pipe(\n get(node),\n Option.flatMap((node) =>\n node.id !== `${SETTINGS_KEY}:custom-plugins` ? Option.none() : Option.some(node),\n ),\n Option.map(() => {\n const manager = get(context.capability(Capabilities.PluginManager));\n const [settingsStore] = get(context.capabilities(Capabilities.SettingsStore));\n return manager.plugins\n .filter((plugin) => !manager.core.includes(plugin.meta.id))\n .map((plugin): [PluginMeta, SettingsStore<SettingsValue>] | null => {\n const settings = settingsStore?.getStore(plugin.meta.id);\n if (!settings) {\n return null;\n }\n\n return [plugin.meta, settings];\n })\n .filter(isNonNullable)\n .map(([meta, settings]) => ({\n id: `${SETTINGS_KEY}:${meta.id.replaceAll('/', ':')}`,\n type: 'category',\n data: settings,\n properties: {\n label: meta.name ?? meta.id,\n icon: meta.icon ?? 'ph--circle--regular',\n },\n }));\n }),\n Option.getOrElse(() => []),\n ),\n ),\n }),\n ]);\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["Rx", "Option", "pipe", "createExtension", "ROOT_ID", "isNonNullable", "context", "contributes", "Capabilities", "AppGraphBuilder", "createExtension", "id", "SETTINGS_PLUGIN", "actions", "node", "Rx", "make", "get", "pipe", "Option", "flatMap", "ROOT_ID", "some", "none", "map", "data", "dispatchPromise", "dispatch", "getCapability", "IntentDispatcher", "createIntent", "SettingsAction", "Open", "properties", "label", "ns", "icon", "disposition", "keyBinding", "macos", "windows", "getOrElse", "connector", "SETTINGS_ID", "type", "position", "testId", "manager", "capability", "PluginManager", "settingsStore", "capabilities", "SettingsStore", "plugins", "filter", "plugin", "core", "includes", "meta", "settings", "getStore", "isNonNullable", "SETTINGS_KEY", "replaceAll", "name", "role"]
|
|
7
|
-
}
|