@dxos/app-framework 0.8.4-main.b97322e → 0.8.4-main.dedc0f3

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 (153) hide show
  1. package/.swc/plugins/linux_x86_64_19.0.0/727453fb3a62f7f1d952a41e051ca8a6f88cadc45cee43c6a4d1aa45f9b75665.wasmer-v7 +0 -0
  2. package/.swc/plugins/{v7_linux_x86_64_13.0.0/fce1bdb8e20a094e4af08bad09cc81497ed0e2e7c51223b07d371063cca18429 → linux_x86_64_19.0.0/fce1bdb8e20a094e4af08bad09cc81497ed0e2e7c51223b07d371063cca18429.wasmer-v7} +0 -0
  3. package/dist/lib/browser/{app-graph-builder-LYF7EKNN.mjs → app-graph-builder-AFFC6VB2.mjs} +3 -3
  4. package/dist/lib/browser/app-graph-builder-AFFC6VB2.mjs.map +7 -0
  5. package/dist/lib/browser/{chunk-FMN65HSW.mjs → chunk-OZY7HV2A.mjs} +376 -252
  6. package/dist/lib/browser/chunk-OZY7HV2A.mjs.map +7 -0
  7. package/dist/lib/browser/{chunk-FO2PH7M3.mjs → chunk-T6M7JB7M.mjs} +186 -130
  8. package/dist/lib/browser/chunk-T6M7JB7M.mjs.map +7 -0
  9. package/dist/lib/browser/index.mjs +11 -5
  10. package/dist/lib/browser/index.mjs.map +2 -2
  11. package/dist/lib/browser/{intent-dispatcher-LSYQZSEB.mjs → intent-dispatcher-QG7UPGQX.mjs} +2 -2
  12. package/dist/lib/browser/{intent-resolver-ZTNOSO3A.mjs → intent-resolver-4S4PSTM5.mjs} +2 -2
  13. package/dist/lib/browser/intent-resolver-4S4PSTM5.mjs.map +7 -0
  14. package/dist/lib/browser/meta.json +1 -1
  15. package/dist/lib/browser/{store-KML2R4IE.mjs → store-6E33KLGK.mjs} +2 -2
  16. package/dist/lib/browser/{store-KML2R4IE.mjs.map → store-6E33KLGK.mjs.map} +1 -1
  17. package/dist/lib/browser/testing/index.mjs +5 -7
  18. package/dist/lib/browser/testing/index.mjs.map +3 -3
  19. package/dist/lib/browser/worker.mjs +7 -1
  20. package/dist/lib/node-esm/{app-graph-builder-SAOWGJDK.mjs → app-graph-builder-S4OAULX5.mjs} +3 -3
  21. package/dist/lib/node-esm/app-graph-builder-S4OAULX5.mjs.map +7 -0
  22. package/dist/lib/node-esm/{chunk-ZEZ4FVEU.mjs → chunk-F63ZRXMK.mjs} +376 -252
  23. package/dist/lib/node-esm/chunk-F63ZRXMK.mjs.map +7 -0
  24. package/dist/lib/node-esm/{chunk-73HGSHKE.mjs → chunk-HJFU7QOR.mjs} +186 -130
  25. package/dist/lib/node-esm/chunk-HJFU7QOR.mjs.map +7 -0
  26. package/dist/lib/node-esm/index.mjs +11 -5
  27. package/dist/lib/node-esm/index.mjs.map +2 -2
  28. package/dist/lib/node-esm/{intent-dispatcher-6CYNGPSW.mjs → intent-dispatcher-NXBGPJOX.mjs} +2 -2
  29. package/dist/lib/node-esm/{intent-resolver-W7Z7WFFM.mjs → intent-resolver-2ZKXI5ET.mjs} +2 -2
  30. package/dist/lib/node-esm/intent-resolver-2ZKXI5ET.mjs.map +7 -0
  31. package/dist/lib/node-esm/meta.json +1 -1
  32. package/dist/lib/node-esm/{store-QEXGXLWZ.mjs → store-QQUTQHHT.mjs} +2 -2
  33. package/dist/lib/node-esm/{store-QEXGXLWZ.mjs.map → store-QQUTQHHT.mjs.map} +1 -1
  34. package/dist/lib/node-esm/testing/index.mjs +5 -7
  35. package/dist/lib/node-esm/testing/index.mjs.map +3 -3
  36. package/dist/lib/node-esm/worker.mjs +7 -1
  37. package/dist/types/src/common/capabilities.d.ts +75 -8
  38. package/dist/types/src/common/capabilities.d.ts.map +1 -1
  39. package/dist/types/src/common/collaboration.d.ts +9 -8
  40. package/dist/types/src/common/collaboration.d.ts.map +1 -1
  41. package/dist/types/src/common/events.d.ts.map +1 -1
  42. package/dist/types/src/common/index.d.ts +1 -1
  43. package/dist/types/src/common/index.d.ts.map +1 -1
  44. package/dist/types/src/common/surface.d.ts +1 -1
  45. package/dist/types/src/common/surface.d.ts.map +1 -1
  46. package/dist/types/src/components/App.d.ts +10 -0
  47. package/dist/types/src/components/App.d.ts.map +1 -0
  48. package/dist/types/src/components/App.stories.d.ts +15 -0
  49. package/dist/types/src/components/App.stories.d.ts.map +1 -0
  50. package/dist/types/src/components/DefaultFallback.d.ts +8 -0
  51. package/dist/types/src/components/DefaultFallback.d.ts.map +1 -0
  52. package/dist/types/src/components/index.d.ts +2 -0
  53. package/dist/types/src/components/index.d.ts.map +1 -0
  54. package/dist/types/src/{App.d.ts → components/useApp.d.ts} +7 -6
  55. package/dist/types/src/components/useApp.d.ts.map +1 -0
  56. package/dist/types/src/components/useLoading.d.ts +19 -0
  57. package/dist/types/src/components/useLoading.d.ts.map +1 -0
  58. package/dist/types/src/core/capabilities.d.ts +4 -1
  59. package/dist/types/src/core/capabilities.d.ts.map +1 -1
  60. package/dist/types/src/core/manager.d.ts +6 -2
  61. package/dist/types/src/core/manager.d.ts.map +1 -1
  62. package/dist/types/src/index.d.ts +1 -1
  63. package/dist/types/src/index.d.ts.map +1 -1
  64. package/dist/types/src/playground/debug/Debug.d.ts +1 -1
  65. package/dist/types/src/playground/generator/Main.d.ts +1 -1
  66. package/dist/types/src/playground/generator/Toolbar.d.ts +1 -1
  67. package/dist/types/src/playground/generator/Toolbar.d.ts.map +1 -1
  68. package/dist/types/src/playground/generator/generator.d.ts.map +1 -1
  69. package/dist/types/src/playground/layout/Layout.d.ts +2 -2
  70. package/dist/types/src/playground/logger/Toolbar.d.ts +1 -1
  71. package/dist/types/src/playground/logger/Toolbar.d.ts.map +1 -1
  72. package/dist/types/src/playground/logger/plugin.d.ts.map +1 -1
  73. package/dist/types/src/playground/playground.stories.d.ts +5 -3
  74. package/dist/types/src/playground/playground.stories.d.ts.map +1 -1
  75. package/dist/types/src/plugin-intent/IntentPlugin.d.ts.map +1 -1
  76. package/dist/types/src/plugin-intent/index.d.ts +1 -0
  77. package/dist/types/src/plugin-intent/index.d.ts.map +1 -1
  78. package/dist/types/src/plugin-intent/intent-dispatcher.d.ts +3 -3
  79. package/dist/types/src/plugin-intent/intent-dispatcher.d.ts.map +1 -1
  80. package/dist/types/src/plugin-settings/SettingsPlugin.d.ts.map +1 -1
  81. package/dist/types/src/plugin-settings/app-graph-builder.d.ts +1 -1
  82. package/dist/types/src/plugin-settings/app-graph-builder.d.ts.map +1 -1
  83. package/dist/types/src/plugin-settings/intent-resolver.d.ts +1 -1
  84. package/dist/types/src/plugin-settings/intent-resolver.d.ts.map +1 -1
  85. package/dist/types/src/plugin-settings/store.d.ts +1 -1
  86. package/dist/types/src/plugin-settings/store.d.ts.map +1 -1
  87. package/dist/types/src/react/ErrorBoundary.d.ts +13 -14
  88. package/dist/types/src/react/ErrorBoundary.d.ts.map +1 -1
  89. package/dist/types/src/react/IntentContext.d.ts.map +1 -1
  90. package/dist/types/src/react/Surface.d.ts.map +1 -1
  91. package/dist/types/src/react/Surface.stories.d.ts +6 -4
  92. package/dist/types/src/react/Surface.stories.d.ts.map +1 -1
  93. package/dist/types/src/react/common.d.ts.map +1 -1
  94. package/dist/types/src/react/useCapabilities.d.ts.map +1 -1
  95. package/dist/types/src/testing/withPluginManager.d.ts +4 -2
  96. package/dist/types/src/testing/withPluginManager.d.ts.map +1 -1
  97. package/dist/types/src/testing/withPluginManager.stories.d.ts +9 -3
  98. package/dist/types/src/testing/withPluginManager.stories.d.ts.map +1 -1
  99. package/dist/types/tsconfig.tsbuildinfo +1 -1
  100. package/package.json +28 -24
  101. package/src/common/capabilities.ts +91 -10
  102. package/src/common/collaboration.ts +5 -8
  103. package/src/common/events.ts +3 -1
  104. package/src/common/index.ts +1 -1
  105. package/src/common/surface.ts +1 -1
  106. package/src/components/App.stories.tsx +35 -0
  107. package/src/components/App.tsx +59 -0
  108. package/src/components/DefaultFallback.tsx +26 -0
  109. package/src/components/index.ts +5 -0
  110. package/src/{App.tsx → components/useApp.tsx} +20 -130
  111. package/src/components/useLoading.tsx +70 -0
  112. package/src/core/capabilities.test.ts +1 -1
  113. package/src/core/capabilities.ts +11 -6
  114. package/src/core/manager.test.ts +4 -3
  115. package/src/core/manager.ts +132 -54
  116. package/src/helpers.test.ts +1 -1
  117. package/src/index.ts +1 -1
  118. package/src/playground/debug/Debug.tsx +1 -1
  119. package/src/playground/generator/Toolbar.tsx +2 -1
  120. package/src/playground/generator/generator.ts +2 -2
  121. package/src/playground/layout/plugin.ts +1 -1
  122. package/src/playground/logger/Toolbar.tsx +2 -1
  123. package/src/playground/logger/plugin.ts +3 -2
  124. package/src/playground/playground.stories.tsx +15 -10
  125. package/src/plugin-intent/IntentPlugin.ts +2 -1
  126. package/src/plugin-intent/index.ts +1 -0
  127. package/src/plugin-intent/intent-dispatcher.test.ts +1 -1
  128. package/src/plugin-intent/intent-dispatcher.ts +10 -8
  129. package/src/plugin-settings/SettingsPlugin.ts +3 -2
  130. package/src/plugin-settings/app-graph-builder.ts +4 -3
  131. package/src/plugin-settings/intent-resolver.ts +3 -2
  132. package/src/plugin-settings/store.ts +1 -1
  133. package/src/react/ErrorBoundary.tsx +24 -15
  134. package/src/react/IntentContext.tsx +3 -2
  135. package/src/react/Surface.stories.tsx +21 -13
  136. package/src/react/Surface.tsx +4 -3
  137. package/src/react/common.ts +2 -1
  138. package/src/react/useCapabilities.ts +2 -1
  139. package/src/testing/withPluginManager.stories.tsx +9 -5
  140. package/src/testing/withPluginManager.tsx +13 -13
  141. package/tsconfig.json +1 -8
  142. package/.swc/plugins/v7_linux_x86_64_13.0.0/f45bdff002284d9e8f9ef3f0be909de12da36c049cbcf261ac78fc00abb09a2d +0 -0
  143. package/dist/lib/browser/app-graph-builder-LYF7EKNN.mjs.map +0 -7
  144. package/dist/lib/browser/chunk-FMN65HSW.mjs.map +0 -7
  145. package/dist/lib/browser/chunk-FO2PH7M3.mjs.map +0 -7
  146. package/dist/lib/browser/intent-resolver-ZTNOSO3A.mjs.map +0 -7
  147. package/dist/lib/node-esm/app-graph-builder-SAOWGJDK.mjs.map +0 -7
  148. package/dist/lib/node-esm/chunk-73HGSHKE.mjs.map +0 -7
  149. package/dist/lib/node-esm/chunk-ZEZ4FVEU.mjs.map +0 -7
  150. package/dist/lib/node-esm/intent-resolver-W7Z7WFFM.mjs.map +0 -7
  151. package/dist/types/src/App.d.ts.map +0 -1
  152. /package/dist/lib/browser/{intent-dispatcher-LSYQZSEB.mjs.map → intent-dispatcher-QG7UPGQX.mjs.map} +0 -0
  153. /package/dist/lib/node-esm/{intent-dispatcher-6CYNGPSW.mjs.map → intent-dispatcher-NXBGPJOX.mjs.map} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/app-framework",
