@dxos/app-framework 0.3.3-main.3806cc2

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.
Files changed (83) hide show
  1. package/.eslintrc.js +9 -0
  2. package/.storybook/main.cjs +36 -0
  3. package/.storybook/preview-head.html +3 -0
  4. package/.storybook/preview.cjs +45 -0
  5. package/LICENSE +8 -0
  6. package/README.md +29 -0
  7. package/README.yml +5 -0
  8. package/dist/lib/browser/index.mjs +453 -0
  9. package/dist/lib/browser/index.mjs.map +7 -0
  10. package/dist/lib/browser/meta.json +1 -0
  11. package/dist/lib/node/index.cjs +522 -0
  12. package/dist/lib/node/index.cjs.map +7 -0
  13. package/dist/lib/node/meta.json +1 -0
  14. package/dist/types/src/App.d.ts +19 -0
  15. package/dist/types/src/App.d.ts.map +1 -0
  16. package/dist/types/src/index.d.ts +3 -0
  17. package/dist/types/src/index.d.ts.map +1 -0
  18. package/dist/types/src/plugins/IntentPlugin/IntentContext.d.ts +8 -0
  19. package/dist/types/src/plugins/IntentPlugin/IntentContext.d.ts.map +1 -0
  20. package/dist/types/src/plugins/IntentPlugin/IntentPlugin.d.ts +19 -0
  21. package/dist/types/src/plugins/IntentPlugin/IntentPlugin.d.ts.map +1 -0
  22. package/dist/types/src/plugins/IntentPlugin/index.d.ts +4 -0
  23. package/dist/types/src/plugins/IntentPlugin/index.d.ts.map +1 -0
  24. package/dist/types/src/plugins/IntentPlugin/intent.d.ts +28 -0
  25. package/dist/types/src/plugins/IntentPlugin/intent.d.ts.map +1 -0
  26. package/dist/types/src/plugins/PluginHost/PluginContext.d.ts +24 -0
  27. package/dist/types/src/plugins/PluginHost/PluginContext.d.ts.map +1 -0
  28. package/dist/types/src/plugins/PluginHost/PluginHost.d.ts +20 -0
  29. package/dist/types/src/plugins/PluginHost/PluginHost.d.ts.map +1 -0
  30. package/dist/types/src/plugins/PluginHost/index.d.ts +4 -0
  31. package/dist/types/src/plugins/PluginHost/index.d.ts.map +1 -0
  32. package/dist/types/src/plugins/PluginHost/plugin.d.ts +66 -0
  33. package/dist/types/src/plugins/PluginHost/plugin.d.ts.map +1 -0
  34. package/dist/types/src/plugins/PluginHost/plugin.test.d.ts +35 -0
  35. package/dist/types/src/plugins/PluginHost/plugin.test.d.ts.map +1 -0
  36. package/dist/types/src/plugins/SurfacePlugin/ErrorBoundary.d.ts +30 -0
  37. package/dist/types/src/plugins/SurfacePlugin/ErrorBoundary.d.ts.map +1 -0
  38. package/dist/types/src/plugins/SurfacePlugin/Surface.d.ts +45 -0
  39. package/dist/types/src/plugins/SurfacePlugin/Surface.d.ts.map +1 -0
  40. package/dist/types/src/plugins/SurfacePlugin/SurfacePlugin.d.ts +20 -0
  41. package/dist/types/src/plugins/SurfacePlugin/SurfacePlugin.d.ts.map +1 -0
  42. package/dist/types/src/plugins/SurfacePlugin/SurfaceRootContext.d.ts +13 -0
  43. package/dist/types/src/plugins/SurfacePlugin/SurfaceRootContext.d.ts.map +1 -0
  44. package/dist/types/src/plugins/SurfacePlugin/index.d.ts +5 -0
  45. package/dist/types/src/plugins/SurfacePlugin/index.d.ts.map +1 -0
  46. package/dist/types/src/plugins/common/graph.d.ts +26 -0
  47. package/dist/types/src/plugins/common/graph.d.ts.map +1 -0
  48. package/dist/types/src/plugins/common/index.d.ts +4 -0
  49. package/dist/types/src/plugins/common/index.d.ts.map +1 -0
  50. package/dist/types/src/plugins/common/layout.d.ts +89 -0
  51. package/dist/types/src/plugins/common/layout.d.ts.map +1 -0
  52. package/dist/types/src/plugins/common/translations.d.ts +22 -0
  53. package/dist/types/src/plugins/common/translations.d.ts.map +1 -0
  54. package/dist/types/src/plugins/helpers.d.ts +22 -0
  55. package/dist/types/src/plugins/helpers.d.ts.map +1 -0
  56. package/dist/types/src/plugins/index.d.ts +6 -0
  57. package/dist/types/src/plugins/index.d.ts.map +1 -0
  58. package/package.json +34 -0
  59. package/project.json +78 -0
  60. package/src/App.tsx +43 -0
  61. package/src/index.ts +7 -0
  62. package/src/plugins/IntentPlugin/IntentContext.tsx +17 -0
  63. package/src/plugins/IntentPlugin/IntentPlugin.tsx +69 -0
  64. package/src/plugins/IntentPlugin/index.ts +7 -0
  65. package/src/plugins/IntentPlugin/intent.ts +34 -0
  66. package/src/plugins/PluginHost/PluginContext.tsx +45 -0
  67. package/src/plugins/PluginHost/PluginHost.tsx +200 -0
  68. package/src/plugins/PluginHost/index.ts +7 -0
  69. package/src/plugins/PluginHost/plugin.test.ts +159 -0
  70. package/src/plugins/PluginHost/plugin.ts +82 -0
  71. package/src/plugins/SurfacePlugin/ErrorBoundary.tsx +45 -0
  72. package/src/plugins/SurfacePlugin/Surface.tsx +116 -0
  73. package/src/plugins/SurfacePlugin/SurfacePlugin.tsx +53 -0
  74. package/src/plugins/SurfacePlugin/SurfaceRootContext.tsx +22 -0
  75. package/src/plugins/SurfacePlugin/index.ts +8 -0
  76. package/src/plugins/common/graph.ts +33 -0
  77. package/src/plugins/common/index.ts +7 -0
  78. package/src/plugins/common/layout.ts +102 -0
  79. package/src/plugins/common/translations.ts +34 -0
  80. package/src/plugins/helpers.ts +43 -0
  81. package/src/plugins/index.ts +10 -0
  82. package/tsconfig.json +43 -0
  83. package/tsconfig.node.json +11 -0
