@dxos/app-framework 0.7.5-labs.e27f9b9 → 0.7.5-main.2567c87
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/{chunk-G3HBVVT5.mjs → chunk-GNLU3GAU.mjs} +819 -627
- package/dist/lib/browser/chunk-GNLU3GAU.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +74 -57
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +3 -10
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/node/chunk-FBA4BB3J.cjs +1639 -0
- package/dist/lib/node/chunk-FBA4BB3J.cjs.map +7 -0
- package/dist/lib/node/index.cjs +118 -106
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/testing/index.cjs +8 -15
- package/dist/lib/node/testing/index.cjs.map +3 -3
- package/dist/lib/node-esm/{chunk-ZTB4TA6Q.mjs → chunk-KPMTPXQI.mjs} +819 -627
- package/dist/lib/node-esm/chunk-KPMTPXQI.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +74 -57
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/testing/index.mjs +3 -10
- package/dist/lib/node-esm/testing/index.mjs.map +3 -3
- package/dist/types/src/App.d.ts.map +1 -1
- package/dist/types/src/common/capabilities.d.ts +110 -66
- package/dist/types/src/common/capabilities.d.ts.map +1 -1
- package/dist/types/src/common/events.d.ts +1 -8
- 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 +1 -0
- package/dist/types/src/common/index.d.ts.map +1 -1
- package/dist/types/src/common/layout.d.ts +121 -204
- package/dist/types/src/common/layout.d.ts.map +1 -1
- package/dist/types/src/common/navigation.d.ts +241 -0
- package/dist/types/src/common/navigation.d.ts.map +1 -0
- 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 +2 -6
- package/dist/types/src/core/capabilities.d.ts.map +1 -1
- package/dist/types/src/core/manager.d.ts +9 -2
- package/dist/types/src/core/manager.d.ts.map +1 -1
- package/dist/types/src/core/plugin.d.ts +2 -5
- package/dist/types/src/core/plugin.d.ts.map +1 -1
- package/dist/types/src/playground/generator/Toolbar.d.ts.map +1 -1
- package/dist/types/src/playground/generator/generator.d.ts +0 -2
- package/dist/types/src/playground/generator/generator.d.ts.map +1 -1
- package/dist/types/src/playground/generator/plugin.d.ts.map +1 -1
- package/dist/types/src/playground/logger/Toolbar.d.ts.map +1 -1
- package/dist/types/src/playground/logger/plugin.d.ts.map +1 -1
- package/dist/types/src/playground/logger/schema.d.ts +1 -1
- package/dist/types/src/playground/logger/schema.d.ts.map +1 -1
- package/dist/types/src/{react → plugin-intent}/IntentContext.d.ts +1 -1
- package/dist/types/src/plugin-intent/IntentContext.d.ts.map +1 -0
- 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 +1 -0
- package/dist/types/src/plugin-intent/index.d.ts.map +1 -1
- package/dist/types/src/plugin-intent/intent-dispatcher.d.ts +20 -27
- 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.map +1 -1
- package/dist/types/src/plugin-settings/actions.d.ts +1 -11
- package/dist/types/src/plugin-settings/actions.d.ts.map +1 -1
- package/dist/types/src/react/Surface.d.ts.map +1 -1
- package/dist/types/src/react/index.d.ts +0 -2
- 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/testing/withPluginManager.d.ts +1 -1
- package/dist/types/src/testing/withPluginManager.d.ts.map +1 -1
- package/package.json +21 -28
- package/project.json +3 -3
- package/src/App.tsx +14 -15
- package/src/common/capabilities.ts +11 -26
- package/src/common/events.ts +1 -10
- package/src/common/file.ts +1 -1
- package/src/common/graph.ts +2 -2
- package/src/common/index.ts +1 -0
- package/src/common/layout.ts +126 -194
- package/src/common/navigation.ts +199 -0
- package/src/common/surface.ts +2 -2
- package/src/common/translations.ts +8 -7
- package/src/core/capabilities.ts +7 -16
- package/src/core/manager.test.ts +73 -22
- package/src/core/manager.ts +91 -105
- package/src/core/plugin.ts +3 -6
- package/src/playground/debug/plugin.ts +1 -1
- package/src/playground/generator/Toolbar.tsx +11 -11
- package/src/playground/generator/generator.ts +0 -25
- package/src/playground/generator/plugin.ts +1 -6
- package/src/playground/layout/plugin.ts +1 -1
- package/src/playground/logger/Toolbar.tsx +1 -2
- package/src/playground/logger/plugin.ts +3 -6
- package/src/playground/logger/schema.ts +1 -1
- package/src/{react → plugin-intent}/IntentContext.tsx +2 -2
- package/src/plugin-intent/IntentPlugin.tsx +43 -3
- package/src/plugin-intent/actions.ts +1 -1
- package/src/plugin-intent/errors.ts +1 -1
- package/src/plugin-intent/index.ts +1 -0
- package/src/plugin-intent/intent-dispatcher.test.ts +29 -48
- package/src/plugin-intent/intent-dispatcher.ts +41 -76
- package/src/plugin-intent/intent.ts +5 -5
- package/src/plugin-settings/SettingsPlugin.ts +13 -19
- package/src/plugin-settings/actions.ts +1 -11
- package/src/react/Surface.tsx +8 -11
- package/src/react/index.ts +0 -2
- package/src/react/useCapabilities.ts +0 -1
- package/src/testing/withPluginManager.tsx +3 -11
- package/tsconfig.json +3 -6
- package/dist/lib/browser/app-graph-builder-MOLT4EHG.mjs +0 -137
- package/dist/lib/browser/app-graph-builder-MOLT4EHG.mjs.map +0 -7
- package/dist/lib/browser/chunk-G3HBVVT5.mjs.map +0 -7
- package/dist/lib/browser/chunk-LDJ3T4V3.mjs +0 -32
- package/dist/lib/browser/chunk-LDJ3T4V3.mjs.map +0 -7
- package/dist/lib/browser/chunk-TGOF2WQZ.mjs +0 -285
- package/dist/lib/browser/chunk-TGOF2WQZ.mjs.map +0 -7
- package/dist/lib/browser/intent-dispatcher-LJKNIGAM.mjs +0 -11
- package/dist/lib/browser/intent-dispatcher-LJKNIGAM.mjs.map +0 -7
- package/dist/lib/browser/intent-resolver-Z724VAMC.mjs +0 -38
- package/dist/lib/browser/intent-resolver-Z724VAMC.mjs.map +0 -7
- package/dist/lib/browser/store-NWCY7LAP.mjs +0 -19
- package/dist/lib/browser/store-NWCY7LAP.mjs.map +0 -7
- package/dist/lib/browser/worker.mjs +0 -77
- package/dist/lib/browser/worker.mjs.map +0 -7
- package/dist/lib/node/app-graph-builder-G7SRXDFD.cjs +0 -146
- package/dist/lib/node/app-graph-builder-G7SRXDFD.cjs.map +0 -7
- package/dist/lib/node/chunk-55KIQ6YK.cjs +0 -1437
- package/dist/lib/node/chunk-55KIQ6YK.cjs.map +0 -7
- package/dist/lib/node/chunk-5GABBW2Q.cjs +0 -308
- package/dist/lib/node/chunk-5GABBW2Q.cjs.map +0 -7
- package/dist/lib/node/chunk-QLVQ6PND.cjs +0 -58
- package/dist/lib/node/chunk-QLVQ6PND.cjs.map +0 -7
- package/dist/lib/node/intent-dispatcher-CGUK3BCJ.cjs +0 -32
- package/dist/lib/node/intent-dispatcher-CGUK3BCJ.cjs.map +0 -7
- package/dist/lib/node/intent-resolver-7GNKPRWT.cjs +0 -45
- package/dist/lib/node/intent-resolver-7GNKPRWT.cjs.map +0 -7
- package/dist/lib/node/store-WMJSEQPC.cjs +0 -34
- package/dist/lib/node/store-WMJSEQPC.cjs.map +0 -7
- package/dist/lib/node/worker.cjs +0 -99
- package/dist/lib/node/worker.cjs.map +0 -7
- package/dist/lib/node-esm/app-graph-builder-MKLYH3NE.mjs +0 -138
- package/dist/lib/node-esm/app-graph-builder-MKLYH3NE.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-47FG42II.mjs +0 -286
- package/dist/lib/node-esm/chunk-47FG42II.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-CNJYZNSL.mjs +0 -34
- package/dist/lib/node-esm/chunk-CNJYZNSL.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-ZTB4TA6Q.mjs.map +0 -7
- package/dist/lib/node-esm/intent-dispatcher-RZAWA4XD.mjs +0 -12
- package/dist/lib/node-esm/intent-dispatcher-RZAWA4XD.mjs.map +0 -7
- package/dist/lib/node-esm/intent-resolver-UIU37CKJ.mjs +0 -39
- package/dist/lib/node-esm/intent-resolver-UIU37CKJ.mjs.map +0 -7
- package/dist/lib/node-esm/store-YUWINFBN.mjs +0 -20
- package/dist/lib/node-esm/store-YUWINFBN.mjs.map +0 -7
- package/dist/lib/node-esm/worker.mjs +0 -78
- package/dist/lib/node-esm/worker.mjs.map +0 -7
- package/dist/types/src/plugin-settings/app-graph-builder.d.ts +0 -197
- package/dist/types/src/plugin-settings/app-graph-builder.d.ts.map +0 -1
- package/dist/types/src/plugin-settings/intent-resolver.d.ts +0 -4
- package/dist/types/src/plugin-settings/intent-resolver.d.ts.map +0 -1
- package/dist/types/src/plugin-settings/store.d.ts +0 -5
- package/dist/types/src/plugin-settings/store.d.ts.map +0 -1
- package/dist/types/src/plugin-settings/translations.d.ts +0 -11
- package/dist/types/src/plugin-settings/translations.d.ts.map +0 -1
- package/dist/types/src/react/IntentContext.d.ts.map +0 -1
- package/dist/types/src/react/Surface.stories.d.ts +0 -16
- package/dist/types/src/react/Surface.stories.d.ts.map +0 -1
- package/dist/types/src/react/common.d.ts +0 -12
- package/dist/types/src/react/common.d.ts.map +0 -1
- package/dist/types/src/react/useIntentResolver.d.ts +0 -3
- package/dist/types/src/react/useIntentResolver.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/plugin-settings/app-graph-builder.ts +0 -122
- package/src/plugin-settings/intent-resolver.ts +0 -28
- package/src/plugin-settings/store.ts +0 -20
- package/src/plugin-settings/translations.ts +0 -17
- package/src/react/Surface.stories.tsx +0 -96
- package/src/react/common.ts +0 -12
- package/src/react/useIntentResolver.ts +0 -22
- package/src/worker.ts +0 -11
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { Schema as S } from '@effect/schema';
|
|
6
5
|
import { Effect, Fiber, pipe } from 'effect';
|
|
7
6
|
import { describe, expect, test } from 'vitest';
|
|
8
7
|
|
|
8
|
+
import { S } from '@dxos/echo-schema';
|
|
9
|
+
|
|
9
10
|
import { chain, createIntent } from './intent';
|
|
10
11
|
import { type AnyIntentResolver, createDispatcher, createResolver } from './intent-dispatcher';
|
|
11
12
|
|
|
@@ -107,8 +108,8 @@ describe('Intent dispatcher', () => {
|
|
|
107
108
|
const { dispatch } = createDispatcher(() => [computeResolver, toStringResolver, concatResolver]);
|
|
108
109
|
const intent = pipe(createIntent(Compute, { value: 1 }), chain(ToString, {}), chain(Concat, { plus: '!' }));
|
|
109
110
|
|
|
110
|
-
expect(intent.first.
|
|
111
|
-
expect(intent.last.
|
|
111
|
+
expect(intent.first.action).toBe(Compute._tag);
|
|
112
|
+
expect(intent.last.action).toBe(Concat._tag);
|
|
112
113
|
expect(intent.all.length).toBe(3);
|
|
113
114
|
|
|
114
115
|
const program = Effect.gen(function* () {
|
|
@@ -136,10 +137,7 @@ describe('Intent dispatcher', () => {
|
|
|
136
137
|
});
|
|
137
138
|
|
|
138
139
|
test('filter resolvers by plugin', async () => {
|
|
139
|
-
const otherComputeResolver = createResolver({
|
|
140
|
-
intent: Compute,
|
|
141
|
-
resolve: async (data) => ({ data: { value: data?.value * 3 } }),
|
|
142
|
-
});
|
|
140
|
+
const otherComputeResolver = createResolver(Compute, async (data) => ({ data: { value: data?.value * 3 } }));
|
|
143
141
|
const { dispatch } = createDispatcher((module) => (module === 'test' ? [computeResolver] : [otherComputeResolver]));
|
|
144
142
|
const program = Effect.gen(function* () {
|
|
145
143
|
const a = yield* dispatch(createIntent(Compute, { value: 1 }));
|
|
@@ -155,10 +153,8 @@ describe('Intent dispatcher', () => {
|
|
|
155
153
|
});
|
|
156
154
|
|
|
157
155
|
test('filter resolvers by predicate', async () => {
|
|
158
|
-
const conditionalComputeResolver = createResolver({
|
|
159
|
-
intent: Compute,
|
|
156
|
+
const conditionalComputeResolver = createResolver(Compute, async (data) => ({ data: { value: data?.value * 3 } }), {
|
|
160
157
|
filter: (data): data is { value: number } => data?.value > 1,
|
|
161
|
-
resolve: async (data) => ({ data: { value: data?.value * 3 } }),
|
|
162
158
|
});
|
|
163
159
|
const { dispatch } = createDispatcher(() => [conditionalComputeResolver, computeResolver]);
|
|
164
160
|
const program = Effect.gen(function* () {
|
|
@@ -175,10 +171,8 @@ describe('Intent dispatcher', () => {
|
|
|
175
171
|
});
|
|
176
172
|
|
|
177
173
|
test('hoist resolvers', async () => {
|
|
178
|
-
const hoistedComputeResolver = createResolver({
|
|
179
|
-
|
|
180
|
-
position: 'hoist',
|
|
181
|
-
resolve: async (data) => ({ data: { value: data?.value * 3 } }),
|
|
174
|
+
const hoistedComputeResolver = createResolver(Compute, async (data) => ({ data: { value: data?.value * 3 } }), {
|
|
175
|
+
disposition: 'hoist',
|
|
182
176
|
});
|
|
183
177
|
const { dispatchPromise } = createDispatcher(() => [computeResolver, hoistedComputeResolver]);
|
|
184
178
|
const { data } = await dispatchPromise(createIntent(Compute, { value: 1 }));
|
|
@@ -186,17 +180,13 @@ describe('Intent dispatcher', () => {
|
|
|
186
180
|
});
|
|
187
181
|
|
|
188
182
|
test('fallback resolvers', async () => {
|
|
189
|
-
const conditionalComputeResolver = createResolver({
|
|
190
|
-
intent: Compute,
|
|
183
|
+
const conditionalComputeResolver = createResolver(Compute, async (data) => ({ data: { value: data?.value * 2 } }), {
|
|
191
184
|
filter: (data): data is { value: number } => data?.value === 1,
|
|
192
|
-
resolve: async (data) => ({ data: { value: data?.value * 2 } }),
|
|
193
185
|
});
|
|
194
|
-
const fallbackComputeResolver = createResolver({
|
|
195
|
-
|
|
196
|
-
position: 'fallback',
|
|
197
|
-
resolve: async (data) => ({ data: { value: data?.value * 3 } }),
|
|
186
|
+
const fallbackComputeResolver = createResolver(Compute, async (data) => ({ data: { value: data?.value * 3 } }), {
|
|
187
|
+
disposition: 'fallback',
|
|
198
188
|
});
|
|
199
|
-
const { dispatch } = createDispatcher(() => [
|
|
189
|
+
const { dispatch } = createDispatcher(() => [fallbackComputeResolver, conditionalComputeResolver]);
|
|
200
190
|
const program = Effect.gen(function* () {
|
|
201
191
|
const a = yield* dispatch(createIntent(Compute, { value: 1 }));
|
|
202
192
|
|
|
@@ -234,9 +224,8 @@ class ToString extends S.TaggedClass<ToString>()('ToString', {
|
|
|
234
224
|
}),
|
|
235
225
|
}) {}
|
|
236
226
|
|
|
237
|
-
const toStringResolver = createResolver({
|
|
238
|
-
|
|
239
|
-
resolve: async (data) => ({ data: { string: data.value.toString() } }),
|
|
227
|
+
const toStringResolver = createResolver(ToString, async (data) => {
|
|
228
|
+
return { data: { string: data.value.toString() } };
|
|
240
229
|
});
|
|
241
230
|
|
|
242
231
|
class Compute extends S.TaggedClass<Compute>()('Compute', {
|
|
@@ -248,19 +237,16 @@ class Compute extends S.TaggedClass<Compute>()('Compute', {
|
|
|
248
237
|
}),
|
|
249
238
|
}) {}
|
|
250
239
|
|
|
251
|
-
const computeResolver = createResolver({
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
return { data: { value }, undoable: { message: 'test', data: { value } } };
|
|
262
|
-
});
|
|
263
|
-
},
|
|
240
|
+
const computeResolver = createResolver(Compute, (data, undo) => {
|
|
241
|
+
return Effect.gen(function* () {
|
|
242
|
+
if (undo) {
|
|
243
|
+
return { data: { value: data.value / 2 } };
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
yield* Effect.sleep(data.value * 10);
|
|
247
|
+
const value = data.value * 2;
|
|
248
|
+
return { data: { value }, undoable: { message: 'test', data: { value } } };
|
|
249
|
+
});
|
|
264
250
|
});
|
|
265
251
|
|
|
266
252
|
class Concat extends S.TaggedClass<Concat>()('Concat', {
|
|
@@ -273,9 +259,8 @@ class Concat extends S.TaggedClass<Concat>()('Concat', {
|
|
|
273
259
|
}),
|
|
274
260
|
}) {}
|
|
275
261
|
|
|
276
|
-
const concatResolver = createResolver({
|
|
277
|
-
|
|
278
|
-
resolve: async (data) => ({ data: { string: data.string + data.plus } }),
|
|
262
|
+
const concatResolver = createResolver(Concat, async (data) => {
|
|
263
|
+
return { data: { string: data.string + data.plus } };
|
|
279
264
|
});
|
|
280
265
|
|
|
281
266
|
class Add extends S.TaggedClass<Add>()('Add', {
|
|
@@ -283,9 +268,8 @@ class Add extends S.TaggedClass<Add>()('Add', {
|
|
|
283
268
|
output: S.Number,
|
|
284
269
|
}) {}
|
|
285
270
|
|
|
286
|
-
const addResolver = createResolver({
|
|
287
|
-
|
|
288
|
-
resolve: async (data) => ({ data: data[0] + data[1] }),
|
|
271
|
+
const addResolver = createResolver(Add, async (data) => {
|
|
272
|
+
return { data: data[0] + data[1] };
|
|
289
273
|
});
|
|
290
274
|
|
|
291
275
|
class SideEffect extends S.TaggedClass<SideEffect>()('SideEffect', {
|
|
@@ -293,7 +277,4 @@ class SideEffect extends S.TaggedClass<SideEffect>()('SideEffect', {
|
|
|
293
277
|
output: S.Void,
|
|
294
278
|
}) {}
|
|
295
279
|
|
|
296
|
-
const sideEffectResolver = createResolver({
|
|
297
|
-
intent: SideEffect,
|
|
298
|
-
resolve: async () => {},
|
|
299
|
-
});
|
|
280
|
+
const sideEffectResolver = createResolver(SideEffect, async () => {});
|
|
@@ -5,8 +5,7 @@
|
|
|
5
5
|
import { Effect, Option, pipe, Ref } from 'effect';
|
|
6
6
|
import { type Simplify } from 'effect/Types';
|
|
7
7
|
|
|
8
|
-
import {
|
|
9
|
-
import { byPosition, type MaybePromise, type Position, type GuardedType } from '@dxos/util';
|
|
8
|
+
import { type MaybePromise, byDisposition, type Disposition } from '@dxos/util';
|
|
10
9
|
|
|
11
10
|
import { IntentAction } from './actions';
|
|
12
11
|
import { CycleDetectedError, NoResolversError } from './errors';
|
|
@@ -22,8 +21,6 @@ import {
|
|
|
22
21
|
type IntentSchema,
|
|
23
22
|
type Label,
|
|
24
23
|
} from './intent';
|
|
25
|
-
import { Events, Capabilities } from '../common';
|
|
26
|
-
import { contributes, type PluginsContext } from '../core';
|
|
27
24
|
|
|
28
25
|
const EXECUTION_LIMIT = 100;
|
|
29
26
|
const HISTORY_LIMIT = 100;
|
|
@@ -31,13 +28,13 @@ const HISTORY_LIMIT = 100;
|
|
|
31
28
|
/**
|
|
32
29
|
* The return value of an intent effect.
|
|
33
30
|
*/
|
|
34
|
-
export type IntentEffectResult<
|
|
31
|
+
export type IntentEffectResult<Fields extends IntentParams> = {
|
|
35
32
|
/**
|
|
36
33
|
* The output of the action that was performed.
|
|
37
34
|
*
|
|
38
35
|
* If the intent is apart of a chain of intents, the data will be passed to the next intent.
|
|
39
36
|
*/
|
|
40
|
-
data?:
|
|
37
|
+
data?: IntentResultData<Fields>;
|
|
41
38
|
|
|
42
39
|
/**
|
|
43
40
|
* If provided, the action will be undoable.
|
|
@@ -51,7 +48,7 @@ export type IntentEffectResult<Input, Output> = {
|
|
|
51
48
|
/**
|
|
52
49
|
* Will be merged with the original intent data when firing the undo intent.
|
|
53
50
|
*/
|
|
54
|
-
data?: Partial<
|
|
51
|
+
data?: Partial<IntentData<Fields>>;
|
|
55
52
|
};
|
|
56
53
|
|
|
57
54
|
/**
|
|
@@ -69,32 +66,33 @@ export type IntentEffectResult<Input, Output> = {
|
|
|
69
66
|
intents?: AnyIntentChain[];
|
|
70
67
|
};
|
|
71
68
|
|
|
72
|
-
export type AnyIntentEffectResult = IntentEffectResult<any
|
|
69
|
+
export type AnyIntentEffectResult = IntentEffectResult<any>;
|
|
73
70
|
|
|
74
71
|
/**
|
|
75
72
|
* The result of an intent dispatcher.
|
|
76
73
|
*/
|
|
77
|
-
export type IntentDispatcherResult<
|
|
74
|
+
export type IntentDispatcherResult<Fields extends IntentParams> = Pick<IntentEffectResult<Fields>, 'data' | 'error'>;
|
|
78
75
|
|
|
79
76
|
/**
|
|
80
77
|
* The implementation of an intent effect.
|
|
81
78
|
*/
|
|
82
|
-
export type IntentEffectDefinition<
|
|
83
|
-
data:
|
|
79
|
+
export type IntentEffectDefinition<Fields extends IntentParams> = (
|
|
80
|
+
data: IntentData<Fields>,
|
|
84
81
|
undo: boolean,
|
|
85
|
-
) => MaybePromise<IntentEffectResult<
|
|
82
|
+
) => MaybePromise<IntentEffectResult<Fields> | void> | Effect.Effect<IntentEffectResult<Fields> | void>;
|
|
86
83
|
|
|
87
84
|
/**
|
|
88
85
|
* Intent resolver to match intents to their effects.
|
|
89
86
|
*/
|
|
90
|
-
export type IntentResolver<Tag extends string, Fields extends IntentParams
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
87
|
+
export type IntentResolver<Tag extends string, Fields extends IntentParams> = Readonly<{
|
|
88
|
+
action: Tag;
|
|
89
|
+
disposition?: Disposition;
|
|
90
|
+
// TODO(wittjosiah): Would be nice to make this a guard for intents with optional data.
|
|
91
|
+
filter?: (data: IntentData<Fields>) => boolean;
|
|
92
|
+
effect: IntentEffectDefinition<Fields>;
|
|
95
93
|
}>;
|
|
96
94
|
|
|
97
|
-
export type AnyIntentResolver = IntentResolver<any, any
|
|
95
|
+
export type AnyIntentResolver = IntentResolver<any, any>;
|
|
98
96
|
|
|
99
97
|
/**
|
|
100
98
|
* Creates an intent resolver to match intents to their effects.
|
|
@@ -103,16 +101,22 @@ export type AnyIntentResolver = IntentResolver<any, any, any>;
|
|
|
103
101
|
* @param params.disposition Determines the priority of the resolver when multiple are resolved.
|
|
104
102
|
* @param params.filter Optional filter to determine if the resolver should be used.
|
|
105
103
|
*/
|
|
106
|
-
export const createResolver = <Tag extends string, Fields extends IntentParams
|
|
107
|
-
|
|
108
|
-
|
|
104
|
+
export const createResolver = <Tag extends string, Fields extends IntentParams>(
|
|
105
|
+
schema: IntentSchema<Tag, Fields>,
|
|
106
|
+
effect: IntentEffectDefinition<Fields>,
|
|
107
|
+
params: Pick<IntentResolver<Tag, Fields>, 'disposition' | 'filter'> = {},
|
|
108
|
+
): IntentResolver<Tag, Fields> => ({
|
|
109
|
+
action: schema._tag,
|
|
110
|
+
effect,
|
|
111
|
+
...params,
|
|
112
|
+
});
|
|
109
113
|
|
|
110
114
|
/**
|
|
111
115
|
* Invokes intents and returns the result.
|
|
112
116
|
*/
|
|
113
117
|
export type PromiseIntentDispatcher = <Fields extends IntentParams>(
|
|
114
118
|
intent: IntentChain<any, any, any, Fields>,
|
|
115
|
-
) => Promise<Simplify<IntentDispatcherResult<
|
|
119
|
+
) => Promise<Simplify<IntentDispatcherResult<Fields>>>;
|
|
116
120
|
|
|
117
121
|
/**
|
|
118
122
|
* Creates an effect for intents.
|
|
@@ -120,15 +124,9 @@ export type PromiseIntentDispatcher = <Fields extends IntentParams>(
|
|
|
120
124
|
export type IntentDispatcher = <Fields extends IntentParams>(
|
|
121
125
|
intent: IntentChain<any, any, any, Fields>,
|
|
122
126
|
depth?: number,
|
|
123
|
-
) => Effect.Effect<
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
>;
|
|
127
|
-
|
|
128
|
-
type IntentResult<Tag extends string, Fields extends IntentParams> = IntentEffectResult<
|
|
129
|
-
IntentData<Fields>,
|
|
130
|
-
IntentResultData<Fields>
|
|
131
|
-
> & {
|
|
127
|
+
) => Effect.Effect<Simplify<Required<IntentDispatcherResult<Fields>>['data']>, Error>;
|
|
128
|
+
|
|
129
|
+
type IntentResult<Tag extends string, Fields extends IntentParams> = IntentEffectResult<Fields> & {
|
|
132
130
|
_intent: Intent<Tag, Fields>;
|
|
133
131
|
};
|
|
134
132
|
|
|
@@ -137,7 +135,7 @@ export type AnyIntentResult = IntentResult<any, any>;
|
|
|
137
135
|
/**
|
|
138
136
|
* Invokes the most recent undoable intent with undo flags.
|
|
139
137
|
*/
|
|
140
|
-
export type PromiseIntentUndo = () => Promise<IntentDispatcherResult<any
|
|
138
|
+
export type PromiseIntentUndo = () => Promise<IntentDispatcherResult<any>>;
|
|
141
139
|
|
|
142
140
|
/**
|
|
143
141
|
* Creates an effect which undoes the last intent.
|
|
@@ -160,7 +158,7 @@ export type IntentContext = {
|
|
|
160
158
|
/**
|
|
161
159
|
* Sets of an intent dispatcher.
|
|
162
160
|
*
|
|
163
|
-
* @param
|
|
161
|
+
* @param resolvers An array of available intent resolvers.
|
|
164
162
|
* @param params.historyLimit The maximum number of intent results to keep in history.
|
|
165
163
|
* @param params.executionLimit The maximum recursion depth of intent chains.
|
|
166
164
|
*/
|
|
@@ -170,20 +168,24 @@ export const createDispatcher = (
|
|
|
170
168
|
): IntentContext => {
|
|
171
169
|
const historyRef = Effect.runSync(Ref.make<AnyIntentResult[][]>([]));
|
|
172
170
|
|
|
173
|
-
const handleIntent = (intent: AnyIntent) =>
|
|
174
|
-
Effect.gen(function* () {
|
|
171
|
+
const handleIntent = (intent: AnyIntent) => {
|
|
172
|
+
return Effect.gen(function* () {
|
|
175
173
|
const candidates = getResolvers(intent.module)
|
|
176
|
-
.filter((r) => r.
|
|
174
|
+
.filter((r) => r.action === intent.action)
|
|
177
175
|
.filter((r) => !r.filter || r.filter(intent.data))
|
|
178
|
-
.toSorted(
|
|
176
|
+
.toSorted(byDisposition);
|
|
179
177
|
if (candidates.length === 0) {
|
|
180
|
-
|
|
178
|
+
return {
|
|
179
|
+
_intent: intent,
|
|
180
|
+
error: new NoResolversError(intent.action),
|
|
181
|
+
} as AnyIntentResult;
|
|
181
182
|
}
|
|
182
183
|
|
|
183
|
-
const effect = candidates[0].
|
|
184
|
+
const effect = candidates[0].effect(intent.data, intent.undo ?? false);
|
|
184
185
|
const result = Effect.isEffect(effect) ? yield* effect : yield* Effect.promise(async () => effect);
|
|
185
186
|
return { _intent: intent, ...result } as AnyIntentResult;
|
|
186
187
|
});
|
|
188
|
+
};
|
|
187
189
|
|
|
188
190
|
const dispatch: IntentDispatcher = (intentChain, depth = 0) => {
|
|
189
191
|
return Effect.gen(function* () {
|
|
@@ -265,40 +267,3 @@ export const createDispatcher = (
|
|
|
265
267
|
|
|
266
268
|
return { dispatch, dispatchPromise, undo, undoPromise };
|
|
267
269
|
};
|
|
268
|
-
|
|
269
|
-
const defaultEffect = () => Effect.fail(new Error('Intent runtime not ready'));
|
|
270
|
-
const defaultPromise = () => Effect.runPromise(defaultEffect());
|
|
271
|
-
|
|
272
|
-
export default (context: PluginsContext) => {
|
|
273
|
-
const state = create<IntentContext>({
|
|
274
|
-
dispatch: defaultEffect,
|
|
275
|
-
dispatchPromise: defaultPromise,
|
|
276
|
-
undo: defaultEffect,
|
|
277
|
-
undoPromise: defaultPromise,
|
|
278
|
-
});
|
|
279
|
-
|
|
280
|
-
// TODO(wittjosiah): Make getResolver callback async and allow resolvers to be requested on demand.
|
|
281
|
-
const { dispatch, dispatchPromise, undo, undoPromise } = createDispatcher((module) =>
|
|
282
|
-
context
|
|
283
|
-
.requestCapabilities(Capabilities.IntentResolver, (c, moduleId): c is AnyIntentResolver => {
|
|
284
|
-
return module ? moduleId === module : true;
|
|
285
|
-
})
|
|
286
|
-
.flat(),
|
|
287
|
-
);
|
|
288
|
-
|
|
289
|
-
const manager = context.requestCapability(Capabilities.PluginManager);
|
|
290
|
-
state.dispatch = (intentChain, depth) => {
|
|
291
|
-
return Effect.gen(function* () {
|
|
292
|
-
yield* manager._activate(Events.SetupIntents);
|
|
293
|
-
return yield* dispatch(intentChain, depth);
|
|
294
|
-
});
|
|
295
|
-
};
|
|
296
|
-
state.dispatchPromise = async (intentChain) => {
|
|
297
|
-
await manager.activate(Events.SetupIntents);
|
|
298
|
-
return await dispatchPromise(intentChain);
|
|
299
|
-
};
|
|
300
|
-
state.undo = undo;
|
|
301
|
-
state.undoPromise = undoPromise;
|
|
302
|
-
|
|
303
|
-
return contributes(Capabilities.IntentDispatcher, state);
|
|
304
|
-
};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { S } from '@dxos/echo-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 action to perform.
|
|
29
29
|
*/
|
|
30
|
-
|
|
30
|
+
action: 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
|
+
action: 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
|
+
action: 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
|
+
|
|
5
7
|
import { SETTINGS_PLUGIN } from './actions';
|
|
6
|
-
import translations from './translations';
|
|
7
8
|
import { Capabilities, Events } from '../common';
|
|
8
|
-
import { contributes, defineModule, definePlugin
|
|
9
|
+
import { contributes, defineModule, definePlugin } from '../core';
|
|
9
10
|
|
|
10
|
-
// TODO(wittjosiah): Add options to exclude some modules.
|
|
11
11
|
export const SettingsPlugin = () =>
|
|
12
12
|
definePlugin({ id: SETTINGS_PLUGIN }, [
|
|
13
13
|
defineModule({
|
|
@@ -15,21 +15,15 @@ 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
|
-
|
|
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')),
|
|
18
|
+
activate: (context) => {
|
|
19
|
+
const allSettings = context.requestCapabilities(Capabilities.Settings);
|
|
20
|
+
const settingsStore = new RootSettingsStore();
|
|
21
|
+
|
|
22
|
+
allSettings.forEach((setting) => {
|
|
23
|
+
settingsStore.createStore(setting as any);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
return contributes(Capabilities.SettingsStore, settingsStore);
|
|
27
|
+
},
|
|
34
28
|
}),
|
|
35
29
|
]);
|
|
@@ -2,12 +2,10 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { S } from '@dxos/echo-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';
|
|
11
9
|
|
|
12
10
|
export namespace SettingsAction {
|
|
13
11
|
export class Open extends S.TaggedClass<Open>()(`${SETTINGS_ACTION}/open`, {
|
|
@@ -16,12 +14,4 @@ export namespace SettingsAction {
|
|
|
16
14
|
}),
|
|
17
15
|
output: S.Void,
|
|
18
16
|
}) {}
|
|
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
|
-
) {}
|
|
27
17
|
}
|
package/src/react/Surface.tsx
CHANGED
|
@@ -5,17 +5,14 @@
|
|
|
5
5
|
import React, { memo, forwardRef, Suspense, useMemo } from 'react';
|
|
6
6
|
|
|
7
7
|
import { useDefaultValue } from '@dxos/react-hooks';
|
|
8
|
-
import {
|
|
8
|
+
import { byDisposition } from '@dxos/util';
|
|
9
9
|
|
|
10
10
|
import { ErrorBoundary } from './ErrorBoundary';
|
|
11
11
|
import { useCapabilities } from './useCapabilities';
|
|
12
12
|
import { Capabilities, type SurfaceDefinition, type SurfaceProps } from '../common';
|
|
13
13
|
import { type PluginsContext } from '../core';
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
* @internal
|
|
17
|
-
*/
|
|
18
|
-
export const useSurfaces = () => {
|
|
15
|
+
const useSurfaces = () => {
|
|
19
16
|
const surfaces = useCapabilities(Capabilities.ReactSurface);
|
|
20
17
|
return useMemo(() => surfaces.flat(), [surfaces]);
|
|
21
18
|
};
|
|
@@ -26,7 +23,7 @@ const findCandidates = (surfaces: SurfaceDefinition[], { role, data }: Pick<Surf
|
|
|
26
23
|
Array.isArray(definition.role) ? definition.role.includes(role) : definition.role === role,
|
|
27
24
|
)
|
|
28
25
|
.filter(({ filter }) => (filter ? filter(data ?? {}) : true))
|
|
29
|
-
.toSorted(
|
|
26
|
+
.toSorted(byDisposition);
|
|
30
27
|
};
|
|
31
28
|
|
|
32
29
|
/**
|
|
@@ -52,9 +49,11 @@ export const Surface = memo(
|
|
|
52
49
|
const surfaces = useSurfaces();
|
|
53
50
|
const data = useDefaultValue(_data, () => ({}));
|
|
54
51
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
52
|
+
const candidates = useMemo(() => {
|
|
53
|
+
const definitions = findCandidates(surfaces, { role, data });
|
|
54
|
+
return limit ? definitions.slice(0, limit) : definitions;
|
|
55
|
+
}, [surfaces, role, data, limit]);
|
|
56
|
+
|
|
58
57
|
const nodes = candidates.map(({ component: Component, id }) => (
|
|
59
58
|
<Component ref={forwardedRef} key={id} id={id} role={role} data={data} limit={limit} {...rest} />
|
|
60
59
|
));
|
|
@@ -71,5 +70,3 @@ export const Surface = memo(
|
|
|
71
70
|
},
|
|
72
71
|
),
|
|
73
72
|
);
|
|
74
|
-
|
|
75
|
-
Surface.displayName = 'Surface';
|
package/src/react/index.ts
CHANGED
|
@@ -12,14 +12,14 @@ import { Capabilities, Events } from '../common';
|
|
|
12
12
|
import { type AnyCapability, contributes, defineModule, definePlugin, PluginManager } from '../core';
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
|
-
*
|
|
15
|
+
* Wraps a story with a plugin manager.
|
|
16
16
|
*/
|
|
17
|
-
export const
|
|
17
|
+
export const withPluginManager = ({
|
|
18
18
|
capabilities,
|
|
19
19
|
plugins = [],
|
|
20
20
|
core = plugins.map(({ meta }) => meta.id),
|
|
21
21
|
...options
|
|
22
|
-
}: CreateAppOptions & { capabilities?: AnyCapability[] } = {}) => {
|
|
22
|
+
}: CreateAppOptions & { capabilities?: AnyCapability[] } = {}): Decorator => {
|
|
23
23
|
const pluginManager = new PluginManager({
|
|
24
24
|
pluginLoader: () => raise(new Error('Not implemented')),
|
|
25
25
|
plugins: [StoryPlugin(), ...plugins],
|
|
@@ -37,14 +37,6 @@ export const setupPluginManager = ({
|
|
|
37
37
|
});
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
return pluginManager;
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Wraps a story with a plugin manager.
|
|
45
|
-
*/
|
|
46
|
-
export const withPluginManager = (options: CreateAppOptions & { capabilities?: AnyCapability[] } = {}): Decorator => {
|
|
47
|
-
const pluginManager = setupPluginManager(options);
|
|
48
40
|
const App = createApp({ pluginManager });
|
|
49
41
|
|
|
50
42
|
return (Story, context) => {
|
package/tsconfig.json
CHANGED
|
@@ -20,6 +20,9 @@
|
|
|
20
20
|
{
|
|
21
21
|
"path": "../../common/async"
|
|
22
22
|
},
|
|
23
|
+
{
|
|
24
|
+
"path": "../../common/context"
|
|
25
|
+
},
|
|
23
26
|
{
|
|
24
27
|
"path": "../../common/debug"
|
|
25
28
|
},
|
|
@@ -32,9 +35,6 @@
|
|
|
32
35
|
{
|
|
33
36
|
"path": "../../common/log"
|
|
34
37
|
},
|
|
35
|
-
{
|
|
36
|
-
"path": "../../common/random"
|
|
37
|
-
},
|
|
38
38
|
{
|
|
39
39
|
"path": "../../common/storybook-utils"
|
|
40
40
|
},
|
|
@@ -50,9 +50,6 @@
|
|
|
50
50
|
{
|
|
51
51
|
"path": "../../core/echo/live-object"
|
|
52
52
|
},
|
|
53
|
-
{
|
|
54
|
-
"path": "../../experimental/artifact"
|
|
55
|
-
},
|
|
56
53
|
{
|
|
57
54
|
"path": "../../ui/primitives/react-hooks"
|
|
58
55
|
},
|