3
- "version": "0.8.4-main.b97322e",
3
+ "version": "0.8.4-main.dedc0f3",
4
4
  "description": "A framework for building applications from composible plugins.",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -10,16 +10,19 @@
10
10
  "type": "module",
11
11
  "exports": {
12
12
  ".": {
13
+ "source": "./src/index.ts",
13
14
  "types": "./dist/types/src/index.d.ts",
14
15
  "browser": "./dist/lib/browser/index.mjs",
15
16
  "node": "./dist/lib/node-esm/index.mjs"
16
17
  },
17
18
  "./testing": {
19
+ "source": "./src/testing/index.ts",
18
20
  "types": "./dist/types/src/testing/index.d.ts",
19
21
  "browser": "./dist/lib/browser/testing/index.mjs",
20
22
  "node": "./dist/lib/node-esm/testing/index.mjs"
21
23
  },
22
24
  "./worker": {
25
+ "source": "./src/worker.ts",
23
26
  "types": "./dist/types/src/worker.d.ts",
24
27
  "browser": "./dist/lib/browser/worker.mjs",
25
28
  "node": "./dist/lib/node-esm/worker.mjs"
@@ -37,37 +40,38 @@
37
40
  }
38
41
  },
39
42
  "dependencies": {
43
+ "@effect/ai": "0.25.2",
40
44
  "@preact-signals/safe-react": "^0.9.0",
41
45
  "@preact/signals-core": "^1.9.0",
42
- "@dxos/ai": "0.8.4-main.b97322e",
43
- "@dxos/app-graph": "0.8.4-main.b97322e",
44
- "@dxos/async": "0.8.4-main.b97322e",
45
- "@dxos/blueprints": "0.8.4-main.b97322e",
46
- "@dxos/client-protocol": "0.8.4-main.b97322e",
47
- "@dxos/debug": "0.8.4-main.b97322e",
48
- "@dxos/echo-schema": "0.8.4-main.b97322e",
49
- "@dxos/invariant": "0.8.4-main.b97322e",
50
- "@dxos/keys": "0.8.4-main.b97322e",
51
- "@dxos/functions": "0.8.4-main.b97322e",
52
- "@dxos/live-object": "0.8.4-main.b97322e",
53
- "@dxos/local-storage": "0.8.4-main.b97322e",
54
- "@dxos/log": "0.8.4-main.b97322e",
55
- "@dxos/react-hooks": "0.8.4-main.b97322e",
56
- "@dxos/schema": "0.8.4-main.b97322e",
57
- "@dxos/util": "0.8.4-main.b97322e"
46
+ "@dxos/ai": "0.8.4-main.dedc0f3",
47
+ "@dxos/app-graph": "0.8.4-main.dedc0f3",
48
+ "@dxos/blueprints": "0.8.4-main.dedc0f3",
49
+ "@dxos/debug": "0.8.4-main.dedc0f3",
50
+ "@dxos/async": "0.8.4-main.dedc0f3",
51
+ "@dxos/echo-schema": "0.8.4-main.dedc0f3",
52
+ "@dxos/client-protocol": "0.8.4-main.dedc0f3",
53
+ "@dxos/functions": "0.8.4-main.dedc0f3",
54
+ "@dxos/keys": "0.8.4-main.dedc0f3",
55
+ "@dxos/invariant": "0.8.4-main.dedc0f3",
56
+ "@dxos/local-storage": "0.8.4-main.dedc0f3",
57
+ "@dxos/live-object": "0.8.4-main.dedc0f3",
58
+ "@dxos/react-hooks": "0.8.4-main.dedc0f3",
59
+ "@dxos/log": "0.8.4-main.dedc0f3",
60
+ "@dxos/schema": "0.8.4-main.dedc0f3",
61
+ "@dxos/util": "0.8.4-main.dedc0f3"
58
62
  },
