@dxos/app-framework 0.8.4-main.e098934 → 0.8.4-main.e8ec1fe
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.storybook/main.mts +11 -0
- package/.storybook/preview.mts +8 -0
- package/dist/lib/browser/{app-graph-builder-AFFC6VB2.mjs → app-graph-builder-OIEZZC45.mjs} +31 -30
- package/dist/lib/browser/app-graph-builder-OIEZZC45.mjs.map +7 -0
- package/dist/lib/browser/{chunk-ORWHM7CO.mjs → chunk-SCPE4ZO2.mjs} +11 -8
- package/dist/lib/browser/chunk-SCPE4ZO2.mjs.map +7 -0
- package/dist/lib/browser/{chunk-T6M7JB7M.mjs → chunk-VFUKEZIN.mjs} +121 -109
- package/dist/lib/browser/chunk-VFUKEZIN.mjs.map +7 -0
- package/dist/lib/browser/{chunk-OZY7HV2A.mjs → chunk-WPW5VVAX.mjs} +281 -273
- package/dist/lib/browser/chunk-WPW5VVAX.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +14 -56
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/{intent-dispatcher-QG7UPGQX.mjs → intent-dispatcher-LZ4AE66E.mjs} +2 -2
- package/dist/lib/browser/{intent-resolver-4S4PSTM5.mjs → intent-resolver-QVCKRX6G.mjs} +7 -7
- package/dist/lib/browser/intent-resolver-QVCKRX6G.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/react/index.mjs +34 -0
- package/dist/lib/browser/{store-6E33KLGK.mjs → store-CNPHOYTJ.mjs} +5 -5
- package/dist/lib/browser/store-CNPHOYTJ.mjs.map +7 -0
- package/dist/lib/browser/testing/index.mjs +14 -16
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/node-esm/{app-graph-builder-S4OAULX5.mjs → app-graph-builder-EBU4NVWD.mjs} +31 -30
- package/dist/lib/node-esm/app-graph-builder-EBU4NVWD.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-HJFU7QOR.mjs → chunk-IJOHO66N.mjs} +121 -109
- package/dist/lib/node-esm/chunk-IJOHO66N.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-F63ZRXMK.mjs → chunk-XJZGUJ3H.mjs} +281 -273
- package/dist/lib/node-esm/chunk-XJZGUJ3H.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-UMZQERLE.mjs → chunk-ZX63QUGE.mjs} +11 -8
- package/dist/lib/node-esm/chunk-ZX63QUGE.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +14 -56
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/{intent-dispatcher-NXBGPJOX.mjs → intent-dispatcher-MGOJ3CHD.mjs} +2 -2
- package/dist/lib/node-esm/{intent-resolver-2ZKXI5ET.mjs → intent-resolver-URF3HN3G.mjs} +7 -7
- package/dist/lib/node-esm/intent-resolver-URF3HN3G.mjs.map +7 -0
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/react/index.mjs +35 -0
- package/dist/lib/node-esm/{store-QQUTQHHT.mjs → store-RK5B4XEL.mjs} +5 -5
- package/dist/lib/node-esm/store-RK5B4XEL.mjs.map +7 -0
- package/dist/lib/node-esm/testing/index.mjs +14 -16
- package/dist/lib/node-esm/testing/index.mjs.map +3 -3
- package/dist/types/src/common/capabilities.d.ts +41 -37
- package/dist/types/src/common/capabilities.d.ts.map +1 -1
- package/dist/types/src/common/collaboration.d.ts +1 -1
- package/dist/types/src/common/collaboration.d.ts.map +1 -1
- package/dist/types/src/common/file.d.ts +1 -1
- package/dist/types/src/common/file.d.ts.map +1 -1
- package/dist/types/src/common/layout.d.ts +1 -3
- package/dist/types/src/common/layout.d.ts.map +1 -1
- package/dist/types/src/common/surface.d.ts +19 -16
- package/dist/types/src/common/surface.d.ts.map +1 -1
- package/dist/types/src/common/translations.d.ts +1 -1
- package/dist/types/src/common/translations.d.ts.map +1 -1
- package/dist/types/src/core/capabilities.d.ts +15 -15
- package/dist/types/src/core/capabilities.d.ts.map +1 -1
- package/dist/types/src/core/manager.d.ts +1 -1
- package/dist/types/src/core/manager.d.ts.map +1 -1
- package/dist/types/src/core/plugin.d.ts +8 -1
- package/dist/types/src/core/plugin.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +0 -2
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/playground/debug/plugin.d.ts +1 -1
- package/dist/types/src/playground/debug/plugin.d.ts.map +1 -1
- package/dist/types/src/playground/generator/Main.d.ts.map +1 -1
- package/dist/types/src/playground/generator/generator.d.ts +1 -1
- package/dist/types/src/playground/generator/generator.d.ts.map +1 -1
- package/dist/types/src/playground/generator/plugin.d.ts +1 -1
- package/dist/types/src/playground/generator/plugin.d.ts.map +1 -1
- package/dist/types/src/playground/layout/plugin.d.ts +1 -1
- package/dist/types/src/playground/layout/plugin.d.ts.map +1 -1
- package/dist/types/src/playground/logger/plugin.d.ts +1 -1
- package/dist/types/src/playground/logger/plugin.d.ts.map +1 -1
- package/dist/types/src/playground/logger/schema.d.ts +1 -1
- package/dist/types/src/playground/logger/schema.d.ts.map +1 -1
- package/dist/types/src/playground/playground.stories.d.ts +0 -1
- package/dist/types/src/playground/playground.stories.d.ts.map +1 -1
- package/dist/types/src/plugin-intent/IntentPlugin.d.ts +1 -1
- package/dist/types/src/plugin-intent/IntentPlugin.d.ts.map +1 -1
- package/dist/types/src/plugin-intent/actions.d.ts +5 -7
- package/dist/types/src/plugin-intent/actions.d.ts.map +1 -1
- package/dist/types/src/plugin-intent/errors.d.ts.map +1 -1
- package/dist/types/src/plugin-intent/intent-dispatcher.d.ts +4 -4
- package/dist/types/src/plugin-intent/intent-dispatcher.d.ts.map +1 -1
- package/dist/types/src/plugin-intent/intent.d.ts +1 -1
- package/dist/types/src/plugin-intent/intent.d.ts.map +1 -1
- package/dist/types/src/plugin-intent/meta.d.ts +3 -0
- package/dist/types/src/plugin-intent/meta.d.ts.map +1 -0
- package/dist/types/src/plugin-settings/SettingsPlugin.d.ts +1 -1
- package/dist/types/src/plugin-settings/SettingsPlugin.d.ts.map +1 -1
- package/dist/types/src/plugin-settings/actions.d.ts +5 -7
- package/dist/types/src/plugin-settings/actions.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/meta.d.ts +3 -0
- package/dist/types/src/plugin-settings/meta.d.ts.map +1 -0
- package/dist/types/src/plugin-settings/translations.d.ts +2 -1
- package/dist/types/src/plugin-settings/translations.d.ts.map +1 -1
- package/dist/types/src/react/App.d.ts.map +1 -0
- package/dist/types/src/{components → react}/App.stories.d.ts +0 -1
- package/dist/types/src/react/App.stories.d.ts.map +1 -0
- package/dist/types/src/react/DefaultFallback.d.ts.map +1 -0
- package/dist/types/src/react/ErrorBoundary.d.ts +2 -2
- package/dist/types/src/react/ErrorBoundary.d.ts.map +1 -1
- package/dist/types/src/react/Surface.d.ts +5 -5
- package/dist/types/src/react/Surface.d.ts.map +1 -1
- package/dist/types/src/react/Surface.stories.d.ts +3 -7
- package/dist/types/src/react/Surface.stories.d.ts.map +1 -1
- package/dist/types/src/react/index.d.ts +2 -0
- package/dist/types/src/react/index.d.ts.map +1 -1
- package/dist/types/src/react/types.d.ts +14 -0
- package/dist/types/src/react/types.d.ts.map +1 -0
- package/dist/types/src/{components → react}/useApp.d.ts +2 -2
- package/dist/types/src/react/useApp.d.ts.map +1 -0
- package/dist/types/src/react/useLoading.d.ts.map +1 -0
- package/dist/types/src/testing/withPluginManager.d.ts +6 -7
- package/dist/types/src/testing/withPluginManager.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/moon.yml +5 -1
- package/package.json +44 -40
- package/src/common/capabilities.ts +34 -19
- package/src/common/collaboration.ts +3 -3
- package/src/common/file.ts +1 -1
- package/src/common/layout.ts +3 -4
- package/src/common/surface.ts +23 -21
- package/src/common/translations.ts +1 -1
- package/src/core/capabilities.test.ts +2 -2
- package/src/core/capabilities.ts +26 -22
- package/src/core/manager.test.ts +19 -19
- package/src/core/manager.ts +14 -7
- package/src/core/plugin.ts +13 -2
- package/src/index.ts +0 -2
- package/src/playground/debug/plugin.ts +7 -8
- package/src/playground/generator/Main.tsx +0 -1
- package/src/playground/generator/generator.ts +2 -2
- package/src/playground/generator/plugin.ts +12 -13
- package/src/playground/layout/plugin.ts +9 -8
- package/src/playground/logger/plugin.ts +27 -23
- package/src/playground/logger/schema.ts +1 -1
- package/src/playground/playground.stories.tsx +6 -7
- package/src/plugin-intent/IntentPlugin.ts +12 -13
- package/src/plugin-intent/actions.ts +4 -6
- package/src/plugin-intent/errors.ts +2 -1
- package/src/plugin-intent/intent-dispatcher.test.ts +10 -3
- package/src/plugin-intent/intent-dispatcher.ts +13 -6
- package/src/plugin-intent/intent.ts +1 -1
- package/src/plugin-intent/meta.ts +10 -0
- package/src/plugin-settings/SettingsPlugin.ts +25 -27
- package/src/plugin-settings/actions.ts +9 -13
- package/src/plugin-settings/app-graph-builder.ts +22 -20
- package/src/plugin-settings/intent-resolver.ts +2 -2
- package/src/plugin-settings/meta.ts +10 -0
- package/src/plugin-settings/store.ts +2 -2
- package/src/plugin-settings/translations.ts +4 -4
- package/src/{components → react}/App.stories.tsx +1 -3
- package/src/{components → react}/App.tsx +1 -1
- package/src/{components → react}/DefaultFallback.tsx +1 -1
- package/src/react/ErrorBoundary.tsx +10 -8
- package/src/react/Surface.stories.tsx +70 -49
- package/src/react/Surface.tsx +67 -36
- package/src/react/index.ts +4 -0
- package/src/react/types.ts +37 -0
- package/src/{components → react}/useApp.tsx +23 -24
- package/src/react/useCapabilities.ts +2 -2
- package/src/testing/withPluginManager.stories.tsx +1 -1
- package/src/testing/withPluginManager.tsx +22 -21
- package/tsconfig.json +10 -1
- package/vitest.config.ts +8 -6
- package/dist/lib/browser/app-graph-builder-AFFC6VB2.mjs.map +0 -7
- package/dist/lib/browser/chunk-ORWHM7CO.mjs.map +0 -7
- package/dist/lib/browser/chunk-OZY7HV2A.mjs.map +0 -7
- package/dist/lib/browser/chunk-T6M7JB7M.mjs.map +0 -7
- package/dist/lib/browser/intent-resolver-4S4PSTM5.mjs.map +0 -7
- package/dist/lib/browser/store-6E33KLGK.mjs.map +0 -7
- package/dist/lib/browser/worker.mjs +0 -85
- package/dist/lib/node-esm/app-graph-builder-S4OAULX5.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-F63ZRXMK.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-HJFU7QOR.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-UMZQERLE.mjs.map +0 -7
- package/dist/lib/node-esm/intent-resolver-2ZKXI5ET.mjs.map +0 -7
- package/dist/lib/node-esm/store-QQUTQHHT.mjs.map +0 -7
- package/dist/lib/node-esm/worker.mjs +0 -86
- package/dist/types/src/components/App.d.ts.map +0 -1
- package/dist/types/src/components/App.stories.d.ts.map +0 -1
- package/dist/types/src/components/DefaultFallback.d.ts.map +0 -1
- package/dist/types/src/components/index.d.ts +0 -2
- package/dist/types/src/components/index.d.ts.map +0 -1
- package/dist/types/src/components/useApp.d.ts.map +0 -1
- package/dist/types/src/components/useLoading.d.ts.map +0 -1
- package/dist/types/src/worker.d.ts +0 -4
- package/dist/types/src/worker.d.ts.map +0 -1
- package/src/components/index.ts +0 -5
- package/src/worker.ts +0 -11
- /package/dist/lib/browser/{intent-dispatcher-QG7UPGQX.mjs.map → intent-dispatcher-LZ4AE66E.mjs.map} +0 -0
- /package/dist/lib/browser/{worker.mjs.map → react/index.mjs.map} +0 -0
- /package/dist/lib/node-esm/{intent-dispatcher-NXBGPJOX.mjs.map → intent-dispatcher-MGOJ3CHD.mjs.map} +0 -0
- /package/dist/lib/node-esm/{worker.mjs.map → react/index.mjs.map} +0 -0
- /package/dist/types/src/{components → react}/App.d.ts +0 -0
- /package/dist/types/src/{components → react}/DefaultFallback.d.ts +0 -0
- /package/dist/types/src/{components → react}/useLoading.d.ts +0 -0
- /package/src/{components → react}/useLoading.tsx +0 -0
|
@@ -2,8 +2,11 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import
|
|
6
|
-
import
|
|
5
|
+
import * as Effect from 'effect/Effect';
|
|
6
|
+
import * as Function from 'effect/Function';
|
|
7
|
+
import * as Option from 'effect/Option';
|
|
8
|
+
import * as Ref from 'effect/Ref';
|
|
9
|
+
import type * as Types from 'effect/Types';
|
|
7
10
|
|
|
8
11
|
import { live } from '@dxos/live-object';
|
|
9
12
|
import { log } from '@dxos/log';
|
|
@@ -132,7 +135,7 @@ export const createResolver = <Tag extends string, Fields extends IntentParams,
|
|
|
132
135
|
*/
|
|
133
136
|
export type PromiseIntentDispatcher = <Fields extends IntentParams>(
|
|
134
137
|
intent: IntentChain<any, any, any, Fields>,
|
|
135
|
-
) => Promise<Simplify<IntentDispatcherResult<IntentData<Fields>, IntentResultData<Fields>>>>;
|
|
138
|
+
) => Promise<Types.Simplify<IntentDispatcherResult<IntentData<Fields>, IntentResultData<Fields>>>>;
|
|
136
139
|
|
|
137
140
|
/**
|
|
138
141
|
* Creates an effect for intents.
|
|
@@ -141,7 +144,7 @@ export type IntentDispatcher = <Fields extends IntentParams>(
|
|
|
141
144
|
intent: IntentChain<any, any, any, Fields>,
|
|
142
145
|
depth?: number,
|
|
143
146
|
) => Effect.Effect<
|
|
144
|
-
Simplify<Required<IntentDispatcherResult<IntentData<Fields>, IntentResultData<Fields>>>['data']>,
|
|
147
|
+
Types.Simplify<Required<IntentDispatcherResult<IntentData<Fields>, IntentResultData<Fields>>>['data']>,
|
|
145
148
|
Error
|
|
146
149
|
>;
|
|
147
150
|
|
|
@@ -197,7 +200,6 @@ export const createDispatcher = (
|
|
|
197
200
|
.filter((resolver) => !resolver.filter || resolver.filter(intent.data))
|
|
198
201
|
.toSorted(byPosition);
|
|
199
202
|
if (candidates.length === 0) {
|
|
200
|
-
log.info('no resolvers found', { intent: intent.id });
|
|
201
203
|
return yield* Effect.fail(new NoResolversError(intent.id));
|
|
202
204
|
}
|
|
203
205
|
|
|
@@ -207,6 +209,7 @@ export const createDispatcher = (
|
|
|
207
209
|
});
|
|
208
210
|
|
|
209
211
|
const dispatch: IntentDispatcher = (intentChain, depth = 0) => {
|
|
212
|
+
log('dispatch', { intentChain: intentChain.all.map((i) => i.id), depth });
|
|
210
213
|
return Effect.gen(function* () {
|
|
211
214
|
if (depth > executionLimit) {
|
|
212
215
|
return yield* Effect.fail(new CycleDetectedError());
|
|
@@ -214,8 +217,10 @@ export const createDispatcher = (
|
|
|
214
217
|
|
|
215
218
|
const resultsRef = yield* Ref.make<AnyIntentResult[]>([]);
|
|
216
219
|
for (const intent of intentChain.all) {
|
|
220
|
+
log('processing', { intent });
|
|
217
221
|
const { data: prev } = (yield* resultsRef.get)[0] ?? {};
|
|
218
222
|
const result = yield* handleIntent({ ...intent, data: { ...intent.data, ...prev } });
|
|
223
|
+
log('ok', { intent: intent.id, result });
|
|
219
224
|
yield* Ref.update(resultsRef, (results) => [result, ...results]);
|
|
220
225
|
if (result.intents) {
|
|
221
226
|
for (const intent of result.intents) {
|
|
@@ -232,6 +237,7 @@ export const createDispatcher = (
|
|
|
232
237
|
// error: result.error.message,
|
|
233
238
|
// }),
|
|
234
239
|
// );
|
|
240
|
+
log.error('failed', { intent: intent.id, error: result.error });
|
|
235
241
|
return yield* Effect.fail(result.error);
|
|
236
242
|
}
|
|
237
243
|
}
|
|
@@ -253,7 +259,7 @@ export const createDispatcher = (
|
|
|
253
259
|
|
|
254
260
|
if (result.undoable && isUndoable(results)) {
|
|
255
261
|
// TODO(wittjosiah): Is there a better way to handle showing undo for chains?
|
|
256
|
-
yield* pipe(
|
|
262
|
+
yield* Function.pipe(
|
|
257
263
|
dispatch(createIntent(IntentAction.ShowUndo, { message: result.undoable.message })),
|
|
258
264
|
Effect.catchSome((err) =>
|
|
259
265
|
err instanceof NoResolversError ? Option.some(Effect.succeed(undefined)) : Option.none(),
|
|
@@ -261,6 +267,7 @@ export const createDispatcher = (
|
|
|
261
267
|
);
|
|
262
268
|
}
|
|
263
269
|
|
|
270
|
+
log('done', { intent: intentChain.all.map((i) => i.id), result: result.data });
|
|
264
271
|
return result.data;
|
|
265
272
|
});
|
|
266
273
|
};
|
|
@@ -5,32 +5,30 @@
|
|
|
5
5
|
import { Capabilities, Events } from '../common';
|
|
6
6
|
import { contributes, defineModule, definePlugin, lazy } from '../core';
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import { meta } from './meta';
|
|
9
9
|
import { translations } from './translations';
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}),
|
|
36
|
-
]);
|
|
11
|
+
export const SettingsPlugin = definePlugin(meta, () => [
|
|
12
|
+
defineModule({
|
|
13
|
+
id: `${meta.id}/module/store`,
|
|
14
|
+
activatesOn: Events.Startup,
|
|
15
|
+
activatesBefore: [Events.SetupSettings],
|
|
16
|
+
activatesAfter: [Events.SettingsReady],
|
|
17
|
+
activate: lazy(() => import('./store')),
|
|
18
|
+
}),
|
|
19
|
+
defineModule({
|
|
20
|
+
id: `${meta.id}/module/translations`,
|
|
21
|
+
activatesOn: Events.SetupTranslations,
|
|
22
|
+
activate: () => contributes(Capabilities.Translations, translations),
|
|
23
|
+
}),
|
|
24
|
+
defineModule({
|
|
25
|
+
id: `${meta.id}/module/intent-resolver`,
|
|
26
|
+
activatesOn: Events.SetupIntentResolver,
|
|
27
|
+
activate: lazy(() => import('./intent-resolver')),
|
|
28
|
+
}),
|
|
29
|
+
defineModule({
|
|
30
|
+
id: `${meta.id}/module/app-graph-builder`,
|
|
31
|
+
activatesOn: Events.SetupAppGraph,
|
|
32
|
+
activate: lazy(() => import('./app-graph-builder')),
|
|
33
|
+
}),
|
|
34
|
+
]);
|
|
@@ -2,28 +2,24 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import * as Schema from 'effect/Schema';
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
// TODO(
|
|
10
|
-
// Ideally this should be worked into the data model in a generic way.
|
|
7
|
+
import { meta } from './meta';
|
|
8
|
+
|
|
9
|
+
// TODO(burdon): Document.
|
|
11
10
|
export const SETTINGS_ID = '!dxos:settings';
|
|
12
11
|
export const SETTINGS_KEY = 'settings';
|
|
13
12
|
|
|
14
13
|
export namespace SettingsAction {
|
|
15
|
-
export class Open extends Schema.TaggedClass<Open>()(`${
|
|
14
|
+
export class Open extends Schema.TaggedClass<Open>()(`${meta.id}/open`, {
|
|
16
15
|
input: Schema.Struct({
|
|
17
16
|
plugin: Schema.optional(Schema.String),
|
|
18
17
|
}),
|
|
19
18
|
output: Schema.Void,
|
|
20
19
|
}) {}
|
|
21
20
|
|
|
22
|
-
export class OpenPluginRegistry extends Schema.TaggedClass<OpenPluginRegistry>()(
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
output: Schema.Void,
|
|
27
|
-
},
|
|
28
|
-
) {}
|
|
21
|
+
export class OpenPluginRegistry extends Schema.TaggedClass<OpenPluginRegistry>()(`${meta.id}/open-plugin-registry`, {
|
|
22
|
+
input: Schema.Void,
|
|
23
|
+
output: Schema.Void,
|
|
24
|
+
}) {}
|
|
29
25
|
}
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
5
|
+
import { Atom } from '@effect-atom/atom-react';
|
|
6
|
+
import * as Function from 'effect/Function';
|
|
7
|
+
import * as Option from 'effect/Option';
|
|
7
8
|
|
|
8
9
|
import { ROOT_ID, createExtension } from '@dxos/app-graph';
|
|
9
10
|
import { type SettingsStore, type SettingsValue } from '@dxos/local-storage';
|
|
@@ -13,26 +14,27 @@ import { Capabilities } from '../common';
|
|
|
13
14
|
import { type PluginContext, type PluginMeta, contributes } from '../core';
|
|
14
15
|
import { createIntent } from '../plugin-intent';
|
|
15
16
|
|
|
16
|
-
import { SETTINGS_ID, SETTINGS_KEY,
|
|
17
|
+
import { SETTINGS_ID, SETTINGS_KEY, SettingsAction } from './actions';
|
|
18
|
+
import { meta } from './meta';
|
|
17
19
|
|
|
18
20
|
export default (context: PluginContext) =>
|
|
19
21
|
contributes(Capabilities.AppGraphBuilder, [
|
|
20
22
|
createExtension({
|
|
21
|
-
id: `${
|
|
23
|
+
id: `${meta.id}/action`,
|
|
22
24
|
actions: (node) =>
|
|
23
|
-
|
|
24
|
-
pipe(
|
|
25
|
+
Atom.make((get) =>
|
|
26
|
+
Function.pipe(
|
|
25
27
|
get(node),
|
|
26
28
|
Option.flatMap((node) => (node.id === ROOT_ID ? Option.some(node) : Option.none())),
|
|
27
29
|
Option.map(() => [
|
|
28
30
|
{
|
|
29
|
-
id:
|
|
31
|
+
id: meta.id,
|
|
30
32
|
data: async () => {
|
|
31
33
|
const { dispatchPromise: dispatch } = context.getCapability(Capabilities.IntentDispatcher);
|
|
32
34
|
await dispatch(createIntent(SettingsAction.Open));
|
|
33
35
|
},
|
|
34
36
|
properties: {
|
|
35
|
-
label: ['open settings label', { ns:
|
|
37
|
+
label: ['open settings label', { ns: meta.id }],
|
|
36
38
|
icon: 'ph--gear--regular',
|
|
37
39
|
disposition: 'menu',
|
|
38
40
|
keyBinding: {
|
|
@@ -47,18 +49,18 @@ export default (context: PluginContext) =>
|
|
|
47
49
|
),
|
|
48
50
|
}),
|
|
49
51
|
createExtension({
|
|
50
|
-
id: `${
|
|
52
|
+
id: `${meta.id}/core`,
|
|
51
53
|
connector: (node) =>
|
|
52
|
-
|
|
53
|
-
pipe(
|
|
54
|
+
Atom.make((get) =>
|
|
55
|
+
Function.pipe(
|
|
54
56
|
get(node),
|
|
55
57
|
Option.flatMap((node) => (node.id === ROOT_ID ? Option.some(node) : Option.none())),
|
|
56
58
|
Option.map(() => [
|
|
57
59
|
{
|
|
58
60
|
id: SETTINGS_ID,
|
|
59
|
-
type:
|
|
61
|
+
type: meta.id,
|
|
60
62
|
properties: {
|
|
61
|
-
label: ['app settings label', { ns:
|
|
63
|
+
label: ['app settings label', { ns: meta.id }],
|
|
62
64
|
icon: 'ph--gear--regular',
|
|
63
65
|
disposition: 'pin-end',
|
|
64
66
|
position: 'hoist',
|
|
@@ -71,10 +73,10 @@ export default (context: PluginContext) =>
|
|
|
71
73
|
),
|
|
72
74
|
}),
|
|
73
75
|
createExtension({
|
|
74
|
-
id: `${
|
|
76
|
+
id: `${meta.id}/core-plugins`,
|
|
75
77
|
connector: (node) =>
|
|
76
|
-
|
|
77
|
-
pipe(
|
|
78
|
+
Atom.make((get) =>
|
|
79
|
+
Function.pipe(
|
|
78
80
|
get(node),
|
|
79
81
|
Option.flatMap((node) => (node.id !== SETTINGS_ID ? Option.none() : Option.some(node))),
|
|
80
82
|
Option.map(() => {
|
|
@@ -106,7 +108,7 @@ export default (context: PluginContext) =>
|
|
|
106
108
|
id: `${SETTINGS_KEY}:custom-plugins`,
|
|
107
109
|
type: 'category',
|
|
108
110
|
properties: {
|
|
109
|
-
label: ['custom plugins label', { ns:
|
|
111
|
+
label: ['custom plugins label', { ns: meta.id }],
|
|
110
112
|
icon: 'ph--squares-four--regular',
|
|
111
113
|
role: 'branch',
|
|
112
114
|
disposition: 'collection',
|
|
@@ -119,10 +121,10 @@ export default (context: PluginContext) =>
|
|
|
119
121
|
),
|
|
120
122
|
}),
|
|
121
123
|
createExtension({
|
|
122
|
-
id: `${
|
|
124
|
+
id: `${meta.id}/custom-plugins`,
|
|
123
125
|
connector: (node) =>
|
|
124
|
-
|
|
125
|
-
pipe(
|
|
126
|
+
Atom.make((get) =>
|
|
127
|
+
Function.pipe(
|
|
126
128
|
get(node),
|
|
127
129
|
Option.flatMap((node) =>
|
|
128
130
|
node.id !== `${SETTINGS_KEY}:custom-plugins` ? Option.none() : Option.some(node),
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import * as Function from 'effect/Function';
|
|
6
6
|
|
|
7
7
|
import { Capabilities, LayoutAction } from '../common';
|
|
8
8
|
import { contributes } from '../core';
|
|
@@ -20,7 +20,7 @@ export default () =>
|
|
|
20
20
|
return {
|
|
21
21
|
intents: [
|
|
22
22
|
plugin
|
|
23
|
-
? pipe(
|
|
23
|
+
? Function.pipe(
|
|
24
24
|
openSettings,
|
|
25
25
|
chain(LayoutAction.Open, {
|
|
26
26
|
part: 'main',
|
|
@@ -8,11 +8,11 @@ import { Capabilities } from '../common';
|
|
|
8
8
|
import { type PluginContext, contributes } from '../core';
|
|
9
9
|
|
|
10
10
|
export default (context: PluginContext) => {
|
|
11
|
-
// TODO(wittjosiah): Replace with
|
|
11
|
+
// TODO(wittjosiah): Replace with atom?
|
|
12
12
|
const settingsStore = new RootSettingsStore();
|
|
13
13
|
|
|
14
14
|
let previous: Capabilities.Settings[] = [];
|
|
15
|
-
const registry = context.getCapability(Capabilities.
|
|
15
|
+
const registry = context.getCapability(Capabilities.AtomRegistry);
|
|
16
16
|
const cancel = registry.subscribe(
|
|
17
17
|
context.capabilities(Capabilities.Settings),
|
|
18
18
|
(allSettings) => {
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
//
|
|
2
|
-
// Copyright
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { type Resource } from '
|
|
5
|
+
import { type Resource } from '../common';
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import { meta } from './meta';
|
|
8
8
|
|
|
9
9
|
export const translations = [
|
|
10
10
|
{
|
|
11
11
|
'en-US': {
|
|
12
|
-
[
|
|
12
|
+
[meta.id]: {
|
|
13
13
|
'open settings label': 'Open settings',
|
|
14
14
|
'app settings label': 'Settings',
|
|
15
15
|
'custom plugins label': 'Plugins',
|
|
@@ -2,12 +2,10 @@
|
|
|
2
2
|
// Copyright 2022 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import '@dxos-theme';
|
|
6
|
-
|
|
7
5
|
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
8
6
|
import React from 'react';
|
|
9
7
|
|
|
10
|
-
import { withTheme } from '@dxos/
|
|
8
|
+
import { withTheme } from '@dxos/react-ui/testing';
|
|
11
9
|
|
|
12
10
|
import { useApp } from './useApp';
|
|
13
11
|
|
|
@@ -6,9 +6,9 @@ import React, { type PropsWithChildren } from 'react';
|
|
|
6
6
|
|
|
7
7
|
import { Capabilities } from '../common';
|
|
8
8
|
import { topologicalSort } from '../helpers';
|
|
9
|
-
import { useCapabilities } from '../react';
|
|
10
9
|
|
|
11
10
|
import { type UseAppOptions } from './useApp';
|
|
11
|
+
import { useCapabilities } from './useCapabilities';
|
|
12
12
|
import { LoadingState, useLoading } from './useLoading';
|
|
13
13
|
|
|
14
14
|
export type AppProps = Pick<UseAppOptions, 'placeholder' | 'debounce'> & {
|
|
@@ -19,7 +19,7 @@ export const DefaultFallback = ({ error }: { error: Error }) => {
|
|
|
19
19
|
}}
|
|
20
20
|
>
|
|
21
21
|
{/* TODO(wittjosiah): Link to docs for replacing default. */}
|
|
22
|
-
<h1 style={{ margin: '0.5rem 0', fontSize: '1.2rem' }}>
|
|
22
|
+
<h1 style={{ margin: '0.5rem 0', fontSize: '1.2rem' }}>ERROR: {error.message}</h1>
|
|
23
23
|
<pre style={{ overflow: 'auto', fontSize: '1rem', whiteSpace: 'pre-wrap', color: '#888888' }}>{error.stack}</pre>
|
|
24
24
|
</div>
|
|
25
25
|
);
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import React, { Component, type FC, type
|
|
5
|
+
import React, { Component, type FC, type PropsWithChildren, type ReactNode } from 'react';
|
|
6
6
|
|
|
7
7
|
type State = {
|
|
8
8
|
error: Error | undefined;
|
|
@@ -32,7 +32,7 @@ export class ErrorBoundary extends Component<ErrorBoundaryProps, State> {
|
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
override render():
|
|
35
|
+
override render(): ReactNode {
|
|
36
36
|
if (this.state.error) {
|
|
37
37
|
const Fallback = this.props.fallback ?? DefaultFallback;
|
|
38
38
|
return <Fallback data={this.props.data} error={this.state.error} />;
|
|
@@ -46,9 +46,11 @@ export class ErrorBoundary extends Component<ErrorBoundaryProps, State> {
|
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
const DefaultFallback: NonNullable<ErrorBoundaryProps['fallback']> = ({ data, error }) =>
|
|
50
|
-
|
|
51
|
-
<
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
49
|
+
const DefaultFallback: NonNullable<ErrorBoundaryProps['fallback']> = ({ data, error }) => {
|
|
50
|
+
return (
|
|
51
|
+
<div className='flex flex-col gap-2 overflow-hidden border border-red-500 rounded-sm'>
|
|
52
|
+
<h1 className='p-2'>ERROR: {error.message}</h1>
|
|
53
|
+
<pre className='p-2 overflow-y-auto text-sm text-subdued'>{JSON.stringify(data, null, 2)}</pre>
|
|
54
|
+
</div>
|
|
55
|
+
);
|
|
56
|
+
};
|
|
@@ -2,98 +2,119 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import '@dxos-theme';
|
|
6
|
-
|
|
7
5
|
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
8
|
-
import React, { useCallback, useState } from 'react';
|
|
6
|
+
import React, { useCallback, useEffect, useState } from 'react';
|
|
9
7
|
|
|
10
8
|
import { faker } from '@dxos/random';
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
9
|
+
import { List, ListItem, Toolbar } from '@dxos/react-ui';
|
|
10
|
+
import { withTheme } from '@dxos/react-ui/testing';
|
|
11
|
+
import { getHashStyles, mx } from '@dxos/react-ui-theme';
|
|
13
12
|
|
|
14
13
|
import { Capabilities, createSurface } from '../common';
|
|
15
|
-
import {
|
|
16
|
-
import { setupPluginManager } from '../testing';
|
|
14
|
+
import { withPluginManager } from '../testing';
|
|
17
15
|
|
|
18
|
-
import {
|
|
16
|
+
import { usePluginManager } from './PluginManagerProvider';
|
|
19
17
|
import { Surface, useSurfaces } from './Surface';
|
|
20
18
|
|
|
21
|
-
const
|
|
22
|
-
const
|
|
23
|
-
const saturation = faker.number.int({ min: 50, max: 90 });
|
|
24
|
-
const lightness = faker.number.int({ min: 40, max: 70 });
|
|
25
|
-
return `hsl(${hue}, ${saturation}%, ${lightness}%)`;
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
const Component = () => {
|
|
19
|
+
const DefaultStory = () => {
|
|
20
|
+
const [selected, setSelected] = useState<string | undefined>();
|
|
29
21
|
const manager = usePluginManager();
|
|
30
22
|
const surfaces = useSurfaces();
|
|
31
|
-
const [picked, setPicked] = useState('test');
|
|
32
23
|
|
|
33
24
|
const handleAdd = useCallback(() => {
|
|
34
|
-
const id = `test-${faker.number.int({ min: 0, max:
|
|
35
|
-
const
|
|
25
|
+
const id = `test-${faker.number.int({ min: 0, max: 1_000 })}`;
|
|
26
|
+
const styles = getHashStyles(id);
|
|
36
27
|
|
|
37
28
|
manager.context.contributeCapability({
|
|
38
29
|
module: 'test',
|
|
39
30
|
interface: Capabilities.ReactSurface,
|
|
40
31
|
implementation: createSurface({
|
|
41
32
|
id,
|
|
42
|
-
role:
|
|
33
|
+
role: 'item',
|
|
34
|
+
filter: (data): data is any => (data as any)?.id === id,
|
|
43
35
|
component: () => (
|
|
44
|
-
<div className='flex-
|
|
45
|
-
{id}
|
|
36
|
+
<div className={mx('flex justify-center items-center border rounded', styles.surface, styles.border)}>
|
|
37
|
+
<span className={mx('dx-tag font-mono text-lg', styles.text)}>{id}</span>
|
|
46
38
|
</div>
|
|
47
39
|
),
|
|
48
40
|
}),
|
|
49
41
|
});
|
|
50
42
|
|
|
51
|
-
|
|
43
|
+
setSelected(id);
|
|
52
44
|
}, [manager]);
|
|
53
45
|
|
|
54
|
-
const
|
|
55
|
-
|
|
46
|
+
const handleSelect = useCallback(() => {
|
|
47
|
+
setSelected(faker.helpers.arrayElement(surfaces)?.id);
|
|
56
48
|
}, [surfaces]);
|
|
57
49
|
|
|
50
|
+
const handleError = useCallback(() => {
|
|
51
|
+
manager.context.contributeCapability({
|
|
52
|
+
module: 'error',
|
|
53
|
+
interface: Capabilities.ReactSurface,
|
|
54
|
+
implementation: createSurface({
|
|
55
|
+
id: 'error',
|
|
56
|
+
role: 'item',
|
|
57
|
+
filter: (data): data is any => (data as any)?.id === 'error',
|
|
58
|
+
component: () => {
|
|
59
|
+
const [count, setCount] = useState(3);
|
|
60
|
+
useEffect(() => {
|
|
61
|
+
const interval = setInterval(() => {
|
|
62
|
+
setCount((count) => {
|
|
63
|
+
if (count <= 1) {
|
|
64
|
+
clearInterval(interval);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return count - 1;
|
|
68
|
+
});
|
|
69
|
+
}, 1_000);
|
|
70
|
+
return () => clearInterval(interval);
|
|
71
|
+
}, []);
|
|
72
|
+
|
|
73
|
+
if (count <= 0) {
|
|
74
|
+
throw new Error('BANG!');
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return (
|
|
78
|
+
<div className='flex justify-center items-center border border-roseFill rounded'>
|
|
79
|
+
<span className='font-mono'>Ticking... {count}</span>
|
|
80
|
+
</div>
|
|
81
|
+
);
|
|
82
|
+
},
|
|
83
|
+
}),
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
setSelected('error');
|
|
87
|
+
}, [manager]);
|
|
88
|
+
|
|
58
89
|
return (
|
|
59
|
-
<div className='flex flex-col
|
|
60
|
-
<
|
|
61
|
-
<Button onClick={handleAdd}>Add</Button>
|
|
62
|
-
<Button onClick={
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
90
|
+
<div className='flex flex-col bs-full overflow-hidden'>
|
|
91
|
+
<Toolbar.Root>
|
|
92
|
+
<Toolbar.Button onClick={handleAdd}>Add</Toolbar.Button>
|
|
93
|
+
<Toolbar.Button onClick={handleSelect}>Pick</Toolbar.Button>
|
|
94
|
+
<Toolbar.Button onClick={handleError}>Error</Toolbar.Button>
|
|
95
|
+
</Toolbar.Root>
|
|
96
|
+
<div className='grid grid-cols-2 bs-full gap-4 overflow-hidden'>
|
|
97
|
+
<Surface role='item' data={selected ? { id: selected } : undefined} limit={1} />
|
|
98
|
+
<div className='overflow-y-auto bs-full'>
|
|
99
|
+
<List>
|
|
67
100
|
{surfaces.map((surface) => (
|
|
68
101
|
<ListItem.Root key={surface.id} id={surface.id}>
|
|
69
|
-
<ListItem.Heading classNames='
|
|
102
|
+
<ListItem.Heading classNames='flex items-center'>{surface.id}</ListItem.Heading>
|
|
70
103
|
</ListItem.Root>
|
|
71
104
|
))}
|
|
72
105
|
</List>
|
|
73
106
|
</div>
|
|
74
|
-
<div className='flex-1'>
|
|
75
|
-
<Surface role={picked} limit={1} />
|
|
76
|
-
</div>
|
|
77
107
|
</div>
|
|
78
108
|
</div>
|
|
79
109
|
);
|
|
80
110
|
};
|
|
81
111
|
|
|
82
|
-
const DefaultStory = (props: { manager: PluginManager }) => {
|
|
83
|
-
return (
|
|
84
|
-
<PluginManagerProvider value={props.manager}>
|
|
85
|
-
<Component />
|
|
86
|
-
</PluginManagerProvider>
|
|
87
|
-
);
|
|
88
|
-
};
|
|
89
|
-
|
|
90
112
|
const meta = {
|
|
91
113
|
title: 'sdk/app-framework/Surface',
|
|
92
114
|
render: DefaultStory,
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
manager: setupPluginManager(),
|
|
115
|
+
decorators: [withTheme, withPluginManager({ capabilities: [] })],
|
|
116
|
+
parameters: {
|
|
117
|
+
layout: 'fullscreen',
|
|
97
118
|
},
|
|
98
119
|
} satisfies Meta<typeof DefaultStory>;
|
|
99
120
|
|