@dxos/app-framework 0.7.5-main.9d2a38b → 0.7.5-main.b19bfc8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/browser/app-graph-builder-S4MYSHQA.mjs +137 -0
- package/dist/lib/browser/app-graph-builder-S4MYSHQA.mjs.map +7 -0
- package/dist/lib/browser/{chunk-GNLU3GAU.mjs → chunk-BCMEJONP.mjs} +660 -823
- package/dist/lib/browser/chunk-BCMEJONP.mjs.map +7 -0
- package/dist/lib/browser/chunk-QS4J6O47.mjs +285 -0
- package/dist/lib/browser/chunk-QS4J6O47.mjs.map +7 -0
- package/dist/lib/browser/chunk-SRZH2PQ2.mjs +32 -0
- package/dist/lib/browser/chunk-SRZH2PQ2.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +57 -74
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/intent-dispatcher-GFBH7T2J.mjs +11 -0
- package/dist/lib/browser/intent-dispatcher-GFBH7T2J.mjs.map +7 -0
- package/dist/lib/browser/intent-resolver-KAFM7CQH.mjs +39 -0
- package/dist/lib/browser/intent-resolver-KAFM7CQH.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/store-L3VRR7II.mjs +29 -0
- package/dist/lib/browser/store-L3VRR7II.mjs.map +7 -0
- package/dist/lib/browser/testing/index.mjs +10 -3
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/browser/worker.mjs +77 -0
- package/dist/lib/browser/worker.mjs.map +7 -0
- package/dist/lib/node/app-graph-builder-VMHWFCTP.cjs +146 -0
- package/dist/lib/node/app-graph-builder-VMHWFCTP.cjs.map +7 -0
- package/dist/lib/node/chunk-7Y6KJ3OK.cjs +1466 -0
- package/dist/lib/node/chunk-7Y6KJ3OK.cjs.map +7 -0
- package/dist/lib/node/chunk-B65NJEIJ.cjs +308 -0
- package/dist/lib/node/chunk-B65NJEIJ.cjs.map +7 -0
- package/dist/lib/node/chunk-VCIHQZSN.cjs +58 -0
- package/dist/lib/node/chunk-VCIHQZSN.cjs.map +7 -0
- package/dist/lib/node/index.cjs +106 -118
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/intent-dispatcher-PRCC4KZT.cjs +32 -0
- package/dist/lib/node/intent-dispatcher-PRCC4KZT.cjs.map +7 -0
- package/dist/lib/node/intent-resolver-OZDKCHPW.cjs +46 -0
- package/dist/lib/node/intent-resolver-OZDKCHPW.cjs.map +7 -0
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/store-BVUKNVKL.cjs +44 -0
- package/dist/lib/node/store-BVUKNVKL.cjs.map +7 -0
- package/dist/lib/node/testing/index.cjs +15 -8
- package/dist/lib/node/testing/index.cjs.map +3 -3
- package/dist/lib/node/worker.cjs +99 -0
- package/dist/lib/node/worker.cjs.map +7 -0
- package/dist/lib/node-esm/app-graph-builder-XHI5IIXQ.mjs +138 -0
- package/dist/lib/node-esm/app-graph-builder-XHI5IIXQ.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-CBT75GCX.mjs +34 -0
- package/dist/lib/node-esm/chunk-CBT75GCX.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-JDAHZRYQ.mjs +286 -0
- package/dist/lib/node-esm/chunk-JDAHZRYQ.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-KPMTPXQI.mjs → chunk-TVIR2PHY.mjs} +660 -823
- package/dist/lib/node-esm/chunk-TVIR2PHY.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +57 -74
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/intent-dispatcher-LGACN32C.mjs +12 -0
- package/dist/lib/node-esm/intent-dispatcher-LGACN32C.mjs.map +7 -0
- package/dist/lib/node-esm/intent-resolver-RBNG76ZX.mjs +40 -0
- package/dist/lib/node-esm/intent-resolver-RBNG76ZX.mjs.map +7 -0
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/store-PHTOEREN.mjs +30 -0
- package/dist/lib/node-esm/store-PHTOEREN.mjs.map +7 -0
- package/dist/lib/node-esm/testing/index.mjs +10 -3
- package/dist/lib/node-esm/testing/index.mjs.map +3 -3
- package/dist/lib/node-esm/worker.mjs +78 -0
- package/dist/lib/node-esm/worker.mjs.map +7 -0
- package/dist/types/src/App.d.ts +2 -2
- package/dist/types/src/App.d.ts.map +1 -1
- package/dist/types/src/common/capabilities.d.ts +88 -124
- package/dist/types/src/common/capabilities.d.ts.map +1 -1
- package/dist/types/src/common/events.d.ts +22 -11
- package/dist/types/src/common/events.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/graph.d.ts +2 -2
- package/dist/types/src/common/graph.d.ts.map +1 -1
- package/dist/types/src/common/index.d.ts +0 -1
- package/dist/types/src/common/index.d.ts.map +1 -1
- package/dist/types/src/common/layout.d.ts +218 -121
- package/dist/types/src/common/layout.d.ts.map +1 -1
- package/dist/types/src/common/surface.d.ts +3 -3
- package/dist/types/src/common/surface.d.ts.map +1 -1
- package/dist/types/src/common/translations.d.ts +7 -7
- package/dist/types/src/common/translations.d.ts.map +1 -1
- package/dist/types/src/core/capabilities.d.ts +6 -2
- package/dist/types/src/core/capabilities.d.ts.map +1 -1
- package/dist/types/src/core/manager.d.ts +2 -9
- package/dist/types/src/core/manager.d.ts.map +1 -1
- package/dist/types/src/core/plugin.d.ts +5 -2
- package/dist/types/src/core/plugin.d.ts.map +1 -1
- package/dist/types/src/playground/debug/Debug.d.ts +2 -3
- package/dist/types/src/playground/debug/Debug.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 +2 -3
- package/dist/types/src/playground/generator/Main.d.ts.map +1 -1
- package/dist/types/src/playground/generator/Toolbar.d.ts +2 -3
- package/dist/types/src/playground/generator/Toolbar.d.ts.map +1 -1
- package/dist/types/src/playground/generator/generator.d.ts +5 -3
- 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/Layout.d.ts +2 -2
- package/dist/types/src/playground/layout/Layout.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/Toolbar.d.ts +2 -3
- package/dist/types/src/playground/logger/Toolbar.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 +2 -3
- 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 +1 -1
- package/dist/types/src/plugin-intent/actions.d.ts.map +1 -1
- package/dist/types/src/plugin-intent/index.d.ts +0 -1
- package/dist/types/src/plugin-intent/index.d.ts.map +1 -1
- package/dist/types/src/plugin-intent/intent-dispatcher.d.ts +27 -20
- package/dist/types/src/plugin-intent/intent-dispatcher.d.ts.map +1 -1
- package/dist/types/src/plugin-intent/intent.d.ts +3 -3
- package/dist/types/src/plugin-intent/intent.d.ts.map +1 -1
- 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 +11 -1
- package/dist/types/src/plugin-settings/actions.d.ts.map +1 -1
- package/dist/types/src/plugin-settings/app-graph-builder.d.ts +197 -0
- package/dist/types/src/plugin-settings/app-graph-builder.d.ts.map +1 -0
- package/dist/types/src/plugin-settings/intent-resolver.d.ts +4 -0
- package/dist/types/src/plugin-settings/intent-resolver.d.ts.map +1 -0
- package/dist/types/src/plugin-settings/store.d.ts +5 -0
- package/dist/types/src/plugin-settings/store.d.ts.map +1 -0
- package/dist/types/src/plugin-settings/translations.d.ts +11 -0
- package/dist/types/src/plugin-settings/translations.d.ts.map +1 -0
- package/dist/types/src/react/ErrorBoundary.d.ts +1 -1
- package/dist/types/src/{plugin-intent → react}/IntentContext.d.ts +1 -1
- package/dist/types/src/react/IntentContext.d.ts.map +1 -0
- package/dist/types/src/react/Surface.d.ts.map +1 -1
- package/dist/types/src/react/Surface.stories.d.ts +15 -0
- package/dist/types/src/react/Surface.stories.d.ts.map +1 -0
- package/dist/types/src/react/common.d.ts +13 -0
- package/dist/types/src/react/common.d.ts.map +1 -0
- 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/useCapabilities.d.ts.map +1 -1
- package/dist/types/src/react/useIntentResolver.d.ts +3 -0
- package/dist/types/src/react/useIntentResolver.d.ts.map +1 -0
- package/dist/types/src/testing/withPluginManager.d.ts +1 -1
- package/dist/types/src/testing/withPluginManager.d.ts.map +1 -1
- package/dist/types/src/worker.d.ts +4 -0
- package/dist/types/src/worker.d.ts.map +1 -0
- package/package.json +29 -21
- package/project.json +4 -3
- package/src/App.tsx +17 -15
- package/src/common/capabilities.ts +30 -11
- package/src/common/events.ts +16 -2
- package/src/common/file.ts +1 -1
- package/src/common/graph.ts +2 -2
- package/src/common/index.ts +0 -1
- package/src/common/layout.ts +207 -126
- package/src/common/surface.ts +2 -2
- package/src/common/translations.ts +7 -8
- package/src/core/capabilities.ts +16 -7
- package/src/core/manager.test.ts +22 -73
- package/src/core/manager.ts +105 -91
- package/src/core/plugin.ts +6 -3
- package/src/playground/debug/plugin.ts +1 -1
- package/src/playground/generator/Toolbar.tsx +11 -11
- package/src/playground/generator/generator.ts +25 -0
- package/src/playground/generator/plugin.ts +6 -1
- package/src/playground/layout/plugin.ts +1 -1
- package/src/playground/logger/Toolbar.tsx +2 -1
- package/src/playground/logger/plugin.ts +7 -4
- package/src/playground/logger/schema.ts +1 -1
- package/src/plugin-intent/IntentPlugin.tsx +3 -43
- package/src/plugin-intent/actions.ts +1 -1
- package/src/plugin-intent/errors.ts +1 -1
- package/src/plugin-intent/index.ts +0 -1
- package/src/plugin-intent/intent-dispatcher.test.ts +48 -29
- package/src/plugin-intent/intent-dispatcher.ts +81 -42
- package/src/plugin-intent/intent.ts +5 -5
- package/src/plugin-settings/SettingsPlugin.ts +19 -13
- package/src/plugin-settings/actions.ts +11 -1
- package/src/plugin-settings/app-graph-builder.ts +122 -0
- package/src/plugin-settings/intent-resolver.ts +34 -0
- package/src/plugin-settings/store.ts +30 -0
- package/src/plugin-settings/translations.ts +17 -0
- package/src/{plugin-intent → react}/IntentContext.tsx +2 -2
- package/src/react/Surface.stories.tsx +96 -0
- package/src/react/Surface.tsx +11 -8
- package/src/react/common.ts +12 -0
- package/src/react/index.ts +2 -0
- package/src/react/useCapabilities.ts +1 -0
- package/src/react/useIntentResolver.ts +22 -0
- package/src/testing/withPluginManager.tsx +11 -3
- package/src/worker.ts +11 -0
- package/tsconfig.json +7 -13
- package/dist/lib/browser/chunk-GNLU3GAU.mjs.map +0 -7
- package/dist/lib/node/chunk-FBA4BB3J.cjs +0 -1639
- package/dist/lib/node/chunk-FBA4BB3J.cjs.map +0 -7
- package/dist/lib/node-esm/chunk-KPMTPXQI.mjs.map +0 -7
- package/dist/types/src/common/navigation.d.ts +0 -241
- package/dist/types/src/common/navigation.d.ts.map +0 -1
- package/dist/types/src/plugin-intent/IntentContext.d.ts.map +0 -1
- package/src/common/navigation.ts +0 -199
- /package/{.eslintrc.js → .eslintrc.cjs} +0 -0
|
@@ -2,11 +2,10 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import { Schema as S } from '@effect/schema';
|
|
5
6
|
import { Effect, Fiber, pipe } from 'effect';
|
|
6
7
|
import { describe, expect, test } from 'vitest';
|
|
7
8
|
|
|
8
|
-
import { S } from '@dxos/echo-schema';
|
|
9
|
-
|
|
10
9
|
import { chain, createIntent } from './intent';
|
|
11
10
|
import { type AnyIntentResolver, createDispatcher, createResolver } from './intent-dispatcher';
|
|
12
11
|
|
|
@@ -108,8 +107,8 @@ describe('Intent dispatcher', () => {
|
|
|
108
107
|
const { dispatch } = createDispatcher(() => [computeResolver, toStringResolver, concatResolver]);
|
|
109
108
|
const intent = pipe(createIntent(Compute, { value: 1 }), chain(ToString, {}), chain(Concat, { plus: '!' }));
|
|
110
109
|
|
|
111
|
-
expect(intent.first.
|
|
112
|
-
expect(intent.last.
|
|
110
|
+
expect(intent.first.id).toBe(Compute._tag);
|
|
111
|
+
expect(intent.last.id).toBe(Concat._tag);
|
|
113
112
|
expect(intent.all.length).toBe(3);
|
|
114
113
|
|
|
115
114
|
const program = Effect.gen(function* () {
|
|
@@ -137,7 +136,10 @@ describe('Intent dispatcher', () => {
|
|
|
137
136
|
});
|
|
138
137
|
|
|
139
138
|
test('filter resolvers by plugin', async () => {
|
|
140
|
-
const otherComputeResolver = createResolver(
|
|
139
|
+
const otherComputeResolver = createResolver({
|
|
140
|
+
intent: Compute,
|
|
141
|
+
resolve: async (data) => ({ data: { value: data?.value * 3 } }),
|
|
142
|
+
});
|
|
141
143
|
const { dispatch } = createDispatcher((module) => (module === 'test' ? [computeResolver] : [otherComputeResolver]));
|
|
142
144
|
const program = Effect.gen(function* () {
|
|
143
145
|
const a = yield* dispatch(createIntent(Compute, { value: 1 }));
|
|
@@ -153,8 +155,10 @@ describe('Intent dispatcher', () => {
|
|
|
153
155
|
});
|
|
154
156
|
|
|
155
157
|
test('filter resolvers by predicate', async () => {
|
|
156
|
-
const conditionalComputeResolver = createResolver(
|
|
158
|
+
const conditionalComputeResolver = createResolver({
|
|
159
|
+
intent: Compute,
|
|
157
160
|
filter: (data): data is { value: number } => data?.value > 1,
|
|
161
|
+
resolve: async (data) => ({ data: { value: data?.value * 3 } }),
|
|
158
162
|
});
|
|
159
163
|
const { dispatch } = createDispatcher(() => [conditionalComputeResolver, computeResolver]);
|
|
160
164
|
const program = Effect.gen(function* () {
|
|
@@ -171,8 +175,10 @@ describe('Intent dispatcher', () => {
|
|
|
171
175
|
});
|
|
172
176
|
|
|
173
177
|
test('hoist resolvers', async () => {
|
|
174
|
-
const hoistedComputeResolver = createResolver(
|
|
175
|
-
|
|
178
|
+
const hoistedComputeResolver = createResolver({
|
|
179
|
+
intent: Compute,
|
|
180
|
+
position: 'hoist',
|
|
181
|
+
resolve: async (data) => ({ data: { value: data?.value * 3 } }),
|
|
176
182
|
});
|
|
177
183
|
const { dispatchPromise } = createDispatcher(() => [computeResolver, hoistedComputeResolver]);
|
|
178
184
|
const { data } = await dispatchPromise(createIntent(Compute, { value: 1 }));
|
|
@@ -180,13 +186,17 @@ describe('Intent dispatcher', () => {
|
|
|
180
186
|
});
|
|
181
187
|
|
|
182
188
|
test('fallback resolvers', async () => {
|
|
183
|
-
const conditionalComputeResolver = createResolver(
|
|
189
|
+
const conditionalComputeResolver = createResolver({
|
|
190
|
+
intent: Compute,
|
|
184
191
|
filter: (data): data is { value: number } => data?.value === 1,
|
|
192
|
+
resolve: async (data) => ({ data: { value: data?.value * 2 } }),
|
|
185
193
|
});
|
|
186
|
-
const fallbackComputeResolver = createResolver(
|
|
187
|
-
|
|
194
|
+
const fallbackComputeResolver = createResolver({
|
|
195
|
+
intent: Compute,
|
|
196
|
+
position: 'fallback',
|
|
197
|
+
resolve: async (data) => ({ data: { value: data?.value * 3 } }),
|
|
188
198
|
});
|
|
189
|
-
const { dispatch } = createDispatcher(() => [
|
|
199
|
+
const { dispatch } = createDispatcher(() => [conditionalComputeResolver, fallbackComputeResolver]);
|
|
190
200
|
const program = Effect.gen(function* () {
|
|
191
201
|
const a = yield* dispatch(createIntent(Compute, { value: 1 }));
|
|
192
202
|
|
|
@@ -224,8 +234,9 @@ class ToString extends S.TaggedClass<ToString>()('ToString', {
|
|
|
224
234
|
}),
|
|
225
235
|
}) {}
|
|
226
236
|
|
|
227
|
-
const toStringResolver = createResolver(
|
|
228
|
-
|
|
237
|
+
const toStringResolver = createResolver({
|
|
238
|
+
intent: ToString,
|
|
239
|
+
resolve: async (data) => ({ data: { string: data.value.toString() } }),
|
|
229
240
|
});
|
|
230
241
|
|
|
231
242
|
class Compute extends S.TaggedClass<Compute>()('Compute', {
|
|
@@ -237,16 +248,19 @@ class Compute extends S.TaggedClass<Compute>()('Compute', {
|
|
|
237
248
|
}),
|
|
238
249
|
}) {}
|
|
239
250
|
|
|
240
|
-
const computeResolver = createResolver(
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
251
|
+
const computeResolver = createResolver({
|
|
252
|
+
intent: Compute,
|
|
253
|
+
resolve: (data, undo) => {
|
|
254
|
+
return Effect.gen(function* () {
|
|
255
|
+
if (undo) {
|
|
256
|
+
return { data: { value: data.value / 2 } };
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
yield* Effect.sleep(data.value * 10);
|
|
260
|
+
const value = data.value * 2;
|
|
261
|
+
return { data: { value }, undoable: { message: 'test', data: { value } } };
|
|
262
|
+
});
|
|
263
|
+
},
|
|
250
264
|
});
|
|
251
265
|
|
|
252
266
|
class Concat extends S.TaggedClass<Concat>()('Concat', {
|
|
@@ -259,8 +273,9 @@ class Concat extends S.TaggedClass<Concat>()('Concat', {
|
|
|
259
273
|
}),
|
|
260
274
|
}) {}
|
|
261
275
|
|
|
262
|
-
const concatResolver = createResolver(
|
|
263
|
-
|
|
276
|
+
const concatResolver = createResolver({
|
|
277
|
+
intent: Concat,
|
|
278
|
+
resolve: async (data) => ({ data: { string: data.string + data.plus } }),
|
|
264
279
|
});
|
|
265
280
|
|
|
266
281
|
class Add extends S.TaggedClass<Add>()('Add', {
|
|
@@ -268,8 +283,9 @@ class Add extends S.TaggedClass<Add>()('Add', {
|
|
|
268
283
|
output: S.Number,
|
|
269
284
|
}) {}
|
|
270
285
|
|
|
271
|
-
const addResolver = createResolver(
|
|
272
|
-
|
|
286
|
+
const addResolver = createResolver({
|
|
287
|
+
intent: Add,
|
|
288
|
+
resolve: async (data) => ({ data: data[0] + data[1] }),
|
|
273
289
|
});
|
|
274
290
|
|
|
275
291
|
class SideEffect extends S.TaggedClass<SideEffect>()('SideEffect', {
|
|
@@ -277,4 +293,7 @@ class SideEffect extends S.TaggedClass<SideEffect>()('SideEffect', {
|
|
|
277
293
|
output: S.Void,
|
|
278
294
|
}) {}
|
|
279
295
|
|
|
280
|
-
const sideEffectResolver = createResolver(
|
|
296
|
+
const sideEffectResolver = createResolver({
|
|
297
|
+
intent: SideEffect,
|
|
298
|
+
resolve: async () => {},
|
|
299
|
+
});
|
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
import { Effect, Option, pipe, Ref } from 'effect';
|
|
6
6
|
import { type Simplify } from 'effect/Types';
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import { create } from '@dxos/live-object';
|
|
9
|
+
import { log } from '@dxos/log';
|
|
10
|
+
import { byPosition, type MaybePromise, type Position, type GuardedType } from '@dxos/util';
|
|
9
11
|
|
|
10
12
|
import { IntentAction } from './actions';
|
|
11
13
|
import { CycleDetectedError, NoResolversError } from './errors';
|
|
@@ -21,6 +23,8 @@ import {
|
|
|
21
23
|
type IntentSchema,
|
|
22
24
|
type Label,
|
|
23
25
|
} from './intent';
|
|
26
|
+
import { Events, Capabilities } from '../common';
|
|
27
|
+
import { contributes, type PluginsContext } from '../core';
|
|
24
28
|
|
|
25
29
|
const EXECUTION_LIMIT = 100;
|
|
26
30
|
const HISTORY_LIMIT = 100;
|
|
@@ -28,13 +32,13 @@ const HISTORY_LIMIT = 100;
|
|
|
28
32
|
/**
|
|
29
33
|
* The return value of an intent effect.
|
|
30
34
|
*/
|
|
31
|
-
export type IntentEffectResult<
|
|
35
|
+
export type IntentEffectResult<Input, Output> = {
|
|
32
36
|
/**
|
|
33
37
|
* The output of the action that was performed.
|
|
34
38
|
*
|
|
35
39
|
* If the intent is apart of a chain of intents, the data will be passed to the next intent.
|
|
36
40
|
*/
|
|
37
|
-
data?:
|
|
41
|
+
data?: Output;
|
|
38
42
|
|
|
39
43
|
/**
|
|
40
44
|
* If provided, the action will be undoable.
|
|
@@ -48,7 +52,7 @@ export type IntentEffectResult<Fields extends IntentParams> = {
|
|
|
48
52
|
/**
|
|
49
53
|
* Will be merged with the original intent data when firing the undo intent.
|
|
50
54
|
*/
|
|
51
|
-
data?: Partial<
|
|
55
|
+
data?: Partial<Input>;
|
|
52
56
|
};
|
|
53
57
|
|
|
54
58
|
/**
|
|
@@ -66,33 +70,32 @@ export type IntentEffectResult<Fields extends IntentParams> = {
|
|
|
66
70
|
intents?: AnyIntentChain[];
|
|
67
71
|
};
|
|
68
72
|
|
|
69
|
-
export type AnyIntentEffectResult = IntentEffectResult<any>;
|
|
73
|
+
export type AnyIntentEffectResult = IntentEffectResult<any, any>;
|
|
70
74
|
|
|
71
75
|
/**
|
|
72
76
|
* The result of an intent dispatcher.
|
|
73
77
|
*/
|
|
74
|
-
export type IntentDispatcherResult<
|
|
78
|
+
export type IntentDispatcherResult<Input, Output> = Pick<IntentEffectResult<Input, Output>, 'data' | 'error'>;
|
|
75
79
|
|
|
76
80
|
/**
|
|
77
81
|
* The implementation of an intent effect.
|
|
78
82
|
*/
|
|
79
|
-
export type IntentEffectDefinition<
|
|
80
|
-
data:
|
|
83
|
+
export type IntentEffectDefinition<Input, Output> = (
|
|
84
|
+
data: Input,
|
|
81
85
|
undo: boolean,
|
|
82
|
-
) => MaybePromise<IntentEffectResult<
|
|
86
|
+
) => MaybePromise<IntentEffectResult<Input, Output> | void> | Effect.Effect<IntentEffectResult<Input, Output> | void>;
|
|
83
87
|
|
|
84
88
|
/**
|
|
85
89
|
* Intent resolver to match intents to their effects.
|
|
86
90
|
*/
|
|
87
|
-
export type IntentResolver<Tag extends string, Fields extends IntentParams
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
effect: IntentEffectDefinition<Fields>;
|
|
91
|
+
export type IntentResolver<Tag extends string, Fields extends IntentParams, Data = IntentData<Fields>> = Readonly<{
|
|
92
|
+
intent: IntentSchema<Tag, Fields>;
|
|
93
|
+
position?: Position;
|
|
94
|
+
filter?: (data: IntentData<Fields>) => data is Data;
|
|
95
|
+
resolve: IntentEffectDefinition<GuardedType<IntentResolver<Tag, Fields, Data>['filter']>, IntentResultData<Fields>>;
|
|
93
96
|
}>;
|
|
94
97
|
|
|
95
|
-
export type AnyIntentResolver = IntentResolver<any, any>;
|
|
98
|
+
export type AnyIntentResolver = IntentResolver<any, any, any>;
|
|
96
99
|
|
|
97
100
|
/**
|
|
98
101
|
* Creates an intent resolver to match intents to their effects.
|
|
@@ -101,22 +104,16 @@ export type AnyIntentResolver = IntentResolver<any, any>;
|
|
|
101
104
|
* @param params.disposition Determines the priority of the resolver when multiple are resolved.
|
|
102
105
|
* @param params.filter Optional filter to determine if the resolver should be used.
|
|
103
106
|
*/
|
|
104
|
-
export const createResolver = <Tag extends string, Fields extends IntentParams
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
params: Pick<IntentResolver<Tag, Fields>, 'disposition' | 'filter'> = {},
|
|
108
|
-
): IntentResolver<Tag, Fields> => ({
|
|
109
|
-
action: schema._tag,
|
|
110
|
-
effect,
|
|
111
|
-
...params,
|
|
112
|
-
});
|
|
107
|
+
export const createResolver = <Tag extends string, Fields extends IntentParams, Data = IntentData<Fields>>(
|
|
108
|
+
resolver: IntentResolver<Tag, Fields, Data>,
|
|
109
|
+
) => resolver;
|
|
113
110
|
|
|
114
111
|
/**
|
|
115
112
|
* Invokes intents and returns the result.
|
|
116
113
|
*/
|
|
117
114
|
export type PromiseIntentDispatcher = <Fields extends IntentParams>(
|
|
118
115
|
intent: IntentChain<any, any, any, Fields>,
|
|
119
|
-
) => Promise<Simplify<IntentDispatcherResult<Fields
|
|
116
|
+
) => Promise<Simplify<IntentDispatcherResult<IntentData<Fields>, IntentResultData<Fields>>>>;
|
|
120
117
|
|
|
121
118
|
/**
|
|
122
119
|
* Creates an effect for intents.
|
|
@@ -124,9 +121,15 @@ export type PromiseIntentDispatcher = <Fields extends IntentParams>(
|
|
|
124
121
|
export type IntentDispatcher = <Fields extends IntentParams>(
|
|
125
122
|
intent: IntentChain<any, any, any, Fields>,
|
|
126
123
|
depth?: number,
|
|
127
|
-
) => Effect.Effect<
|
|
128
|
-
|
|
129
|
-
|
|
124
|
+
) => Effect.Effect<
|
|
125
|
+
Simplify<Required<IntentDispatcherResult<IntentData<Fields>, IntentResultData<Fields>>>['data']>,
|
|
126
|
+
Error
|
|
127
|
+
>;
|
|
128
|
+
|
|
129
|
+
type IntentResult<Tag extends string, Fields extends IntentParams> = IntentEffectResult<
|
|
130
|
+
IntentData<Fields>,
|
|
131
|
+
IntentResultData<Fields>
|
|
132
|
+
> & {
|
|
130
133
|
_intent: Intent<Tag, Fields>;
|
|
131
134
|
};
|
|
132
135
|
|
|
@@ -135,7 +138,7 @@ export type AnyIntentResult = IntentResult<any, any>;
|
|
|
135
138
|
/**
|
|
136
139
|
* Invokes the most recent undoable intent with undo flags.
|
|
137
140
|
*/
|
|
138
|
-
export type PromiseIntentUndo = () => Promise<IntentDispatcherResult<any>>;
|
|
141
|
+
export type PromiseIntentUndo = () => Promise<IntentDispatcherResult<any, any>>;
|
|
139
142
|
|
|
140
143
|
/**
|
|
141
144
|
* Creates an effect which undoes the last intent.
|
|
@@ -158,7 +161,7 @@ export type IntentContext = {
|
|
|
158
161
|
/**
|
|
159
162
|
* Sets of an intent dispatcher.
|
|
160
163
|
*
|
|
161
|
-
* @param
|
|
164
|
+
* @param getResolvers A function that returns an array of available intent resolvers.
|
|
162
165
|
* @param params.historyLimit The maximum number of intent results to keep in history.
|
|
163
166
|
* @param params.executionLimit The maximum recursion depth of intent chains.
|
|
164
167
|
*/
|
|
@@ -168,24 +171,20 @@ export const createDispatcher = (
|
|
|
168
171
|
): IntentContext => {
|
|
169
172
|
const historyRef = Effect.runSync(Ref.make<AnyIntentResult[][]>([]));
|
|
170
173
|
|
|
171
|
-
const handleIntent = (intent: AnyIntent) =>
|
|
172
|
-
|
|
174
|
+
const handleIntent = (intent: AnyIntent) =>
|
|
175
|
+
Effect.gen(function* () {
|
|
173
176
|
const candidates = getResolvers(intent.module)
|
|
174
|
-
.filter((r) => r.
|
|
177
|
+
.filter((r) => r.intent._tag === intent.id)
|
|
175
178
|
.filter((r) => !r.filter || r.filter(intent.data))
|
|
176
|
-
.toSorted(
|
|
179
|
+
.toSorted(byPosition);
|
|
177
180
|
if (candidates.length === 0) {
|
|
178
|
-
|
|
179
|
-
_intent: intent,
|
|
180
|
-
error: new NoResolversError(intent.action),
|
|
181
|
-
} as AnyIntentResult;
|
|
181
|
+
yield* Effect.fail(new NoResolversError(intent.id));
|
|
182
182
|
}
|
|
183
183
|
|
|
184
|
-
const effect = candidates[0].
|
|
184
|
+
const effect = candidates[0].resolve(intent.data, intent.undo ?? false);
|
|
185
185
|
const result = Effect.isEffect(effect) ? yield* effect : yield* Effect.promise(async () => effect);
|
|
186
186
|
return { _intent: intent, ...result } as AnyIntentResult;
|
|
187
187
|
});
|
|
188
|
-
};
|
|
189
188
|
|
|
190
189
|
const dispatch: IntentDispatcher = (intentChain, depth = 0) => {
|
|
191
190
|
return Effect.gen(function* () {
|
|
@@ -238,7 +237,10 @@ export const createDispatcher = (
|
|
|
238
237
|
const dispatchPromise: PromiseIntentDispatcher = (intentChain) => {
|
|
239
238
|
return Effect.runPromise(dispatch(intentChain))
|
|
240
239
|
.then((data) => ({ data }))
|
|
241
|
-
.catch((error) =>
|
|
240
|
+
.catch((error) => {
|
|
241
|
+
log.catch(error);
|
|
242
|
+
return { error };
|
|
243
|
+
});
|
|
242
244
|
};
|
|
243
245
|
|
|
244
246
|
const undo: IntentUndo = () => {
|
|
@@ -267,3 +269,40 @@ export const createDispatcher = (
|
|
|
267
269
|
|
|
268
270
|
return { dispatch, dispatchPromise, undo, undoPromise };
|
|
269
271
|
};
|
|
272
|
+
|
|
273
|
+
const defaultEffect = () => Effect.fail(new Error('Intent runtime not ready'));
|
|
274
|
+
const defaultPromise = () => Effect.runPromise(defaultEffect());
|
|
275
|
+
|
|
276
|
+
export default (context: PluginsContext) => {
|
|
277
|
+
const state = create<IntentContext>({
|
|
278
|
+
dispatch: defaultEffect,
|
|
279
|
+
dispatchPromise: defaultPromise,
|
|
280
|
+
undo: defaultEffect,
|
|
281
|
+
undoPromise: defaultPromise,
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
// TODO(wittjosiah): Make getResolver callback async and allow resolvers to be requested on demand.
|
|
285
|
+
const { dispatch, dispatchPromise, undo, undoPromise } = createDispatcher((module) =>
|
|
286
|
+
context
|
|
287
|
+
.requestCapabilities(Capabilities.IntentResolver, (c, moduleId): c is AnyIntentResolver => {
|
|
288
|
+
return module ? moduleId === module : true;
|
|
289
|
+
})
|
|
290
|
+
.flat(),
|
|
291
|
+
);
|
|
292
|
+
|
|
293
|
+
const manager = context.requestCapability(Capabilities.PluginManager);
|
|
294
|
+
state.dispatch = (intentChain, depth) => {
|
|
295
|
+
return Effect.gen(function* () {
|
|
296
|
+
yield* manager._activate(Events.SetupIntentResolver);
|
|
297
|
+
return yield* dispatch(intentChain, depth);
|
|
298
|
+
});
|
|
299
|
+
};
|
|
300
|
+
state.dispatchPromise = async (intentChain) => {
|
|
301
|
+
await manager.activate(Events.SetupIntentResolver);
|
|
302
|
+
return await dispatchPromise(intentChain);
|
|
303
|
+
};
|
|
304
|
+
state.undo = undo;
|
|
305
|
+
state.undoPromise = undoPromise;
|
|
306
|
+
|
|
307
|
+
return contributes(Capabilities.IntentDispatcher, state);
|
|
308
|
+
};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { S } from '@
|
|
5
|
+
import { Schema as S } from '@effect/schema';
|
|
6
6
|
|
|
7
7
|
export type IntentParams = {
|
|
8
8
|
readonly input: S.Schema.All;
|
|
@@ -25,9 +25,9 @@ export type Intent<Tag extends string, Fields extends IntentParams> = {
|
|
|
25
25
|
_schema: IntentSchema<Tag, Fields>;
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
|
-
* The
|
|
28
|
+
* The id of the intent.
|
|
29
29
|
*/
|
|
30
|
-
|
|
30
|
+
id: Tag;
|
|
31
31
|
|
|
32
32
|
/**
|
|
33
33
|
* Any data needed to perform the desired action.
|
|
@@ -84,7 +84,7 @@ export const createIntent = <Tag extends string, Fields extends IntentParams>(
|
|
|
84
84
|
const intent = {
|
|
85
85
|
...params,
|
|
86
86
|
_schema: schema,
|
|
87
|
-
|
|
87
|
+
id: schema._tag,
|
|
88
88
|
data,
|
|
89
89
|
} satisfies Intent<Tag, Fields>;
|
|
90
90
|
|
|
@@ -122,7 +122,7 @@ export const chain =
|
|
|
122
122
|
const last = {
|
|
123
123
|
...params,
|
|
124
124
|
_schema: schema,
|
|
125
|
-
|
|
125
|
+
id: schema._tag,
|
|
126
126
|
data,
|
|
127
127
|
} satisfies Intent<NextTag, NextFields>;
|
|
128
128
|
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { RootSettingsStore } from '@dxos/local-storage';
|
|
6
|
-
|
|
7
5
|
import { SETTINGS_PLUGIN } from './actions';
|
|
6
|
+
import translations from './translations';
|
|
8
7
|
import { Capabilities, Events } from '../common';
|
|
9
|
-
import { contributes, defineModule, definePlugin } from '../core';
|
|
8
|
+
import { contributes, defineModule, definePlugin, lazy } from '../core';
|
|
10
9
|
|
|
10
|
+
// TODO(wittjosiah): Add options to exclude some modules.
|
|
11
11
|
export const SettingsPlugin = () =>
|
|
12
12
|
definePlugin({ id: SETTINGS_PLUGIN }, [
|
|
13
13
|
defineModule({
|
|
@@ -15,15 +15,21 @@ export const SettingsPlugin = () =>
|
|
|
15
15
|
activatesOn: Events.Startup,
|
|
16
16
|
activatesBefore: [Events.SetupSettings],
|
|
17
17
|
activatesAfter: [Events.SettingsReady],
|
|
18
|
-
activate: (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
18
|
+
activate: lazy(() => import('./store')),
|
|
19
|
+
}),
|
|
20
|
+
defineModule({
|
|
21
|
+
id: `${SETTINGS_PLUGIN}/module/translations`,
|
|
22
|
+
activatesOn: Events.SetupTranslations,
|
|
23
|
+
activate: () => contributes(Capabilities.Translations, translations),
|
|
24
|
+
}),
|
|
25
|
+
defineModule({
|
|
26
|
+
id: `${SETTINGS_PLUGIN}/module/intent-resolver`,
|
|
27
|
+
activatesOn: Events.SetupIntentResolver,
|
|
28
|
+
activate: lazy(() => import('./intent-resolver')),
|
|
29
|
+
}),
|
|
30
|
+
defineModule({
|
|
31
|
+
id: `${SETTINGS_PLUGIN}/module/app-graph-builder`,
|
|
32
|
+
activatesOn: Events.SetupAppGraph,
|
|
33
|
+
activate: lazy(() => import('./app-graph-builder')),
|
|
28
34
|
}),
|
|
29
35
|
]);
|
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { S } from '@
|
|
5
|
+
import { Schema as S } from '@effect/schema';
|
|
6
6
|
|
|
7
7
|
export const SETTINGS_PLUGIN = 'dxos.org/plugin/settings';
|
|
8
8
|
export const SETTINGS_ACTION = `${SETTINGS_PLUGIN}/action`;
|
|
9
|
+
export const SETTINGS_ID = '!dxos:settings';
|
|
10
|
+
export const SETTINGS_KEY = 'settings';
|
|
9
11
|
|
|
10
12
|
export namespace SettingsAction {
|
|
11
13
|
export class Open extends S.TaggedClass<Open>()(`${SETTINGS_ACTION}/open`, {
|
|
@@ -14,4 +16,12 @@ export namespace SettingsAction {
|
|
|
14
16
|
}),
|
|
15
17
|
output: S.Void,
|
|
16
18
|
}) {}
|
|
19
|
+
|
|
20
|
+
export class OpenPluginRegistry extends S.TaggedClass<OpenPluginRegistry>()(
|
|
21
|
+
`${SETTINGS_ACTION}/open-plugin-registry`,
|
|
22
|
+
{
|
|
23
|
+
input: S.Void,
|
|
24
|
+
output: S.Void,
|
|
25
|
+
},
|
|
26
|
+
) {}
|
|
17
27
|
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { createExtension, type Node } from '@dxos/app-graph';
|
|
6
|
+
import { type SettingsStore, type SettingsValue } from '@dxos/local-storage';
|
|
7
|
+
import { isNonNullable } from '@dxos/util';
|
|
8
|
+
|
|
9
|
+
import { SETTINGS_ID, SETTINGS_KEY, SETTINGS_PLUGIN, SettingsAction } from './actions';
|
|
10
|
+
import { Capabilities } from '../common';
|
|
11
|
+
import { contributes, type PluginMeta, type PluginsContext } from '../core';
|
|
12
|
+
import { createIntent } from '../plugin-intent';
|
|
13
|
+
|
|
14
|
+
export default (context: PluginsContext) =>
|
|
15
|
+
contributes(Capabilities.AppGraphBuilder, [
|
|
16
|
+
createExtension({
|
|
17
|
+
id: `${SETTINGS_PLUGIN}/action`,
|
|
18
|
+
filter: (node): node is Node<null> => node.id === 'root',
|
|
19
|
+
actions: () => [
|
|
20
|
+
{
|
|
21
|
+
id: SETTINGS_PLUGIN,
|
|
22
|
+
data: async () => {
|
|
23
|
+
const { dispatchPromise: dispatch } = context.requestCapability(Capabilities.IntentDispatcher);
|
|
24
|
+
await dispatch(createIntent(SettingsAction.Open));
|
|
25
|
+
},
|
|
26
|
+
properties: {
|
|
27
|
+
label: ['open settings label', { ns: SETTINGS_PLUGIN }],
|
|
28
|
+
icon: 'ph--gear--regular',
|
|
29
|
+
keyBinding: {
|
|
30
|
+
macos: 'meta+,',
|
|
31
|
+
windows: 'alt+,',
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
}),
|
|
37
|
+
createExtension({
|
|
38
|
+
id: `${SETTINGS_PLUGIN}/core`,
|
|
39
|
+
filter: (node): node is Node<null> => node.id === 'root',
|
|
40
|
+
connector: () => [
|
|
41
|
+
{
|
|
42
|
+
id: SETTINGS_ID,
|
|
43
|
+
type: SETTINGS_PLUGIN,
|
|
44
|
+
properties: {
|
|
45
|
+
label: ['app settings label', { ns: SETTINGS_PLUGIN }],
|
|
46
|
+
icon: 'ph--gear--regular',
|
|
47
|
+
disposition: 'pin-end',
|
|
48
|
+
position: 'hoist',
|
|
49
|
+
testId: 'treeView.appSettings',
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
}),
|
|
54
|
+
createExtension({
|
|
55
|
+
id: `${SETTINGS_PLUGIN}/core-plugins`,
|
|
56
|
+
filter: (node): node is Node<null> => node.id === SETTINGS_ID,
|
|
57
|
+
connector: () => {
|
|
58
|
+
const manager = context.requestCapability(Capabilities.PluginManager);
|
|
59
|
+
const [settingsStore] = context.requestCapabilities(Capabilities.SettingsStore);
|
|
60
|
+
return [
|
|
61
|
+
...manager.plugins
|
|
62
|
+
.filter((plugin) => manager.core.includes(plugin.meta.id))
|
|
63
|
+
.map((plugin): [PluginMeta, SettingsStore<SettingsValue>] | null => {
|
|
64
|
+
const settings = settingsStore?.getStore(plugin.meta.id);
|
|
65
|
+
if (!settings) {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return [plugin.meta, settings];
|
|
70
|
+
})
|
|
71
|
+
.filter(isNonNullable)
|
|
72
|
+
.map(([meta, settings]) => ({
|
|
73
|
+
id: `${SETTINGS_KEY}:${meta.id.replaceAll('/', ':')}`,
|
|
74
|
+
type: 'category',
|
|
75
|
+
data: settings,
|
|
76
|
+
properties: {
|
|
77
|
+
label: meta.name ?? meta.id,
|
|
78
|
+
icon: meta.icon ?? 'ph--circle--regular',
|
|
79
|
+
},
|
|
80
|
+
})),
|
|
81
|
+
|
|
82
|
+
{
|
|
83
|
+
id: `${SETTINGS_KEY}:custom-plugins`,
|
|
84
|
+
type: 'collection',
|
|
85
|
+
properties: {
|
|
86
|
+
label: ['custom plugins label', { ns: SETTINGS_PLUGIN }],
|
|
87
|
+
icon: 'ph--squares-four--regular',
|
|
88
|
+
role: 'branch',
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
];
|
|
92
|
+
},
|
|
93
|
+
}),
|
|
94
|
+
createExtension({
|
|
95
|
+
id: `${SETTINGS_PLUGIN}/custom-plugins`,
|
|
96
|
+
filter: (node): node is Node<null> => node.id === `${SETTINGS_KEY}:custom-plugins`,
|
|
97
|
+
connector: () => {
|
|
98
|
+
const manager = context.requestCapability(Capabilities.PluginManager);
|
|
99
|
+
const [settingsStore] = context.requestCapabilities(Capabilities.SettingsStore);
|
|
100
|
+
return manager.plugins
|
|
101
|
+
.filter((plugin) => !manager.core.includes(plugin.meta.id))
|
|
102
|
+
.map((plugin): [PluginMeta, SettingsStore<SettingsValue>] | null => {
|
|
103
|
+
const settings = settingsStore?.getStore(plugin.meta.id);
|
|
104
|
+
if (!settings) {
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return [plugin.meta, settings];
|
|
109
|
+
})
|
|
110
|
+
.filter(isNonNullable)
|
|
111
|
+
.map(([meta, settings]) => ({
|
|
112
|
+
id: `${SETTINGS_KEY}:${meta.id.replaceAll('/', ':')}`,
|
|
113
|
+
type: 'category',
|
|
114
|
+
data: settings,
|
|
115
|
+
properties: {
|
|
116
|
+
label: meta.name ?? meta.id,
|
|
117
|
+
icon: meta.icon ?? 'ph--circle--regular',
|
|
118
|
+
},
|
|
119
|
+
}));
|
|
120
|
+
},
|
|
121
|
+
}),
|
|
122
|
+
]);
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { pipe } from 'effect';
|
|
6
|
+
|
|
7
|
+
import { SETTINGS_ID, SETTINGS_KEY, SettingsAction } from './actions';
|
|
8
|
+
import { Capabilities, LayoutAction } from '../common';
|
|
9
|
+
import { contributes } from '../core';
|
|
10
|
+
import { createResolver, createIntent, chain } from '../plugin-intent';
|
|
11
|
+
|
|
12
|
+
export default () =>
|
|
13
|
+
contributes(
|
|
14
|
+
Capabilities.IntentResolver,
|
|
15
|
+
createResolver({
|
|
16
|
+
intent: SettingsAction.Open,
|
|
17
|
+
resolve: ({ plugin }) => {
|
|
18
|
+
const openSettings = createIntent(LayoutAction.SwitchWorkspace, { part: 'workspace', subject: SETTINGS_ID });
|
|
19
|
+
return {
|
|
20
|
+
intents: [
|
|
21
|
+
plugin
|
|
22
|
+
? pipe(
|
|
23
|
+
openSettings,
|
|
24
|
+
chain(LayoutAction.Open, {
|
|
25
|
+
part: 'main',
|
|
26
|
+
subject: [`${SETTINGS_KEY}:${plugin.replaceAll('/', ':')}`],
|
|
27
|
+
}),
|
|
28
|
+
)
|
|
29
|
+
: openSettings,
|
|
30
|
+
],
|
|
31
|
+
};
|
|
32
|
+
},
|
|
33
|
+
}),
|
|
34
|
+
);
|