59
63
  "devDependencies": {
60
64
  "@effect-rx/rx-react": "0.38.0",
61
- "@effect/platform": "0.89.0",
65
+ "@effect/platform": "0.90.2",
62
66
  "@types/react": "~18.2.0",
63
- "effect": "3.17.0",
67
+ "effect": "3.17.7",
64
68
  "react": "~18.2.0",
65
69
  "typedoc": "0.28.1",
66
- "@dxos/random": "0.8.4-main.b97322e",
67
- "@dxos/echo-signals": "0.8.4-main.b97322e",
68
- "@dxos/react-ui": "0.8.4-main.b97322e",
69
- "@dxos/react-ui-syntax-highlighter": "0.8.4-main.b97322e",
70
- "@dxos/storybook-utils": "0.8.4-main.b97322e"
70
+ "@dxos/echo-signals": "0.8.4-main.dedc0f3",
71
+ "@dxos/random": "0.8.4-main.dedc0f3",
72
+ "@dxos/react-ui": "0.8.4-main.dedc0f3",
73
+ "@dxos/react-ui-syntax-highlighter": "0.8.4-main.dedc0f3",
74
+ "@dxos/storybook-utils": "0.8.4-main.dedc0f3"
71
75
  },
72
76
  "peerDependencies": {
73
77
  "@effect-rx/rx-react": "^0.34.1",
@@ -2,44 +2,74 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
+ import { type AiTool, type AiToolkit } from '@effect/ai';
5
6
  import { type Registry } from '@effect-rx/rx-react';
6
- import { type Schema } from 'effect';
7
+ import { type Layer, type Schema } from 'effect';
7
8
  import { type FC, type PropsWithChildren } from 'react';
8
9
 
9
- import { type ExecutableTool } from '@dxos/ai';
10
- import { type GraphBuilder, type BuilderExtensions } from '@dxos/app-graph';
11
- import { type ArtifactDefinition } from '@dxos/blueprints';
10
+ import { type BuilderExtensions, type GraphBuilder } from '@dxos/app-graph';
11
+ import { type Blueprint } from '@dxos/blueprints';
12
12
  import { type Space } from '@dxos/client-protocol';
13
13
  import { type FunctionDefinition } from '@dxos/functions';
14
14
  import { type RootSettingsStore } from '@dxos/local-storage';
15
15
  import { type AnchoredTo } from '@dxos/schema';
16
16
 
17
+ import { type PluginManager, defineCapability } from '../core';
18
+ import { type AnyIntentResolver, type IntentContext } from '../plugin-intent';
19
+
17
20
  import { type FileInfo } from './file';
18
21
  import { type NodeSerializer } from './graph';
19
22
  import { type SurfaceDefinition } from './surface';
20
23
  import { type Resource } from './translations';
21
- import { type PluginManager, defineCapability } from '../core';
22
- import { type AnyIntentResolver, type IntentContext } from '../plugin-intent';
23
24
 
25
+ // TODO(burdon): Sort.
24
26
  export namespace Capabilities {
27
+ /**
28
+ * @category Capability
29
+ */
25
30
  export const Null = defineCapability<null>('dxos.org/app-framework/capability/null');
26
31
 
32
+ /**
33
+ * @category Capability
34
+ */
27
35
  export const PluginManager = defineCapability<PluginManager>('dxos.org/app-framework/capability/plugin-manager');
28
36
 
37
+ /**
38
+ * @category Capability
39
+ */
29
40
  export const RxRegistry = defineCapability<Registry.Registry>('dxos.org/app-framework/capability/rx-registry');
30
41
 
31
42
  export type ReactContext = Readonly<{ id: string; dependsOn?: string[]; context: FC<PropsWithChildren> }>;
43
+
44
+ /**
45
+ * @category Capability
46
+ */
32
47
  export const ReactContext = defineCapability<ReactContext>('dxos.org/app-framework/capability/react-context');
33
48
 
34
49
  export type ReactRoot = Readonly<{ id: string; root: FC<PropsWithChildren> }>;
50
+
51
+ /**
52
+ * @category Capability
53
+ */
35
54
  export const ReactRoot = defineCapability<ReactRoot>('dxos.org/app-framework/capability/react-root');
36
55
 
37
56
  export type ReactSurface = SurfaceDefinition | readonly SurfaceDefinition[];
57
+
58
+ /**
59
+ * @category Capability
60
+ */
38
61
  export const ReactSurface = defineCapability<ReactSurface>('dxos.org/app-framework/common/react-surface');
39
62
 
40
63
  export type IntentResolver = AnyIntentResolver | readonly AnyIntentResolver[];
64
+
65
+ /**
66
+ * @category Capability
67
+ */
41
68
  export const IntentResolver = defineCapability<IntentResolver>('dxos.org/app-framework/capability/intent-resolver');
42
69
 
70
+ /**
71
+ * @category Capability
72
+ */
43
73
  export const IntentDispatcher = defineCapability<IntentContext>(
44
74
  'dxos.org/app-framework/capability/intent-dispatcher',
45
75
  );
@@ -66,23 +96,41 @@ export namespace Capabilities {
66
96
  */
67
97
  scrollIntoView: string | undefined;
68
98
  }>;
99
+
100
+ /**
101
+ * @category Capability
102
+ */
69
103
  export const Layout = defineCapability<Layout>('dxos.org/app-framework/capability/layout');
70
104
 
71
- // TODO(burdon): Why array?
105
+ /**
106
+ * @category Capability
107
+ */
72
108
  export const Translations = defineCapability<Readonly<Resource[]>>('dxos.org/app-framework/capability/translations');
73
109
 
110
+ /**
111
+ * @category Capability
112
+ */
74
113
  export const AppGraph = defineCapability<Readonly<Pick<GraphBuilder, 'graph' | 'explore'>>>(
75
114
  'dxos.org/app-framework/capability/app-graph',
76
115
  );
77
116
 
117
+ /**
118
+ * @category Capability
119
+ */
78
120
  export const AppGraphBuilder = defineCapability<BuilderExtensions>(
79
121
  'dxos.org/app-framework/capability/app-graph-builder',
80
122
  );
81
123
 
124
+ /**
125
+ * @category Capability
126
+ */
82
127
  export const AppGraphSerializer = defineCapability<NodeSerializer[]>(
83
128
  'dxos.org/app-framework/capability/app-graph-serializer',
84
129
  );
85
130
 
131
+ /**
132
+ * @category Capability
133
+ */
86
134
  export const SettingsStore = defineCapability<RootSettingsStore>('dxos.org/app-framework/capability/settings-store');
87
135
 
88
136
  // TODO(wittjosiah): The generics caused type inference issues for schemas when contributing settings.
@@ -93,26 +141,59 @@ export namespace Capabilities {
93
141
  schema: Schema.Schema.All;
94
142
  value?: Record<string, any>;
95
143
  };
144
+
145
+ /**
146
+ * @category Capability
147
+ */
96
148
  export const Settings = defineCapability<Settings>('dxos.org/app-framework/capability/settings');
97
149
 
98
150
  export type Metadata = Readonly<{ id: string; metadata: Record<string, any> }>;
151
+
152
+ /**
153
+ * @category Capability
154
+ */
99
155
  export const Metadata = defineCapability<Metadata>('dxos.org/app-framework/capability/metadata');
100
156
 
101
- export const Tools = defineCapability<ExecutableTool[]>('dxos.org/app-framework/capability/tools');
102
- export const ArtifactDefinition = defineCapability<ArtifactDefinition>(
103
- 'dxos.org/app-framework/capability/artifact-definition',
157
+ /**
158
+ * @category Capability
159
+ */
160
+ export const Toolkit = defineCapability<AiToolkit.Any>('dxos.org/app-framework/capability/ai-toolkit');
161
+
162
+ /**
163
+ * @category Capability
164
+ */
165
+ export const ToolkitHandler = defineCapability<Layer.Layer<AiTool.ToHandler<AiTool.AiTool<any>>, never, never>>(
166
+ 'dxos.org/app-framework/capability/ai-toolkit-handler',
104
167
  );
105
168
 
169
+ /**
170
+ * @category Capability
171
+ */
172
+ export const BlueprintDefinition = defineCapability<Blueprint.Blueprint>(
173
+ 'dxos.org/app-framework/capability/blueprint-definition',
174
+ );
175
+
176
+ /**
177
+ * @category Capability
178
+ */
106
179
  export const Functions = defineCapability<FunctionDefinition<any, any>[]>(
107
180
  'dxos.org/app-framework/capability/functions',
108
181
  );
109
182
 
110
183
  export type FileUploader = (file: File, space: Space) => Promise<FileInfo | undefined>;
184
+
185
+ /**
186
+ * @category Capability
187
+ */
111
188
  export const FileUploader = defineCapability<FileUploader>('dxos.org/app-framework/capability/file-uploader');
112
189
 
113
190
  type AnchorSort = {
114
191
  key: string;
115
192
  sort: (anchorA: AnchoredTo, anchorB: AnchoredTo) => number;
116
193
  };
194
+
195
+ /**
196
+ * @category Capability
197
+ */
117
198
  export const AnchorSort = defineCapability<AnchorSort>('dxos.org/app-framework/capability/anchor-sort');
118
199
  }
@@ -4,17 +4,14 @@
4
4
 
5
5
  import { Schema } from 'effect';
6
6
 
7
- import { Expando, Ref } from '@dxos/echo-schema';
7
+ import { DataType } from '@dxos/schema';
8
8
 
9
9
  export namespace CollaborationActions {
10
- export class InsertContent extends Schema.TaggedClass<InsertContent>()('assistant/intent-content', {
10
+ export class AcceptProposal extends Schema.TaggedClass<AcceptProposal>()('collaboration/accept-proposal', {
11
11
  input: Schema.Struct({
12
- target: Expando,
13
- object: Ref(Expando),
14
- at: Schema.optional(Schema.String),
15
- label: Schema.String.pipe(Schema.optional),
16
- }).annotations({
17
- description: 'Enables plugins to inject content blocks or references into a related entity.',
12
+ subject: Schema.Any,
13
+ anchor: Schema.String,
14
+ proposal: DataType.MessageBlock.Proposal,
18
15
  }),
19
16
  output: Schema.Void,
20
17
  }) {}
@@ -2,9 +2,10 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { Capabilities } from './capabilities';
6
5
  import { defineEvent } from '../core';
7
6
 
7
+ import { Capabilities } from './capabilities';
8
+
8
9
  export namespace Events {
9
10
  /**
10
11
  * Fired when the app is started.
@@ -48,6 +49,7 @@ export namespace Events {
48
49
  /**
49
50
  * Fired to load any newly available artifacts definitions.
50
51
  */
52
+ // TODO(burdon): Rename.
51
53
  export const SetupArtifactDefinition = defineEvent('dxos.org/app-framework/event/setup-artifact-definition');
52
54
 
53
55
  //
@@ -6,7 +6,7 @@ export * from './capabilities';
6
6
  export * from './collaboration';
7
7
  export * from './events';
8
8
  export * from './file';
9
- export type * from './graph';
9
+ export * from './graph';
10
10
  export * from './layout';
11
11
  export * from './surface';
12
12
  export * from './translations';
@@ -2,7 +2,7 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { type JSX, type ForwardedRef, type PropsWithChildren, type ReactNode } from 'react';
5
+ import { type ForwardedRef, type JSX, type PropsWithChildren, type ReactNode } from 'react';
6
6
 
7
7
  import { type GuardedType, type MakeOptional, type Position } from '@dxos/util';
8
8
 
@@ -0,0 +1,35 @@
1
+ //
2
+ // Copyright 2022 DXOS.org
3
+ //
4
+
5
+ import '@dxos-theme';
6
+
7
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
8
+ import React from 'react';
9
+
10
+ import { withTheme } from '@dxos/storybook-utils';
11
+
12
+ import { useApp } from './useApp';
13
+
14
+ const DefaultStory = () => {
15
+ const App = useApp({
16
+ placeholder: () => <div className='fixed inset-0 flex items-center justify-center'>Loading...</div>,
17
+ });
18
+
19
+ return <App />;
20
+ };
21
+
22
+ const meta = {
23
+ title: 'sdk/app-framework/App',
24
+ render: DefaultStory,
25
+ decorators: [withTheme],
26
+ parameters: {
27
+ layout: 'fullscreen',
28
+ },
29
+ } satisfies Meta;
30
+
31
+ export default meta;
32
+
33
+ type Story = StoryObj<typeof meta>;
34
+
35
+ export const Default: Story = {};
@@ -0,0 +1,59 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import React, { type PropsWithChildren } from 'react';
6
+
7
+ import { Capabilities } from '../common';
8
+ import { topologicalSort } from '../helpers';
9
+ import { useCapabilities } from '../react';
10
+
11
+ import { type UseAppOptions } from './useApp';
12
+ import { LoadingState, useLoading } from './useLoading';
13
+
14
+ export type AppProps = Pick<UseAppOptions, 'placeholder' | 'debounce'> & {
15
+ state: { ready: boolean; error: unknown };
16
+ };
17
+
18
+ export const App = ({ placeholder: Placeholder, state, debounce }: AppProps) => {
19
+ const reactContexts = useCapabilities(Capabilities.ReactContext);
20
+ const reactRoots = useCapabilities(Capabilities.ReactRoot);
21
+ const stage = useLoading(state, debounce);
22
+
23
+ if (state.error) {
24
+ // This triggers the error boundary to provide UI feedback for the startup error.
25
+ throw state.error;
26
+ }
27
+
28
+ // TODO(wittjosiah): Consider using Suspense instead.
29
+ if (stage < LoadingState.Done) {
30
+ if (!Placeholder) {
31
+ return null;
32
+ }
33
+
34
+ return <Placeholder stage={stage} />;
35
+ }
36
+
37
+ const ComposedContext = composeContexts(reactContexts);
38
+ return (
39
+ <ComposedContext>
40
+ {reactRoots.map(({ id, root: Component }) => (
41
+ <Component key={id} />
42
+ ))}
43
+ </ComposedContext>
44
+ );
45
+ };
46
+
47
+ const composeContexts = (contexts: Capabilities.ReactContext[]) => {
48
+ if (contexts.length === 0) {
49
+ return ({ children }: PropsWithChildren) => <>{children}</>;
50
+ }
51
+
52
+ return topologicalSort(contexts)
53
+ .map(({ context }) => context)
54
+ .reduce((Acc, Next) => ({ children }) => (
55
+ <Acc>
56
+ <Next>{children}</Next>
57
+ </Acc>
58
+ ));
59
+ };
@@ -0,0 +1,26 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import React from 'react';
6
+
7
+ /**
8
+ * NOTE: Default fallback should not use tailwind or theme.
9
+ */
10
+ export const DefaultFallback = ({ error }: { error: Error }) => {
11
+ return (
12
+ <div
13
+ style={{
14
+ margin: '1rem',
15
+ padding: '1rem',
16
+ overflow: 'hidden',
17
+ border: '4px solid teal',
18
+ borderRadius: '1rem',
19
+ }}
20
+ >
21
+ {/* TODO(wittjosiah): Link to docs for replacing default. */}
22
+ <h1 style={{ margin: '0.5rem 0', fontSize: '1.2rem' }}>[ERROR]: {error.message}</h1>
23
+ <pre style={{ overflow: 'auto', fontSize: '1rem', whiteSpace: 'pre-wrap', color: '#888888' }}>{error.stack}</pre>
24
+ </div>
25
+ );
26
+ };
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ export * from './useApp';
@@ -4,20 +4,22 @@
4
4
 
5
5
  import { RegistryContext } from '@effect-rx/rx-react';
6
6
  import { effect } from '@preact/signals-core';
7
- import React, { useCallback, useEffect, useMemo, useState, type FC, type PropsWithChildren } from 'react';
7
+ import React, { type FC, useCallback, useEffect, useMemo } from 'react';
8
8
 
9
9
  import { invariant } from '@dxos/invariant';
10
10
  import { live } from '@dxos/live-object';
11
- import { useDefaultValue } from '@dxos/react-hooks';
11
+ import { useAsyncEffect, useDefaultValue } from '@dxos/react-hooks';
12
12
 
13
- import { Capabilities, Events } from './common';
14
- import { PluginManager, type PluginManagerOptions, type Plugin } from './core';
15
- import { topologicalSort } from './helpers';
16
- import { ErrorBoundary, PluginManagerProvider, useCapabilities } from './react';
13
+ import { Capabilities, Events } from '../common';
14
+ import { type Plugin, PluginManager, type PluginManagerOptions } from '../core';
15
+ import { ErrorBoundary, PluginManagerProvider } from '../react';
16
+
17
+ import { App } from './App';
18
+ import { DefaultFallback } from './DefaultFallback';
17
19
 
18
20
  const ENABLED_KEY = 'dxos.org/app-framework/enabled';
19
21
 
20
- export type CreateAppOptions = {
22
+ export type UseAppOptions = {
21
23
  pluginManager?: PluginManager;
22
24
  pluginLoader?: PluginManagerOptions['pluginLoader'];
23
25
  plugins?: Plugin[];
@@ -27,6 +29,7 @@ export type CreateAppOptions = {
27
29
  fallback?: ErrorBoundary['props']['fallback'];
28
30
  cacheEnabled?: boolean;
29
31
  safeMode?: boolean;
32
+ debounce?: number;
30
33
  };
31
34
 
32
35
  /**
@@ -38,7 +41,7 @@ export type CreateAppOptions = {
38
41
  * const core = [LayoutPluginId];
39
42
  * const default = [MyPluginId];
40
43
  * const fallback = <div>Initializing Plugins...</div>;
41
- * const App = createApp({ plugins, core, default, fallback });
44
+ * const App = useApp({ plugins, core, default, fallback });
42
45
  * createRoot(document.getElementById('root')!).render(
43
46
  * <StrictMode>
44
47
  * <App />
@@ -64,7 +67,8 @@ export const useApp = ({
64
67
  fallback = DefaultFallback,
65
68
  cacheEnabled = false,
66
69
  safeMode = false,
67
- }: CreateAppOptions) => {
70
+ debounce = 0,
71
+ }: UseAppOptions) => {
68
72
  const plugins = useDefaultValue(_plugins, () => []);
69
73
  const core = useDefaultValue(_core, () => plugins.map(({ meta }) => meta.id));
70
74
  const defaults = useDefaultValue(_defaults, () => []);
@@ -134,16 +138,12 @@ export const useApp = ({
134
138
  setupDevtools(manager);
135
139
  }, [manager]);
136
140
 
137
- useEffect(() => {
138
- const timeout = setTimeout(async () => {
139
- await Promise.all([
140
- // TODO(wittjosiah): Factor out such that this could be called per surface role when attempting to render.
141
- manager.activate(Events.SetupReactSurface),
142
- manager.activate(Events.Startup),
143
- ]);
144
- });
145
-
146
- return () => clearTimeout(timeout);
141
+ useAsyncEffect(async () => {
142
+ await Promise.all([
143
+ // TODO(wittjosiah): Factor out such that this could be called per surface role when attempting to render.
144
+ manager.activate(Events.SetupReactSurface),
145
+ manager.activate(Events.Startup),
146
+ ]);
147
147
  }, [manager]);
148
148
 
149
149
  return useCallback(
@@ -151,7 +151,7 @@ export const useApp = ({
151
151
  <ErrorBoundary fallback={fallback}>
152
152
  <PluginManagerProvider value={manager}>
153
153
  <RegistryContext.Provider value={manager.registry}>
154
- <App placeholder={placeholder} state={state} />
154
+ <App placeholder={placeholder} state={state} debounce={debounce} />
155
155
  </RegistryContext.Provider>
156
156
  </PluginManagerProvider>
157
157
  </ErrorBoundary>
@@ -160,116 +160,6 @@ export const useApp = ({
160
160
  );
161
161
  };
162
162
 
163
- const DELAY_PLACEHOLDER = 2_000;
164
-
165
- enum LoadingState {
166
- Loading = 0,
167
- FadeIn = 1,
168
- FadeOut = 2,
169
- Done = 3,
170
- }
171
-
172
- /**
173
- * To avoid "flashing" the placeholder, we wait a period of time before starting the loading animation.
174
- * If loading completes during this time the placehoder is not shown, otherwise is it displayed for a minimum period of time.
175
- *
176
- * States:
177
- * 0: Loading - Wait for a period of time before starting the loading animation.
178
- * 1: Fade-in - Display a loading animation.
179
- * 2: Fade-out - Fade out the loading animation.
180
- * 3: Done - Remove the placeholder.
181
- */
182
- const useLoading = (state: AppProps['state']) => {
183
- const [stage, setStage] = useState<LoadingState>(LoadingState.Loading);
184
- useEffect(() => {
185
- const i = setInterval(() => {
186
- setStage((tick) => {
187
- switch (tick) {
188
- case LoadingState.Loading:
189
- if (!state.ready) {
190
- return LoadingState.FadeIn;
191
- } else {
192
- clearInterval(i);
193
- return LoadingState.Done;
194
- }
195
- case LoadingState.FadeIn:
196
- if (state.ready) {
197
- return LoadingState.FadeOut;
198
- }
199
- break;
200
- case LoadingState.FadeOut:
201
- clearInterval(i);
202
- return LoadingState.Done;
203
- }
204
-
205
- return tick;
206
- });
207
- }, DELAY_PLACEHOLDER);
208
-
209
- return () => clearInterval(i);
210
- }, []);
211
-
212
- return stage;
213
- };
214
-
215
- type AppProps = Pick<CreateAppOptions, 'placeholder'> & {
216
- state: { ready: boolean; error: unknown };
217
- };
218
-
219
- const App = ({ placeholder: Placeholder, state }: AppProps) => {
220
- const reactContexts = useCapabilities(Capabilities.ReactContext);
221
- const reactRoots = useCapabilities(Capabilities.ReactRoot);
222
- const stage = useLoading(state);
223
-
224
- if (state.error) {
225
- // This triggers the error boundary to provide UI feedback for the startup error.
226
- throw state.error;
227
- }
228
-
229
- // TODO(wittjosiah): Consider using Suspense instead?
230
- if (stage < LoadingState.Done) {
231
- if (!Placeholder) {
232
- return null;
233
- }
234
-
235
- return <Placeholder stage={stage} />;
236
- }
237
-
238
- const ComposedContext = composeContexts(reactContexts);
239
- return (
240
- <ComposedContext>
241
- {reactRoots.map(({ id, root: Component }) => (
242
- <Component key={id} />
243
- ))}
244
- </ComposedContext>
245
- );
246
- };
247
-
248
- // Default fallback does not use tailwind or theme.
249
- const DefaultFallback = ({ error }: { error: Error }) => {
250
- return (
251
- <div style={{ margin: '0.5rem', padding: '1rem', overflow: 'hidden', border: '1px solid red' }}>
252
- {/* TODO(wittjosiah): Link to docs for replacing default. */}
253
- <h1 style={{ margin: '0.5rem 0', fontSize: '1.2rem' }}>[ERROR]: {error.message}</h1>
254
- <pre style={{ overflow: 'auto', fontSize: '1rem', whiteSpace: 'pre-wrap', color: '#888888' }}>{error.stack}</pre>
255
- </div>
256
- );
257
- };
258
-
259
- const composeContexts = (contexts: Capabilities.ReactContext[]) => {
260
- if (contexts.length === 0) {
261
- return ({ children }: PropsWithChildren) => <>{children}</>;
262
- }
263
-
264
- return topologicalSort(contexts)
265
- .map(({ context }) => context)
266
- .reduce((Acc, Next) => ({ children }) => (
267
- <Acc>
268
- <Next>{children}</Next>
269
- </Acc>
270
- ));
271
- };
272
-
273
163
  const setupDevtools = (manager: PluginManager) => {
274
164
  (globalThis as any).composer ??= {};
275
165
  (globalThis as any).composer.manager = manager;