@dxos/app-framework 0.8.4-main.5ea62a8 → 0.8.4-main.72ec0f3
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-DND4XMN4.mjs → chunk-VFUKEZIN.mjs} +233 -191
- 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-E2TK7Z4P.mjs → chunk-IJOHO66N.mjs} +233 -191
- 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 +10 -0
- package/dist/types/src/react/App.d.ts.map +1 -0
- package/dist/types/src/react/App.stories.d.ts +14 -0
- package/dist/types/src/react/App.stories.d.ts.map +1 -0
- package/dist/types/src/react/DefaultFallback.d.ts +8 -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/{App.d.ts → react/useApp.d.ts} +7 -6
- package/dist/types/src/react/useApp.d.ts.map +1 -0
- package/dist/types/src/react/useLoading.d.ts +19 -0
- package/dist/types/src/react/useLoading.d.ts.map +1 -0
- package/dist/types/src/testing/withPluginManager.d.ts +7 -8
- 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/Debug.tsx +1 -1
- 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/react/App.stories.tsx +33 -0
- package/src/react/App.tsx +59 -0
- package/src/react/DefaultFallback.tsx +26 -0
- 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/{App.tsx → react/useApp.tsx} +35 -150
- package/src/react/useCapabilities.ts +2 -2
- package/src/react/useLoading.tsx +70 -0
- package/src/testing/withPluginManager.stories.tsx +1 -1
- package/src/testing/withPluginManager.tsx +24 -23
- package/tsconfig.json +11 -9
- package/vitest.config.ts +8 -6
- package/dist/lib/browser/app-graph-builder-AFFC6VB2.mjs.map +0 -7
- package/dist/lib/browser/chunk-DND4XMN4.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/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-E2TK7Z4P.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-F63ZRXMK.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/App.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/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/src/core/manager.test.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { afterEach, describe, expect, it } from 'vitest';
|
|
|
7
7
|
|
|
8
8
|
import { Trigger } from '@dxos/async';
|
|
9
9
|
import { raise } from '@dxos/debug';
|
|
10
|
-
import { updateCounter } from '@dxos/echo
|
|
10
|
+
import { updateCounter } from '@dxos/echo/testing';
|
|
11
11
|
import { registerSignalsRuntime } from '@dxos/echo-signals';
|
|
12
12
|
import { invariant } from '@dxos/invariant';
|
|
13
13
|
import { live } from '@dxos/live-object';
|
|
@@ -17,7 +17,7 @@ import { Events } from '../common';
|
|
|
17
17
|
import { type PluginContext, contributes, defineCapability } from './capabilities';
|
|
18
18
|
import { allOf, defineEvent, oneOf } from './events';
|
|
19
19
|
import { PluginManager } from './manager';
|
|
20
|
-
import {
|
|
20
|
+
import { Plugin, defineModule } from './plugin';
|
|
21
21
|
|
|
22
22
|
registerSignalsRuntime();
|
|
23
23
|
|
|
@@ -43,7 +43,7 @@ describe('PluginManager', () => {
|
|
|
43
43
|
});
|
|
44
44
|
|
|
45
45
|
it('should be able to add and remove plugins', async () => {
|
|
46
|
-
const Test =
|
|
46
|
+
const Test = new Plugin(testMeta, []);
|
|
47
47
|
plugins = [Test];
|
|
48
48
|
|
|
49
49
|
const manager = new PluginManager({ pluginLoader });
|
|
@@ -59,7 +59,7 @@ describe('PluginManager', () => {
|
|
|
59
59
|
activatesOn: Events.Startup,
|
|
60
60
|
activate: () => contributes(String, { string: 'hello' }),
|
|
61
61
|
});
|
|
62
|
-
const Test =
|
|
62
|
+
const Test = new Plugin(testMeta, [Hello]);
|
|
63
63
|
|
|
64
64
|
const manager = new PluginManager({ plugins: [Test], core: [], pluginLoader });
|
|
65
65
|
await manager.enable(testMeta.id);
|
|
@@ -76,7 +76,7 @@ describe('PluginManager', () => {
|
|
|
76
76
|
activatesOn: Events.Startup,
|
|
77
77
|
activate: () => contributes(String, { string: 'hello' }),
|
|
78
78
|
});
|
|
79
|
-
const Test =
|
|
79
|
+
const Test = new Plugin(testMeta, [Hello]);
|
|
80
80
|
|
|
81
81
|
const manager = new PluginManager({ plugins: [Test], enabled: [Test.meta.id], pluginLoader });
|
|
82
82
|
expect(manager.plugins).toEqual([Test]);
|
|
@@ -95,7 +95,7 @@ describe('PluginManager', () => {
|
|
|
95
95
|
activatesOn: FailEvent,
|
|
96
96
|
activate: async () => raise(new Error('test')),
|
|
97
97
|
});
|
|
98
|
-
plugins = [
|
|
98
|
+
plugins = [new Plugin(testMeta, [Fail])];
|
|
99
99
|
|
|
100
100
|
const manager = new PluginManager({ pluginLoader });
|
|
101
101
|
await manager.add(testMeta.id);
|
|
@@ -114,7 +114,7 @@ describe('PluginManager', () => {
|
|
|
114
114
|
// TODO(wittjosiah): Test and catch more failure modes.
|
|
115
115
|
activate: async () => async () => raise(new Error('test')),
|
|
116
116
|
});
|
|
117
|
-
plugins = [
|
|
117
|
+
plugins = [new Plugin(testMeta, [Hello, Fail])];
|
|
118
118
|
|
|
119
119
|
const manager = new PluginManager({ pluginLoader });
|
|
120
120
|
const activating = new Trigger<boolean>();
|
|
@@ -149,7 +149,7 @@ describe('PluginManager', () => {
|
|
|
149
149
|
return contributes(String, { string: 'hello' });
|
|
150
150
|
},
|
|
151
151
|
});
|
|
152
|
-
plugins = [
|
|
152
|
+
plugins = [new Plugin(testMeta, [Hello])];
|
|
153
153
|
|
|
154
154
|
const manager = new PluginManager({ pluginLoader });
|
|
155
155
|
|
|
@@ -180,21 +180,21 @@ describe('PluginManager', () => {
|
|
|
180
180
|
});
|
|
181
181
|
|
|
182
182
|
it('should be able to fire custom activation events', async () => {
|
|
183
|
-
const Plugin1 =
|
|
183
|
+
const Plugin1 = new Plugin({ id: 'dxos.org/test/plugin-1', name: 'Plugin 1' }, [
|
|
184
184
|
defineModule({
|
|
185
185
|
id: 'dxos.org/test/plugin-1',
|
|
186
186
|
activatesOn: CountEvent,
|
|
187
187
|
activate: () => [contributes(Number, { number: 1 })],
|
|
188
188
|
}),
|
|
189
189
|
]);
|
|
190
|
-
const Plugin2 =
|
|
190
|
+
const Plugin2 = new Plugin({ id: 'dxos.org/test/plugin-2', name: 'Plugin 2' }, [
|
|
191
191
|
defineModule({
|
|
192
192
|
id: 'dxos.org/test/plugin-2',
|
|
193
193
|
activatesOn: CountEvent,
|
|
194
194
|
activate: () => [contributes(Number, { number: 2 })],
|
|
195
195
|
}),
|
|
196
196
|
]);
|
|
197
|
-
const Plugin3 =
|
|
197
|
+
const Plugin3 = new Plugin({ id: 'dxos.org/test/plugin-3', name: 'Plugin 3' }, [
|
|
198
198
|
defineModule({
|
|
199
199
|
id: 'dxos.org/test/plugin-3',
|
|
200
200
|
activatesOn: CountEvent,
|
|
@@ -231,7 +231,7 @@ describe('PluginManager', () => {
|
|
|
231
231
|
return contributes(String, { string: 'hello' });
|
|
232
232
|
},
|
|
233
233
|
});
|
|
234
|
-
plugins = [
|
|
234
|
+
plugins = [new Plugin(testMeta, [Hello])];
|
|
235
235
|
|
|
236
236
|
const manager = new PluginManager({ pluginLoader });
|
|
237
237
|
expect(manager.active).toEqual([]);
|
|
@@ -257,7 +257,7 @@ describe('PluginManager', () => {
|
|
|
257
257
|
return contributes(String, { string: 'hello' });
|
|
258
258
|
},
|
|
259
259
|
});
|
|
260
|
-
plugins = [
|
|
260
|
+
plugins = [new Plugin(testMeta, [Hello])];
|
|
261
261
|
|
|
262
262
|
const manager = new PluginManager({ pluginLoader });
|
|
263
263
|
expect(manager.active).toEqual([]);
|
|
@@ -283,7 +283,7 @@ describe('PluginManager', () => {
|
|
|
283
283
|
state.total = numbers.reduce((acc, n) => acc + n.number, 0);
|
|
284
284
|
};
|
|
285
285
|
|
|
286
|
-
const Count =
|
|
286
|
+
const Count = new Plugin({ id: 'dxos.org/test/count', name: 'Count' }, [
|
|
287
287
|
defineModule({
|
|
288
288
|
id: 'dxos.org/test/count',
|
|
289
289
|
activatesOn: Events.Startup,
|
|
@@ -295,7 +295,7 @@ describe('PluginManager', () => {
|
|
|
295
295
|
}),
|
|
296
296
|
]);
|
|
297
297
|
|
|
298
|
-
const Test =
|
|
298
|
+
const Test = new Plugin(testMeta, [
|
|
299
299
|
defineModule({
|
|
300
300
|
id: 'dxos.org/test/plugin-1',
|
|
301
301
|
activatesOn: CountEvent,
|
|
@@ -353,7 +353,7 @@ describe('PluginManager', () => {
|
|
|
353
353
|
const id = 'dxos.org/test/counter';
|
|
354
354
|
const stateEvent = Events.createStateEvent(id);
|
|
355
355
|
|
|
356
|
-
const Test =
|
|
356
|
+
const Test = new Plugin(testMeta, [
|
|
357
357
|
defineModule({
|
|
358
358
|
id,
|
|
359
359
|
activatesOn: Events.Startup,
|
|
@@ -390,21 +390,21 @@ describe('PluginManager', () => {
|
|
|
390
390
|
});
|
|
391
391
|
|
|
392
392
|
it('should be reactive', async () => {
|
|
393
|
-
const Plugin1 =
|
|
393
|
+
const Plugin1 = new Plugin({ id: 'dxos.org/test/plugin-1', name: 'Plugin 1' }, [
|
|
394
394
|
defineModule({
|
|
395
395
|
id: 'dxos.org/test/plugin-1',
|
|
396
396
|
activatesOn: CountEvent,
|
|
397
397
|
activate: () => [contributes(Number, { number: 1 })],
|
|
398
398
|
}),
|
|
399
399
|
]);
|
|
400
|
-
const Plugin2 =
|
|
400
|
+
const Plugin2 = new Plugin({ id: 'dxos.org/test/plugin-2', name: 'Plugin 2' }, [
|
|
401
401
|
defineModule({
|
|
402
402
|
id: 'dxos.org/test/plugin-2',
|
|
403
403
|
activatesOn: CountEvent,
|
|
404
404
|
activate: () => [contributes(Number, { number: 2 })],
|
|
405
405
|
}),
|
|
406
406
|
]);
|
|
407
|
-
const Plugin3 =
|
|
407
|
+
const Plugin3 = new Plugin({ id: 'dxos.org/test/plugin-3', name: 'Plugin 3' }, [
|
|
408
408
|
defineModule({
|
|
409
409
|
id: 'dxos.org/test/plugin-3',
|
|
410
410
|
activatesOn: CountEvent,
|
package/src/core/manager.ts
CHANGED
|
@@ -2,9 +2,16 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { Registry } from '@effect-
|
|
5
|
+
import { Registry } from '@effect-atom/atom-react';
|
|
6
6
|
import { untracked } from '@preact/signals-core';
|
|
7
|
-
import
|
|
7
|
+
import * as Array from 'effect/Array';
|
|
8
|
+
import * as Duration from 'effect/Duration';
|
|
9
|
+
import * as Effect from 'effect/Effect';
|
|
10
|
+
import * as Fiber from 'effect/Fiber';
|
|
11
|
+
import * as Function from 'effect/Function';
|
|
12
|
+
import * as HashSet from 'effect/HashSet';
|
|
13
|
+
import * as Match from 'effect/Match';
|
|
14
|
+
import * as Ref from 'effect/Ref';
|
|
8
15
|
|
|
9
16
|
import { Event } from '@dxos/async';
|
|
10
17
|
import { type Live, live } from '@dxos/live-object';
|
|
@@ -48,7 +55,7 @@ export class PluginManager {
|
|
|
48
55
|
readonly context: PluginContext;
|
|
49
56
|
readonly registry: Registry.Registry;
|
|
50
57
|
|
|
51
|
-
// TODO(wittjosiah): Replace with
|
|
58
|
+
// TODO(wittjosiah): Replace with Atom.
|
|
52
59
|
private readonly _state: Live<PluginManagerState>;
|
|
53
60
|
private readonly _pluginLoader: PluginManagerOptions['pluginLoader'];
|
|
54
61
|
private readonly _capabilities = new Map<string, AnyCapability[]>();
|
|
@@ -396,7 +403,7 @@ export class PluginManager {
|
|
|
396
403
|
this.activation.emit({ event: key, state: 'activating' });
|
|
397
404
|
|
|
398
405
|
// Fire activatesBefore events.
|
|
399
|
-
yield* pipe(
|
|
406
|
+
yield* Function.pipe(
|
|
400
407
|
modules,
|
|
401
408
|
Array.flatMap((module) => module.activatesBefore ?? []),
|
|
402
409
|
HashSet.fromIterable,
|
|
@@ -407,7 +414,7 @@ export class PluginManager {
|
|
|
407
414
|
);
|
|
408
415
|
|
|
409
416
|
// Concurrently triggers loading of lazy capabilities.
|
|
410
|
-
const getCapabilities = yield* pipe(
|
|
417
|
+
const getCapabilities = yield* Function.pipe(
|
|
411
418
|
modules,
|
|
412
419
|
Array.map((mod) => this._loadModule(mod)),
|
|
413
420
|
Effect.allWith({ concurrency: 'unbounded' }),
|
|
@@ -418,7 +425,7 @@ export class PluginManager {
|
|
|
418
425
|
);
|
|
419
426
|
|
|
420
427
|
// Contribute the capabilities from the activated modules.
|
|
421
|
-
yield* pipe(
|
|
428
|
+
yield* Function.pipe(
|
|
422
429
|
modules,
|
|
423
430
|
Array.zip(getCapabilities),
|
|
424
431
|
Array.map(([module, capabilities]) => this._contributeCapabilities(module, capabilities)),
|
|
@@ -428,7 +435,7 @@ export class PluginManager {
|
|
|
428
435
|
);
|
|
429
436
|
|
|
430
437
|
// Fire activatesAfter events.
|
|
431
|
-
yield* pipe(
|
|
438
|
+
yield* Function.pipe(
|
|
432
439
|
modules,
|
|
433
440
|
Array.flatMap((module) => module.activatesAfter ?? []),
|
|
434
441
|
HashSet.fromIterable,
|
package/src/core/plugin.ts
CHANGED
|
@@ -110,6 +110,11 @@ export type PluginMeta = {
|
|
|
110
110
|
* A grep-able symbol string which can be resolved to an icon asset by @ch-ui/icons, via @ch-ui/vite-plugin-icons.
|
|
111
111
|
*/
|
|
112
112
|
icon?: string;
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Icon hue (ChromaticPalette).
|
|
116
|
+
*/
|
|
117
|
+
iconHue?: string;
|
|
113
118
|
};
|
|
114
119
|
|
|
115
120
|
/**
|
|
@@ -124,9 +129,15 @@ export class Plugin {
|
|
|
124
129
|
) {}
|
|
125
130
|
}
|
|
126
131
|
|
|
132
|
+
export type PluginFactory<T = void> = ((args: T) => Plugin) & { meta: PluginMeta };
|
|
133
|
+
|
|
127
134
|
/**
|
|
128
135
|
* Helper to define a plugin.
|
|
129
136
|
*/
|
|
130
|
-
export const definePlugin = (meta: PluginMeta,
|
|
131
|
-
|
|
137
|
+
export const definePlugin = <T = void>(meta: PluginMeta, provider: (args: T) => PluginModule[]): PluginFactory<T> => {
|
|
138
|
+
const factory = (args: T) => {
|
|
139
|
+
return new Plugin(meta, provider(args));
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
return Object.assign(factory, { meta });
|
|
132
143
|
};
|
package/src/index.ts
CHANGED
|
@@ -22,7 +22,7 @@ export const Debug = () => {
|
|
|
22
22
|
};
|
|
23
23
|
|
|
24
24
|
return (
|
|
25
|
-
<SyntaxHighlighter language='json' classNames='
|
|
25
|
+
<SyntaxHighlighter language='json' classNames='text-xs opacity-75 rounded'>
|
|
26
26
|
{JSON.stringify(object, undefined, 2)}
|
|
27
27
|
</SyntaxHighlighter>
|
|
28
28
|
);
|
|
@@ -7,11 +7,10 @@ import { defineModule, definePlugin, lazy } from '../../core';
|
|
|
7
7
|
|
|
8
8
|
const Debug = lazy(() => import('./Debug'));
|
|
9
9
|
|
|
10
|
-
export const DebugPlugin = () =>
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
]);
|
|
10
|
+
export const DebugPlugin = definePlugin({ id: 'dxos.org/test/plugin-debug', name: 'Debug' }, () => [
|
|
11
|
+
defineModule({
|
|
12
|
+
id: 'dxos.org/test/debug/main',
|
|
13
|
+
activatesOn: Events.Startup,
|
|
14
|
+
activate: Debug,
|
|
15
|
+
}),
|
|
16
|
+
]);
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import * as Schema from 'effect/Schema';
|
|
6
6
|
|
|
7
7
|
import { Capabilities, Events } from '../../common';
|
|
8
8
|
import { contributes, defineCapability, defineEvent, defineModule, definePlugin } from '../../core';
|
|
@@ -26,7 +26,7 @@ export const createGeneratorIntent = (id: string) => {
|
|
|
26
26
|
export const createNumberPlugin = (id: string) => {
|
|
27
27
|
const number = Math.floor(Math.random() * 100);
|
|
28
28
|
|
|
29
|
-
return definePlugin({ id, name: `Plugin ${id}` }, [
|
|
29
|
+
return definePlugin({ id, name: `Plugin ${id}` }, () => [
|
|
30
30
|
defineModule({
|
|
31
31
|
id: `${id}/main`,
|
|
32
32
|
activatesOn: CountEvent,
|
|
@@ -8,16 +8,15 @@ import { defineModule, definePlugin, lazy } from '../../core';
|
|
|
8
8
|
const Main = lazy(() => import('./Main'));
|
|
9
9
|
const Toolbar = lazy(() => import('./Toolbar'));
|
|
10
10
|
|
|
11
|
-
export const GeneratorPlugin = () =>
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
]);
|
|
11
|
+
export const GeneratorPlugin = definePlugin({ id: 'dxos.org/test/generator', name: 'Generator' }, () => [
|
|
12
|
+
defineModule({
|
|
13
|
+
id: 'dxos.org/test/generator/main',
|
|
14
|
+
activatesOn: Events.Startup,
|
|
15
|
+
activate: Main,
|
|
16
|
+
}),
|
|
17
|
+
defineModule({
|
|
18
|
+
id: 'dxos.org/test/generator/toolbar',
|
|
19
|
+
activatesOn: Events.Startup,
|
|
20
|
+
activate: Toolbar,
|
|
21
|
+
}),
|
|
22
|
+
]);
|
|
@@ -7,11 +7,12 @@ import { defineModule, definePlugin, lazy } from '../../core';
|
|
|
7
7
|
|
|
8
8
|
const Layout = lazy(() => import('./Layout'));
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
10
|
+
const meta = { id: 'dxos.org/test/layout', name: 'Layout' };
|
|
11
|
+
|
|
12
|
+
export const LayoutPlugin = definePlugin(meta, () => [
|
|
13
|
+
defineModule({
|
|
14
|
+
id: 'dxos.org/test/layout/root',
|
|
15
|
+
activatesOn: Events.Startup,
|
|
16
|
+
activate: Layout,
|
|
17
|
+
}),
|
|
18
|
+
]);
|
|
@@ -12,26 +12,30 @@ import { Log } from './schema';
|
|
|
12
12
|
|
|
13
13
|
const Toolbar = lazy(() => import('./Toolbar'));
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
15
|
+
const meta = {
|
|
16
|
+
id: 'dxos.org/test/logger',
|
|
17
|
+
name: 'Logger',
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export const LoggerPlugin = definePlugin(meta, () => [
|
|
21
|
+
defineModule({
|
|
22
|
+
id: 'dxos.org/test/logger/intents',
|
|
23
|
+
activatesOn: Events.SetupIntentResolver,
|
|
24
|
+
activate: () => [
|
|
25
|
+
contributes(
|
|
26
|
+
Capabilities.IntentResolver,
|
|
27
|
+
createResolver({
|
|
28
|
+
intent: Log,
|
|
29
|
+
resolve: ({ message }) => {
|
|
30
|
+
log.info(message);
|
|
31
|
+
},
|
|
32
|
+
}),
|
|
33
|
+
),
|
|
34
|
+
],
|
|
35
|
+
}),
|
|
36
|
+
defineModule({
|
|
37
|
+
id: 'dxos.org/test/logger/surfaces',
|
|
38
|
+
activatesOn: Events.Startup,
|
|
39
|
+
activate: Toolbar,
|
|
40
|
+
}),
|
|
41
|
+
]);
|
|
@@ -2,22 +2,21 @@
|
|
|
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
6
|
import React from 'react';
|
|
9
7
|
|
|
10
|
-
import {
|
|
8
|
+
import { withTheme } from '@dxos/react-ui/testing';
|
|
11
9
|
|
|
12
|
-
import { useApp } from '../App';
|
|
13
10
|
import { IntentPlugin } from '../plugin-intent';
|
|
11
|
+
import { useApp } from '../react';
|
|
14
12
|
|
|
15
13
|
import { DebugPlugin } from './debug';
|
|
16
14
|
import { GeneratorPlugin, createNumberPlugin } from './generator';
|
|
17
15
|
import { LayoutPlugin } from './layout';
|
|
18
16
|
import { LoggerPlugin } from './logger';
|
|
19
17
|
|
|
20
|
-
const
|
|
18
|
+
const pluginFactories = [IntentPlugin, LayoutPlugin, DebugPlugin(), LoggerPlugin(), GeneratorPlugin()];
|
|
19
|
+
const plugins = pluginFactories.map((factory) => (typeof factory === 'function' ? factory() : factory));
|
|
21
20
|
|
|
22
21
|
const Placeholder = () => {
|
|
23
22
|
return <div>Loading...</div>;
|
|
@@ -25,7 +24,7 @@ const Placeholder = () => {
|
|
|
25
24
|
|
|
26
25
|
const DefaultStory = () => {
|
|
27
26
|
const App = useApp({
|
|
28
|
-
pluginLoader: (id) => createNumberPlugin(id),
|
|
27
|
+
pluginLoader: (id) => createNumberPlugin(id)(),
|
|
29
28
|
plugins,
|
|
30
29
|
core: plugins.map((plugin) => plugin.meta.id),
|
|
31
30
|
placeholder: Placeholder,
|
|
@@ -37,7 +36,7 @@ const DefaultStory = () => {
|
|
|
37
36
|
const meta = {
|
|
38
37
|
title: 'sdk/app-framework/playground',
|
|
39
38
|
render: DefaultStory,
|
|
40
|
-
decorators: [withTheme
|
|
39
|
+
decorators: [withTheme],
|
|
41
40
|
} satisfies Meta<typeof DefaultStory>;
|
|
42
41
|
|
|
43
42
|
export default meta;
|
|
@@ -5,17 +5,16 @@
|
|
|
5
5
|
import { Events } from '../common';
|
|
6
6
|
import { defineModule, definePlugin, lazy } from '../core';
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import { meta } from './meta';
|
|
9
9
|
|
|
10
|
-
export const IntentPlugin = () =>
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
]);
|
|
10
|
+
export const IntentPlugin = definePlugin(meta, () => [
|
|
11
|
+
defineModule({
|
|
12
|
+
id: `${meta.id}/module/dispatcher`,
|
|
13
|
+
// TODO(wittjosiah): This will mean that startup needs to be reset when intents are added or removed.
|
|
14
|
+
// This is fine for now because it's how it worked prior to capabilities api anyways.
|
|
15
|
+
// In the future, the intent dispatcher should be able to be reset without resetting the entire app.
|
|
16
|
+
activatesOn: Events.Startup,
|
|
17
|
+
activatesAfter: [Events.DispatcherReady],
|
|
18
|
+
activate: lazy(() => import('./intent-dispatcher')),
|
|
19
|
+
}),
|
|
20
|
+
]);
|
|
@@ -2,18 +2,16 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import * as Schema from 'effect/Schema';
|
|
6
6
|
|
|
7
7
|
import { Label } from './intent';
|
|
8
|
-
|
|
9
|
-
export const INTENT_PLUGIN = 'dxos.org/plugin/intent';
|
|
10
|
-
export const INTENT_ACTION = `${INTENT_PLUGIN}/action`;
|
|
8
|
+
import { meta } from './meta';
|
|
11
9
|
|
|
12
10
|
export namespace IntentAction {
|
|
13
11
|
/**
|
|
14
12
|
* Log an intent.
|
|
15
13
|
*/
|
|
16
|
-
export class Track extends Schema.TaggedClass<Track>()(`${
|
|
14
|
+
export class Track extends Schema.TaggedClass<Track>()(`${meta.id}/action/track`, {
|
|
17
15
|
input: Schema.Struct({
|
|
18
16
|
intents: Schema.Array(Schema.String),
|
|
19
17
|
error: Schema.optional(Schema.String),
|
|
@@ -24,7 +22,7 @@ export namespace IntentAction {
|
|
|
24
22
|
/**
|
|
25
23
|
* Fired after an intent is dispatched if the intent is undoable.
|
|
26
24
|
*/
|
|
27
|
-
export class ShowUndo extends Schema.TaggedClass<ShowUndo>()(`${
|
|
25
|
+
export class ShowUndo extends Schema.TaggedClass<ShowUndo>()(`${meta.id}/action/show-undo`, {
|
|
28
26
|
input: Schema.Struct({
|
|
29
27
|
message: Label,
|
|
30
28
|
}),
|
|
@@ -24,10 +24,11 @@ export class BaseError extends Error {
|
|
|
24
24
|
|
|
25
25
|
export class NoResolversError extends BaseError {
|
|
26
26
|
constructor(action: string) {
|
|
27
|
-
super('NO_RESOLVERS',
|
|
27
|
+
super('NO_RESOLVERS', `No resolvers were found for the action: ${action}`, { action });
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
// TODO(burdon): Detect loops.
|
|
31
32
|
export class CycleDetectedError extends BaseError {
|
|
32
33
|
constructor(context?: Record<string, any>) {
|
|
33
34
|
super(
|
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import * as Effect from 'effect/Effect';
|
|
6
|
+
import * as Fiber from 'effect/Fiber';
|
|
7
|
+
import * as Function from 'effect/Function';
|
|
8
|
+
import * as Schema from 'effect/Schema';
|
|
6
9
|
import { describe, expect, test } from 'vitest';
|
|
7
10
|
|
|
8
11
|
import { chain, createIntent } from './intent';
|
|
@@ -104,7 +107,11 @@ describe('Intent dispatcher', () => {
|
|
|
104
107
|
|
|
105
108
|
test('chain intents', async () => {
|
|
106
109
|
const { dispatch } = createDispatcher(() => [computeResolver, toStringResolver, concatResolver]);
|
|
107
|
-
const intent = pipe(
|
|
110
|
+
const intent = Function.pipe(
|
|
111
|
+
createIntent(Compute, { value: 1 }),
|
|
112
|
+
chain(ToString, {}),
|
|
113
|
+
chain(Concat, { plus: '!' }),
|
|
114
|
+
);
|
|
108
115
|
|
|
109
116
|
expect(intent.first.id).toBe(Compute._tag);
|
|
110
117
|
expect(intent.last.id).toBe(Concat._tag);
|
|
@@ -120,7 +127,7 @@ describe('Intent dispatcher', () => {
|
|
|
120
127
|
|
|
121
128
|
test('undo chained intent', async () => {
|
|
122
129
|
const { dispatch, undo } = createDispatcher(() => [computeResolver, toStringResolver, concatResolver]);
|
|
123
|
-
const intent = pipe(createIntent(Compute, { value: 1 }), chain(Compute, {}), chain(Compute, {}));
|
|
130
|
+
const intent = Function.pipe(createIntent(Compute, { value: 1 }), chain(Compute, {}), chain(Compute, {}));
|
|
124
131
|
const program = Effect.gen(function* () {
|
|
125
132
|
const a = yield* dispatch(intent);
|
|
126
133
|
|