@dxos/app-framework 0.8.4-main.e098934 → 0.8.4-main.ead640a

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 (157) hide show
  1. package/.storybook/main.mts +11 -0
  2. package/.storybook/preview.mts +8 -0
  3. package/dist/lib/browser/{app-graph-builder-AFFC6VB2.mjs → app-graph-builder-LG4RG2LM.mjs} +30 -29
  4. package/dist/lib/browser/app-graph-builder-LG4RG2LM.mjs.map +7 -0
  5. package/dist/lib/browser/{chunk-OZY7HV2A.mjs → chunk-2GRQ4QXA.mjs} +96 -93
  6. package/dist/lib/browser/chunk-2GRQ4QXA.mjs.map +7 -0
  7. package/dist/lib/browser/{chunk-T6M7JB7M.mjs → chunk-FRUTKCPG.mjs} +16 -20
  8. package/dist/lib/browser/chunk-FRUTKCPG.mjs.map +7 -0
  9. package/dist/lib/browser/{chunk-ORWHM7CO.mjs → chunk-SCPE4ZO2.mjs} +11 -8
  10. package/dist/lib/browser/chunk-SCPE4ZO2.mjs.map +7 -0
  11. package/dist/lib/browser/index.mjs +14 -28
  12. package/dist/lib/browser/index.mjs.map +3 -3
  13. package/dist/lib/browser/{intent-dispatcher-QG7UPGQX.mjs → intent-dispatcher-6SHA5B3N.mjs} +2 -2
  14. package/dist/lib/browser/{intent-resolver-4S4PSTM5.mjs → intent-resolver-UZZ4OANZ.mjs} +7 -7
  15. package/dist/lib/browser/intent-resolver-UZZ4OANZ.mjs.map +7 -0
  16. package/dist/lib/browser/meta.json +1 -1
  17. package/dist/lib/browser/{store-6E33KLGK.mjs → store-ACBEYK4B.mjs} +4 -4
  18. package/dist/lib/browser/{store-6E33KLGK.mjs.map → store-ACBEYK4B.mjs.map} +1 -1
  19. package/dist/lib/browser/testing/index.mjs +11 -14
  20. package/dist/lib/browser/testing/index.mjs.map +3 -3
  21. package/dist/lib/browser/worker.mjs +1 -9
  22. package/dist/lib/node-esm/{app-graph-builder-S4OAULX5.mjs → app-graph-builder-FMHVHPWA.mjs} +30 -29
  23. package/dist/lib/node-esm/app-graph-builder-FMHVHPWA.mjs.map +7 -0
  24. package/dist/lib/node-esm/{chunk-HJFU7QOR.mjs → chunk-CXT6CYPE.mjs} +16 -20
  25. package/dist/lib/node-esm/chunk-CXT6CYPE.mjs.map +7 -0
  26. package/dist/lib/node-esm/{chunk-F63ZRXMK.mjs → chunk-KSPOOYT3.mjs} +96 -93
  27. package/dist/lib/node-esm/chunk-KSPOOYT3.mjs.map +7 -0
  28. package/dist/lib/node-esm/{chunk-UMZQERLE.mjs → chunk-ZX63QUGE.mjs} +11 -8
  29. package/dist/lib/node-esm/chunk-ZX63QUGE.mjs.map +7 -0
  30. package/dist/lib/node-esm/index.mjs +14 -28
  31. package/dist/lib/node-esm/index.mjs.map +3 -3
  32. package/dist/lib/node-esm/{intent-dispatcher-NXBGPJOX.mjs → intent-dispatcher-SIYQ5ZIU.mjs} +2 -2
  33. package/dist/lib/node-esm/{intent-resolver-2ZKXI5ET.mjs → intent-resolver-7FYJMXAG.mjs} +7 -7
  34. package/dist/lib/node-esm/intent-resolver-7FYJMXAG.mjs.map +7 -0
  35. package/dist/lib/node-esm/meta.json +1 -1
  36. package/dist/lib/node-esm/{store-QQUTQHHT.mjs → store-6OBLTVXC.mjs} +4 -4
  37. package/dist/lib/node-esm/{store-QQUTQHHT.mjs.map → store-6OBLTVXC.mjs.map} +1 -1
  38. package/dist/lib/node-esm/testing/index.mjs +11 -14
  39. package/dist/lib/node-esm/testing/index.mjs.map +3 -3
  40. package/dist/lib/node-esm/worker.mjs +1 -9
  41. package/dist/types/src/common/capabilities.d.ts +14 -4
  42. package/dist/types/src/common/capabilities.d.ts.map +1 -1
  43. package/dist/types/src/common/collaboration.d.ts +1 -1
  44. package/dist/types/src/common/collaboration.d.ts.map +1 -1
  45. package/dist/types/src/common/file.d.ts +1 -1
  46. package/dist/types/src/common/file.d.ts.map +1 -1
  47. package/dist/types/src/common/layout.d.ts +1 -3
  48. package/dist/types/src/common/layout.d.ts.map +1 -1
  49. package/dist/types/src/common/surface.d.ts +7 -13
  50. package/dist/types/src/common/surface.d.ts.map +1 -1
  51. package/dist/types/src/common/translations.d.ts +1 -1
  52. package/dist/types/src/common/translations.d.ts.map +1 -1
  53. package/dist/types/src/components/App.stories.d.ts +0 -1
  54. package/dist/types/src/components/App.stories.d.ts.map +1 -1
  55. package/dist/types/src/components/useApp.d.ts.map +1 -1
  56. package/dist/types/src/core/capabilities.d.ts +1 -1
  57. package/dist/types/src/core/capabilities.d.ts.map +1 -1
  58. package/dist/types/src/core/manager.d.ts.map +1 -1
  59. package/dist/types/src/core/plugin.d.ts +4 -1
  60. package/dist/types/src/core/plugin.d.ts.map +1 -1
  61. package/dist/types/src/playground/debug/plugin.d.ts +1 -1
  62. package/dist/types/src/playground/debug/plugin.d.ts.map +1 -1
  63. package/dist/types/src/playground/generator/generator.d.ts +1 -1
  64. package/dist/types/src/playground/generator/generator.d.ts.map +1 -1
  65. package/dist/types/src/playground/generator/plugin.d.ts +1 -1
  66. package/dist/types/src/playground/generator/plugin.d.ts.map +1 -1
  67. package/dist/types/src/playground/layout/plugin.d.ts +1 -1
  68. package/dist/types/src/playground/layout/plugin.d.ts.map +1 -1
  69. package/dist/types/src/playground/logger/plugin.d.ts +1 -1
  70. package/dist/types/src/playground/logger/plugin.d.ts.map +1 -1
  71. package/dist/types/src/playground/logger/schema.d.ts +1 -1
  72. package/dist/types/src/playground/logger/schema.d.ts.map +1 -1
  73. package/dist/types/src/playground/playground.stories.d.ts +0 -1
  74. package/dist/types/src/playground/playground.stories.d.ts.map +1 -1
  75. package/dist/types/src/plugin-intent/IntentPlugin.d.ts +1 -1
  76. package/dist/types/src/plugin-intent/IntentPlugin.d.ts.map +1 -1
  77. package/dist/types/src/plugin-intent/actions.d.ts +5 -7
  78. package/dist/types/src/plugin-intent/actions.d.ts.map +1 -1
  79. package/dist/types/src/plugin-intent/errors.d.ts.map +1 -1
  80. package/dist/types/src/plugin-intent/intent-dispatcher.d.ts +4 -4
  81. package/dist/types/src/plugin-intent/intent-dispatcher.d.ts.map +1 -1
  82. package/dist/types/src/plugin-intent/intent.d.ts +1 -1
  83. package/dist/types/src/plugin-intent/intent.d.ts.map +1 -1
  84. package/dist/types/src/plugin-intent/meta.d.ts +3 -0
  85. package/dist/types/src/plugin-intent/meta.d.ts.map +1 -0
  86. package/dist/types/src/plugin-settings/SettingsPlugin.d.ts +1 -1
  87. package/dist/types/src/plugin-settings/SettingsPlugin.d.ts.map +1 -1
  88. package/dist/types/src/plugin-settings/actions.d.ts +5 -7
  89. package/dist/types/src/plugin-settings/actions.d.ts.map +1 -1
  90. package/dist/types/src/plugin-settings/app-graph-builder.d.ts.map +1 -1
  91. package/dist/types/src/plugin-settings/meta.d.ts +3 -0
  92. package/dist/types/src/plugin-settings/meta.d.ts.map +1 -0
  93. package/dist/types/src/plugin-settings/translations.d.ts +2 -1
  94. package/dist/types/src/plugin-settings/translations.d.ts.map +1 -1
  95. package/dist/types/src/react/ErrorBoundary.d.ts +2 -2
  96. package/dist/types/src/react/ErrorBoundary.d.ts.map +1 -1
  97. package/dist/types/src/react/Surface.d.ts +2 -2
  98. package/dist/types/src/react/Surface.d.ts.map +1 -1
  99. package/dist/types/src/react/Surface.stories.d.ts +0 -1
  100. package/dist/types/src/react/Surface.stories.d.ts.map +1 -1
  101. package/dist/types/src/testing/withPluginManager.d.ts +2 -4
  102. package/dist/types/src/testing/withPluginManager.d.ts.map +1 -1
  103. package/dist/types/tsconfig.tsbuildinfo +1 -1
  104. package/moon.yml +4 -0
  105. package/package.json +31 -30
  106. package/src/common/capabilities.ts +22 -4
  107. package/src/common/collaboration.ts +1 -1
  108. package/src/common/file.ts +1 -1
  109. package/src/common/layout.ts +3 -4
  110. package/src/common/surface.ts +15 -18
  111. package/src/common/translations.ts +1 -1
  112. package/src/components/App.stories.tsx +1 -3
  113. package/src/components/useApp.tsx +9 -11
  114. package/src/core/capabilities.test.ts +1 -1
  115. package/src/core/capabilities.ts +1 -1
  116. package/src/core/manager.test.ts +19 -19
  117. package/src/core/manager.ts +12 -5
  118. package/src/core/plugin.ts +8 -2
  119. package/src/playground/debug/plugin.ts +7 -8
  120. package/src/playground/generator/generator.ts +2 -2
  121. package/src/playground/generator/plugin.ts +12 -13
  122. package/src/playground/layout/plugin.ts +9 -8
  123. package/src/playground/logger/plugin.ts +27 -23
  124. package/src/playground/logger/schema.ts +1 -1
  125. package/src/playground/playground.stories.tsx +5 -6
  126. package/src/plugin-intent/IntentPlugin.ts +12 -13
  127. package/src/plugin-intent/actions.ts +4 -6
  128. package/src/plugin-intent/errors.ts +2 -1
  129. package/src/plugin-intent/intent-dispatcher.test.ts +10 -3
  130. package/src/plugin-intent/intent-dispatcher.ts +8 -6
  131. package/src/plugin-intent/intent.ts +1 -1
  132. package/src/plugin-intent/meta.ts +10 -0
  133. package/src/plugin-settings/SettingsPlugin.ts +25 -27
  134. package/src/plugin-settings/actions.ts +9 -13
  135. package/src/plugin-settings/app-graph-builder.ts +17 -15
  136. package/src/plugin-settings/intent-resolver.ts +2 -2
  137. package/src/plugin-settings/meta.ts +10 -0
  138. package/src/plugin-settings/translations.ts +3 -3
  139. package/src/react/ErrorBoundary.tsx +10 -8
  140. package/src/react/Surface.stories.tsx +2 -5
  141. package/src/react/Surface.tsx +11 -3
  142. package/src/testing/withPluginManager.stories.tsx +1 -1
  143. package/src/testing/withPluginManager.tsx +13 -17
  144. package/tsconfig.json +1 -1
  145. package/vitest.config.ts +8 -6
  146. package/dist/lib/browser/app-graph-builder-AFFC6VB2.mjs.map +0 -7
  147. package/dist/lib/browser/chunk-ORWHM7CO.mjs.map +0 -7
  148. package/dist/lib/browser/chunk-OZY7HV2A.mjs.map +0 -7
  149. package/dist/lib/browser/chunk-T6M7JB7M.mjs.map +0 -7
  150. package/dist/lib/browser/intent-resolver-4S4PSTM5.mjs.map +0 -7
  151. package/dist/lib/node-esm/app-graph-builder-S4OAULX5.mjs.map +0 -7
  152. package/dist/lib/node-esm/chunk-F63ZRXMK.mjs.map +0 -7
  153. package/dist/lib/node-esm/chunk-HJFU7QOR.mjs.map +0 -7
  154. package/dist/lib/node-esm/chunk-UMZQERLE.mjs.map +0 -7
  155. package/dist/lib/node-esm/intent-resolver-2ZKXI5ET.mjs.map +0 -7
  156. /package/dist/lib/browser/{intent-dispatcher-QG7UPGQX.mjs.map → intent-dispatcher-6SHA5B3N.mjs.map} +0 -0
  157. /package/dist/lib/node-esm/{intent-dispatcher-NXBGPJOX.mjs.map → intent-dispatcher-SIYQ5ZIU.mjs.map} +0 -0
