@dxos/plugin-registry 0.8.4-main.422d1c7879 → 0.8.4-main.4f23b4e393
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/neutral/RegistryPlugin.mjs +27 -0
- package/dist/lib/neutral/RegistryPlugin.mjs.map +7 -0
- package/dist/lib/{browser/cli/index.mjs → neutral/RegistryPlugin.node.mjs} +29 -95
- package/dist/lib/neutral/RegistryPlugin.node.mjs.map +7 -0
- package/dist/lib/neutral/chunk-XK2JMH3H.mjs +33 -0
- package/dist/lib/neutral/chunk-XK2JMH3H.mjs.map +7 -0
- package/dist/lib/neutral/chunk-YV7A523U.mjs +29 -0
- package/dist/lib/neutral/chunk-YV7A523U.mjs.map +7 -0
- package/dist/lib/neutral/index.mjs +21 -0
- package/dist/lib/neutral/index.mjs.map +7 -0
- package/dist/lib/neutral/meta.json +1 -0
- package/dist/lib/neutral/open-plugin-registry-II735N76.mjs +15 -0
- package/dist/lib/neutral/open-plugin-registry-II735N76.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/translations.mjs +61 -0
- package/dist/lib/neutral/translations.mjs.map +7 -0
- package/dist/types/src/RegistryPlugin.d.ts +1 -0
- package/dist/types/src/RegistryPlugin.d.ts.map +1 -1
- package/dist/types/src/{cli/plugin.d.ts → RegistryPlugin.node.d.ts} +2 -1
- package/dist/types/src/RegistryPlugin.node.d.ts.map +1 -0
- package/dist/types/src/RegistryPlugin.test.d.ts +2 -0
- package/dist/types/src/RegistryPlugin.test.d.ts.map +1 -0
- package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
- package/dist/types/src/capabilities/dev-plugin-loader.d.ts +11 -0
- package/dist/types/src/capabilities/dev-plugin-loader.d.ts.map +1 -0
- package/dist/types/src/capabilities/index.d.ts +11 -2
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/operation-handler.d.ts +1 -1
- package/dist/types/src/capabilities/operation-handler.d.ts.map +1 -1
- package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
- package/dist/types/src/capabilities/settings.d.ts +14 -0
- package/dist/types/src/capabilities/settings.d.ts.map +1 -0
- package/dist/types/src/{cli/commands → commands}/disable.d.ts +2 -2
- package/dist/types/src/commands/disable.d.ts.map +1 -0
- package/dist/types/src/{cli/commands → commands}/enable.d.ts +2 -2
- package/dist/types/src/commands/enable.d.ts.map +1 -0
- package/dist/types/src/commands/index.d.ts.map +1 -0
- package/dist/types/src/commands/list.d.ts +7 -0
- package/dist/types/src/commands/list.d.ts.map +1 -0
- package/dist/types/src/commands/util.d.ts.map +1 -0
- package/dist/types/src/components/PluginDetail/PluginDetail.d.ts +26 -2
- package/dist/types/src/components/PluginDetail/PluginDetail.d.ts.map +1 -1
- package/dist/types/src/components/PluginDetail/PluginDetail.stories.d.ts +49 -23
- package/dist/types/src/components/PluginDetail/PluginDetail.stories.d.ts.map +1 -1
- package/dist/types/src/components/PluginFailureBadge/PluginFailureBadge.d.ts +20 -0
- package/dist/types/src/components/PluginFailureBadge/PluginFailureBadge.d.ts.map +1 -0
- package/dist/types/src/components/PluginFailureBadge/index.d.ts +2 -0
- package/dist/types/src/components/PluginFailureBadge/index.d.ts.map +1 -0
- package/dist/types/src/components/PluginList/PluginItem.d.ts +17 -3
- package/dist/types/src/components/PluginList/PluginItem.d.ts.map +1 -1
- package/dist/types/src/components/PluginList/PluginList.d.ts +14 -4
- package/dist/types/src/components/PluginList/PluginList.d.ts.map +1 -1
- package/dist/types/src/components/PluginList/PluginList.stories.d.ts +49 -23
- package/dist/types/src/components/PluginList/PluginList.stories.d.ts.map +1 -1
- package/dist/types/src/components/RegistrySettings/RegistrySettings.d.ts +18 -0
- package/dist/types/src/components/RegistrySettings/RegistrySettings.d.ts.map +1 -0
- package/dist/types/src/components/RegistrySettings/index.d.ts +2 -0
- package/dist/types/src/components/RegistrySettings/index.d.ts.map +1 -0
- package/dist/types/src/components/index.d.ts +2 -0
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/containers/BaseRegistryArticle/BaseRegistryArticle.d.ts +20 -0
- package/dist/types/src/containers/BaseRegistryArticle/BaseRegistryArticle.d.ts.map +1 -0
- package/dist/types/src/containers/BaseRegistryArticle/index.d.ts +2 -0
- package/dist/types/src/containers/BaseRegistryArticle/index.d.ts.map +1 -0
- package/dist/types/src/containers/LoadPluginDialog/LoadPluginDialog.d.ts.map +1 -1
- package/dist/types/src/containers/PluginArticle/PluginArticle.d.ts.map +1 -1
- package/dist/types/src/containers/PublicRegistryArticle/PublicRegistryArticle.d.ts +8 -0
- package/dist/types/src/containers/PublicRegistryArticle/PublicRegistryArticle.d.ts.map +1 -0
- package/dist/types/src/containers/PublicRegistryArticle/index.d.ts +2 -0
- package/dist/types/src/containers/PublicRegistryArticle/index.d.ts.map +1 -0
- package/dist/types/src/containers/RegistryArticle/RegistryArticle.d.ts +14 -0
- package/dist/types/src/containers/RegistryArticle/RegistryArticle.d.ts.map +1 -0
- package/dist/types/src/containers/RegistryArticle/index.d.ts +2 -0
- package/dist/types/src/containers/RegistryArticle/index.d.ts.map +1 -0
- package/dist/types/src/containers/RegistrySettingsContainer/RegistrySettingsContainer.d.ts +13 -0
- package/dist/types/src/containers/RegistrySettingsContainer/RegistrySettingsContainer.d.ts.map +1 -0
- package/dist/types/src/containers/RegistrySettingsContainer/index.d.ts +2 -0
- package/dist/types/src/containers/RegistrySettingsContainer/index.d.ts.map +1 -0
- package/dist/types/src/containers/index.d.ts +3 -2
- package/dist/types/src/containers/index.d.ts.map +1 -1
- package/dist/types/src/hooks/index.d.ts +2 -1
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- package/dist/types/src/hooks/use-auto-tags.d.ts +4 -4
- package/dist/types/src/hooks/use-auto-tags.d.ts.map +1 -1
- package/dist/types/src/hooks/use-registry-plugins.d.ts +15 -0
- package/dist/types/src/hooks/use-registry-plugins.d.ts.map +1 -0
- package/dist/types/src/hooks/use-update-available.d.ts +18 -0
- package/dist/types/src/hooks/use-update-available.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +1 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/operations/index.d.ts +1 -1
- package/dist/types/src/operations/index.d.ts.map +1 -1
- package/dist/types/src/operations/open-plugin-registry.d.ts +1 -1
- package/dist/types/src/operations/open-plugin-registry.d.ts.map +1 -1
- package/dist/types/src/plugin.d.ts +4 -0
- package/dist/types/src/plugin.d.ts.map +1 -0
- package/dist/types/src/{cli/storage.d.ts → storage.d.ts} +1 -1
- package/dist/types/src/storage.d.ts.map +1 -0
- package/dist/types/src/translations.d.ts +48 -23
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types.d.ts +28 -10
- package/dist/types/src/types.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +46 -36
- package/src/{cli/plugin.ts → RegistryPlugin.node.ts} +2 -0
- package/src/RegistryPlugin.test.ts +24 -0
- package/src/RegistryPlugin.tsx +9 -7
- package/src/capabilities/app-graph-builder.ts +25 -17
- package/src/capabilities/dev-plugin-loader.ts +39 -0
- package/src/capabilities/index.ts +3 -2
- package/src/capabilities/operation-handler.ts +1 -1
- package/src/capabilities/react-surface.tsx +63 -47
- package/src/capabilities/settings.ts +34 -0
- package/src/components/PluginDetail/PluginDetail.stories.tsx +3 -2
- package/src/components/PluginDetail/PluginDetail.tsx +105 -15
- package/src/components/PluginFailureBadge/PluginFailureBadge.tsx +68 -0
- package/src/components/PluginFailureBadge/index.ts +5 -0
- package/src/components/PluginList/PluginItem.tsx +46 -7
- package/src/components/PluginList/PluginList.stories.tsx +1 -1
- package/src/components/PluginList/PluginList.tsx +28 -5
- package/src/components/RegistrySettings/RegistrySettings.tsx +120 -0
- package/src/components/RegistrySettings/index.ts +5 -0
- package/src/components/index.ts +2 -0
- package/src/containers/BaseRegistryArticle/BaseRegistryArticle.tsx +163 -0
- package/src/containers/BaseRegistryArticle/index.ts +5 -0
- package/src/containers/LoadPluginDialog/LoadPluginDialog.tsx +4 -3
- package/src/containers/PluginArticle/PluginArticle.tsx +296 -32
- package/src/containers/PublicRegistryArticle/PublicRegistryArticle.tsx +192 -0
- package/src/containers/PublicRegistryArticle/index.ts +5 -0
- package/src/containers/RegistryArticle/RegistryArticle.tsx +53 -0
- package/src/containers/RegistryArticle/index.ts +5 -0
- package/src/containers/RegistrySettingsContainer/RegistrySettingsContainer.tsx +59 -0
- package/src/containers/RegistrySettingsContainer/index.ts +5 -0
- package/src/containers/index.ts +3 -2
- package/src/hooks/index.ts +2 -1
- package/src/hooks/use-auto-tags.ts +7 -8
- package/src/hooks/use-registry-plugins.ts +29 -0
- package/src/hooks/use-update-available.ts +31 -0
- package/src/index.ts +1 -1
- package/src/meta.ts +2 -0
- package/src/operations/index.ts +1 -1
- package/src/operations/open-plugin-registry.ts +1 -1
- package/src/plugin.ts +11 -0
- package/src/translations.ts +33 -3
- package/src/types.ts +21 -14
- package/dist/lib/browser/cli/index.mjs.map +0 -7
- package/dist/lib/browser/index.mjs +0 -78
- package/dist/lib/browser/index.mjs.map +0 -7
- package/dist/lib/browser/meta.json +0 -1
- package/dist/lib/node-esm/cli/index.mjs +0 -221
- package/dist/lib/node-esm/cli/index.mjs.map +0 -7
- package/dist/lib/node-esm/index.mjs +0 -80
- package/dist/lib/node-esm/index.mjs.map +0 -7
- package/dist/lib/node-esm/meta.json +0 -1
- package/dist/types/src/capabilities/state.d.ts +0 -7
- package/dist/types/src/capabilities/state.d.ts.map +0 -1
- package/dist/types/src/cli/commands/disable.d.ts.map +0 -1
- package/dist/types/src/cli/commands/enable.d.ts.map +0 -1
- package/dist/types/src/cli/commands/index.d.ts.map +0 -1
- package/dist/types/src/cli/commands/list.d.ts +0 -7
- package/dist/types/src/cli/commands/list.d.ts.map +0 -1
- package/dist/types/src/cli/commands/util.d.ts.map +0 -1
- package/dist/types/src/cli/index.d.ts +0 -3
- package/dist/types/src/cli/index.d.ts.map +0 -1
- package/dist/types/src/cli/plugin.d.ts.map +0 -1
- package/dist/types/src/cli/storage.d.ts.map +0 -1
- package/dist/types/src/containers/CommunityRegistry/CommunityRegistry.d.ts +0 -8
- package/dist/types/src/containers/CommunityRegistry/CommunityRegistry.d.ts.map +0 -1
- package/dist/types/src/containers/CommunityRegistry/index.d.ts +0 -2
- package/dist/types/src/containers/CommunityRegistry/index.d.ts.map +0 -1
- package/dist/types/src/containers/PluginRegistry/PluginRegistry.d.ts +0 -14
- package/dist/types/src/containers/PluginRegistry/PluginRegistry.d.ts.map +0 -1
- package/dist/types/src/containers/PluginRegistry/index.d.ts +0 -2
- package/dist/types/src/containers/PluginRegistry/index.d.ts.map +0 -1
- package/dist/types/src/hooks/use-community-plugins.d.ts +0 -16
- package/dist/types/src/hooks/use-community-plugins.d.ts.map +0 -1
- package/src/capabilities/state.ts +0 -40
- package/src/cli/index.ts +0 -6
- package/src/containers/CommunityRegistry/CommunityRegistry.tsx +0 -181
- package/src/containers/CommunityRegistry/index.ts +0 -5
- package/src/containers/PluginRegistry/PluginRegistry.tsx +0 -98
- package/src/containers/PluginRegistry/index.ts +0 -5
- package/src/hooks/use-community-plugins.ts +0 -35
- /package/dist/types/src/{cli/commands → commands}/index.d.ts +0 -0
- /package/dist/types/src/{cli/commands → commands}/util.d.ts +0 -0
- /package/src/{cli/commands → commands}/disable.ts +0 -0
- /package/src/{cli/commands → commands}/enable.ts +0 -0
- /package/src/{cli/commands → commands}/index.ts +0 -0
- /package/src/{cli/commands → commands}/list.ts +0 -0
- /package/src/{cli/commands → commands}/util.ts +0 -0
- /package/src/{cli/storage.ts → storage.ts} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/containers/PluginRegistry/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,cAAc,IAAI,OAAO,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import * as Effect from 'effect/Effect';
|
|
2
|
-
import { type EdgeHttpClient } from '@dxos/edge-client';
|
|
3
|
-
import { type PluginEntry } from '@dxos/protocols';
|
|
4
|
-
import { type CommunityPluginsState } from '#types';
|
|
5
|
-
/**
|
|
6
|
-
* Fetches the community plugin catalog from the Edge registry service and
|
|
7
|
-
* filters out unhealthy entries.
|
|
8
|
-
*/
|
|
9
|
-
export declare const loadCommunityPlugins: (client: EdgeHttpClient) => Effect.Effect<readonly PluginEntry[], Error>;
|
|
10
|
-
/**
|
|
11
|
-
* Reads the community plugin catalog from the registry state capability. The
|
|
12
|
-
* catalog is loaded once at plugin startup so this hook is purely reactive.
|
|
13
|
-
* Returns the empty/loading state until the state capability activates.
|
|
14
|
-
*/
|
|
15
|
-
export declare const useCommunityPlugins: () => CommunityPluginsState;
|
|
16
|
-
//# sourceMappingURL=use-community-plugins.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"use-community-plugins.d.ts","sourceRoot":"","sources":["../../../../src/hooks/use-community-plugins.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAIxC,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEnD,OAAO,EAAwB,KAAK,qBAAqB,EAAE,MAAM,QAAQ,CAAC;AAE1E;;;GAGG;AACH,eAAO,MAAM,oBAAoB,GAAI,QAAQ,cAAc,KAAG,MAAM,CAAC,MAAM,CAAC,SAAS,WAAW,EAAE,EAAE,KAAK,CAInB,CAAC;AAIvF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,QAAO,qBAGtC,CAAC"}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2026 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import { Atom } from '@effect-atom/atom-react';
|
|
6
|
-
import * as Effect from 'effect/Effect';
|
|
7
|
-
|
|
8
|
-
import { Capabilities, Capability } from '@dxos/app-framework';
|
|
9
|
-
import { log } from '@dxos/log';
|
|
10
|
-
import { ClientCapabilities } from '@dxos/plugin-client/types';
|
|
11
|
-
|
|
12
|
-
import { RegistryCapabilities, type CommunityPluginsState } from '#types';
|
|
13
|
-
|
|
14
|
-
import { loadCommunityPlugins } from '../hooks';
|
|
15
|
-
|
|
16
|
-
export default Capability.makeModule(
|
|
17
|
-
Effect.fnUntraced(function* () {
|
|
18
|
-
const capabilities = yield* Capability.Service;
|
|
19
|
-
const registry = yield* Capability.get(Capabilities.AtomRegistry);
|
|
20
|
-
|
|
21
|
-
const communityPluginsAtom = Atom.make<CommunityPluginsState>({ entries: [], loading: true, error: null }).pipe(
|
|
22
|
-
Atom.keepAlive,
|
|
23
|
-
);
|
|
24
|
-
|
|
25
|
-
const client = capabilities.get(ClientCapabilities.Client);
|
|
26
|
-
|
|
27
|
-
yield* loadCommunityPlugins(client.edge.http).pipe(
|
|
28
|
-
Effect.match({
|
|
29
|
-
onSuccess: (entries) => registry.set(communityPluginsAtom, { entries, loading: false, error: null }),
|
|
30
|
-
onFailure: (error) => {
|
|
31
|
-
log.catch(error);
|
|
32
|
-
registry.set(communityPluginsAtom, { entries: [], loading: false, error });
|
|
33
|
-
},
|
|
34
|
-
}),
|
|
35
|
-
Effect.forkDaemon,
|
|
36
|
-
);
|
|
37
|
-
|
|
38
|
-
return Capability.contributes(RegistryCapabilities.State, communityPluginsAtom);
|
|
39
|
-
}),
|
|
40
|
-
);
|
package/src/cli/index.ts
DELETED
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2026 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import { useAtomValue } from '@effect-atom/atom-react';
|
|
6
|
-
import * as Effect from 'effect/Effect';
|
|
7
|
-
import React, { useCallback, useMemo, useState } from 'react';
|
|
8
|
-
|
|
9
|
-
import { Plugin, UrlLoader } from '@dxos/app-framework';
|
|
10
|
-
import { useCapabilities, useOperationInvoker, usePluginManager } from '@dxos/app-framework/ui';
|
|
11
|
-
import { AppCapabilities, LayoutOperation, SettingsOperation } from '@dxos/app-toolkit';
|
|
12
|
-
import { runAndForwardErrors } from '@dxos/effect';
|
|
13
|
-
import { ObservabilityOperation } from '@dxos/plugin-observability/operations';
|
|
14
|
-
import { type PluginEntry } from '@dxos/protocols';
|
|
15
|
-
import { ScrollArea, useTranslation } from '@dxos/react-ui';
|
|
16
|
-
import { composable, composableProps } from '@dxos/ui-theme';
|
|
17
|
-
|
|
18
|
-
import { PluginList } from '#components';
|
|
19
|
-
import { getPluginPath, meta } from '#meta';
|
|
20
|
-
|
|
21
|
-
import { useAutoTags, useCommunityPlugins } from '../../hooks';
|
|
22
|
-
|
|
23
|
-
const sortEntries = (a: PluginEntry, b: PluginEntry) =>
|
|
24
|
-
(a.meta.name ?? a.meta.id).localeCompare(b.meta.name ?? b.meta.id);
|
|
25
|
-
|
|
26
|
-
const sortPlugins = (a: Plugin.Plugin, b: Plugin.Plugin) =>
|
|
27
|
-
(a.meta.name ?? a.meta.id).localeCompare(b.meta.name ?? b.meta.id);
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Turns a community manifest entry into a minimal Plugin object so we can reuse
|
|
31
|
-
* {@link PluginList} for rendering. The synthesized plugin has no modules — it
|
|
32
|
-
* exists only for display until the user installs it.
|
|
33
|
-
*/
|
|
34
|
-
const toDisplayPlugin = (entry: PluginEntry): Plugin.Plugin =>
|
|
35
|
-
({
|
|
36
|
-
[Plugin.PluginTypeId]: Plugin.PluginTypeId,
|
|
37
|
-
meta: entry.meta,
|
|
38
|
-
modules: [],
|
|
39
|
-
}) as Plugin.Plugin;
|
|
40
|
-
|
|
41
|
-
export type CommunityRegistryProps = {
|
|
42
|
-
id: string;
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
export const CommunityRegistry = composable<HTMLDivElement, CommunityRegistryProps>(
|
|
46
|
-
({ id, ...props }, forwardedRef) => {
|
|
47
|
-
const { t } = useTranslation(meta.id);
|
|
48
|
-
const manager = usePluginManager();
|
|
49
|
-
const { invoke, invokePromise } = useOperationInvoker();
|
|
50
|
-
const { entries, loading, error } = useCommunityPlugins();
|
|
51
|
-
const enabled = useAtomValue(manager.enabled);
|
|
52
|
-
const plugins = useAtomValue(manager.plugins);
|
|
53
|
-
const installedIds = useMemo(() => plugins.map((plugin) => plugin.meta.id), [plugins]);
|
|
54
|
-
const allSettings = useCapabilities(AppCapabilities.Settings);
|
|
55
|
-
const extraTagsById = useAutoTags(entries);
|
|
56
|
-
|
|
57
|
-
// Snapshot of installed plugin ids at mount time. Used to sort installed
|
|
58
|
-
// plugins to the top without having newly-installed rows jump up mid-session.
|
|
59
|
-
const [installedSnapshot] = useState<ReadonlySet<string>>(
|
|
60
|
-
() => new Set(manager.getPlugins().map((plugin) => plugin.meta.id)),
|
|
61
|
-
);
|
|
62
|
-
|
|
63
|
-
const [installingIds, setInstallingIds] = useState<readonly string[]>([]);
|
|
64
|
-
|
|
65
|
-
const sortedEntries = useMemo(() => [...entries].sort(sortEntries), [entries]);
|
|
66
|
-
const moduleUrlById = useMemo(() => {
|
|
67
|
-
const map: Record<string, string> = {};
|
|
68
|
-
for (const entry of sortedEntries) {
|
|
69
|
-
map[entry.meta.id] = entry.moduleUrl;
|
|
70
|
-
}
|
|
71
|
-
return map;
|
|
72
|
-
}, [sortedEntries]);
|
|
73
|
-
|
|
74
|
-
// Single list with installed-at-mount plugins sorted to the top. Sort order
|
|
75
|
-
// is based on the mount-time snapshot so rows don't jump as the user
|
|
76
|
-
// installs plugins during the session.
|
|
77
|
-
const items = useMemo(() => {
|
|
78
|
-
const catalogIds = new Set(sortedEntries.map((entry) => entry.meta.id));
|
|
79
|
-
const remoteIds = new Set(UrlLoader.getRemoteEntries().map((entry) => entry.id));
|
|
80
|
-
const fromCatalog = sortedEntries.map(toDisplayPlugin);
|
|
81
|
-
const fromUrlOnly = plugins.filter((plugin) => remoteIds.has(plugin.meta.id) && !catalogIds.has(plugin.meta.id));
|
|
82
|
-
const installedFirst = [...fromCatalog, ...fromUrlOnly].sort((a, b) => {
|
|
83
|
-
const aInstalled = installedSnapshot.has(a.meta.id);
|
|
84
|
-
const bInstalled = installedSnapshot.has(b.meta.id);
|
|
85
|
-
if (aInstalled !== bInstalled) {
|
|
86
|
-
return aInstalled ? -1 : 1;
|
|
87
|
-
}
|
|
88
|
-
return sortPlugins(a, b);
|
|
89
|
-
});
|
|
90
|
-
return installedFirst;
|
|
91
|
-
}, [sortedEntries, installedSnapshot, plugins]);
|
|
92
|
-
|
|
93
|
-
const handleChange = useCallback(
|
|
94
|
-
(pluginId: string, nextEnabled: boolean) =>
|
|
95
|
-
Effect.gen(function* () {
|
|
96
|
-
if (nextEnabled) {
|
|
97
|
-
yield* manager.enable(pluginId);
|
|
98
|
-
} else {
|
|
99
|
-
yield* manager.disable(pluginId);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
yield* invoke(ObservabilityOperation.SendEvent, {
|
|
103
|
-
name: 'plugins.toggle',
|
|
104
|
-
properties: { plugin: pluginId, enabled: nextEnabled, source: 'community' },
|
|
105
|
-
});
|
|
106
|
-
}).pipe(runAndForwardErrors),
|
|
107
|
-
[invoke, manager],
|
|
108
|
-
);
|
|
109
|
-
|
|
110
|
-
const handleInstall = useCallback(
|
|
111
|
-
(pluginId: string) => {
|
|
112
|
-
const moduleUrl = moduleUrlById[pluginId];
|
|
113
|
-
if (!moduleUrl) {
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
|
-
setInstallingIds((prev) => (prev.includes(pluginId) ? prev : [...prev, pluginId]));
|
|
117
|
-
void void Effect.gen(function* () {
|
|
118
|
-
const plugin = yield* manager.add(moduleUrl);
|
|
119
|
-
yield* manager.enable(plugin.meta.id);
|
|
120
|
-
yield* invoke(ObservabilityOperation.SendEvent, {
|
|
121
|
-
name: 'plugins.install',
|
|
122
|
-
properties: { plugin: plugin.meta.id, source: 'community' },
|
|
123
|
-
});
|
|
124
|
-
}).pipe(
|
|
125
|
-
Effect.ensuring(Effect.sync(() => setInstallingIds((prev) => prev.filter((pid) => pid !== pluginId)))),
|
|
126
|
-
runAndForwardErrors,
|
|
127
|
-
);
|
|
128
|
-
},
|
|
129
|
-
[invoke, manager, moduleUrlById],
|
|
130
|
-
);
|
|
131
|
-
|
|
132
|
-
const handleClick = useCallback(
|
|
133
|
-
(pluginId: string) =>
|
|
134
|
-
invokePromise(LayoutOperation.Open, {
|
|
135
|
-
subject: [getPluginPath(pluginId)],
|
|
136
|
-
pivotId: id,
|
|
137
|
-
positioning: 'end',
|
|
138
|
-
}),
|
|
139
|
-
[invokePromise, id],
|
|
140
|
-
);
|
|
141
|
-
|
|
142
|
-
const hasSettings = useCallback(
|
|
143
|
-
(pluginId: string) => allSettings.some((setting) => setting.prefix === pluginId),
|
|
144
|
-
[allSettings],
|
|
145
|
-
);
|
|
146
|
-
|
|
147
|
-
const handleSettings = useCallback(
|
|
148
|
-
(pluginId: string) => invokePromise(SettingsOperation.Open, { plugin: pluginId }),
|
|
149
|
-
[invokePromise],
|
|
150
|
-
);
|
|
151
|
-
|
|
152
|
-
return (
|
|
153
|
-
<ScrollArea.Root {...composableProps(props)} orientation='vertical' ref={forwardedRef}>
|
|
154
|
-
<ScrollArea.Viewport>
|
|
155
|
-
{items.length > 0 ? (
|
|
156
|
-
<PluginList
|
|
157
|
-
plugins={items}
|
|
158
|
-
installed={installedIds}
|
|
159
|
-
installing={installingIds}
|
|
160
|
-
enabled={enabled}
|
|
161
|
-
extraTagsById={extraTagsById}
|
|
162
|
-
onClick={handleClick}
|
|
163
|
-
onChange={handleChange}
|
|
164
|
-
onInstall={handleInstall}
|
|
165
|
-
hasSettings={hasSettings}
|
|
166
|
-
onSettings={handleSettings}
|
|
167
|
-
/>
|
|
168
|
-
) : error ? (
|
|
169
|
-
<div className='p-4 text-description'>Failed to load community plugins: {error.message}</div>
|
|
170
|
-
) : loading ? (
|
|
171
|
-
<div className='p-4 text-description'>{t('loading.label')}</div>
|
|
172
|
-
) : (
|
|
173
|
-
<div className='p-4 text-description'>No community plugins available.</div>
|
|
174
|
-
)}
|
|
175
|
-
</ScrollArea.Viewport>
|
|
176
|
-
</ScrollArea.Root>
|
|
177
|
-
);
|
|
178
|
-
},
|
|
179
|
-
);
|
|
180
|
-
|
|
181
|
-
CommunityRegistry.displayName = 'CommunityRegistry';
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2023 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import { useAtomValue } from '@effect-atom/atom-react';
|
|
6
|
-
import * as Effect from 'effect/Effect';
|
|
7
|
-
import React, { useCallback, useMemo } from 'react';
|
|
8
|
-
|
|
9
|
-
import { type Plugin } from '@dxos/app-framework';
|
|
10
|
-
import { useCapabilities, useOperationInvoker, usePluginManager } from '@dxos/app-framework/ui';
|
|
11
|
-
import { AppCapabilities, LayoutOperation, SettingsOperation } from '@dxos/app-toolkit';
|
|
12
|
-
import { runAndForwardErrors } from '@dxos/effect';
|
|
13
|
-
import { ObservabilityOperation } from '@dxos/plugin-observability/operations';
|
|
14
|
-
import { ScrollArea } from '@dxos/react-ui';
|
|
15
|
-
import { composable, composableProps } from '@dxos/ui-theme';
|
|
16
|
-
|
|
17
|
-
import { PluginList } from '#components';
|
|
18
|
-
import { getPluginPath } from '#meta';
|
|
19
|
-
|
|
20
|
-
const sortByPluginMeta = ({ meta: { name: a = '' } }: Plugin.Plugin, { meta: { name: b = '' } }: Plugin.Plugin) =>
|
|
21
|
-
a.localeCompare(b);
|
|
22
|
-
|
|
23
|
-
export type PluginRegistryProps = {
|
|
24
|
-
id: string;
|
|
25
|
-
plugins: Plugin.Plugin[];
|
|
26
|
-
/**
|
|
27
|
-
* Map from plugin id → display-only tags (e.g. `community`, `local`) computed by the caller.
|
|
28
|
-
*/
|
|
29
|
-
extraTagsById?: Record<string, readonly string[]>;
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
export const PluginRegistry = composable<HTMLDivElement, PluginRegistryProps>(
|
|
33
|
-
({ id, plugins: pluginsProp, extraTagsById, ...props }, forwardedRef) => {
|
|
34
|
-
const manager = usePluginManager();
|
|
35
|
-
const { invoke, invokePromise } = useOperationInvoker();
|
|
36
|
-
const plugins = useMemo(() => pluginsProp.sort(sortByPluginMeta), [pluginsProp]);
|
|
37
|
-
const enabled = useAtomValue(manager.enabled);
|
|
38
|
-
const allSettings = useCapabilities(AppCapabilities.Settings);
|
|
39
|
-
|
|
40
|
-
const handleChange = useCallback(
|
|
41
|
-
(id: string, enabled: boolean) =>
|
|
42
|
-
Effect.gen(function* () {
|
|
43
|
-
if (enabled) {
|
|
44
|
-
yield* manager.enable(id);
|
|
45
|
-
} else {
|
|
46
|
-
yield* manager.disable(id);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
yield* invoke(ObservabilityOperation.SendEvent, {
|
|
50
|
-
name: 'plugins.toggle',
|
|
51
|
-
properties: {
|
|
52
|
-
plugin: id,
|
|
53
|
-
enabled,
|
|
54
|
-
},
|
|
55
|
-
});
|
|
56
|
-
}).pipe(runAndForwardErrors),
|
|
57
|
-
[invoke, manager],
|
|
58
|
-
);
|
|
59
|
-
|
|
60
|
-
const handleClick = useCallback(
|
|
61
|
-
(pluginId: string) =>
|
|
62
|
-
invokePromise(LayoutOperation.Open, {
|
|
63
|
-
subject: [getPluginPath(pluginId)],
|
|
64
|
-
pivotId: id,
|
|
65
|
-
positioning: 'end',
|
|
66
|
-
}),
|
|
67
|
-
[invokePromise, id],
|
|
68
|
-
);
|
|
69
|
-
|
|
70
|
-
const hasSettings = useCallback(
|
|
71
|
-
(pluginId: string) => allSettings.some((s) => s.prefix === pluginId),
|
|
72
|
-
[allSettings],
|
|
73
|
-
);
|
|
74
|
-
|
|
75
|
-
const handleSettings = useCallback(
|
|
76
|
-
(pluginId: string) => invokePromise(SettingsOperation.Open, { plugin: pluginId }),
|
|
77
|
-
[invokePromise],
|
|
78
|
-
);
|
|
79
|
-
|
|
80
|
-
return (
|
|
81
|
-
<ScrollArea.Root {...composableProps(props)} orientation='vertical' ref={forwardedRef}>
|
|
82
|
-
<ScrollArea.Viewport>
|
|
83
|
-
<PluginList
|
|
84
|
-
plugins={plugins}
|
|
85
|
-
enabled={enabled}
|
|
86
|
-
extraTagsById={extraTagsById}
|
|
87
|
-
onClick={handleClick}
|
|
88
|
-
onChange={handleChange}
|
|
89
|
-
hasSettings={hasSettings}
|
|
90
|
-
onSettings={handleSettings}
|
|
91
|
-
/>
|
|
92
|
-
</ScrollArea.Viewport>
|
|
93
|
-
</ScrollArea.Root>
|
|
94
|
-
);
|
|
95
|
-
},
|
|
96
|
-
);
|
|
97
|
-
|
|
98
|
-
PluginRegistry.displayName = 'PluginRegistry';
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2026 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import { Atom, useAtomValue } from '@effect-atom/atom-react';
|
|
6
|
-
import * as Effect from 'effect/Effect';
|
|
7
|
-
|
|
8
|
-
import { useCapabilities } from '@dxos/app-framework/ui';
|
|
9
|
-
import { Context } from '@dxos/context';
|
|
10
|
-
import { type EdgeHttpClient } from '@dxos/edge-client';
|
|
11
|
-
import { type PluginEntry } from '@dxos/protocols';
|
|
12
|
-
|
|
13
|
-
import { RegistryCapabilities, type CommunityPluginsState } from '#types';
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Fetches the community plugin catalog from the Edge registry service and
|
|
17
|
-
* filters out unhealthy entries.
|
|
18
|
-
*/
|
|
19
|
-
export const loadCommunityPlugins = (client: EdgeHttpClient): Effect.Effect<readonly PluginEntry[], Error> =>
|
|
20
|
-
Effect.tryPromise({
|
|
21
|
-
try: () => client.getRegistryPlugins(Context.default()),
|
|
22
|
-
catch: (error) => (error instanceof Error ? error : new Error(String(error))),
|
|
23
|
-
}).pipe(Effect.map((body) => body.plugins.filter((entry) => entry.health === 'ok')));
|
|
24
|
-
|
|
25
|
-
const emptyAtom = Atom.make<CommunityPluginsState>({ entries: [], loading: true, error: null });
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Reads the community plugin catalog from the registry state capability. The
|
|
29
|
-
* catalog is loaded once at plugin startup so this hook is purely reactive.
|
|
30
|
-
* Returns the empty/loading state until the state capability activates.
|
|
31
|
-
*/
|
|
32
|
-
export const useCommunityPlugins = (): CommunityPluginsState => {
|
|
33
|
-
const atoms = useCapabilities(RegistryCapabilities.State);
|
|
34
|
-
return useAtomValue(atoms[0] ?? emptyAtom);
|
|
35
|
-
};
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|