@dxos/plugin-settings 0.8.4-main.d05673bc65 → 0.8.4-main.d9fc60f731
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/LICENSE +102 -5
- package/dist/lib/neutral/SettingsPlugin.mjs +9 -0
- package/dist/lib/neutral/SettingsPlugin.mjs.map +7 -0
- package/dist/lib/neutral/chunk-3DJRTSII.mjs +16 -0
- package/dist/lib/neutral/chunk-3DJRTSII.mjs.map +7 -0
- package/dist/lib/{browser/chunk-DIKK4DQC.mjs → neutral/chunk-J2FJOTAW.mjs} +4 -11
- package/dist/lib/neutral/chunk-J2FJOTAW.mjs.map +7 -0
- package/dist/lib/neutral/chunk-XP4EHGJW.mjs +22 -0
- package/dist/lib/neutral/chunk-XP4EHGJW.mjs.map +7 -0
- package/dist/lib/neutral/index.mjs +18 -0
- package/dist/lib/neutral/index.mjs.map +7 -0
- package/dist/lib/neutral/meta.json +1 -0
- package/dist/lib/neutral/open-NRUWKEGC.mjs +28 -0
- package/dist/lib/neutral/open-NRUWKEGC.mjs.map +7 -0
- package/dist/lib/neutral/open-plugin-registry-XGFG2JWB.mjs +26 -0
- package/dist/lib/neutral/open-plugin-registry-XGFG2JWB.mjs.map +7 -0
- package/dist/lib/neutral/plugin.mjs +18 -0
- package/dist/lib/neutral/plugin.mjs.map +7 -0
- package/dist/lib/neutral/testing.mjs +7 -0
- package/dist/lib/neutral/testing.mjs.map +7 -0
- package/dist/lib/neutral/translations.mjs +15 -0
- package/dist/lib/neutral/translations.mjs.map +7 -0
- package/dist/types/src/SettingsPlugin.d.ts +1 -0
- package/dist/types/src/SettingsPlugin.d.ts.map +1 -1
- package/dist/types/src/SettingsPlugin.test.d.ts +2 -0
- package/dist/types/src/SettingsPlugin.test.d.ts.map +1 -0
- package/dist/types/src/actions.d.ts +4 -4
- package/dist/types/src/actions.d.ts.map +1 -1
- package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -0
- package/dist/types/src/capabilities/index.d.ts +5 -2
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/operation-handler.d.ts +6 -0
- package/dist/types/src/capabilities/operation-handler.d.ts.map +1 -0
- package/dist/types/src/capabilities/{operation-resolver/operation-resolver.d.ts → react-surface.d.ts} +2 -2
- package/dist/types/src/capabilities/react-surface.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +2 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts +1 -1
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/operations/index.d.ts +3 -0
- package/dist/types/src/operations/index.d.ts.map +1 -0
- package/dist/types/src/operations/open-plugin-registry.d.ts +5 -0
- package/dist/types/src/operations/open-plugin-registry.d.ts.map +1 -0
- package/dist/types/src/operations/open.d.ts +5 -0
- package/dist/types/src/operations/open.d.ts.map +1 -0
- package/dist/types/src/plugin.d.ts +4 -0
- package/dist/types/src/plugin.d.ts.map +1 -0
- package/dist/types/src/testing.d.ts +2 -0
- package/dist/types/src/testing.d.ts.map +1 -0
- package/dist/types/src/translations.d.ts +2 -4
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types/index.d.ts +3 -0
- package/dist/types/src/types/index.d.ts.map +1 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +38 -16
- package/src/SettingsPlugin.test.ts +33 -0
- package/src/SettingsPlugin.ts +7 -4
- package/src/actions.ts +4 -4
- package/src/capabilities/{app-graph-builder/app-graph-builder.ts → app-graph-builder.ts} +27 -22
- package/src/capabilities/index.ts +9 -2
- package/src/capabilities/operation-handler.ts +16 -0
- package/src/capabilities/react-surface.tsx +50 -0
- package/src/index.ts +2 -1
- package/src/meta.ts +7 -4
- package/src/operations/index.ts +10 -0
- package/src/operations/open-plugin-registry.ts +28 -0
- package/src/operations/open.ts +30 -0
- package/src/plugin.ts +11 -0
- package/src/testing.ts +7 -0
- package/src/translations.ts +2 -3
- package/src/types/index.ts +8 -0
- package/dist/lib/browser/app-graph-builder-YWCB3EZC.mjs +0 -97
- package/dist/lib/browser/app-graph-builder-YWCB3EZC.mjs.map +0 -7
- package/dist/lib/browser/chunk-DIKK4DQC.mjs.map +0 -7
- package/dist/lib/browser/index.mjs +0 -46
- package/dist/lib/browser/index.mjs.map +0 -7
- package/dist/lib/browser/meta.json +0 -1
- package/dist/lib/browser/operation-resolver-7AAHDR6U.mjs +0 -54
- package/dist/lib/browser/operation-resolver-7AAHDR6U.mjs.map +0 -7
- package/dist/lib/node-esm/app-graph-builder-WSMWJBGZ.mjs +0 -98
- package/dist/lib/node-esm/app-graph-builder-WSMWJBGZ.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-NAEV3LFJ.mjs +0 -37
- package/dist/lib/node-esm/chunk-NAEV3LFJ.mjs.map +0 -7
- package/dist/lib/node-esm/index.mjs +0 -47
- package/dist/lib/node-esm/index.mjs.map +0 -7
- package/dist/lib/node-esm/meta.json +0 -1
- package/dist/lib/node-esm/operation-resolver-QY6K6X7D.mjs +0 -55
- package/dist/lib/node-esm/operation-resolver-QY6K6X7D.mjs.map +0 -7
- package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts.map +0 -1
- package/dist/types/src/capabilities/app-graph-builder/index.d.ts +0 -3
- package/dist/types/src/capabilities/app-graph-builder/index.d.ts.map +0 -1
- package/dist/types/src/capabilities/operation-resolver/index.d.ts +0 -3
- package/dist/types/src/capabilities/operation-resolver/index.d.ts.map +0 -1
- package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts.map +0 -1
- package/src/capabilities/app-graph-builder/index.ts +0 -7
- package/src/capabilities/operation-resolver/index.ts +0 -10
- package/src/capabilities/operation-resolver/operation-resolver.ts +0 -53
- /package/dist/types/src/capabilities/{app-graph-builder/app-graph-builder.d.ts → app-graph-builder.d.ts} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/plugin-settings",
|
|
3
|
-
"version": "0.8.4-main.
|
|
3
|
+
"version": "0.8.4-main.d9fc60f731",
|
|
4
4
|
"description": "DXOS Settings plugin for managing application settings.",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -8,40 +8,62 @@
|
|
|
8
8
|
"type": "git",
|
|
9
9
|
"url": "https://github.com/dxos/dxos"
|
|
10
10
|
},
|
|
11
|
-
"license": "
|
|
11
|
+
"license": "FSL-1.1-Apache-2.0",
|
|
12
12
|
"author": "DXOS.org",
|
|
13
13
|
"sideEffects": true,
|
|
14
14
|
"type": "module",
|
|
15
|
+
"imports": {
|
|
16
|
+
"#capabilities": "./src/capabilities/index.ts",
|
|
17
|
+
"#meta": "./src/meta.ts",
|
|
18
|
+
"#operations": "./src/operations/index.ts",
|
|
19
|
+
"#plugin": "./src/SettingsPlugin.ts",
|
|
20
|
+
"#translations": "./src/translations.ts",
|
|
21
|
+
"#types": "./src/types/index.ts"
|
|
22
|
+
},
|
|
15
23
|
"exports": {
|
|
16
24
|
".": {
|
|
17
25
|
"source": "./src/index.ts",
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
|
|
26
|
+
"types": "./dist/types/src/index.d.ts",
|
|
27
|
+
"default": "./dist/lib/neutral/index.mjs"
|
|
28
|
+
},
|
|
29
|
+
"./plugin": {
|
|
30
|
+
"source": "./src/plugin.ts",
|
|
31
|
+
"types": "./dist/types/src/plugin.d.ts",
|
|
32
|
+
"default": "./dist/lib/neutral/plugin.mjs"
|
|
33
|
+
},
|
|
34
|
+
"./testing": {
|
|
35
|
+
"source": "./src/testing.ts",
|
|
36
|
+
"types": "./dist/types/src/testing.d.ts",
|
|
37
|
+
"default": "./dist/lib/neutral/testing.mjs"
|
|
38
|
+
},
|
|
39
|
+
"./translations": {
|
|
40
|
+
"source": "./src/translations.ts",
|
|
41
|
+
"types": "./dist/types/src/translations.d.ts",
|
|
42
|
+
"default": "./dist/lib/neutral/translations.mjs"
|
|
21
43
|
}
|
|
22
44
|
},
|
|
23
45
|
"types": "dist/types/src/index.d.ts",
|
|
24
|
-
"typesVersions": {
|
|
25
|
-
"*": {}
|
|
26
|
-
},
|
|
27
46
|
"files": [
|
|
28
47
|
"dist",
|
|
29
48
|
"src"
|
|
30
49
|
],
|
|
31
50
|
"dependencies": {
|
|
32
|
-
"@dxos/app-framework": "0.8.4-main.
|
|
33
|
-
"@dxos/app-graph": "0.8.4-main.
|
|
34
|
-
"@dxos/app-toolkit": "0.8.4-main.
|
|
35
|
-
"@dxos/
|
|
36
|
-
"@dxos/
|
|
51
|
+
"@dxos/app-framework": "0.8.4-main.d9fc60f731",
|
|
52
|
+
"@dxos/app-graph": "0.8.4-main.d9fc60f731",
|
|
53
|
+
"@dxos/app-toolkit": "0.8.4-main.d9fc60f731",
|
|
54
|
+
"@dxos/react-ui-form": "0.8.4-main.d9fc60f731",
|
|
55
|
+
"@dxos/compute": "0.8.4-main.d9fc60f731",
|
|
56
|
+
"@dxos/util": "0.8.4-main.d9fc60f731",
|
|
57
|
+
"@dxos/keys": "0.8.4-main.d9fc60f731"
|
|
37
58
|
},
|
|
38
59
|
"devDependencies": {
|
|
39
60
|
"@types/react": "~19.2.7",
|
|
40
|
-
"effect": "3.
|
|
41
|
-
"react": "~19.2.3"
|
|
61
|
+
"effect": "3.21.2",
|
|
62
|
+
"react": "~19.2.3",
|
|
63
|
+
"@dxos/plugin-graph": "0.8.4-main.d9fc60f731"
|
|
42
64
|
},
|
|
43
65
|
"peerDependencies": {
|
|
44
|
-
"effect": "3.
|
|
66
|
+
"effect": "3.21.2",
|
|
45
67
|
"react": "~19.2.3"
|
|
46
68
|
},
|
|
47
69
|
"publishConfig": {
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { describe, test } from 'vitest';
|
|
6
|
+
|
|
7
|
+
import { ProcessManagerPlugin } from '@dxos/app-framework';
|
|
8
|
+
import { createTestApp } from '@dxos/app-framework/testing';
|
|
9
|
+
import { GraphPlugin } from '@dxos/plugin-graph/plugin';
|
|
10
|
+
|
|
11
|
+
import { SettingsPlugin } from '#plugin';
|
|
12
|
+
|
|
13
|
+
import { meta } from './meta';
|
|
14
|
+
|
|
15
|
+
const moduleId = (name: string) => `${meta.id}.module.${name}`;
|
|
16
|
+
|
|
17
|
+
describe('SettingsPlugin', () => {
|
|
18
|
+
test('modules activate on the expected events', async ({ expect }) => {
|
|
19
|
+
// Use createTestApp directly to avoid a circular dep with plugin-testing.
|
|
20
|
+
// GraphPlugin fires SetupAppGraph (via firesBeforeActivation) during Startup,
|
|
21
|
+
// activating SettingsAppGraphBuilder. ProcessManagerPlugin fires SetupProcessManager
|
|
22
|
+
// during Startup, activating OperationHandler.
|
|
23
|
+
await using harness = await createTestApp({
|
|
24
|
+
plugins: [GraphPlugin(), ProcessManagerPlugin(), SettingsPlugin()],
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
// SettingsAppGraphBuilder activates on SetupAppGraph (fired by GraphPlugin during Startup).
|
|
28
|
+
// OperationHandler activates on SetupProcessManager (fired by ProcessManagerPlugin during Startup).
|
|
29
|
+
expect(harness.manager.getActive()).toEqual(
|
|
30
|
+
expect.arrayContaining([moduleId('SettingsAppGraphBuilder'), moduleId('OperationHandler')]),
|
|
31
|
+
);
|
|
32
|
+
});
|
|
33
|
+
});
|
package/src/SettingsPlugin.ts
CHANGED
|
@@ -5,13 +5,16 @@
|
|
|
5
5
|
import { Plugin } from '@dxos/app-framework';
|
|
6
6
|
import { AppPlugin } from '@dxos/app-toolkit';
|
|
7
7
|
|
|
8
|
-
import {
|
|
9
|
-
import { meta } from '
|
|
10
|
-
import { translations } from '
|
|
8
|
+
import { OperationHandler, ReactSurface, SettingsAppGraphBuilder } from '#capabilities';
|
|
9
|
+
import { meta } from '#meta';
|
|
10
|
+
import { translations } from '#translations';
|
|
11
11
|
|
|
12
12
|
export const SettingsPlugin = Plugin.define(meta).pipe(
|
|
13
13
|
AppPlugin.addAppGraphModule({ activate: SettingsAppGraphBuilder }),
|
|
14
|
-
AppPlugin.
|
|
14
|
+
AppPlugin.addOperationHandlerModule({ activate: OperationHandler }),
|
|
15
|
+
AppPlugin.addSurfaceModule({ activate: ReactSurface }),
|
|
15
16
|
AppPlugin.addTranslationsModule({ translations }),
|
|
16
17
|
Plugin.make,
|
|
17
18
|
);
|
|
19
|
+
|
|
20
|
+
export default SettingsPlugin;
|
package/src/actions.ts
CHANGED
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
|
|
5
5
|
import * as Schema from 'effect/Schema';
|
|
6
6
|
|
|
7
|
-
import { meta } from '
|
|
7
|
+
import { meta } from '#meta';
|
|
8
|
+
import { SETTINGS_ID, SETTINGS_KEY } from '#types';
|
|
8
9
|
|
|
9
|
-
export
|
|
10
|
-
export const SETTINGS_KEY = 'settings';
|
|
10
|
+
export { SETTINGS_ID, SETTINGS_KEY };
|
|
11
11
|
|
|
12
12
|
export namespace SettingsAction {
|
|
13
13
|
export class Open extends Schema.TaggedClass<Open>()(`${meta.id}.open`, {
|
|
@@ -17,7 +17,7 @@ export namespace SettingsAction {
|
|
|
17
17
|
output: Schema.Void,
|
|
18
18
|
}) {}
|
|
19
19
|
|
|
20
|
-
export class OpenPluginRegistry extends Schema.TaggedClass<OpenPluginRegistry>()(`${meta.id}.
|
|
20
|
+
export class OpenPluginRegistry extends Schema.TaggedClass<OpenPluginRegistry>()(`${meta.id}.openPluginRegistry`, {
|
|
21
21
|
input: Schema.Void,
|
|
22
22
|
output: Schema.Void,
|
|
23
23
|
}) {}
|
|
@@ -5,13 +5,14 @@
|
|
|
5
5
|
import * as Effect from 'effect/Effect';
|
|
6
6
|
|
|
7
7
|
import { Capabilities, Capability, type Plugin as Plugin$ } from '@dxos/app-framework';
|
|
8
|
-
import { GraphBuilder, NodeMatcher } from '@dxos/app-graph';
|
|
8
|
+
import { GraphBuilder, Node, NodeMatcher } from '@dxos/app-graph';
|
|
9
9
|
import { AppCapabilities, SettingsOperation, getSpacePath } from '@dxos/app-toolkit';
|
|
10
|
-
import { Operation } from '@dxos/
|
|
10
|
+
import { Operation } from '@dxos/compute';
|
|
11
11
|
import { isNonNullable } from '@dxos/util';
|
|
12
12
|
|
|
13
|
-
import {
|
|
14
|
-
|
|
13
|
+
import { meta } from '#meta';
|
|
14
|
+
|
|
15
|
+
import { SETTINGS_ID, SETTINGS_KEY } from '../actions';
|
|
15
16
|
|
|
16
17
|
export default Capability.makeModule(
|
|
17
18
|
Effect.fnUntraced(function* () {
|
|
@@ -22,15 +23,15 @@ export default Capability.makeModule(
|
|
|
22
23
|
|
|
23
24
|
const extensions = yield* Effect.all([
|
|
24
25
|
GraphBuilder.createExtension({
|
|
25
|
-
id:
|
|
26
|
+
id: 'action',
|
|
26
27
|
match: NodeMatcher.whenRoot,
|
|
27
28
|
actions: () =>
|
|
28
29
|
Effect.succeed([
|
|
29
30
|
{
|
|
30
|
-
id:
|
|
31
|
+
id: 'root',
|
|
31
32
|
data: () => Operation.invoke(SettingsOperation.Open, {}),
|
|
32
33
|
properties: {
|
|
33
|
-
label: ['
|
|
34
|
+
label: ['plugin-settings.label', { ns: meta.id }],
|
|
34
35
|
icon: 'ph--gear--regular',
|
|
35
36
|
disposition: 'menu',
|
|
36
37
|
keyBinding: {
|
|
@@ -42,25 +43,25 @@ export default Capability.makeModule(
|
|
|
42
43
|
]),
|
|
43
44
|
}),
|
|
44
45
|
GraphBuilder.createExtension({
|
|
45
|
-
id:
|
|
46
|
+
id: 'core',
|
|
46
47
|
match: NodeMatcher.whenRoot,
|
|
47
48
|
connector: () =>
|
|
48
49
|
Effect.succeed([
|
|
49
|
-
{
|
|
50
|
+
Node.make({
|
|
50
51
|
id: SETTINGS_ID,
|
|
51
52
|
type: meta.id,
|
|
52
53
|
properties: {
|
|
53
|
-
label: ['
|
|
54
|
+
label: ['plugin-settings.label', { ns: meta.id }],
|
|
54
55
|
icon: 'ph--gear--regular',
|
|
55
56
|
disposition: 'pin-end',
|
|
56
|
-
position: '
|
|
57
|
+
position: 'first',
|
|
57
58
|
testId: 'treeView.appSettings',
|
|
58
59
|
},
|
|
59
|
-
},
|
|
60
|
+
}),
|
|
60
61
|
]),
|
|
61
62
|
}),
|
|
62
63
|
GraphBuilder.createExtension({
|
|
63
|
-
id:
|
|
64
|
+
id: 'plugins',
|
|
64
65
|
match: NodeMatcher.whenId(getSpacePath(SETTINGS_ID)),
|
|
65
66
|
connector: (node, get) => {
|
|
66
67
|
const [manager] = get(managerAtom);
|
|
@@ -77,15 +78,19 @@ export default Capability.makeModule(
|
|
|
77
78
|
return [plugin.meta, settings];
|
|
78
79
|
})
|
|
79
80
|
.filter(isNonNullable)
|
|
80
|
-
.
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
81
|
+
.sort(([a], [b]) => (a.name ?? a.id).localeCompare(b.name ?? b.id, undefined, { sensitivity: 'base' }))
|
|
82
|
+
.map(([meta, settings]: [Plugin$.Meta, AppCapabilities.Settings]) =>
|
|
83
|
+
Node.make({
|
|
84
|
+
id: `${SETTINGS_KEY}:${meta.id.replaceAll('/', ':')}`,
|
|
85
|
+
type: 'category',
|
|
86
|
+
data: settings,
|
|
87
|
+
properties: {
|
|
88
|
+
label: meta.name ?? meta.id,
|
|
89
|
+
icon: meta.icon ?? 'ph--circle--regular',
|
|
90
|
+
iconHue: meta.iconHue,
|
|
91
|
+
},
|
|
92
|
+
}),
|
|
93
|
+
),
|
|
89
94
|
);
|
|
90
95
|
},
|
|
91
96
|
}),
|
|
@@ -2,5 +2,12 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
import { Capability } from '@dxos/app-framework';
|
|
6
|
+
import { OperationHandlerSet } from '@dxos/compute';
|
|
7
|
+
|
|
8
|
+
export const SettingsAppGraphBuilder = Capability.lazy('SettingsAppGraphBuilder', () => import('./app-graph-builder'));
|
|
9
|
+
export const OperationHandler = Capability.lazy<OperationHandlerSet.OperationHandlerSet>(
|
|
10
|
+
'OperationHandler',
|
|
11
|
+
() => import('./operation-handler'),
|
|
12
|
+
);
|
|
13
|
+
export const ReactSurface = Capability.lazy('ReactSurface', () => import('./react-surface'));
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import * as Effect from 'effect/Effect';
|
|
6
|
+
|
|
7
|
+
import { Capabilities, Capability } from '@dxos/app-framework';
|
|
8
|
+
import type { OperationHandlerSet } from '@dxos/compute';
|
|
9
|
+
|
|
10
|
+
import { SettingsOperationHandlerSet } from '#operations';
|
|
11
|
+
|
|
12
|
+
export default Capability.makeModule<OperationHandlerSet.OperationHandlerSet>(
|
|
13
|
+
Effect.fnUntraced(function* () {
|
|
14
|
+
return Capability.contributes(Capabilities.OperationHandler, SettingsOperationHandlerSet);
|
|
15
|
+
}),
|
|
16
|
+
);
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import * as Effect from 'effect/Effect';
|
|
6
|
+
import React from 'react';
|
|
7
|
+
|
|
8
|
+
import { Capabilities, Capability } from '@dxos/app-framework';
|
|
9
|
+
import { Surface, useSettingsState } from '@dxos/app-framework/ui';
|
|
10
|
+
import { type AppCapabilities } from '@dxos/app-toolkit';
|
|
11
|
+
import { AppSurface } from '@dxos/app-toolkit/ui';
|
|
12
|
+
import { Settings as SettingsForm } from '@dxos/react-ui-form';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Generic settings surface rendered for any plugin that contributes an
|
|
16
|
+
* `AppCapabilities.Settings` entry. It drives a schema-based form from the
|
|
17
|
+
* contributed `schema`/`atom`, so plugins whose settings are plain editable
|
|
18
|
+
* fields need not register a bespoke settings surface.
|
|
19
|
+
*
|
|
20
|
+
* No section title is rendered: the settings plank heading already names the
|
|
21
|
+
* plugin. Registered with `position: 'last'` so a plugin-specific surface
|
|
22
|
+
* (matching by prefix) always wins under the settings article's `limit={1}`
|
|
23
|
+
* dispatch.
|
|
24
|
+
*/
|
|
25
|
+
const DefaultSettings = ({ subject }: { subject: AppCapabilities.Settings }) => {
|
|
26
|
+
const { settings, updateSettings } = useSettingsState<Record<string, any>>(subject.atom);
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<SettingsForm.Viewport>
|
|
30
|
+
<SettingsForm.FieldSet
|
|
31
|
+
schema={subject.schema}
|
|
32
|
+
values={settings}
|
|
33
|
+
onValuesChanged={(values) => updateSettings(() => values)}
|
|
34
|
+
/>
|
|
35
|
+
</SettingsForm.Viewport>
|
|
36
|
+
);
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export default Capability.makeModule(() =>
|
|
40
|
+
Effect.succeed(
|
|
41
|
+
Capability.contributes(Capabilities.ReactSurface, [
|
|
42
|
+
Surface.create({
|
|
43
|
+
id: 'defaultPluginSettings',
|
|
44
|
+
position: 'last',
|
|
45
|
+
filter: AppSurface.settings(AppSurface.Article),
|
|
46
|
+
component: ({ data: { subject } }) => <DefaultSettings subject={subject} />,
|
|
47
|
+
}),
|
|
48
|
+
]),
|
|
49
|
+
),
|
|
50
|
+
);
|
package/src/index.ts
CHANGED
package/src/meta.ts
CHANGED
|
@@ -2,9 +2,12 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { Plugin } from '@dxos/app-framework';
|
|
6
|
+
import { DXN } from '@dxos/keys';
|
|
6
7
|
|
|
7
|
-
export const meta
|
|
8
|
-
|
|
8
|
+
export const meta = Plugin.makeMeta({
|
|
9
|
+
key: DXN.make('org.dxos.plugin.settings'),
|
|
9
10
|
name: 'Settings',
|
|
10
|
-
|
|
11
|
+
author: 'DXOS',
|
|
12
|
+
tags: ['system'],
|
|
13
|
+
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import * as Effect from 'effect/Effect';
|
|
6
|
+
|
|
7
|
+
import { Capabilities, Capability } from '@dxos/app-framework';
|
|
8
|
+
import { LayoutOperation, SettingsOperation, getSpacePath } from '@dxos/app-toolkit';
|
|
9
|
+
import { Operation } from '@dxos/compute';
|
|
10
|
+
|
|
11
|
+
import { SETTINGS_ID, SETTINGS_KEY } from '../actions';
|
|
12
|
+
|
|
13
|
+
const handler: Operation.WithHandler<typeof SettingsOperation.OpenPluginRegistry> =
|
|
14
|
+
SettingsOperation.OpenPluginRegistry.pipe(
|
|
15
|
+
Operation.withHandler(() =>
|
|
16
|
+
Effect.gen(function* () {
|
|
17
|
+
const { invoke } = yield* Capability.get(Capabilities.OperationInvoker);
|
|
18
|
+
yield* invoke(LayoutOperation.SwitchWorkspace, { subject: getSpacePath(SETTINGS_ID) });
|
|
19
|
+
// Await (don't fork): SwitchWorkspace selects the workspace's first child, so a forked Open
|
|
20
|
+
// races/drops before its deck update applies. Awaiting guarantees the registry is selected.
|
|
21
|
+
yield* invoke(LayoutOperation.Open, {
|
|
22
|
+
subject: [`${getSpacePath(SETTINGS_ID)}/${SETTINGS_KEY}:plugins`],
|
|
23
|
+
});
|
|
24
|
+
}),
|
|
25
|
+
),
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
export default handler;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import * as Effect from 'effect/Effect';
|
|
6
|
+
|
|
7
|
+
import { Capabilities, Capability } from '@dxos/app-framework';
|
|
8
|
+
import { LayoutOperation, SettingsOperation, getSpacePath } from '@dxos/app-toolkit';
|
|
9
|
+
import { Operation } from '@dxos/compute';
|
|
10
|
+
|
|
11
|
+
import { SETTINGS_ID, SETTINGS_KEY } from '../actions';
|
|
12
|
+
|
|
13
|
+
const handler: Operation.WithHandler<typeof SettingsOperation.Open> = SettingsOperation.Open.pipe(
|
|
14
|
+
Operation.withHandler((input) =>
|
|
15
|
+
Effect.gen(function* () {
|
|
16
|
+
const { invoke } = yield* Capability.get(Capabilities.OperationInvoker);
|
|
17
|
+
yield* invoke(LayoutOperation.SwitchWorkspace, { subject: getSpacePath(SETTINGS_ID) });
|
|
18
|
+
if (input.plugin) {
|
|
19
|
+
// Await (don't fork): SwitchWorkspace already selects the workspace's first child, so a
|
|
20
|
+
// forked Open for the requested plugin races/drops before its deck update applies, leaving
|
|
21
|
+
// the wrong plugin selected. Awaiting guarantees the requested plugin becomes the selection.
|
|
22
|
+
yield* invoke(LayoutOperation.Open, {
|
|
23
|
+
subject: [`${getSpacePath(SETTINGS_ID)}/${SETTINGS_KEY}:${input.plugin.replaceAll('/', ':')}`],
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
}),
|
|
27
|
+
),
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
export default handler;
|
package/src/plugin.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2024 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { Plugin } from '@dxos/app-framework';
|
|
6
|
+
|
|
7
|
+
import { meta } from './meta';
|
|
8
|
+
|
|
9
|
+
export const SettingsPlugin = Plugin.lazy(meta, () => import('#plugin'));
|
|
10
|
+
|
|
11
|
+
export { SettingsOperationHandlerSet } from './operations';
|
package/src/testing.ts
ADDED
package/src/translations.ts
CHANGED
|
@@ -4,14 +4,13 @@
|
|
|
4
4
|
|
|
5
5
|
import { type Resource } from '@dxos/app-toolkit';
|
|
6
6
|
|
|
7
|
-
import { meta } from '
|
|
7
|
+
import { meta } from '#meta';
|
|
8
8
|
|
|
9
9
|
export const translations = [
|
|
10
10
|
{
|
|
11
11
|
'en-US': {
|
|
12
12
|
[meta.id]: {
|
|
13
|
-
'
|
|
14
|
-
'app settings label': 'Settings',
|
|
13
|
+
'plugin-settings.label': 'Plugin Settings',
|
|
15
14
|
},
|
|
16
15
|
},
|
|
17
16
|
},
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
SETTINGS_ID,
|
|
3
|
-
SETTINGS_KEY,
|
|
4
|
-
meta
|
|
5
|
-
} from "./chunk-DIKK4DQC.mjs";
|
|
6
|
-
|
|
7
|
-
// src/capabilities/app-graph-builder/app-graph-builder.ts
|
|
8
|
-
import * as Effect from "effect/Effect";
|
|
9
|
-
import { Capabilities, Capability } from "@dxos/app-framework";
|
|
10
|
-
import { GraphBuilder, NodeMatcher } from "@dxos/app-graph";
|
|
11
|
-
import { AppCapabilities, SettingsOperation, getSpacePath } from "@dxos/app-toolkit";
|
|
12
|
-
import { Operation } from "@dxos/operation";
|
|
13
|
-
import { isNonNullable } from "@dxos/util";
|
|
14
|
-
var app_graph_builder_default = Capability.makeModule(Effect.fnUntraced(function* () {
|
|
15
|
-
const capabilities = yield* Capability.Service;
|
|
16
|
-
const managerAtom = capabilities.atom(Capabilities.PluginManager);
|
|
17
|
-
const settingsAtom = capabilities.atom(AppCapabilities.Settings);
|
|
18
|
-
const extensions = yield* Effect.all([
|
|
19
|
-
GraphBuilder.createExtension({
|
|
20
|
-
id: `${meta.id}.action`,
|
|
21
|
-
match: NodeMatcher.whenRoot,
|
|
22
|
-
actions: () => Effect.succeed([
|
|
23
|
-
{
|
|
24
|
-
id: meta.id,
|
|
25
|
-
data: () => Operation.invoke(SettingsOperation.Open, {}),
|
|
26
|
-
properties: {
|
|
27
|
-
label: [
|
|
28
|
-
"open settings label",
|
|
29
|
-
{
|
|
30
|
-
ns: meta.id
|
|
31
|
-
}
|
|
32
|
-
],
|
|
33
|
-
icon: "ph--gear--regular",
|
|
34
|
-
disposition: "menu",
|
|
35
|
-
keyBinding: {
|
|
36
|
-
macos: "meta+,",
|
|
37
|
-
windows: "alt+,"
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
])
|
|
42
|
-
}),
|
|
43
|
-
GraphBuilder.createExtension({
|
|
44
|
-
id: `${meta.id}.core`,
|
|
45
|
-
match: NodeMatcher.whenRoot,
|
|
46
|
-
connector: () => Effect.succeed([
|
|
47
|
-
{
|
|
48
|
-
id: SETTINGS_ID,
|
|
49
|
-
type: meta.id,
|
|
50
|
-
properties: {
|
|
51
|
-
label: [
|
|
52
|
-
"app settings label",
|
|
53
|
-
{
|
|
54
|
-
ns: meta.id
|
|
55
|
-
}
|
|
56
|
-
],
|
|
57
|
-
icon: "ph--gear--regular",
|
|
58
|
-
disposition: "pin-end",
|
|
59
|
-
position: "hoist",
|
|
60
|
-
testId: "treeView.appSettings"
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
])
|
|
64
|
-
}),
|
|
65
|
-
GraphBuilder.createExtension({
|
|
66
|
-
id: `${meta.id}.plugins`,
|
|
67
|
-
match: NodeMatcher.whenId(getSpacePath(SETTINGS_ID)),
|
|
68
|
-
connector: (node, get) => {
|
|
69
|
-
const [manager] = get(managerAtom);
|
|
70
|
-
const allSettings = get(settingsAtom);
|
|
71
|
-
return Effect.succeed(manager.getPlugins().map((plugin) => {
|
|
72
|
-
const settings = allSettings.find((s) => s.prefix === plugin.meta.id);
|
|
73
|
-
if (!settings) {
|
|
74
|
-
return null;
|
|
75
|
-
}
|
|
76
|
-
return [
|
|
77
|
-
plugin.meta,
|
|
78
|
-
settings
|
|
79
|
-
];
|
|
80
|
-
}).filter(isNonNullable).map(([meta2, settings]) => ({
|
|
81
|
-
id: `${SETTINGS_KEY}:${meta2.id.replaceAll("/", ":")}`,
|
|
82
|
-
type: "category",
|
|
83
|
-
data: settings,
|
|
84
|
-
properties: {
|
|
85
|
-
label: meta2.name ?? meta2.id,
|
|
86
|
-
icon: meta2.icon ?? "ph--circle--regular"
|
|
87
|
-
}
|
|
88
|
-
})));
|
|
89
|
-
}
|
|
90
|
-
})
|
|
91
|
-
]);
|
|
92
|
-
return Capability.contributes(AppCapabilities.AppGraphBuilder, extensions);
|
|
93
|
-
}));
|
|
94
|
-
export {
|
|
95
|
-
app_graph_builder_default as default
|
|
96
|
-
};
|
|
97
|
-
//# sourceMappingURL=app-graph-builder-YWCB3EZC.mjs.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/capabilities/app-graph-builder/app-graph-builder.ts"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\n\nimport { Capabilities, Capability, type Plugin as Plugin$ } from '@dxos/app-framework';\nimport { GraphBuilder, NodeMatcher } from '@dxos/app-graph';\nimport { AppCapabilities, SettingsOperation, getSpacePath } from '@dxos/app-toolkit';\nimport { Operation } from '@dxos/operation';\nimport { isNonNullable } from '@dxos/util';\n\nimport { SETTINGS_ID, SETTINGS_KEY } from '../../actions';\nimport { meta } from '../../meta';\n\nexport default Capability.makeModule(\n Effect.fnUntraced(function* () {\n // Get context for lazy capability access in callbacks.\n const capabilities = yield* Capability.Service;\n const managerAtom = capabilities.atom(Capabilities.PluginManager);\n const settingsAtom = capabilities.atom(AppCapabilities.Settings);\n\n const extensions = yield* Effect.all([\n GraphBuilder.createExtension({\n id: `${meta.id}.action`,\n match: NodeMatcher.whenRoot,\n actions: () =>\n Effect.succeed([\n {\n id: meta.id,\n data: () => Operation.invoke(SettingsOperation.Open, {}),\n properties: {\n label: ['open settings label', { ns: meta.id }],\n icon: 'ph--gear--regular',\n disposition: 'menu',\n keyBinding: {\n macos: 'meta+,',\n windows: 'alt+,',\n },\n },\n },\n ]),\n }),\n GraphBuilder.createExtension({\n id: `${meta.id}.core`,\n match: NodeMatcher.whenRoot,\n connector: () =>\n Effect.succeed([\n {\n id: SETTINGS_ID,\n type: meta.id,\n properties: {\n label: ['app settings label', { ns: meta.id }],\n icon: 'ph--gear--regular',\n disposition: 'pin-end',\n position: 'hoist',\n testId: 'treeView.appSettings',\n },\n },\n ]),\n }),\n GraphBuilder.createExtension({\n id: `${meta.id}.plugins`,\n match: NodeMatcher.whenId(getSpacePath(SETTINGS_ID)),\n connector: (node, get) => {\n const [manager] = get(managerAtom);\n const allSettings = get(settingsAtom);\n return Effect.succeed(\n manager\n .getPlugins()\n .map((plugin: Plugin$.Plugin): [Plugin$.Meta, AppCapabilities.Settings] | null => {\n const settings = allSettings.find((s) => s.prefix === plugin.meta.id);\n if (!settings) {\n return null;\n }\n\n return [plugin.meta, settings];\n })\n .filter(isNonNullable)\n .map(([meta, settings]: [Plugin$.Meta, AppCapabilities.Settings]) => ({\n id: `${SETTINGS_KEY}:${meta.id.replaceAll('/', ':')}`,\n type: 'category',\n data: settings,\n properties: {\n label: meta.name ?? meta.id,\n icon: meta.icon ?? 'ph--circle--regular',\n },\n })),\n );\n },\n }),\n ]);\n\n return Capability.contributes(AppCapabilities.AppGraphBuilder, extensions);\n }),\n);\n"],
|
|
5
|
-
"mappings": ";;;;;;;AAIA,YAAYA,YAAY;AAExB,SAASC,cAAcC,kBAA0C;AACjE,SAASC,cAAcC,mBAAmB;AAC1C,SAASC,iBAAiBC,mBAAmBC,oBAAoB;AACjE,SAASC,iBAAiB;AAC1B,SAASC,qBAAqB;AAK9B,IAAA,4BAAeC,WAAWC,WACjBC,kBAAW,aAAA;AAEhB,QAAMC,eAAe,OAAOH,WAAWI;AACvC,QAAMC,cAAcF,aAAaG,KAAKC,aAAaC,aAAa;AAChE,QAAMC,eAAeN,aAAaG,KAAKI,gBAAgBC,QAAQ;AAE/D,QAAMC,aAAa,OAAcC,WAAI;IACnCC,aAAaC,gBAAgB;MAC3BC,IAAI,GAAGC,KAAKD,EAAE;MACdE,OAAOC,YAAYC;MACnBC,SAAS,MACAC,eAAQ;QACb;UACEN,IAAIC,KAAKD;UACTO,MAAM,MAAMC,UAAUC,OAAOC,kBAAkBC,MAAM,CAAC,CAAA;UACtDC,YAAY;YACVC,OAAO;cAAC;cAAuB;gBAAEC,IAAIb,KAAKD;cAAG;;YAC7Ce,MAAM;YACNC,aAAa;YACbC,YAAY;cACVC,OAAO;cACPC,SAAS;YACX;UACF;QACF;OACD;IACL,CAAA;IACArB,aAAaC,gBAAgB;MAC3BC,IAAI,GAAGC,KAAKD,EAAE;MACdE,OAAOC,YAAYC;MACnBgB,WAAW,MACFd,eAAQ;QACb;UACEN,IAAIqB;UACJC,MAAMrB,KAAKD;UACXY,YAAY;YACVC,OAAO;cAAC;cAAsB;gBAAEC,IAAIb,KAAKD;cAAG;;YAC5Ce,MAAM;YACNC,aAAa;YACbO,UAAU;YACVC,QAAQ;UACV;QACF;OACD;IACL,CAAA;IACA1B,aAAaC,gBAAgB;MAC3BC,IAAI,GAAGC,KAAKD,EAAE;MACdE,OAAOC,YAAYsB,OAAOC,aAAaL,WAAAA,CAAAA;MACvCD,WAAW,CAACO,MAAMC,QAAAA;AAChB,cAAM,CAACC,OAAAA,IAAWD,IAAIvC,WAAAA;AACtB,cAAMyC,cAAcF,IAAInC,YAAAA;AACxB,eAAca,eACZuB,QACGE,WAAU,EACVC,IAAI,CAACC,WAAAA;AACJ,gBAAMC,WAAWJ,YAAYK,KAAK,CAACC,MAAMA,EAAEC,WAAWJ,OAAOhC,KAAKD,EAAE;AACpE,cAAI,CAACkC,UAAU;AACb,mBAAO;UACT;AAEA,iBAAO;YAACD,OAAOhC;YAAMiC;;QACvB,CAAA,EACCI,OAAOC,aAAAA,EACPP,IAAI,CAAC,CAAC/B,OAAMiC,QAAAA,OAAyD;UACpElC,IAAI,GAAGwC,YAAAA,IAAgBvC,MAAKD,GAAGyC,WAAW,KAAK,GAAA,CAAA;UAC/CnB,MAAM;UACNf,MAAM2B;UACNtB,YAAY;YACVC,OAAOZ,MAAKyC,QAAQzC,MAAKD;YACzBe,MAAMd,MAAKc,QAAQ;UACrB;QACF,EAAA,CAAA;MAEN;IACF,CAAA;GACD;AAED,SAAO/B,WAAW2D,YAAYjD,gBAAgBkD,iBAAiBhD,UAAAA;AACjE,CAAA,CAAA;",
|
|
6
|
-
"names": ["Effect", "Capabilities", "Capability", "GraphBuilder", "NodeMatcher", "AppCapabilities", "SettingsOperation", "getSpacePath", "Operation", "isNonNullable", "Capability", "makeModule", "fnUntraced", "capabilities", "Service", "managerAtom", "atom", "Capabilities", "PluginManager", "settingsAtom", "AppCapabilities", "Settings", "extensions", "all", "GraphBuilder", "createExtension", "id", "meta", "match", "NodeMatcher", "whenRoot", "actions", "succeed", "data", "Operation", "invoke", "SettingsOperation", "Open", "properties", "label", "ns", "icon", "disposition", "keyBinding", "macos", "windows", "connector", "SETTINGS_ID", "type", "position", "testId", "whenId", "getSpacePath", "node", "get", "manager", "allSettings", "getPlugins", "map", "plugin", "settings", "find", "s", "prefix", "filter", "isNonNullable", "SETTINGS_KEY", "replaceAll", "name", "contributes", "AppGraphBuilder"]
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/meta.ts", "../../../src/actions.ts"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport { type Plugin } from '@dxos/app-framework';\n\nexport const meta: Plugin.Meta = {\n id: 'org.dxos.plugin.settings',\n name: 'Settings',\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport * as Schema from 'effect/Schema';\n\nimport { meta } from './meta';\n\nexport const SETTINGS_ID = '!dxos:settings';\nexport const SETTINGS_KEY = 'settings';\n\nexport namespace SettingsAction {\n export class Open extends Schema.TaggedClass<Open>()(`${meta.id}.open`, {\n input: Schema.Struct({\n plugin: Schema.optional(Schema.String),\n }),\n output: Schema.Void,\n }) {}\n\n export class OpenPluginRegistry extends Schema.TaggedClass<OpenPluginRegistry>()(`${meta.id}.open-plugin-registry`, {\n input: Schema.Void,\n output: Schema.Void,\n }) {}\n}\n"],
|
|
5
|
-
"mappings": ";AAMO,IAAMA,OAAoB;EAC/BC,IAAI;EACJC,MAAM;AACR;;;ACLA,YAAYC,YAAY;AAIjB,IAAMC,cAAc;AACpB,IAAMC,eAAe;UAEXC,iBAAAA;EACR,MAAMC,aAAoBC,mBAAW,EAAS,GAAGC,KAAKC,EAAE,SAAS;IACtEC,OAAcC,cAAO;MACnBC,QAAeC,gBAAgBC,aAAM;IACvC,CAAA;IACAC,QAAeC;EACjB,CAAA,EAAA;EAAI;kBALSV,OAAAA;EAON,MAAMW,2BAAkCV,mBAAW,EAAuB,GAAGC,KAAKC,EAAE,yBAAyB;IAClHC,OAAcM;IACdD,QAAeC;EACjB,CAAA,EAAA;EAAI;kBAHSC,qBAAAA;AAIf,GAZiBZ,mBAAAA,iBAAAA,CAAAA,EAAAA;;",
|
|
6
|
-
"names": ["meta", "id", "name", "Schema", "SETTINGS_ID", "SETTINGS_KEY", "SettingsAction", "Open", "TaggedClass", "meta", "id", "input", "Struct", "plugin", "optional", "String", "output", "Void", "OpenPluginRegistry"]
|
|
7
|
-
}
|