package/moon.yml CHANGED
@@ -5,6 +5,7 @@ tags:
5
5
  - ts-build
6
6
  - ts-test
7
7
  - typedoc
8
+ - storybook
8
9
  tasks:
9
10
  compile:
10
11
  args:
@@ -12,3 +13,6 @@ tasks:
12
13
  - '--entryPoint=src/testing/index.ts'
13
14
  - '--entryPoint=src/worker.ts'
14
15
  - '--preactSignalTracking'
16
+ test:
17
+ inputs:
18
+ - .storybook/*
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/app-framework",
3
- "version": "0.8.4-main.e098934",
3
+ "version": "0.8.4-main.ead640a",
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",
@@ -40,44 +40,45 @@
40
40
  }
41
41
  },
42
42
  "dependencies": {
43
- "@effect/ai": "0.25.2",
43
+ "@effect/ai": "0.29.1",
44
+ "@effect/experimental": "0.56.0",
44
45
  "@preact-signals/safe-react": "^0.9.0",
45
- "@preact/signals-core": "^1.9.0",
46
- "@dxos/ai": "0.8.4-main.e098934",
47
- "@dxos/async": "0.8.4-main.e098934",
48
- "@dxos/app-graph": "0.8.4-main.e098934",
49
- "@dxos/blueprints": "0.8.4-main.e098934",
50
- "@dxos/client-protocol": "0.8.4-main.e098934",
51
- "@dxos/debug": "0.8.4-main.e098934",
52
- "@dxos/echo-schema": "0.8.4-main.e098934",
53
- "@dxos/functions": "0.8.4-main.e098934",
54
- "@dxos/invariant": "0.8.4-main.e098934",
55
- "@dxos/keys": "0.8.4-main.e098934",
56
- "@dxos/live-object": "0.8.4-main.e098934",
57
- "@dxos/log": "0.8.4-main.e098934",
58
- "@dxos/local-storage": "0.8.4-main.e098934",
59
- "@dxos/react-hooks": "0.8.4-main.e098934",
60
- "@dxos/util": "0.8.4-main.e098934",
61
- "@dxos/schema": "0.8.4-main.e098934"
46
+ "@preact/signals-core": "^1.12.1",
47
+ "@dxos/ai": "0.8.4-main.ead640a",
48
+ "@dxos/app-graph": "0.8.4-main.ead640a",
49
+ "@dxos/blueprints": "0.8.4-main.ead640a",
50
+ "@dxos/client-protocol": "0.8.4-main.ead640a",
51
+ "@dxos/async": "0.8.4-main.ead640a",
52
+ "@dxos/debug": "0.8.4-main.ead640a",
53
+ "@dxos/echo": "0.8.4-main.ead640a",
54
+ "@dxos/invariant": "0.8.4-main.ead640a",
55
+ "@dxos/functions": "0.8.4-main.ead640a",
56
+ "@dxos/keys": "0.8.4-main.ead640a",
57
+ "@dxos/live-object": "0.8.4-main.ead640a",
58
+ "@dxos/local-storage": "0.8.4-main.ead640a",
59
+ "@dxos/log": "0.8.4-main.ead640a",
60
+ "@dxos/react-hooks": "0.8.4-main.ead640a",
61
+ "@dxos/schema": "0.8.4-main.ead640a",
62
+ "@dxos/util": "0.8.4-main.ead640a"
62
63
  },
63
64
  "devDependencies": {
64
- "@effect-rx/rx-react": "0.38.0",
65
- "@effect/platform": "0.90.2",
66
- "@types/react": "~18.2.0",
67
- "effect": "3.17.7",
68
- "react": "~18.2.0",
65
+ "@effect-rx/rx-react": "0.42.4",
66
+ "@effect/platform": "0.92.1",
67
+ "@types/react": "~19.2.2",
68
+ "effect": "3.18.3",
69
+ "react": "~19.2.0",
69
70
  "typedoc": "0.28.1",
70
- "@dxos/echo-signals": "0.8.4-main.e098934",
71
- "@dxos/random": "0.8.4-main.e098934",
72
- "@dxos/react-ui": "0.8.4-main.e098934",
73
- "@dxos/react-ui-syntax-highlighter": "0.8.4-main.e098934",
74
- "@dxos/storybook-utils": "0.8.4-main.e098934"
71
+ "@dxos/react-ui": "0.8.4-main.ead640a",
72
+ "@dxos/echo-signals": "0.8.4-main.ead640a",
73
+ "@dxos/random": "0.8.4-main.ead640a",
74
+ "@dxos/react-ui-syntax-highlighter": "0.8.4-main.ead640a",
75
+ "@dxos/storybook-utils": "0.8.4-main.ead640a"
75
76
  },
76
77
  "peerDependencies": {
77
78
  "@effect-rx/rx-react": "^0.34.1",
78
79
  "@effect/platform": "^0.80.12",
79
80
  "effect": "^3.13.3",
80
- "react": "~18.2.0"
81
+ "react": "^19.0.0"
81
82
  },
82
83
  "publishConfig": {
83
84
  "access": "public"
@@ -2,11 +2,15 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { type AiTool, type AiToolkit } from '@effect/ai';
5
+ import type * as Tool from '@effect/ai/Tool';
6
+ import type * as Toolkit from '@effect/ai/Toolkit';
6
7
  import { type Registry } from '@effect-rx/rx-react';
7
- import { type Layer, type Schema } from 'effect';
8
+ import type * as Layer from 'effect/Layer';
9
+ import type * as Schema from 'effect/Schema';
8
10
  import { type FC, type PropsWithChildren } from 'react';
9
11
 
12
+ import { type AiService } from '@dxos/ai';
13
+ import type * as AiServiceRouter from '@dxos/ai/AiServiceRouter';
10
14
  import { type BuilderExtensions, type GraphBuilder } from '@dxos/app-graph';
11
15
  import { type Blueprint } from '@dxos/blueprints';
12
16
  import { type Space } from '@dxos/client-protocol';
@@ -154,15 +158,17 @@ export namespace Capabilities {
154
158
  */