package/.eslintrc.js ADDED
@@ -0,0 +1,9 @@
1
+ module.exports = {
2
+ "extends": [
3
+ "../../../.eslintrc.js"
4
+ ],
5
+ "parserOptions": {
6
+ "project": "tsconfig.json",
7
+ "tsconfigRootDir": __dirname,
8
+ }
9
+ }
@@ -0,0 +1,36 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ const { mergeConfig } = require('vite');
6
+ const { resolve } = require('path');
7
+
8
+ const { ThemePlugin } = require('@dxos/react-ui-theme/plugin');
9
+
10
+ module.exports = {
11
+ stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
12
+ addons: [
13
+ '@storybook/addon-links',
14
+ '@storybook/addon-essentials',
15
+ '@storybook/addon-interactions'
16
+ ],
17
+ framework: {
18
+ name: '@storybook/react-vite',
19
+ options: {
20
+ // TODO(wittjosiah): Enable strict mode.
21
+ strictMode: false
22
+ }
23
+ },
24
+ viteFinal: async (config) =>
25
+ mergeConfig(config, {
26
+ plugins: [
27
+ ThemePlugin({
28
+ root: __dirname,
29
+ content: [
30
+ resolve(__dirname, '../src') + '/**/*.{ts,tsx,js,jsx}',
31
+ resolve(__dirname, '../node_modules/@dxos/kai-frames/dist/**/*.mjs')
32
+ ]
33
+ })
34
+ ]
35
+ })
36
+ };
@@ -0,0 +1,3 @@
1
+ <script>
2
+ window.global = window;
3
+ </script>
@@ -0,0 +1,45 @@
1
+ //
2
+ // Copyright 2022 DXOS.org
3
+ //
4
+
5
+ // import React, { createElement, useEffect } from 'react';
6
+ // import { ThemeProvider } from '@dxos/react-appkit';
7
+
8
+ export const parameters = {
9
+ actions: { argTypesRegex: '^on[A-Z].*' },
10
+ controls: {
11
+ matchers: {
12
+ color: /(background|color)$/i,
13
+ date: /Date$/
14
+ }
15
+ }
16
+ };
17
+
18
+ export const globalTypes = {
19
+ theme: {
20
+ name: 'Theme',
21
+ description: 'Global theme for components',
22
+ defaultValue: 'light',
23
+ toolbar: {
24
+ // The icon for the toolbar item
25
+ icon: 'circlehollow',
26
+ // Array of options
27
+ items: [
28
+ { value: 'light', icon: 'circlehollow', title: 'light' },
29
+ { value: 'dark', icon: 'circle', title: 'dark' },
30
+ ],
31
+ // Property that specifies if the name of the item will be displayed
32
+ showName: true,
33
+ },
34
+ },
35
+ }
36
+
37
+ // const withTheme = (StoryFn, context) => {
38
+ // const theme = context?.parameters?.theme || context?.globals?.theme;
39
+ // useEffect(()=>{
40
+ // document.documentElement.classList[theme === 'dark' ? 'add' : 'remove']('dark')
41
+ // }, [theme])
42
+ // return createElement(ThemeProvider, {children: createElement(StoryFn)})
43
+ // }
44
+
45
+ // export const decorators = [withTheme];
package/LICENSE ADDED
@@ -0,0 +1,8 @@
1
+ MIT License
2
+ Copyright (c) 2022 DXOS
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
5
+
6
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
7
+
8
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # @dxos/app-framework
2
+
3
+ A framework for building applications from composible plugins.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pnpm i @dxos/app-framework
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ Run with
14
+
15
+ ```bash
16
+ pnpm nx storybook app-framework
17
+ ```
18
+
19
+ ## DXOS Resources
20
+
21
+ - [Website](https://dxos.org)
22
+ - [Developer Documentation](https://docs.dxos.org)
23
+ - Talk to us on [Discord](https://discord.gg/eXVfryv3sW)
24
+
25
+ ## Contributions
26
+
27
+ Your ideas, issues, and code are most welcome. Please take a look at our [community code of conduct](https://github.com/dxos/dxos/blob/main/CODE_OF_CONDUCT.md), the [issue guide](https://github.com/dxos/dxos/blob/main/CONTRIBUTING.md#submitting-issues), and the [PR contribution guide](https://github.com/dxos/dxos/blob/main/CONTRIBUTING.md#submitting-prs).
28
+
29
+ License: [MIT](./LICENSE) Copyright 2022 © DXOS
package/README.yml ADDED
@@ -0,0 +1,5 @@
1
+ usage: |
2
+ Run with
3
+ ```bash
4
+ pnpm nx storybook surface
5
+ ```
@@ -0,0 +1,453 @@
1
+ // packages/sdk/app-framework/src/plugins/common/graph.ts
2
+ var parseGraphPlugin = (plugin) => plugin.provides.graph?.root ? plugin : void 0;
3
+ var parseGraphBuilderPlugin = (plugin) => plugin.provides.graph?.builder ? plugin : void 0;
4
+
5
+ // packages/sdk/app-framework/src/plugins/common/layout.ts
6
+ import { z } from "zod";
7
+ var Layout = z.object({
8
+ fullscreen: z.boolean(),
9
+ sidebarOpen: z.boolean(),
10
+ complementarySidebarOpen: z.boolean(),
11
+ dialogContent: z.any().optional().describe("Data to be passed to the dialog Surface."),
12
+ dialogOpen: z.boolean(),
13
+ popoverAnchorId: z.string().optional(),
14
+ popoverContent: z.any().optional().describe("Data to be passed to the popover Surface."),
15
+ popoverOpen: z.boolean(),
16
+ // TODO(wittjosiah): Array?
17
+ active: z.string().optional().describe("Id of the currently active item."),
18
+ // TODO(wittjosiah): History?
19
+ previous: z.string().optional()
20
+ });
21
+ var parseLayoutPlugin = (plugin) => {
22
+ const { success } = Layout.safeParse(plugin.provides.layout);
23
+ return success ? plugin : void 0;
24
+ };
25
+ var LAYOUT_ACTION = "dxos.org/plugin/intent";
26
+ var LayoutAction;
27
+ (function(LayoutAction2) {
28
+ LayoutAction2[LayoutAction2["TOGGLE_FULLSCREEN"] = `${LAYOUT_ACTION}/toggle-fullscreen`] = "TOGGLE_FULLSCREEN";
29
+ LayoutAction2[LayoutAction2["TOGGLE_SIDEBAR"] = `${LAYOUT_ACTION}/toggle-sidebar`] = "TOGGLE_SIDEBAR";
30
+ LayoutAction2[LayoutAction2["TOGGLE_COMPLEMENTARY_SIDEBAR"] = `${LAYOUT_ACTION}/toggle-complementary-sidebar`] = "TOGGLE_COMPLEMENTARY_SIDEBAR";
31
+ LayoutAction2[LayoutAction2["OPEN_DIALOG"] = `${LAYOUT_ACTION}/open-dialog`] = "OPEN_DIALOG";
32
+ LayoutAction2[LayoutAction2["CLOSE_DIALOG"] = `${LAYOUT_ACTION}/close-dialog`] = "CLOSE_DIALOG";
33
+ LayoutAction2[LayoutAction2["OPEN_POPOVER"] = `${LAYOUT_ACTION}/open-popover`] = "OPEN_POPOVER";
34
+ LayoutAction2[LayoutAction2["CLOSE_POPOVER"] = `${LAYOUT_ACTION}/close-popover`] = "CLOSE_POPOVER";
35
+ LayoutAction2[LayoutAction2["ACTIVATE"] = `${LAYOUT_ACTION}/activate`] = "ACTIVATE";
36
+ })(LayoutAction || (LayoutAction = {}));
37
+
38
+ // packages/sdk/app-framework/src/plugins/common/translations.ts
39
+ import { z as z2 } from "zod";
40
+ var ResourceKey = z2.union([
41
+ z2.string(),
42
+ z2.record(z2.any())
43
+ ]);
44
+ var ResourceLanguage = z2.record(ResourceKey);
45
+ var Resource = z2.record(ResourceLanguage);
46
+ var parseTranslationsPlugin = (plugin) => {
47
+ const { success } = z2.array(Resource).safeParse(plugin.provides.translations);
48
+ return success ? plugin : void 0;
49
+ };
50
+
51
+ // packages/sdk/app-framework/src/plugins/helpers.ts
52
+ import { raise } from "@dxos/debug";
53
+ var findPlugin = (plugins, id) => {
54
+ return plugins.find((plugin) => plugin.meta.id === id || typeof plugin.meta.shortId === "string" && plugin.meta.shortId === id);
55
+ };
56
+ var getPlugin = (plugins, id) => {
57
+ return findPlugin(plugins, id) ?? raise(new Error(`Plugin not found: ${id}`));
58
+ };
59
+ var filterPlugins = (plugins, predicate) => plugins.map((plugin) => predicate(plugin)).filter((plugin) => !!plugin);
60
+ var resolvePlugin = (plugins, predicate) => filterPlugins(plugins, predicate)[0];
61
+
62
+ // packages/sdk/app-framework/src/plugins/IntentPlugin/IntentContext.tsx
63
+ import { createContext, useContext } from "react";
64
+ var IntentContext = /* @__PURE__ */ createContext({
65
+ dispatch: async () => {
66
+ }
67
+ });
68
+ var useIntent = () => useContext(IntentContext);
69
+ var IntentProvider = IntentContext.Provider;
70
+
71
+ // packages/sdk/app-framework/src/plugins/IntentPlugin/IntentPlugin.tsx
72
+ import { deepSignal } from "deepsignal/react";
73
+ import React from "react";
74
+ var parseIntentPlugin = (plugin) => plugin.provides.intent?.dispatch ? plugin : void 0;
75
+ var parseIntentResolverPlugin = (plugin) => plugin.provides.intent?.resolver ? plugin : void 0;
76
+ var IntentPlugin = () => {
77
+ const state = deepSignal({
78
+ dispatch: async () => {
79
+ }
80
+ });
81
+ return {
82
+ meta: {
83
+ id: "dxos.org/plugin/intent"
84
+ },
85
+ ready: async (plugins) => {
86
+ const dispatch = (intent) => {
87
+ if (intent.plugin) {
88
+ const plugin = findPlugin(plugins, intent.plugin);
89
+ return plugin?.provides.intent.resolver(intent, plugins);
90
+ }
91
+ return filterPlugins(plugins, parseIntentResolverPlugin).reduce((acc, plugin) => {
92
+ return acc ?? plugin.provides.intent.resolver(intent, plugins);
93
+ }, void 0);
94
+ };
95
+ state.dispatch = async (intentOrArray) => {
96
+ let result = null;
97
+ for (const intent of Array.isArray(intentOrArray) ? intentOrArray : [
98
+ intentOrArray
99
+ ]) {
100
+ const data = intent.data ? {
101
+ ...result,
102
+ ...intent.data
103
+ } : result;
104
+ result = await dispatch({
105
+ ...intent,
106
+ data
107
+ });
108
+ }
109
+ return result;
110
+ };
111
+ },
112
+ provides: {
113
+ intent: state,
114
+ context: ({ children }) => /* @__PURE__ */ React.createElement(IntentProvider, {
115
+ value: state
116
+ }, children)
117
+ }
118
+ };
119
+ };
120
+
121
+ // packages/sdk/app-framework/src/plugins/PluginHost/PluginContext.tsx
122
+ import { createContext as createContext2, useContext as useContext2 } from "react";
123
+ var PluginContext = /* @__PURE__ */ createContext2({
124
+ ready: false,
125
+ initializing: [],
126
+ loading: [],
127
+ plugins: []
128
+ });
129
+ var usePlugins = () => useContext2(PluginContext);
130
+ var usePlugin = (id) => {
131
+ const { plugins } = usePlugins();
132
+ return findPlugin(plugins, id);
133
+ };
134
+ var useResolvePlugin = (predicate) => {
135
+ const { plugins } = usePlugins();
136
+ return resolvePlugin(plugins, predicate);
137
+ };
138
+ var PluginProvider = PluginContext.Provider;
139
+
140
+ // packages/sdk/app-framework/src/plugins/PluginHost/PluginHost.tsx
141
+ import { deepSignal as deepSignal2, shallow } from "deepsignal/react";
142
+ import React2, { useEffect } from "react";
143
+ import { log } from "@dxos/log";
144
+ var __dxlog_file = "/home/runner/work/dxos/dxos/packages/sdk/app-framework/src/plugins/PluginHost/PluginHost.tsx";
145
+ var parsePluginHost = (plugin) => plugin.provides.plugins ? plugin : void 0;
146
+ var PluginHost = ({ plugins: definitions, fallback }) => {
147
+ const state = deepSignal2({
148
+ ready: false,
149
+ initializing: [],
150
+ loading: [],
151
+ plugins: []
152
+ });
153
+ return {
154
+ meta: {
155
+ id: "dxos.org/plugin/host"
156
+ },
157
+ provides: {
158
+ plugins: state,
159
+ context: ({ children }) => /* @__PURE__ */ React2.createElement(PluginProvider, {
160
+ value: state
161
+ }, children),
162
+ root: () => {
163
+ useEffect(() => {
164
+ log("initializing plugins", {
165
+ definitions
166
+ }, {
167
+ F: __dxlog_file,
168
+ L: 43,
169
+ S: void 0,
170
+ C: (f, a) => f(...a)
171
+ });
172
+ const timeout = setTimeout(async () => {
173
+ state.initializing = shallow(definitions);
174
+ const plugins = await Promise.all(definitions.map(async (definition) => {
175
+ const plugin = await initializePlugin(definition).catch((err) => {
176
+ console.error("Failed to initialize plugin:", definition.meta.id, err);
177
+ return void 0;
178
+ });
179
+ state.initializing = shallow(state.initializing.filter((plugin2) => plugin2 !== definition));
180
+ return plugin;
181
+ })).then((plugins2) => plugins2.filter((plugin) => Boolean(plugin)));
182
+ log("plugins initialized", {
183
+ plugins
184
+ }, {
185
+ F: __dxlog_file,
186
+ L: 57,
187
+ S: void 0,
188
+ C: (f, a) => f(...a)
189
+ });
190
+ state.loading = shallow(definitions);
191
+ await Promise.all(definitions.map(async (pluginDefinition) => {
192
+ await pluginDefinition.ready?.(plugins);
193
+ state.loading = shallow(state.loading.filter((plugin) => plugin !== pluginDefinition));
194
+ }));
195
+ log("plugins ready", {
196
+ plugins
197
+ }, {
198
+ F: __dxlog_file,
199
+ L: 66,
200
+ S: void 0,
201
+ C: (f, a) => f(...a)
202
+ });
203
+ state.plugins = shallow(plugins);
204
+ state.ready = true;
205
+ });
206
+ return () => {
207
+ clearTimeout(timeout);
208
+ state.ready = false;
209
+ void Promise.all(definitions.map((definition) => definition.unload?.()));
210
+ };
211
+ }, []);
212
+ if (!state.ready) {
213
+ if (typeof fallback === "function") {
214
+ const FallbackComponent = fallback;
215
+ return /* @__PURE__ */ React2.createElement(FallbackComponent, {
216
+ initializing: state.initializing,
217
+ loading: state.loading,
218
+ plugins: state.plugins
219
+ });
220
+ }
221
+ return /* @__PURE__ */ React2.createElement(React2.Fragment, null, fallback ?? null);
222
+ }
223
+ const ComposedContext = composeContext(state.plugins);
224
+ return /* @__PURE__ */ React2.createElement(ComposedContext, null, rootComponents(state.plugins));
225
+ }
226
+ }
227
+ };
228
+ };
229
+ var initializePlugin = async (pluginDefinition) => {
230
+ const provides = await pluginDefinition.initialize?.();
231
+ return {
232
+ ...pluginDefinition,
233
+ provides: {
234
+ ...pluginDefinition.provides,
235
+ ...provides
236
+ }
237
+ };
238
+ };
239
+ var rootComponents = (plugins) => {
240
+ return plugins.map((plugin) => {
241
+ const Component2 = plugin.provides.root;
242
+ if (Component2) {
243
+ return /* @__PURE__ */ React2.createElement(Component2, {
244
+ key: plugin.meta.id
245
+ });
246
+ } else {
247
+ return null;
248
+ }
249
+ }).filter((node) => Boolean(node));
250
+ };
251
+ var composeContext = (plugins) => {
252
+ return compose(plugins.map((p) => p.provides.context).filter(Boolean));
253
+ };
254
+ var compose = (contexts) => {
255
+ return [
256
+ ...contexts
257
+ ].reduce((Acc, Next) => ({ children }) => /* @__PURE__ */ React2.createElement(Acc, null, /* @__PURE__ */ React2.createElement(Next, null, children)));
258
+ };
259
+
260
+ // packages/sdk/app-framework/src/plugins/SurfacePlugin/ErrorBoundary.tsx
261
+ import React3, { Component } from "react";
262
+ var ErrorBoundary = class extends Component {
263
+ constructor(props) {
264
+ super(props);
265
+ this.state = {
266
+ error: void 0
267
+ };
268
+ }
269
+ static getDerivedStateFromError(error) {
270
+ return {
271
+ error
272
+ };
273
+ }
274
+ componentDidUpdate(prevProps) {
275
+ if (prevProps.data !== this.props.data) {
276
+ this.resetError();
277
+ }
278
+ }
279
+ render() {
280
+ if (this.state.error) {
281
+ return /* @__PURE__ */ React3.createElement(this.props.fallback, {
282
+ error: this.state.error,
283
+ reset: this.resetError
284
+ });
285
+ }
286
+ return this.props.children;
287
+ }
288
+ resetError() {
289
+ this.setState({
290
+ error: void 0
291
+ });
292
+ }
293
+ };
294
+
295
+ // packages/sdk/app-framework/src/plugins/SurfacePlugin/Surface.tsx
296
+ import React4 from "react";
297
+ import { createContext as createContext4, useContext as useContext4 } from "react";
298
+
299
+ // packages/sdk/app-framework/src/plugins/SurfacePlugin/SurfaceRootContext.tsx
300
+ import { createContext as createContext3, useContext as useContext3 } from "react";
301
+ var SurfaceRootContext = /* @__PURE__ */ createContext3({
302
+ components: {}
303
+ });
304
+ var useSurface = () => useContext3(SurfaceRootContext);
305
+ var SurfaceProvider = SurfaceRootContext.Provider;
306
+
307
+ // packages/sdk/app-framework/src/plugins/SurfacePlugin/Surface.tsx
308
+ var Surface = ({ role, name = role, fallback, ...rest }) => {
309
+ const props = {
310
+ role,
311
+ name,
312
+ fallback,
313
+ ...rest
314
+ };
315
+ const context = useContext4(SurfaceContext);
316
+ const data = props.data ?? (name && context?.surfaces?.[name]?.data || {});
317
+ return /* @__PURE__ */ React4.createElement(React4.Fragment, null, fallback ? /* @__PURE__ */ React4.createElement(ErrorBoundary, {
318
+ data,
319
+ fallback
320
+ }, /* @__PURE__ */ React4.createElement(SurfaceResolver, props)) : /* @__PURE__ */ React4.createElement(SurfaceResolver, props));
321
+ };
322
+ var SurfaceContext = /* @__PURE__ */ createContext4(null);
323
+ var SurfaceResolver = (props) => {
324
+ const { components } = useSurface();
325
+ const parent = useContext4(SurfaceContext);
326
+ const nodes = resolveNodes(components, props, parent);
327
+ const currentContext = {
328
+ ...props,
329
+ surfaces: {
330
+ ...props.name && parent?.surfaces?.[props.name]?.surfaces || {},
331
+ ...props.surfaces
332
+ }
333
+ };
334
+ return /* @__PURE__ */ React4.createElement(SurfaceContext.Provider, {
335
+ value: currentContext
336
+ }, nodes);
337
+ };
338
+ var resolveNodes = (components, props, context) => {
339
+ const data = {
340
+ ...props.name && context?.surfaces?.[props.name]?.data || {},
341
+ ...props.data
342
+ };
343
+ const nodes = Object.entries(components).map(([key, component]) => {
344
+ const result = component(data, props.role);
345
+ return result ? /* @__PURE__ */ React4.createElement(Wrapper, {
346
+ key
347
+ }, result) : void 0;
348
+ }).filter((Component2) => Boolean(Component2));
349
+ return props.limit ? nodes.slice(0, props.limit) : nodes;
350
+ };
351
+ var Wrapper = ({ children }) => /* @__PURE__ */ React4.createElement(React4.Fragment, null, children);
352
+
353
+ // packages/sdk/app-framework/src/plugins/SurfacePlugin/SurfacePlugin.tsx
354
+ import { deepSignal as deepSignal3, shallow as shallow2 } from "deepsignal/react";
355
+ import React5 from "react";
356
+ var parseRootSurfacePlugin = (plugin) => plugin?.provides?.surface?.components ? plugin : void 0;
357
+ var parseSurfacePlugin = (plugin) => plugin?.provides?.surface?.component ? plugin : void 0;
358
+ var SurfacePlugin = () => {
359
+ const state = deepSignal3({
360
+ components: {}
361
+ });
362
+ return {
363
+ meta: {
364
+ id: "dxos.org/plugin/surface"
365
+ },
366
+ ready: async (plugins) => {
367
+ state.components = shallow2(filterPlugins(plugins, parseSurfacePlugin).reduce((acc, plugin) => {
368
+ return {
369
+ ...acc,
370
+ [plugin.meta.id]: plugin.provides.surface.component
371
+ };
372
+ }, {}));
373
+ },
374
+ provides: {
375
+ surface: state,
376
+ context: ({ children }) => /* @__PURE__ */ React5.createElement(SurfaceProvider, {
377
+ value: state
378
+ }, children)
379
+ }
380
+ };
381
+ };
382
+
383
+ // packages/sdk/app-framework/src/App.tsx
384
+ import React6 from "react";
385
+ import { invariant } from "@dxos/invariant";
386
+ var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/sdk/app-framework/src/App.tsx";
387
+ var createApp = ({ plugins, fallback }) => {
388
+ const host = PluginHost({
389
+ plugins: [
390
+ SurfacePlugin(),
391
+ IntentPlugin(),
392
+ ...plugins
393
+ ],
394
+ fallback
395
+ });
396
+ invariant(host.provides?.context, void 0, {
397
+ F: __dxlog_file2,
398
+ L: 33,
399
+ S: void 0,
400
+ A: [
401
+ "host.provides?.context",
402
+ ""
403
+ ]
404
+ });
405
+ invariant(host.provides?.root, void 0, {
406
+ F: __dxlog_file2,
407
+ L: 34,
408
+ S: void 0,
409
+ A: [
410
+ "host.provides?.root",
411
+ ""
412
+ ]
413
+ });
414
+ const Context = host.provides.context;
415
+ const Root = host.provides.root;
416
+ return () => /* @__PURE__ */ React6.createElement(Context, null, /* @__PURE__ */ React6.createElement(Root, null));
417
+ };
418
+ export {
419
+ ErrorBoundary,
420
+ IntentPlugin,
421
+ IntentProvider,
422
+ Layout,
423
+ LayoutAction,
424
+ PluginHost,
425
+ PluginProvider,
426
+ Resource,
427
+ ResourceKey,
428
+ ResourceLanguage,
429
+ Surface,
430
+ SurfacePlugin,
431
+ SurfaceProvider,
432
+ createApp,
433
+ filterPlugins,
434
+ findPlugin,
435
+ getPlugin,
436
+ initializePlugin,
437
+ parseGraphBuilderPlugin,
438
+ parseGraphPlugin,
439
+ parseIntentPlugin,
440
+ parseIntentResolverPlugin,
441
+ parseLayoutPlugin,
442
+ parsePluginHost,
443
+ parseRootSurfacePlugin,
444
+ parseSurfacePlugin,
445
+ parseTranslationsPlugin,
446
+ resolvePlugin,
447
+ useIntent,
448
+ usePlugin,
449
+ usePlugins,
450
+ useResolvePlugin,
451
+ useSurface
452
+ };
453
+ //# sourceMappingURL=index.mjs.map