@dxos/app-framework 0.6.14-main.2b6a0f3 → 0.6.14-main.f49f251
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/browser/chunk-3E7RY3CE.mjs +72 -0
- package/dist/lib/browser/chunk-3E7RY3CE.mjs.map +7 -0
- package/dist/lib/browser/chunk-653Y45CL.mjs +41 -0
- package/dist/lib/browser/chunk-653Y45CL.mjs.map +7 -0
- package/dist/lib/browser/{plugin-MM66VRCO.mjs → chunk-CDLQO5K2.mjs} +66 -20
- package/dist/lib/browser/chunk-CDLQO5K2.mjs.map +7 -0
- package/dist/lib/browser/chunk-EQTQGGE6.mjs +214 -0
- package/dist/lib/browser/chunk-EQTQGGE6.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +78 -212
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/plugin-intent-Q5KFPKFA.mjs +22 -0
- package/dist/lib/browser/plugin-intent-Q5KFPKFA.mjs.map +7 -0
- package/dist/lib/browser/plugin-settings-OM3G2QFY.mjs +11 -0
- package/dist/lib/browser/plugin-settings-OM3G2QFY.mjs.map +7 -0
- package/dist/lib/browser/plugin-surface-ZQXFAL46.mjs +24 -0
- package/dist/lib/browser/plugin-surface-ZQXFAL46.mjs.map +7 -0
- package/dist/lib/node/chunk-EF67TRWJ.cjs +236 -0
- package/dist/lib/node/chunk-EF67TRWJ.cjs.map +7 -0
- package/dist/lib/node/chunk-JZ2JVKRY.cjs +58 -0
- package/dist/lib/node/chunk-JZ2JVKRY.cjs.map +7 -0
- package/dist/lib/node/{chunk-62W6CMGM.cjs → chunk-QBM42OQ6.cjs} +56 -5
- package/dist/lib/node/chunk-QBM42OQ6.cjs.map +7 -0
- package/dist/lib/node/{plugin-QV7ESETI.cjs → chunk-VOKMWTKO.cjs} +74 -20
- package/dist/lib/node/chunk-VOKMWTKO.cjs.map +7 -0
- package/dist/lib/node/index.cjs +89 -223
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/plugin-intent-FMC4SDI3.cjs +43 -0
- package/dist/lib/node/plugin-intent-FMC4SDI3.cjs.map +7 -0
- package/dist/lib/node/plugin-settings-OZ6IKAE5.cjs +32 -0
- package/dist/lib/node/plugin-settings-OZ6IKAE5.cjs.map +7 -0
- package/dist/lib/node/plugin-surface-B5NHOBSW.cjs +45 -0
- package/dist/lib/node/plugin-surface-B5NHOBSW.cjs.map +7 -0
- package/dist/lib/node-esm/chunk-3FCLBEOX.mjs +215 -0
- package/dist/lib/node-esm/chunk-3FCLBEOX.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-EYCTSFEJ.mjs +74 -0
- package/dist/lib/node-esm/chunk-EYCTSFEJ.mjs.map +7 -0
- package/dist/lib/node-esm/{plugin-5AAUGDB3.mjs → chunk-MYNXI5VG.mjs} +66 -20
- package/dist/lib/node-esm/chunk-MYNXI5VG.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-YNU7FTGJ.mjs +43 -0
- package/dist/lib/node-esm/chunk-YNU7FTGJ.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +78 -212
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/plugin-intent-KETLP7UL.mjs +23 -0
- package/dist/lib/node-esm/plugin-intent-KETLP7UL.mjs.map +7 -0
- package/dist/lib/node-esm/plugin-settings-37UVWF2V.mjs +12 -0
- package/dist/lib/node-esm/plugin-settings-37UVWF2V.mjs.map +7 -0
- package/dist/lib/node-esm/plugin-surface-QXQRR534.mjs +25 -0
- package/dist/lib/node-esm/plugin-surface-QXQRR534.mjs.map +7 -0
- package/dist/types/src/App.d.ts +2 -2
- package/dist/types/src/App.d.ts.map +1 -1
- package/dist/types/src/plugins/common/file.d.ts +1 -1
- package/dist/types/src/plugins/common/file.d.ts.map +1 -1
- package/dist/types/src/plugins/common/graph.d.ts +1 -1
- package/dist/types/src/plugins/common/graph.d.ts.map +1 -1
- package/dist/types/src/plugins/common/index.d.ts +0 -1
- package/dist/types/src/plugins/common/index.d.ts.map +1 -1
- package/dist/types/src/plugins/common/layout.d.ts +6 -6
- package/dist/types/src/plugins/common/layout.d.ts.map +1 -1
- package/dist/types/src/plugins/common/metadata.d.ts +1 -1
- package/dist/types/src/plugins/common/metadata.d.ts.map +1 -1
- package/dist/types/src/plugins/common/navigation.d.ts +8 -8
- package/dist/types/src/plugins/common/navigation.d.ts.map +1 -1
- package/dist/types/src/plugins/common/translations.d.ts +1 -1
- package/dist/types/src/plugins/common/translations.d.ts.map +1 -1
- package/dist/types/src/plugins/helpers.d.ts +20 -5
- package/dist/types/src/plugins/helpers.d.ts.map +1 -1
- package/dist/types/src/plugins/index.d.ts +4 -3
- package/dist/types/src/plugins/index.d.ts.map +1 -1
- package/dist/types/src/plugins/{PluginHost/PluginHost.d.ts → plugin-host/HostPlugin.d.ts} +6 -6
- package/dist/types/src/plugins/plugin-host/HostPlugin.d.ts.map +1 -0
- package/dist/types/src/plugins/{PluginHost → plugin-host}/PluginContainer.d.ts +2 -2
- package/dist/types/src/plugins/plugin-host/PluginContainer.d.ts.map +1 -0
- package/dist/types/src/plugins/plugin-host/PluginContext.d.ts.map +1 -0
- package/dist/types/src/plugins/plugin-host/index.d.ts +4 -0
- package/dist/types/src/plugins/plugin-host/index.d.ts.map +1 -0
- package/dist/types/src/plugins/plugin-host/plugin.d.ts.map +1 -0
- package/dist/types/src/plugins/plugin-host/plugin.test.d.ts.map +1 -0
- package/dist/types/src/plugins/plugin-intent/IntentContext.d.ts.map +1 -0
- package/dist/types/src/plugins/{IntentPlugin/plugin.d.ts → plugin-intent/IntentPlugin.d.ts} +3 -4
- package/dist/types/src/plugins/plugin-intent/IntentPlugin.d.ts.map +1 -0
- package/dist/types/src/plugins/plugin-intent/helpers.d.ts.map +1 -0
- package/dist/types/src/plugins/plugin-intent/index.d.ts +6 -0
- package/dist/types/src/plugins/plugin-intent/index.d.ts.map +1 -0
- package/dist/types/src/plugins/{IntentPlugin → plugin-intent}/intent.d.ts +1 -1
- package/dist/types/src/plugins/plugin-intent/intent.d.ts.map +1 -0
- package/dist/types/src/plugins/plugin-intent/meta.d.ts.map +1 -0
- package/dist/types/src/plugins/{IntentPlugin → plugin-intent}/provides.d.ts +2 -2
- package/dist/types/src/plugins/plugin-intent/provides.d.ts.map +1 -0
- package/dist/types/src/plugins/plugin-settings/SettingsPlugin.d.ts +4 -0
- package/dist/types/src/plugins/plugin-settings/SettingsPlugin.d.ts.map +1 -0
- package/dist/types/src/plugins/plugin-settings/index.d.ts +4 -0
- package/dist/types/src/plugins/plugin-settings/index.d.ts.map +1 -0
- package/dist/types/src/plugins/plugin-settings/meta.d.ts +5 -0
- package/dist/types/src/plugins/plugin-settings/meta.d.ts.map +1 -0
- package/dist/types/src/plugins/plugin-settings/provides.d.ts +13 -0
- package/dist/types/src/plugins/plugin-settings/provides.d.ts.map +1 -0
- package/dist/types/src/plugins/plugin-surface/ErrorBoundary.d.ts.map +1 -0
- package/dist/types/src/plugins/{SurfacePlugin → plugin-surface}/Surface.d.ts +4 -0
- package/dist/types/src/plugins/plugin-surface/Surface.d.ts.map +1 -0
- package/dist/types/src/plugins/plugin-surface/SurfacePlugin.d.ts +7 -0
- package/dist/types/src/plugins/plugin-surface/SurfacePlugin.d.ts.map +1 -0
- package/dist/types/src/plugins/plugin-surface/SurfaceRootContext.d.ts.map +1 -0
- package/dist/types/src/plugins/plugin-surface/helpers.d.ts.map +1 -0
- package/dist/types/src/plugins/{SurfacePlugin → plugin-surface}/index.d.ts +2 -0
- package/dist/types/src/plugins/plugin-surface/index.d.ts.map +1 -0
- package/dist/types/src/plugins/plugin-surface/meta.d.ts.map +1 -0
- package/dist/types/src/plugins/{SurfacePlugin → plugin-surface}/provides.d.ts +1 -1
- package/dist/types/src/plugins/plugin-surface/provides.d.ts.map +1 -0
- package/package.json +14 -16
- package/src/App.tsx +13 -12
- package/src/plugins/common/file.ts +1 -1
- package/src/plugins/common/graph.ts +1 -1
- package/src/plugins/common/index.ts +0 -1
- package/src/plugins/common/layout.ts +6 -3
- package/src/plugins/common/metadata.ts +1 -1
- package/src/plugins/common/navigation.ts +6 -3
- package/src/plugins/common/translations.ts +2 -8
- package/src/plugins/helpers.ts +55 -11
- package/src/plugins/index.ts +4 -3
- package/src/plugins/{PluginHost/PluginHost.tsx → plugin-host/HostPlugin.tsx} +10 -9
- package/src/plugins/{PluginHost → plugin-host}/PluginContainer.tsx +2 -2
- package/src/plugins/{PluginHost → plugin-host}/PluginContext.tsx +1 -0
- package/src/plugins/{PluginHost → plugin-host}/index.ts +2 -1
- package/src/plugins/{IntentPlugin/plugin.tsx → plugin-intent/IntentPlugin.tsx} +3 -6
- package/src/plugins/{IntentPlugin → plugin-intent}/index.ts +4 -0
- package/src/plugins/{IntentPlugin → plugin-intent}/intent.ts +1 -1
- package/src/plugins/{IntentPlugin → plugin-intent}/provides.ts +5 -2
- package/src/plugins/plugin-settings/SettingsPlugin.tsx +22 -0
- package/src/plugins/plugin-settings/index.ts +9 -0
- package/src/plugins/plugin-settings/meta.ts +9 -0
- package/src/plugins/plugin-settings/provides.ts +29 -0
- package/src/plugins/{SurfacePlugin → plugin-surface}/Surface.tsx +60 -46
- package/src/plugins/{SurfacePlugin/plugin.tsx → plugin-surface/SurfacePlugin.tsx} +2 -4
- package/src/plugins/{SurfacePlugin → plugin-surface}/index.ts +4 -0
- package/src/plugins/{SurfacePlugin → plugin-surface}/provides.ts +2 -1
- package/dist/lib/browser/chunk-J45KR4DI.mjs +0 -52
- package/dist/lib/browser/chunk-J45KR4DI.mjs.map +0 -7
- package/dist/lib/browser/chunk-S5CI6EUQ.mjs +0 -20
- package/dist/lib/browser/chunk-S5CI6EUQ.mjs.map +0 -7
- package/dist/lib/browser/chunk-SB4XRTGZ.mjs +0 -25
- package/dist/lib/browser/chunk-SB4XRTGZ.mjs.map +0 -7
- package/dist/lib/browser/plugin-MM66VRCO.mjs.map +0 -7
- package/dist/lib/browser/plugin-Y4KRQJE4.mjs +0 -40
- package/dist/lib/browser/plugin-Y4KRQJE4.mjs.map +0 -7
- package/dist/lib/node/chunk-62W6CMGM.cjs.map +0 -7
- package/dist/lib/node/chunk-DFST5IG5.cjs +0 -77
- package/dist/lib/node/chunk-DFST5IG5.cjs.map +0 -7
- package/dist/lib/node/chunk-PJGE52CN.cjs +0 -47
- package/dist/lib/node/chunk-PJGE52CN.cjs.map +0 -7
- package/dist/lib/node/plugin-6TEDSCXW.cjs +0 -62
- package/dist/lib/node/plugin-6TEDSCXW.cjs.map +0 -7
- package/dist/lib/node/plugin-QV7ESETI.cjs.map +0 -7
- package/dist/lib/node-esm/chunk-IY7HCP4K.mjs +0 -22
- package/dist/lib/node-esm/chunk-IY7HCP4K.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-MBHRXQTR.mjs +0 -27
- package/dist/lib/node-esm/chunk-MBHRXQTR.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-P2TQLXZR.mjs +0 -54
- package/dist/lib/node-esm/chunk-P2TQLXZR.mjs.map +0 -7
- package/dist/lib/node-esm/plugin-5AAUGDB3.mjs.map +0 -7
- package/dist/lib/node-esm/plugin-J5IRJLM6.mjs +0 -41
- package/dist/lib/node-esm/plugin-J5IRJLM6.mjs.map +0 -7
- package/dist/types/src/plugins/IntentPlugin/IntentContext.d.ts.map +0 -1
- package/dist/types/src/plugins/IntentPlugin/helpers.d.ts.map +0 -1
- package/dist/types/src/plugins/IntentPlugin/index.d.ts +0 -4
- package/dist/types/src/plugins/IntentPlugin/index.d.ts.map +0 -1
- package/dist/types/src/plugins/IntentPlugin/intent.d.ts.map +0 -1
- package/dist/types/src/plugins/IntentPlugin/meta.d.ts.map +0 -1
- package/dist/types/src/plugins/IntentPlugin/plugin.d.ts.map +0 -1
- package/dist/types/src/plugins/IntentPlugin/provides.d.ts.map +0 -1
- package/dist/types/src/plugins/PluginHost/PluginContainer.d.ts.map +0 -1
- package/dist/types/src/plugins/PluginHost/PluginContext.d.ts.map +0 -1
- package/dist/types/src/plugins/PluginHost/PluginHost.d.ts.map +0 -1
- package/dist/types/src/plugins/PluginHost/index.d.ts +0 -4
- package/dist/types/src/plugins/PluginHost/index.d.ts.map +0 -1
- package/dist/types/src/plugins/PluginHost/plugin.d.ts.map +0 -1
- package/dist/types/src/plugins/PluginHost/plugin.test.d.ts.map +0 -1
- package/dist/types/src/plugins/SurfacePlugin/ErrorBoundary.d.ts.map +0 -1
- package/dist/types/src/plugins/SurfacePlugin/Surface.d.ts.map +0 -1
- package/dist/types/src/plugins/SurfacePlugin/SurfaceRootContext.d.ts.map +0 -1
- package/dist/types/src/plugins/SurfacePlugin/helpers.d.ts.map +0 -1
- package/dist/types/src/plugins/SurfacePlugin/index.d.ts.map +0 -1
- package/dist/types/src/plugins/SurfacePlugin/meta.d.ts.map +0 -1
- package/dist/types/src/plugins/SurfacePlugin/plugin.d.ts +0 -8
- package/dist/types/src/plugins/SurfacePlugin/plugin.d.ts.map +0 -1
- package/dist/types/src/plugins/SurfacePlugin/provides.d.ts.map +0 -1
- package/dist/types/src/plugins/common/settings.d.ts +0 -9
- package/dist/types/src/plugins/common/settings.d.ts.map +0 -1
- package/src/plugins/common/settings.ts +0 -22
- /package/dist/types/src/plugins/{PluginHost → plugin-host}/PluginContext.d.ts +0 -0
- /package/dist/types/src/plugins/{PluginHost → plugin-host}/plugin.d.ts +0 -0
- /package/dist/types/src/plugins/{PluginHost → plugin-host}/plugin.test.d.ts +0 -0
- /package/dist/types/src/plugins/{IntentPlugin → plugin-intent}/IntentContext.d.ts +0 -0
- /package/dist/types/src/plugins/{IntentPlugin → plugin-intent}/helpers.d.ts +0 -0
- /package/dist/types/src/plugins/{IntentPlugin → plugin-intent}/meta.d.ts +0 -0
- /package/dist/types/src/plugins/{SurfacePlugin → plugin-surface}/ErrorBoundary.d.ts +0 -0
- /package/dist/types/src/plugins/{SurfacePlugin → plugin-surface}/SurfaceRootContext.d.ts +0 -0
- /package/dist/types/src/plugins/{SurfacePlugin → plugin-surface}/helpers.d.ts +0 -0
- /package/dist/types/src/plugins/{SurfacePlugin → plugin-surface}/meta.d.ts +0 -0
- /package/src/plugins/{PluginHost → plugin-host}/plugin.test.ts +0 -0
- /package/src/plugins/{PluginHost → plugin-host}/plugin.ts +0 -0
- /package/src/plugins/{IntentPlugin → plugin-intent}/IntentContext.tsx +0 -0
- /package/src/plugins/{IntentPlugin → plugin-intent}/helpers.ts +0 -0
- /package/src/plugins/{IntentPlugin → plugin-intent}/meta.ts +0 -0
- /package/src/plugins/{SurfacePlugin → plugin-surface}/ErrorBoundary.tsx +0 -0
- /package/src/plugins/{SurfacePlugin → plugin-surface}/SurfaceRootContext.tsx +0 -0
- /package/src/plugins/{SurfacePlugin → plugin-surface}/helpers.ts +0 -0
- /package/src/plugins/{SurfacePlugin → plugin-surface}/meta.ts +0 -0
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
import { z } from 'zod';
|
|
6
6
|
|
|
7
|
-
import { type
|
|
8
|
-
import type
|
|
7
|
+
import { type Plugin } from '../plugin-host';
|
|
8
|
+
import { type IntentData } from '../plugin-intent';
|
|
9
9
|
|
|
10
10
|
//
|
|
11
11
|
// Provides
|
|
@@ -90,7 +90,10 @@ export const parseLayoutPlugin = (plugin: Plugin) => {
|
|
|
90
90
|
// Intents
|
|
91
91
|
//
|
|
92
92
|
|
|
93
|
-
const
|
|
93
|
+
const LAYOUT_PLUGIN = 'dxos.org/plugin/layout';
|
|
94
|
+
|
|
95
|
+
const LAYOUT_ACTION = `${LAYOUT_PLUGIN}/action`;
|
|
96
|
+
|
|
94
97
|
export enum LayoutAction {
|
|
95
98
|
SET_LAYOUT = `${LAYOUT_ACTION}/set-layout`,
|
|
96
99
|
SET_LAYOUT_MODE = `${LAYOUT_ACTION}/set-layout-mode`,
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
import { Schema as S } from '@effect/schema';
|
|
6
6
|
import { z } from 'zod';
|
|
7
7
|
|
|
8
|
-
import type
|
|
9
|
-
import type
|
|
8
|
+
import { type Plugin } from '../plugin-host';
|
|
9
|
+
import { type IntentData } from '../plugin-intent';
|
|
10
10
|
|
|
11
11
|
// NOTE(thure): These are chosen from RFC 1738’s `safe` characters: http://www.faqs.org/rfcs/rfc1738.html
|
|
12
12
|
export const SLUG_LIST_SEPARATOR = '+';
|
|
@@ -133,7 +133,10 @@ export const partLength = (layout: LayoutParts | undefined, part: LayoutPart | u
|
|
|
133
133
|
// Intents
|
|
134
134
|
//
|
|
135
135
|
|
|
136
|
-
const
|
|
136
|
+
const NAVIGATION_PLUGIN = 'dxos.org/plugin/navigation';
|
|
137
|
+
|
|
138
|
+
const NAVIGATION_ACTION = `${NAVIGATION_PLUGIN}/action`;
|
|
139
|
+
|
|
137
140
|
export enum NavigationAction {
|
|
138
141
|
OPEN = `${NAVIGATION_ACTION}/open`,
|
|
139
142
|
ADD_TO_ACTIVE = `${NAVIGATION_ACTION}/add-to-active`,
|
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
import { z } from 'zod';
|
|
6
6
|
|
|
7
|
-
import type
|
|
7
|
+
import { type Plugin } from '../plugin-host';
|
|
8
8
|
|
|
9
|
+
// TODO(burdon): Replace zed with effect.
|
|
9
10
|
export const ResourceKey = z.union([z.string(), z.record(z.any())]);
|
|
10
11
|
export type ResourceKey = z.infer<typeof ResourceKey>;
|
|
11
12
|
|
|
@@ -26,13 +27,6 @@ export type TranslationsProvides = {
|
|
|
26
27
|
translations: Readonly<Resource[]>;
|
|
27
28
|
};
|
|
28
29
|
|
|
29
|
-
// TODO(wittjosiah): Add TranslationsProvides.
|
|
30
|
-
// export type TranslationsProvides = {
|
|
31
|
-
// translations: {
|
|
32
|
-
// t: TFunction;
|
|
33
|
-
// };
|
|
34
|
-
// };
|
|
35
|
-
|
|
36
30
|
/**
|
|
37
31
|
* Type guard for translation plugins.
|
|
38
32
|
*/
|
package/src/plugins/helpers.ts
CHANGED
|
@@ -2,14 +2,16 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import { Context, type DisposeCallback } from '@dxos/context';
|
|
5
6
|
import { raise } from '@dxos/debug';
|
|
7
|
+
import { invariant } from '@dxos/invariant';
|
|
6
8
|
|
|
7
|
-
import { type Plugin } from './
|
|
9
|
+
import { type Plugin, type PluginDefinition } from './plugin-host';
|
|
8
10
|
|
|
9
11
|
/**
|
|
10
|
-
*
|
|
12
|
+
* Resolvers allow different instances of plugins to provide a particular capability.
|
|
11
13
|
*/
|
|
12
|
-
export
|
|
14
|
+
export type PluginResolver<T> = (plugin: Plugin) => Plugin<T> | undefined;
|
|
13
15
|
|
|
14
16
|
/**
|
|
15
17
|
* Find a plugin by ID.
|
|
@@ -30,10 +32,8 @@ export const getPlugin = <T>(plugins: Plugin[], id: string): Plugin<T> => {
|
|
|
30
32
|
/**
|
|
31
33
|
* Filter a list of plugins to only those that match a predicate.
|
|
32
34
|
*/
|
|
33
|
-
export const filterPlugins = <T>(
|
|
34
|
-
plugins: Plugin
|
|
35
|
-
predicate: (plugin: Plugin) => Plugin<T> | undefined,
|
|
36
|
-
): Plugin<T>[] => plugins.map((plugin) => predicate(plugin)).filter((plugin): plugin is Plugin<T> => !!plugin);
|
|
35
|
+
export const filterPlugins = <T>(plugins: Plugin[], predicate: PluginResolver<T>): Plugin<T>[] =>
|
|
36
|
+
plugins.map((plugin) => predicate(plugin)).filter((plugin): plugin is Plugin<T> => !!plugin);
|
|
37
37
|
|
|
38
38
|
/**
|
|
39
39
|
* Resolves a plugin by predicate.
|
|
@@ -42,7 +42,51 @@ export const filterPlugins = <T>(
|
|
|
42
42
|
* import { parseIntentPlugin, resolvePlugin } from '@dxos/app-framework';
|
|
43
43
|
* const intentPlugin = resolvePlugin(plugins, parseIntentPlugin);
|
|
44
44
|
*/
|
|
45
|
-
export const resolvePlugin = <T>(
|
|
46
|
-
plugins
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
export const resolvePlugin = <T>(plugins: Plugin[], predicate: PluginResolver<T>): Plugin<T> | undefined =>
|
|
46
|
+
filterPlugins(plugins, predicate)[0];
|
|
47
|
+
|
|
48
|
+
class PluginContext {
|
|
49
|
+
// TODO(burdon): Use Resource (@dima)?
|
|
50
|
+
public readonly ctx = new Context();
|
|
51
|
+
|
|
52
|
+
private _plugins?: Plugin[];
|
|
53
|
+
|
|
54
|
+
init(plugins: Plugin[]) {
|
|
55
|
+
this._plugins = plugins;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
getPlugin<T>(id: string): Plugin<T> {
|
|
59
|
+
invariant(this._plugins);
|
|
60
|
+
return getPlugin(this._plugins, id);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
resolvePlugin<T>(resolver: PluginResolver<T>): Plugin<T>;
|
|
64
|
+
resolvePlugin<T>(resolver: PluginResolver<T>, required = false): Plugin<T> | undefined {
|
|
65
|
+
invariant(this._plugins, 'context not initialized');
|
|
66
|
+
const plugin = resolvePlugin(this._plugins, resolver);
|
|
67
|
+
if (required && !plugin) {
|
|
68
|
+
// TODO(burdon): Resolver should have a name.
|
|
69
|
+
throw new Error('Plugin not found.');
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return plugin;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
onDispose(cb: DisposeCallback) {
|
|
76
|
+
this.ctx.onDispose(cb);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
dispose() {
|
|
80
|
+
void this.ctx.dispose();
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Plugin helper with dependency injection and life-cycle support.
|
|
86
|
+
*/
|
|
87
|
+
export const definePlugin = <Provides>(
|
|
88
|
+
cb: (context: PluginContext) => PluginDefinition<Provides>,
|
|
89
|
+
): (() => PluginDefinition<Provides>) => {
|
|
90
|
+
const context = new PluginContext();
|
|
91
|
+
return () => cb(context);
|
|
92
|
+
};
|
package/src/plugins/index.ts
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
export * from './common';
|
|
6
6
|
export * from './helpers';
|
|
7
7
|
|
|
8
|
-
export * from './
|
|
9
|
-
export * from './
|
|
10
|
-
export * from './
|
|
8
|
+
export * from './plugin-intent';
|
|
9
|
+
export * from './plugin-host';
|
|
10
|
+
export * from './plugin-settings';
|
|
11
|
+
export * from './plugin-surface';
|
|
@@ -9,9 +9,9 @@ import { LocalStorageStore } from '@dxos/local-storage';
|
|
|
9
9
|
import { PluginContainer } from './PluginContainer';
|
|
10
10
|
import { type PluginContext, PluginProvider } from './PluginContext';
|
|
11
11
|
import { type Plugin, type PluginDefinition, type PluginMeta } from './plugin';
|
|
12
|
-
import { ErrorBoundary } from '../
|
|
12
|
+
import { ErrorBoundary } from '../plugin-surface';
|
|
13
13
|
|
|
14
|
-
export type
|
|
14
|
+
export type HostPluginParams = {
|
|
15
15
|
plugins: Record<string, () => Promise<PluginDefinition>>;
|
|
16
16
|
// Ordered list of plugins.
|
|
17
17
|
meta: PluginMeta[];
|
|
@@ -21,32 +21,33 @@ export type BootstrapPluginsParams = {
|
|
|
21
21
|
placeholder?: ReactNode;
|
|
22
22
|
};
|
|
23
23
|
|
|
24
|
-
export type
|
|
24
|
+
export type HostPluginProvides = {
|
|
25
25
|
plugins: PluginContext;
|
|
26
26
|
};
|
|
27
27
|
|
|
28
28
|
export const parsePluginHost = (plugin: Plugin) =>
|
|
29
|
-
(plugin.provides as
|
|
29
|
+
(plugin.provides as HostPluginProvides).plugins ? (plugin as Plugin<HostPluginProvides>) : undefined;
|
|
30
30
|
|
|
31
|
-
const
|
|
31
|
+
const HOST_PLUGIN = 'dxos.org/plugin/host';
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
34
|
* Bootstraps an application by initializing plugins and rendering root components.
|
|
35
35
|
*/
|
|
36
|
-
export const
|
|
36
|
+
export const HostPlugin = ({
|
|
37
37
|
plugins,
|
|
38
38
|
meta,
|
|
39
39
|
core,
|
|
40
40
|
defaults = [],
|
|
41
41
|
fallback = DefaultFallback,
|
|
42
42
|
placeholder = null,
|
|
43
|
-
}:
|
|
44
|
-
const state = new LocalStorageStore<PluginContext>(
|
|
43
|
+
}: HostPluginParams): PluginDefinition<HostPluginProvides> => {
|
|
44
|
+
const state = new LocalStorageStore<PluginContext>(HOST_PLUGIN, {
|
|
45
45
|
ready: false,
|
|
46
46
|
core,
|
|
47
47
|
enabled: [...defaults],
|
|
48
48
|
plugins: [],
|
|
49
49
|
available: meta.filter(({ id }) => !core.includes(id)),
|
|
50
|
+
// TODO(burdon): Functions should not be part of the settings type.
|
|
50
51
|
setPlugin: (id: string, enabled: boolean) => {
|
|
51
52
|
if (enabled) {
|
|
52
53
|
state.values.enabled.push(id);
|
|
@@ -62,7 +63,7 @@ export const PluginHost = ({
|
|
|
62
63
|
|
|
63
64
|
return {
|
|
64
65
|
meta: {
|
|
65
|
-
id:
|
|
66
|
+
id: HOST_PLUGIN,
|
|
66
67
|
name: 'Plugin host',
|
|
67
68
|
},
|
|
68
69
|
provides: {
|
|
@@ -6,11 +6,11 @@ import React, { type JSX, type FC, type PropsWithChildren, type ReactNode, useEf
|
|
|
6
6
|
|
|
7
7
|
import { log } from '@dxos/log';
|
|
8
8
|
|
|
9
|
+
import { type HostPluginParams } from './HostPlugin';
|
|
9
10
|
import { type PluginContext } from './PluginContext';
|
|
10
|
-
import { type BootstrapPluginsParams } from './PluginHost';
|
|
11
11
|
import { type Plugin, type PluginDefinition, type PluginProvides } from './plugin';
|
|
12
12
|
|
|
13
|
-
export type PluginContainerProps = Pick<
|
|
13
|
+
export type PluginContainerProps = Pick<HostPluginParams, 'core'> & {
|
|
14
14
|
plugins: Record<string, () => Promise<PluginDefinition>>;
|
|
15
15
|
state: PluginContext;
|
|
16
16
|
placeholder: ReactNode;
|
|
@@ -17,8 +17,8 @@ import {
|
|
|
17
17
|
parseIntentResolverPlugin,
|
|
18
18
|
IntentAction,
|
|
19
19
|
} from './provides';
|
|
20
|
-
import type { PluginDefinition } from '../PluginHost';
|
|
21
20
|
import { filterPlugins, findPlugin } from '../helpers';
|
|
21
|
+
import { type PluginDefinition } from '../plugin-host';
|
|
22
22
|
|
|
23
23
|
const EXECUTION_LIMIT = 1000;
|
|
24
24
|
const HISTORY_LIMIT = 100;
|
|
@@ -27,7 +27,7 @@ const HISTORY_LIMIT = 100;
|
|
|
27
27
|
* Allows plugins to register intent handlers and routes sent intents to the appropriate plugin.
|
|
28
28
|
* Inspired by https://developer.android.com/reference/android/content/Intent.
|
|
29
29
|
*/
|
|
30
|
-
const IntentPlugin = (): PluginDefinition<IntentPluginProvides> => {
|
|
30
|
+
export const IntentPlugin = (): PluginDefinition<IntentPluginProvides> => {
|
|
31
31
|
const state = create<IntentContext>({
|
|
32
32
|
dispatch: async () => ({}),
|
|
33
33
|
undo: async () => ({}),
|
|
@@ -54,8 +54,7 @@ const IntentPlugin = (): PluginDefinition<IntentPluginProvides> => {
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
const plugin = findPlugin<IntentResolverProvides>(plugins, intent.plugin);
|
|
57
|
-
|
|
58
|
-
return result;
|
|
57
|
+
return plugin?.provides.intent.resolver(intent, plugins);
|
|
59
58
|
}
|
|
60
59
|
|
|
61
60
|
for (const entry of dynamicResolvers) {
|
|
@@ -150,5 +149,3 @@ const IntentPlugin = (): PluginDefinition<IntentPluginProvides> => {
|
|
|
150
149
|
},
|
|
151
150
|
};
|
|
152
151
|
};
|
|
153
|
-
|
|
154
|
-
export default IntentPlugin;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { type IntentContext } from './IntentContext';
|
|
6
6
|
import { type IntentResolver } from './intent';
|
|
7
|
-
import { type Plugin } from '../
|
|
7
|
+
import { type Plugin } from '../plugin-host';
|
|
8
8
|
|
|
9
9
|
export type IntentResolverProvides = {
|
|
10
10
|
intent: {
|
|
@@ -26,7 +26,10 @@ export const parseIntentResolverPlugin = (plugin: Plugin) =>
|
|
|
26
26
|
// Intents
|
|
27
27
|
//
|
|
28
28
|
|
|
29
|
-
const
|
|
29
|
+
const INTENT_PLUGIN = 'dxos.org/plugin/intent';
|
|
30
|
+
|
|
31
|
+
const INTENT_ACTION = `${INTENT_PLUGIN}/action`;
|
|
32
|
+
|
|
30
33
|
export enum IntentAction {
|
|
31
34
|
/**
|
|
32
35
|
* Fired after an intent is dispatched if the intent is undoable.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2024 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { RootSettingsStore } from '@dxos/local-storage';
|
|
6
|
+
|
|
7
|
+
import SettingsMeta from './meta';
|
|
8
|
+
import { type SettingsPluginProvides } from './provides';
|
|
9
|
+
import { type PluginDefinition } from '../plugin-host';
|
|
10
|
+
|
|
11
|
+
export const SettingsPlugin = (): PluginDefinition<SettingsPluginProvides> => {
|
|
12
|
+
// Global settings singleton.
|
|
13
|
+
// TODO(burdon): Make settings storage extensible so that other plugins can decide the persistence of them.
|
|
14
|
+
const settingsStore = new RootSettingsStore();
|
|
15
|
+
|
|
16
|
+
return {
|
|
17
|
+
meta: SettingsMeta,
|
|
18
|
+
provides: {
|
|
19
|
+
settingsStore,
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type SettingsStoreFactory, type SettingsValue } from '@dxos/local-storage';
|
|
6
|
+
|
|
7
|
+
import { type Plugin } from '../plugin-host';
|
|
8
|
+
|
|
9
|
+
export type SettingsProvides<T extends SettingsValue> = {
|
|
10
|
+
settings: T;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export type SettingsPluginProvides = {
|
|
14
|
+
settingsStore: SettingsStoreFactory;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const parseSettingsPlugin = (plugin: Plugin) => {
|
|
18
|
+
return typeof (plugin.provides as any).settingsStore === 'object'
|
|
19
|
+
? (plugin as Plugin<SettingsPluginProvides>)
|
|
20
|
+
: undefined;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const SETTINGS_PLUGIN = 'dxos.org/plugin/settings';
|
|
24
|
+
|
|
25
|
+
const SETTINGS_ACTION = `${SETTINGS_PLUGIN}/action`;
|
|
26
|
+
|
|
27
|
+
export enum SettingsAction {
|
|
28
|
+
OPEN = `${SETTINGS_ACTION}/open`,
|
|
29
|
+
}
|
|
@@ -18,6 +18,7 @@ import React, {
|
|
|
18
18
|
} from 'react';
|
|
19
19
|
|
|
20
20
|
import { raise } from '@dxos/debug';
|
|
21
|
+
import { log } from '@dxos/log';
|
|
21
22
|
|
|
22
23
|
import { ErrorBoundary } from './ErrorBoundary';
|
|
23
24
|
import { type SurfaceComponent, type SurfaceResult, useSurfaceRoot } from './SurfaceRootContext';
|
|
@@ -31,6 +32,11 @@ export type Direction = 'inline' | 'inline-reverse' | 'block' | 'block-reverse';
|
|
|
31
32
|
* SurfaceProps are the props that are passed to the Surface component.
|
|
32
33
|
*/
|
|
33
34
|
export type SurfaceProps = PropsWithChildren<{
|
|
35
|
+
/**
|
|
36
|
+
* Optional ID for debugging.
|
|
37
|
+
*/
|
|
38
|
+
id?: string;
|
|
39
|
+
|
|
34
40
|
/**
|
|
35
41
|
* Role defines how the data should be rendered.
|
|
36
42
|
*/
|
|
@@ -82,40 +88,45 @@ export type SurfaceProps = PropsWithChildren<{
|
|
|
82
88
|
[key: string]: unknown;
|
|
83
89
|
}>;
|
|
84
90
|
|
|
91
|
+
let count = 0;
|
|
92
|
+
|
|
85
93
|
/**
|
|
86
94
|
* A surface is a named region of the screen that can be populated by plugins.
|
|
87
95
|
*/
|
|
88
96
|
export const Surface = memo(
|
|
89
|
-
forwardRef<HTMLElement, SurfaceProps>(
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
97
|
+
forwardRef<HTMLElement, SurfaceProps>(
|
|
98
|
+
({ id: _id, role, name = role, fallback, placeholder, ...rest }, forwardedRef) => {
|
|
99
|
+
const props = { role, name, fallback, ...rest };
|
|
100
|
+
const { debugInfo } = useSurfaceRoot();
|
|
101
|
+
|
|
102
|
+
// Track debug info.
|
|
103
|
+
const [id] = useState<string>(() => _id ?? `surface-${++count}`);
|
|
104
|
+
useEffect(() => {
|
|
105
|
+
debugInfo?.set(id, { id, created: Date.now(), name, role, renderCount: 0 });
|
|
106
|
+
return () => {
|
|
107
|
+
debugInfo?.delete(id);
|
|
108
|
+
};
|
|
109
|
+
}, [id]);
|
|
110
|
+
|
|
111
|
+
if (debugInfo?.get(id)) {
|
|
112
|
+
debugInfo.get(id)!.renderCount++;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const context = useContext(SurfaceContext);
|
|
116
|
+
const data = props.data ?? ((name && context?.surfaces?.[name]?.data) || {});
|
|
117
|
+
|
|
118
|
+
const resolver = <SurfaceResolver {...props} id={id} ref={forwardedRef} />;
|
|
119
|
+
const suspense = placeholder ? <Suspense fallback={placeholder}>{resolver}</Suspense> : resolver;
|
|
120
|
+
|
|
121
|
+
return fallback ? (
|
|
122
|
+
<ErrorBoundary data={data} fallback={fallback}>
|
|
123
|
+
{suspense}
|
|
124
|
+
</ErrorBoundary>
|
|
125
|
+
) : (
|
|
126
|
+
suspense
|
|
127
|
+
);
|
|
128
|
+
},
|
|
129
|
+
),
|
|
119
130
|
);
|
|
120
131
|
|
|
121
132
|
const SurfaceContext = createContext<SurfaceProps | undefined>(undefined);
|
|
@@ -123,6 +134,9 @@ const SurfaceContext = createContext<SurfaceProps | undefined>(undefined);
|
|
|
123
134
|
export const useSurface = (): SurfaceProps =>
|
|
124
135
|
useContext(SurfaceContext) ?? raise(new Error('Surface context not found'));
|
|
125
136
|
|
|
137
|
+
/**
|
|
138
|
+
* Root surface component.
|
|
139
|
+
*/
|
|
126
140
|
const SurfaceResolver = forwardRef<HTMLElement, SurfaceProps>((props, forwardedRef) => {
|
|
127
141
|
const { components } = useSurfaceRoot();
|
|
128
142
|
const parent = useContext(SurfaceContext);
|
|
@@ -152,30 +166,30 @@ const resolveNodes = (
|
|
|
152
166
|
...props.data,
|
|
153
167
|
};
|
|
154
168
|
|
|
155
|
-
const
|
|
169
|
+
const candidates = Object.entries(components)
|
|
156
170
|
.map(([key, component]): [string, SurfaceResult] | undefined => {
|
|
171
|
+
// TODO(burdon): Avoid variable return types in plugin contract.
|
|
157
172
|
const result = component({ ...props, data }, forwardedRef);
|
|
158
173
|
if (!result || typeof result !== 'object') {
|
|
159
174
|
return undefined;
|
|
160
175
|
}
|
|
161
176
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
return
|
|
170
|
-
} else if (aDisposition === 'hoist' || bDisposition === 'fallback') {
|
|
171
|
-
return -1;
|
|
172
|
-
} else if (bDisposition === 'hoist' || aDisposition === 'fallback') {
|
|
173
|
-
return 1;
|
|
177
|
+
// Normalize tuple.
|
|
178
|
+
if ('node' in result) {
|
|
179
|
+
return [key, result];
|
|
180
|
+
} else if (isValidElement(result)) {
|
|
181
|
+
return [key, { node: result }];
|
|
182
|
+
} else {
|
|
183
|
+
log.warn('invalid result', { result });
|
|
184
|
+
return undefined;
|
|
174
185
|
}
|
|
175
|
-
|
|
176
|
-
return 0;
|
|
177
186
|
})
|
|
178
|
-
.
|
|
187
|
+
.filter((result): result is [string, SurfaceResult] => Boolean(result))
|
|
188
|
+
.sort(([, { disposition: a = 'default' }], [, { disposition: b = 'default' }]) => {
|
|
189
|
+
return a === b ? 0 : a === 'hoist' || b === 'fallback' ? -1 : b === 'hoist' || a === 'fallback' ? 1 : 0;
|
|
190
|
+
});
|
|
179
191
|
|
|
192
|
+
// TODO(burdon): Does this prematurely process the node?
|
|
193
|
+
const nodes = candidates.map(([key, result]) => <Fragment key={key}>{result.node}</Fragment>);
|
|
180
194
|
return props.limit ? nodes.slice(0, props.limit) : nodes;
|
|
181
195
|
};
|
|
@@ -9,13 +9,13 @@ import { create } from '@dxos/echo-schema';
|
|
|
9
9
|
import { SurfaceProvider, type SurfaceRootContext } from './SurfaceRootContext';
|
|
10
10
|
import SurfaceMeta from './meta';
|
|
11
11
|
import { parseSurfacePlugin, type SurfacePluginProvides } from './provides';
|
|
12
|
-
import { type PluginDefinition } from '../PluginHost';
|
|
13
12
|
import { filterPlugins } from '../helpers';
|
|
13
|
+
import { type PluginDefinition } from '../plugin-host';
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* Provides a registry of surface components.
|
|
17
17
|
*/
|
|
18
|
-
const SurfacePlugin = (): PluginDefinition<SurfacePluginProvides> => {
|
|
18
|
+
export const SurfacePlugin = (): PluginDefinition<SurfacePluginProvides> => {
|
|
19
19
|
const state = create<SurfaceRootContext>({ components: {}, debugInfo: new Map() });
|
|
20
20
|
|
|
21
21
|
return {
|
|
@@ -31,5 +31,3 @@ const SurfacePlugin = (): PluginDefinition<SurfacePluginProvides> => {
|
|
|
31
31
|
},
|
|
32
32
|
};
|
|
33
33
|
};
|
|
34
|
-
|
|
35
|
-
export default SurfacePlugin;
|
|
@@ -2,9 +2,13 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import { SurfacePlugin } from './SurfacePlugin';
|
|
6
|
+
|
|
5
7
|
export * from './helpers';
|
|
6
8
|
export * from './provides';
|
|
7
9
|
|
|
8
10
|
export * from './ErrorBoundary';
|
|
9
11
|
export * from './Surface';
|
|
10
12
|
export * from './SurfaceRootContext';
|
|
13
|
+
|
|
14
|
+
export default SurfacePlugin;
|
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { type SurfaceComponent, type SurfaceRootContext } from './SurfaceRootContext';
|
|
6
|
-
import { type Plugin } from '../
|
|
6
|
+
import { type Plugin } from '../plugin-host';
|
|
7
7
|
|
|
8
|
+
// TODO(burdon): Predicate based providers?
|
|
8
9
|
export type SurfaceProvides = {
|
|
9
10
|
surface: {
|
|
10
11
|
/**
|