155
159
  export const Metadata = defineCapability<Metadata>('dxos.org/app-framework/capability/metadata');
156
160
 
161
+ // TODO(dmaretskyi): Consider combining Toolkit and ToolkitHandler for type-safe context.
162
+
157
163
  /**
158
164
  * @category Capability
159
165
  */
160
- export const Toolkit = defineCapability<AiToolkit.Any>('dxos.org/app-framework/capability/ai-toolkit');
166
+ export const Toolkit = defineCapability<Toolkit.Any>('dxos.org/app-framework/capability/ai-toolkit');
161
167
 
162
168
  /**
163
169
  * @category Capability
164
170
  */
165
- export const ToolkitHandler = defineCapability<Layer.Layer<AiTool.ToHandler<AiTool.AiTool<any>>, never, never>>(
171
+ export const ToolkitHandler = defineCapability<Layer.Layer<Tool.Handler<any>, never, never>>(
166
172
  'dxos.org/app-framework/capability/ai-toolkit-handler',
167
173
  );
168
174
 
@@ -173,6 +179,18 @@ export namespace Capabilities {
173
179
  'dxos.org/app-framework/capability/blueprint-definition',
174
180
  );
175
181
 
182
+ export type AiServiceLayer = Layer.Layer<AiService.AiService>;
183
+ export const AiServiceLayer = defineCapability<AiServiceLayer>(
184
+ 'dxos.org/app-framework/capability/ai-service-factory',
185
+ );
186
+
187
+ /**
188
+ * Plugins can contribute them to provide model resolvers.
189
+ */
190
+ export const AiModelResolver = defineCapability<Layer.Layer<AiServiceRouter.AiModelResolver>>(
191
+ 'dxos.org/app-framework/capability/ai-model-resolver',
192
+ );
193
+
176
194
  /**
177
195
  * @category Capability
178
196
  */
@@ -2,7 +2,7 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { Schema } from 'effect';
5
+ import * as Schema from 'effect/Schema';
6
6
 
7
7
  import { DataType } from '@dxos/schema';
8
8
 
@@ -2,7 +2,7 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import { Schema } from 'effect';
5
+ import * as Schema from 'effect/Schema';
6
6
 
7
7
  // TODO(burdon): See Accept attribute (uses MIME types).
8
8
  // E.g., 'image/*': ['.jpg', '.jpeg', '.png', '.gif'],
@@ -2,18 +2,17 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { Schema } from 'effect';
5
+ import * as Schema from 'effect/Schema';
6
6
 
7
7
  import { Label } from '../plugin-intent';
8
8
 
9
- export const LAYOUT_PLUGIN = 'dxos.org/plugin/layout';
10
- export const LAYOUT_ACTION = `${LAYOUT_PLUGIN}/action`;
9
+ const LAYOUT_PLUGIN = 'dxos.org/plugin/layout';
11
10
 
12
11
  /**
13
12
  * Expected payload for layout actions.
14
13
  */
15
14
  export namespace LayoutAction {
16
- export const UPDATE_LAYOUT = `${LAYOUT_ACTION}/update-layout`;
15
+ export const UPDATE_LAYOUT = `${LAYOUT_PLUGIN}/action/update-layout`;
17
16
 
18
17
  /**
19
18
  * Generic layout action.
@@ -2,7 +2,7 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { type ForwardedRef, type JSX, type PropsWithChildren, type ReactNode } from 'react';
5
+ import type { ComponentType, PropsWithChildren, ReactNode } from 'react';
6
6
 
7
7
  import { type GuardedType, type MakeOptional, type Position } from '@dxos/util';
8
8
 
@@ -11,7 +11,7 @@ import { type ErrorBoundary } from '../react';
11
11
  /**
12
12
  * SurfaceProps are the props that are passed to the Surface component.
13
13
  */
14
- export type SurfaceProps<T extends Record<string, any> = Record<string, unknown>> = PropsWithChildren<{
14
+ export type SurfaceProps<T extends Record<string, any> = Record<string, unknown>> = {
15
15
  /**
16
16
  * If specified, the Surface will be wrapped in an error boundary.
17
17
  * The fallback component will be rendered if an error occurs.
@@ -23,17 +23,16 @@ export type SurfaceProps<T extends Record<string, any> = Record<string, unknown>
23
23
  * The placeholder component will be rendered while the surface component is loading.
24
24
  */
25
25
  placeholder?: ReactNode;
26
- }> &
27
- MakeOptional<CoreSurfaceProps<T>, 'id' | 'data'> & {
28
- /**
29
- * Additional props to pass to the component.
30
- * These props are not used by Surface itself but may be used by components which resolve the surface.
31
- */
32
- [key: string]: unknown;
26
+ } & MakeOptional<CoreSurfaceProps<T>, 'id' | 'data'> &
27
+ // Additional props to pass to the component.
28
+ // These props are not used by Surface itself but may be used by components which resolve the surface.
29
+ // Exclude known prop names to prevent overriding well-defined props.
30
+ {
31
+ [K in keyof Record<string, any>]: K extends keyof CoreSurfaceProps<T> | 'fallback' | 'placeholder' ? never : any;
33
32
  };
34
33
 
35
34
  // NOTE: If `[key: string]: unknown` is included in shared types, when re-used other fields become unknown as well.
36
- type CoreSurfaceProps<T extends Record<string, any> = Record<string, unknown>> = {
35
+ type CoreSurfaceProps<T extends Record<string, any> = Record<string, unknown>> = PropsWithChildren<{
37
36
  /**
38
37
  * ID for debugging.
39
38
  */
@@ -53,19 +52,17 @@ type CoreSurfaceProps<T extends Record<string, any> = Record<string, unknown>> =
53
52
  * If more than one component is resolved, the limit determines how many are rendered.
54
53
  */
55
54
  limit?: number | undefined;
56
- };
55
+ }>;
57
56
 
58
- type SurfaceComponentProps<T extends Record<string, any> = Record<string, unknown>> = PropsWithChildren<
59
- CoreSurfaceProps<T> & { [key: string]: unknown }
60
- >;
57
+ type SurfaceComponentProps<T extends Record<string, any> = Record<string, unknown>> = CoreSurfaceProps<T> &
58
+ Record<string, any>;
61
59
 
62
60
  /**
63
61
  * React component used to render a surface once is has matched.
64
62
  */
65
- export type SurfaceComponent<T extends Record<string, any> = Record<string, unknown>> = (
66
- props: SurfaceComponentProps<T>,
67
- forwardedRef: ForwardedRef<HTMLElement>,
68
- ) => JSX.Element | null;
63
+ export type SurfaceComponent<T extends Record<string, any> = Record<string, unknown>> = ComponentType<
64
+ SurfaceComponentProps<T>
65
+ >;
69
66
 
70
67
  /**
71
68
  * Definition of when a SurfaceComponent should be rendered.
@@ -2,7 +2,7 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { Schema } from 'effect';
5
+ import * as Schema from 'effect/Schema';
6
6
 
7
7
  export const ResourceKey = Schema.Union(Schema.String, Schema.Record({ key: Schema.String, value: Schema.Any }));
8
8
  export type ResourceKey = Schema.Schema.Type<typeof ResourceKey>;
@@ -2,12 +2,10 @@
2
2
  // Copyright 2022 DXOS.org
3
3
  //
4
4
 
5
- import '@dxos-theme';
6
-
7
5
  import { type Meta, type StoryObj } from '@storybook/react-vite';
8
6
  import React from 'react';
9
7
 
10
- import { withTheme } from '@dxos/storybook-utils';
8
+ import { withTheme } from '@dxos/react-ui/testing';
11
9
 
12
10
  import { useApp } from './useApp';
13
11
 
@@ -116,6 +116,10 @@ export const useApp = ({
116
116
  }, [cacheEnabled, manager]);
117
117
 
118
118
  useEffect(() => {
119
+ setupDevtools(manager);
120
+ }, [manager]);
121
+
122
+ useAsyncEffect(async () => {
119
123
  manager.context.contributeCapability({
120
124
  interface: Capabilities.PluginManager,
121
125
  implementation: manager,
@@ -128,22 +132,16 @@ export const useApp = ({
128
132
  module: 'dxos.org/app-framework/rx-registry',
129
133
  });
130
134
 
131
- return () => {
132
- manager.context.removeCapability(Capabilities.PluginManager, manager);
133
- manager.context.removeCapability(Capabilities.RxRegistry, manager.registry);
134
- };
135
- }, [manager]);
136
-
137
- useEffect(() => {
138
- setupDevtools(manager);
139
- }, [manager]);
140
-
141
- useAsyncEffect(async () => {
142
135
  await Promise.all([
143
136
  // TODO(wittjosiah): Factor out such that this could be called per surface role when attempting to render.
144
137
  manager.activate(Events.SetupReactSurface),
145
138
  manager.activate(Events.Startup),
146
139
  ]);
140
+
141
+ return () => {
142
+ manager.context.removeCapability(Capabilities.PluginManager, manager);
143
+ manager.context.removeCapability(Capabilities.RxRegistry, manager.registry);
144
+ };
147
145
  }, [manager]);
148
146
 
149
147
  return useCallback(
@@ -3,7 +3,7 @@
3
3
  //
4
4
 
5
5
  import { Registry } from '@effect-rx/rx-react';
6
- import { Effect } from 'effect';
6
+ import * as Effect from 'effect/Effect';
7
7
  import { describe, expect, it, onTestFinished } from 'vitest';
8
8
 
9
9
  import { PluginContext, defineCapability } from './capabilities';
@@ -3,7 +3,7 @@
3
3
  //
4
4
 
5
5
  import { type Registry, Rx } from '@effect-rx/rx-react';
6
- import { Effect } from 'effect';
6
+ import * as Effect from 'effect/Effect';
7
7
 
8
8
  import { Trigger } from '@dxos/async';
9
9
  import { invariant } from '@dxos/invariant';
@@ -7,7 +7,7 @@ import { afterEach, describe, expect, it } from 'vitest';
7
7
 
8
8
  import { Trigger } from '@dxos/async';
9
9
  import { raise } from '@dxos/debug';
10
- import { updateCounter } from '@dxos/echo-schema/testing';
10
+ import { updateCounter } from '@dxos/echo/testing';
11
11
  import { registerSignalsRuntime } from '@dxos/echo-signals';
12
12
  import { invariant } from '@dxos/invariant';
13
13
  import { live } from '@dxos/live-object';
@@ -17,7 +17,7 @@ import { Events } from '../common';
17
17
  import { type PluginContext, contributes, defineCapability } from './capabilities';
18
18
  import { allOf, defineEvent, oneOf } from './events';
19
19
  import { PluginManager } from './manager';
20
- import { type Plugin, defineModule, definePlugin } from './plugin';
20
+ import { Plugin, defineModule } from './plugin';
21
21
 
22
22
  registerSignalsRuntime();
23
23
 
@@ -43,7 +43,7 @@ describe('PluginManager', () => {
43
43
  });
44
44
 
45
45
  it('should be able to add and remove plugins', async () => {
46
- const Test = definePlugin(testMeta, []);
46
+ const Test = new Plugin(testMeta, []);
47
47
  plugins = [Test];
48
48
 
49
49
  const manager = new PluginManager({ pluginLoader });
@@ -59,7 +59,7 @@ describe('PluginManager', () => {
59
59
  activatesOn: Events.Startup,
60
60
  activate: () => contributes(String, { string: 'hello' }),
61
61
  });
62
- const Test = definePlugin(testMeta, [Hello]);
62
+ const Test = new Plugin(testMeta, [Hello]);
63
63
 
64
64
  const manager = new PluginManager({ plugins: [Test], core: [], pluginLoader });
65
65
  await manager.enable(testMeta.id);
@@ -76,7 +76,7 @@ describe('PluginManager', () => {
76
76
  activatesOn: Events.Startup,
77
77
  activate: () => contributes(String, { string: 'hello' }),
78
78
  });
79
- const Test = definePlugin(testMeta, [Hello]);
79
+ const Test = new Plugin(testMeta, [Hello]);
80
80
 
81
81
  const manager = new PluginManager({ plugins: [Test], enabled: [Test.meta.id], pluginLoader });
82
82
  expect(manager.plugins).toEqual([Test]);
@@ -95,7 +95,7 @@ describe('PluginManager', () => {
95
95
  activatesOn: FailEvent,
96
96
  activate: async () => raise(new Error('test')),
97
97
  });
98
- plugins = [definePlugin(testMeta, [Fail])];
98
+ plugins = [new Plugin(testMeta, [Fail])];
99
99
 
100
100
  const manager = new PluginManager({ pluginLoader });
101
101
  await manager.add(testMeta.id);
@@ -114,7 +114,7 @@ describe('PluginManager', () => {
114
114
  // TODO(wittjosiah): Test and catch more failure modes.
115
115
  activate: async () => async () => raise(new Error('test')),
116
116
  });
117
- plugins = [definePlugin(testMeta, [Hello, Fail])];
117
+ plugins = [new Plugin(testMeta, [Hello, Fail])];
118
118
 
119
119
  const manager = new PluginManager({ pluginLoader });
120
120
  const activating = new Trigger<boolean>();
@@ -149,7 +149,7 @@ describe('PluginManager', () => {
149
149
  return contributes(String, { string: 'hello' });
150
150
  },
151
151
  });
152
- plugins = [definePlugin(testMeta, [Hello])];
152
+ plugins = [new Plugin(testMeta, [Hello])];
153
153
 
154
154
  const manager = new PluginManager({ pluginLoader });
155
155
 
@@ -180,21 +180,21 @@ describe('PluginManager', () => {
180
180
  });
181
181
 
182
182
  it('should be able to fire custom activation events', async () => {
183
- const Plugin1 = definePlugin({ id: 'dxos.org/test/plugin-1', name: 'Plugin 1' }, [
183
+ const Plugin1 = new Plugin({ id: 'dxos.org/test/plugin-1', name: 'Plugin 1' }, [
184
184
  defineModule({
185
185
  id: 'dxos.org/test/plugin-1',
186
186
  activatesOn: CountEvent,
187
187
  activate: () => [contributes(Number, { number: 1 })],
188
188
  }),
189
189
  ]);
190
- const Plugin2 = definePlugin({ id: 'dxos.org/test/plugin-2', name: 'Plugin 2' }, [
190
+ const Plugin2 = new Plugin({ id: 'dxos.org/test/plugin-2', name: 'Plugin 2' }, [
191
191
  defineModule({
192
192
  id: 'dxos.org/test/plugin-2',
193
193
  activatesOn: CountEvent,
194
194
  activate: () => [contributes(Number, { number: 2 })],
195
195
  }),
196
196
  ]);
197
- const Plugin3 = definePlugin({ id: 'dxos.org/test/plugin-3', name: 'Plugin 3' }, [
197
+ const Plugin3 = new Plugin({ id: 'dxos.org/test/plugin-3', name: 'Plugin 3' }, [
198
198
  defineModule({
199
199
  id: 'dxos.org/test/plugin-3',
200
200
  activatesOn: CountEvent,
@@ -231,7 +231,7 @@ describe('PluginManager', () => {
231
231
  return contributes(String, { string: 'hello' });
232
232
  },
233
233
  });
234
- plugins = [definePlugin(testMeta, [Hello])];
234
+ plugins = [new Plugin(testMeta, [Hello])];
235
235
 
236
236
  const manager = new PluginManager({ pluginLoader });
237
237
  expect(manager.active).toEqual([]);
@@ -257,7 +257,7 @@ describe('PluginManager', () => {
257
257
  return contributes(String, { string: 'hello' });
258
258
  },
259
259
  });
260
- plugins = [definePlugin(testMeta, [Hello])];
260
+ plugins = [new Plugin(testMeta, [Hello])];
261
261
 
262
262
  const manager = new PluginManager({ pluginLoader });
263
263
  expect(manager.active).toEqual([]);
@@ -283,7 +283,7 @@ describe('PluginManager', () => {
283
283
  state.total = numbers.reduce((acc, n) => acc + n.number, 0);
284
284
  };
285
285
 
286
- const Count = definePlugin({ id: 'dxos.org/test/count', name: 'Count' }, [
286
+ const Count = new Plugin({ id: 'dxos.org/test/count', name: 'Count' }, [
287
287
  defineModule({
288
288
  id: 'dxos.org/test/count',
289
289
  activatesOn: Events.Startup,
@@ -295,7 +295,7 @@ describe('PluginManager', () => {
295
295
  }),
296
296
  ]);
297
297
 
298
- const Test = definePlugin(testMeta, [
298
+ const Test = new Plugin(testMeta, [
299
299
  defineModule({
300
300
  id: 'dxos.org/test/plugin-1',
301
301
  activatesOn: CountEvent,
@@ -353,7 +353,7 @@ describe('PluginManager', () => {
353
353
  const id = 'dxos.org/test/counter';
354
354
  const stateEvent = Events.createStateEvent(id);
355
355
 
356
- const Test = definePlugin(testMeta, [
356
+ const Test = new Plugin(testMeta, [
357
357
  defineModule({
358
358
  id,
359
359
  activatesOn: Events.Startup,
@@ -390,21 +390,21 @@ describe('PluginManager', () => {
390
390
  });
391
391
 
392
392
  it('should be reactive', async () => {
393
- const Plugin1 = definePlugin({ id: 'dxos.org/test/plugin-1', name: 'Plugin 1' }, [
393
+ const Plugin1 = new Plugin({ id: 'dxos.org/test/plugin-1', name: 'Plugin 1' }, [
394
394
  defineModule({
395
395
  id: 'dxos.org/test/plugin-1',
396
396
  activatesOn: CountEvent,
397
397
  activate: () => [contributes(Number, { number: 1 })],
398
398
  }),
399
399
  ]);
400
- const Plugin2 = definePlugin({ id: 'dxos.org/test/plugin-2', name: 'Plugin 2' }, [
400
+ const Plugin2 = new Plugin({ id: 'dxos.org/test/plugin-2', name: 'Plugin 2' }, [
401
401
  defineModule({
402
402
  id: 'dxos.org/test/plugin-2',
403
403
  activatesOn: CountEvent,
404
404
  activate: () => [contributes(Number, { number: 2 })],
405
405
  }),
406
406
  ]);
407
- const Plugin3 = definePlugin({ id: 'dxos.org/test/plugin-3', name: 'Plugin 3' }, [
407
+ const Plugin3 = new Plugin({ id: 'dxos.org/test/plugin-3', name: 'Plugin 3' }, [
408
408
  defineModule({
409
409
  id: 'dxos.org/test/plugin-3',
410
410
  activatesOn: CountEvent,
@@ -4,7 +4,14 @@
4
4
 
5
5
  import { Registry } from '@effect-rx/rx-react';
6
6
  import { untracked } from '@preact/signals-core';
7
- import { Array, Duration, Effect, Fiber, HashSet, Match, Ref, pipe } from 'effect';
7
+ import * as Array from 'effect/Array';
8
+ import * as Duration from 'effect/Duration';
9
+ import * as Effect from 'effect/Effect';
10
+ import * as Fiber from 'effect/Fiber';
11
+ import * as Function from 'effect/Function';
12
+ import * as HashSet from 'effect/HashSet';
13
+ import * as Match from 'effect/Match';
14
+ import * as Ref from 'effect/Ref';
8
15
 
9
16
  import { Event } from '@dxos/async';
10
17
  import { type Live, live } from '@dxos/live-object';
@@ -396,7 +403,7 @@ export class PluginManager {
396
403
  this.activation.emit({ event: key, state: 'activating' });
397
404
 
398
405
  // Fire activatesBefore events.
399
- yield* pipe(
406
+ yield* Function.pipe(
400
407
  modules,
401
408
  Array.flatMap((module) => module.activatesBefore ?? []),
402
409
  HashSet.fromIterable,
@@ -407,7 +414,7 @@ export class PluginManager {
407
414
  );
408
415
 
409
416
  // Concurrently triggers loading of lazy capabilities.
410
- const getCapabilities = yield* pipe(
417
+ const getCapabilities = yield* Function.pipe(
411
418
  modules,
412
419
  Array.map((mod) => this._loadModule(mod)),
413
420
  Effect.allWith({ concurrency: 'unbounded' }),
@@ -418,7 +425,7 @@ export class PluginManager {
418
425
  );
419
426
 
420
427
  // Contribute the capabilities from the activated modules.
421
- yield* pipe(
428
+ yield* Function.pipe(
422
429
  modules,
423
430
  Array.zip(getCapabilities),
424
431
  Array.map(([module, capabilities]) => this._contributeCapabilities(module, capabilities)),
@@ -428,7 +435,7 @@ export class PluginManager {
428
435
  );
429
436
 
430
437
  // Fire activatesAfter events.
431
- yield* pipe(
438
+ yield* Function.pipe(
432
439
  modules,
433
440
  Array.flatMap((module) => module.activatesAfter ?? []),
434
441
  HashSet.fromIterable,
@@ -124,9 +124,15 @@ export class Plugin {
124
124
  ) {}
125
125
  }
126
126
 
127
+ export type PluginFactory<T = void> = ((args: T) => Plugin) & { meta: PluginMeta };
128
+
127
129
  /**
128
130
  * Helper to define a plugin.
129
131
  */
130
- export const definePlugin = (meta: PluginMeta, modules: PluginModule[]) => {
131
- return new Plugin(meta, modules);
132
+ export const definePlugin = <T = void>(meta: PluginMeta, provider: (args: T) => PluginModule[]): PluginFactory<T> => {
133
+ const factory = (args: T) => {
134
+ return new Plugin(meta, provider(args));
135
+ };
136
+
137
+ return Object.assign(factory, { meta });
132
138
  };
@@ -7,11 +7,10 @@ import { defineModule, definePlugin, lazy } from '../../core';
7
7
 
8
8
  const Debug = lazy(() => import('./Debug'));
9
9
 
10
- export const DebugPlugin = () =>
11
- definePlugin({ id: 'dxos.org/test/plugin-debug', name: 'Debug' }, [
12
- defineModule({
13
- id: 'dxos.org/test/debug/main',
14
- activatesOn: Events.Startup,
15
- activate: Debug,
16
- }),
17
- ]);
10
+ export const DebugPlugin = definePlugin({ id: 'dxos.org/test/plugin-debug', name: 'Debug' }, () => [
11
+ defineModule({
12
+ id: 'dxos.org/test/debug/main',
13
+ activatesOn: Events.Startup,
14
+ activate: Debug,
15
+ }),
16
+ ]);
@@ -2,7 +2,7 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { Schema } from 'effect';
5
+ import * as Schema from 'effect/Schema';
6
6
 
7
7
  import { Capabilities, Events } from '../../common';
8
8
  import { contributes, defineCapability, defineEvent, defineModule, definePlugin } from '../../core';
@@ -26,7 +26,7 @@ export const createGeneratorIntent = (id: string) => {
26
26
  export const createNumberPlugin = (id: string) => {
27
27
  const number = Math.floor(Math.random() * 100);
28
28
 
29
- return definePlugin({ id, name: `Plugin ${id}` }, [
29
+ return definePlugin({ id, name: `Plugin ${id}` }, () => [
30
30
  defineModule({
31
31
  id: `${id}/main`,
32
32
  activatesOn: CountEvent,
@@ -8,16 +8,15 @@ import { defineModule, definePlugin, lazy } from '../../core';
8
8
  const Main = lazy(() => import('./Main'));
9
9
  const Toolbar = lazy(() => import('./Toolbar'));
10
10
 
11
- export const GeneratorPlugin = () =>
12
- definePlugin({ id: 'dxos.org/test/generator', name: 'Generator' }, [
13
- defineModule({
14
- id: 'dxos.org/test/generator/main',
15
- activatesOn: Events.Startup,
16
- activate: Main,
17
- }),
18
- defineModule({
19
- id: 'dxos.org/test/generator/toolbar',
20
- activatesOn: Events.Startup,
21
- activate: Toolbar,
22
- }),
23
- ]);
11
+ export const GeneratorPlugin = definePlugin({ id: 'dxos.org/test/generator', name: 'Generator' }, () => [
12
+ defineModule({
13
+ id: 'dxos.org/test/generator/main',
14
+ activatesOn: Events.Startup,
15
+ activate: Main,
16
+ }),
17
+ defineModule({
18
+ id: 'dxos.org/test/generator/toolbar',
19
+ activatesOn: Events.Startup,
20
+ activate: Toolbar,
21
+ }),
22
+ ]);