@dxos/react-ui-canvas-compute 0.13.0 → 0.14.0

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 (244) hide show
  1. package/dist/lib/chunk-types.mjs +142 -0
  2. package/dist/lib/chunk-types.mjs.map +1 -0
  3. package/dist/lib/index.mjs +526 -430
  4. package/dist/lib/index.mjs.map +1 -1
  5. package/dist/lib/types.mjs +2 -0
  6. package/dist/types/src/graph/controller.d.ts +1 -1
  7. package/dist/types/src/graph/controller.d.ts.map +1 -1
  8. package/dist/types/src/hooks/compute-context.d.ts +5 -4
  9. package/dist/types/src/hooks/compute-context.d.ts.map +1 -1
  10. package/dist/types/src/hooks/index.d.ts +0 -1
  11. package/dist/types/src/hooks/index.d.ts.map +1 -1
  12. package/dist/types/src/hooks/useGraphMonitor.d.ts +18 -1
  13. package/dist/types/src/hooks/useGraphMonitor.d.ts.map +1 -1
  14. package/dist/types/src/index.d.ts +1 -1
  15. package/dist/types/src/index.d.ts.map +1 -1
  16. package/dist/types/src/registry.d.ts +5 -8
  17. package/dist/types/src/registry.d.ts.map +1 -1
  18. package/dist/types/src/scene/compute.stories.d.ts.map +1 -1
  19. package/dist/types/src/scene/echo-store.d.ts +1 -1
  20. package/dist/types/src/scene/echo-store.d.ts.map +1 -1
  21. package/dist/types/src/scene/index.d.ts +0 -3
  22. package/dist/types/src/scene/index.d.ts.map +1 -1
  23. package/dist/types/src/scene/projection.d.ts.map +1 -1
  24. package/dist/types/src/scene/scene.d.ts +2 -2
  25. package/dist/types/src/scene/scene.d.ts.map +1 -1
  26. package/dist/types/src/shapes/Append.d.ts +2 -2
  27. package/dist/types/src/shapes/Append.d.ts.map +1 -1
  28. package/dist/types/src/shapes/Array.d.ts +3 -3
  29. package/dist/types/src/shapes/Array.d.ts.map +1 -1
  30. package/dist/types/src/shapes/Audio.d.ts +2 -2
  31. package/dist/types/src/shapes/Audio.d.ts.map +1 -1
  32. package/dist/types/src/shapes/Beacon.d.ts +2 -2
  33. package/dist/types/src/shapes/Beacon.d.ts.map +1 -1
  34. package/dist/types/src/shapes/Boolean.d.ts +4 -52
  35. package/dist/types/src/shapes/Boolean.d.ts.map +1 -1
  36. package/dist/types/src/shapes/Chat.d.ts +3 -3
  37. package/dist/types/src/shapes/Chat.d.ts.map +1 -1
  38. package/dist/types/src/shapes/Constant.d.ts +3 -4
  39. package/dist/types/src/shapes/Constant.d.ts.map +1 -1
  40. package/dist/types/src/shapes/Database.d.ts +2 -2
  41. package/dist/types/src/shapes/Database.d.ts.map +1 -1
  42. package/dist/types/src/shapes/Feed.d.ts +2 -2
  43. package/dist/types/src/shapes/Feed.d.ts.map +1 -1
  44. package/dist/types/src/shapes/Function.d.ts +3 -5
  45. package/dist/types/src/shapes/Function.d.ts.map +1 -1
  46. package/dist/types/src/shapes/Gpt.d.ts +2 -2
  47. package/dist/types/src/shapes/Gpt.d.ts.map +1 -1
  48. package/dist/types/src/shapes/GptRealtime.d.ts +2 -2
  49. package/dist/types/src/shapes/GptRealtime.d.ts.map +1 -1
  50. package/dist/types/src/shapes/Json.d.ts +5 -5
  51. package/dist/types/src/shapes/Json.d.ts.map +1 -1
  52. package/dist/types/src/shapes/Logic.d.ts +5 -5
  53. package/dist/types/src/shapes/Logic.d.ts.map +1 -1
  54. package/dist/types/src/shapes/RNG.d.ts +2 -2
  55. package/dist/types/src/shapes/RNG.d.ts.map +1 -1
  56. package/dist/types/src/shapes/Scope.d.ts +2 -2
  57. package/dist/types/src/shapes/Scope.d.ts.map +1 -1
  58. package/dist/types/src/shapes/Surface.d.ts +2 -2
  59. package/dist/types/src/shapes/Surface.d.ts.map +1 -1
  60. package/dist/types/src/shapes/Switch.d.ts +2 -2
  61. package/dist/types/src/shapes/Switch.d.ts.map +1 -1
  62. package/dist/types/src/shapes/Table.d.ts +2 -2
  63. package/dist/types/src/shapes/Table.d.ts.map +1 -1
  64. package/dist/types/src/shapes/Template.d.ts +2 -2
  65. package/dist/types/src/shapes/Template.d.ts.map +1 -1
  66. package/dist/types/src/shapes/Text.d.ts +2 -2
  67. package/dist/types/src/shapes/Text.d.ts.map +1 -1
  68. package/dist/types/src/shapes/TextToImage.d.ts +2 -2
  69. package/dist/types/src/shapes/TextToImage.d.ts.map +1 -1
  70. package/dist/types/src/shapes/Thread.d.ts +2 -2
  71. package/dist/types/src/shapes/Thread.d.ts.map +1 -1
  72. package/dist/types/src/shapes/Trigger.d.ts +3 -3
  73. package/dist/types/src/shapes/Trigger.d.ts.map +1 -1
  74. package/dist/types/src/shapes/append-def.d.ts +1 -2
  75. package/dist/types/src/shapes/append-def.d.ts.map +1 -1
  76. package/dist/types/src/shapes/array-def.d.ts +2 -3
  77. package/dist/types/src/shapes/array-def.d.ts.map +1 -1
  78. package/dist/types/src/shapes/audio-def.d.ts +1 -2
  79. package/dist/types/src/shapes/audio-def.d.ts.map +1 -1
  80. package/dist/types/src/shapes/beacon-def.d.ts +1 -2
  81. package/dist/types/src/shapes/beacon-def.d.ts.map +1 -1
  82. package/dist/types/src/shapes/chat-def.d.ts +1 -2
  83. package/dist/types/src/shapes/chat-def.d.ts.map +1 -1
  84. package/dist/types/src/shapes/common/Box.d.ts.map +1 -1
  85. package/dist/types/src/shapes/common/FunctionBody.d.ts.map +1 -1
  86. package/dist/types/src/shapes/common/TextBox.d.ts +26 -0
  87. package/dist/types/src/shapes/common/TextBox.d.ts.map +1 -0
  88. package/dist/types/src/shapes/common/index.d.ts +3 -1
  89. package/dist/types/src/shapes/common/index.d.ts.map +1 -1
  90. package/dist/types/src/shapes/common/node-def.d.ts +24 -0
  91. package/dist/types/src/shapes/common/node-def.d.ts.map +1 -0
  92. package/dist/types/src/shapes/common/ports.d.ts +33 -0
  93. package/dist/types/src/shapes/common/ports.d.ts.map +1 -0
  94. package/dist/types/src/shapes/constant-def.d.ts +1 -2
  95. package/dist/types/src/shapes/constant-def.d.ts.map +1 -1
  96. package/dist/types/src/shapes/database-def.d.ts +1 -2
  97. package/dist/types/src/shapes/database-def.d.ts.map +1 -1
  98. package/dist/types/src/shapes/defs.d.ts +7 -2
  99. package/dist/types/src/shapes/defs.d.ts.map +1 -1
  100. package/dist/types/src/shapes/feed-def.d.ts +1 -2
  101. package/dist/types/src/shapes/feed-def.d.ts.map +1 -1
  102. package/dist/types/src/shapes/function-def.d.ts +1 -2
  103. package/dist/types/src/shapes/function-def.d.ts.map +1 -1
  104. package/dist/types/src/shapes/gpt-def.d.ts +1 -2
  105. package/dist/types/src/shapes/gpt-def.d.ts.map +1 -1
  106. package/dist/types/src/shapes/gpt-realtime-def.d.ts +1 -2
  107. package/dist/types/src/shapes/gpt-realtime-def.d.ts.map +1 -1
  108. package/dist/types/src/shapes/json-def.d.ts +2 -3
  109. package/dist/types/src/shapes/json-def.d.ts.map +1 -1
  110. package/dist/types/src/shapes/logic-def.d.ts +2 -3
  111. package/dist/types/src/shapes/logic-def.d.ts.map +1 -1
  112. package/dist/types/src/shapes/ports.test.d.ts +2 -0
  113. package/dist/types/src/shapes/ports.test.d.ts.map +1 -0
  114. package/dist/types/src/shapes/rng-def.d.ts +1 -2
  115. package/dist/types/src/shapes/rng-def.d.ts.map +1 -1
  116. package/dist/types/src/shapes/scope-def.d.ts +1 -2
  117. package/dist/types/src/shapes/scope-def.d.ts.map +1 -1
  118. package/dist/types/src/shapes/surface-def.d.ts +1 -2
  119. package/dist/types/src/shapes/surface-def.d.ts.map +1 -1
  120. package/dist/types/src/shapes/switch-def.d.ts +1 -2
  121. package/dist/types/src/shapes/switch-def.d.ts.map +1 -1
  122. package/dist/types/src/shapes/table-def.d.ts +1 -2
  123. package/dist/types/src/shapes/table-def.d.ts.map +1 -1
  124. package/dist/types/src/shapes/template-def.d.ts +1 -2
  125. package/dist/types/src/shapes/template-def.d.ts.map +1 -1
  126. package/dist/types/src/shapes/text-def.d.ts +1 -2
  127. package/dist/types/src/shapes/text-def.d.ts.map +1 -1
  128. package/dist/types/src/shapes/text-to-image-def.d.ts +1 -2
  129. package/dist/types/src/shapes/text-to-image-def.d.ts.map +1 -1
  130. package/dist/types/src/shapes/thread-def.d.ts +1 -2
  131. package/dist/types/src/shapes/thread-def.d.ts.map +1 -1
  132. package/dist/types/src/shapes/trigger-def.d.ts +1 -2
  133. package/dist/types/src/shapes/trigger-def.d.ts.map +1 -1
  134. package/dist/types/src/testing/circuits.d.ts +1 -1
  135. package/dist/types/src/testing/circuits.d.ts.map +1 -1
  136. package/dist/types/src/types/canvas-board.test.d.ts +2 -0
  137. package/dist/types/src/types/canvas-board.test.d.ts.map +1 -0
  138. package/dist/types/src/types/index.d.ts +4 -0
  139. package/dist/types/src/types/index.d.ts.map +1 -0
  140. package/dist/types/src/types/model.d.ts +10 -0
  141. package/dist/types/src/types/model.d.ts.map +1 -0
  142. package/dist/types/src/types/schema.d.ts +66 -0
  143. package/dist/types/src/types/schema.d.ts.map +1 -0
  144. package/dist/types/src/types/shapes.d.ts +114 -0
  145. package/dist/types/src/types/shapes.d.ts.map +1 -0
  146. package/dist/types/tsconfig.tsbuildinfo +1 -1
  147. package/package.json +43 -35
  148. package/src/graph/controller.ts +1 -1
  149. package/src/hooks/compute-context.ts +7 -4
  150. package/src/hooks/index.ts +0 -1
  151. package/src/hooks/useGraphMonitor.ts +10 -1
  152. package/src/index.ts +1 -1
  153. package/src/playwright/scene.spec.ts +3 -3
  154. package/src/registry.ts +63 -91
  155. package/src/scene/compute.stories.tsx +3 -6
  156. package/src/scene/echo-store.test.ts +18 -7
  157. package/src/scene/echo-store.ts +7 -10
  158. package/src/scene/index.ts +0 -3
  159. package/src/scene/projection.ts +2 -3
  160. package/src/scene/scene.test.ts +4 -4
  161. package/src/scene/scene.ts +6 -4
  162. package/src/schema.test.ts +7 -36
  163. package/src/shapes/Append.tsx +2 -3
  164. package/src/shapes/Array.tsx +3 -4
  165. package/src/shapes/Audio.tsx +2 -2
  166. package/src/shapes/Beacon.tsx +2 -2
  167. package/src/shapes/Boolean.tsx +32 -29
  168. package/src/shapes/Chat.tsx +5 -10
  169. package/src/shapes/Constant.tsx +19 -12
  170. package/src/shapes/Database.tsx +2 -4
  171. package/src/shapes/Feed.tsx +2 -3
  172. package/src/shapes/Function.tsx +4 -10
  173. package/src/shapes/Gpt.tsx +2 -3
  174. package/src/shapes/GptRealtime.tsx +2 -2
  175. package/src/shapes/Json.tsx +5 -6
  176. package/src/shapes/Logic.tsx +5 -6
  177. package/src/shapes/RNG.tsx +2 -2
  178. package/src/shapes/Scope.tsx +2 -2
  179. package/src/shapes/Surface.tsx +9 -6
  180. package/src/shapes/Switch.tsx +10 -12
  181. package/src/shapes/Table.tsx +2 -4
  182. package/src/shapes/Template.tsx +10 -9
  183. package/src/shapes/Text.tsx +2 -3
  184. package/src/shapes/TextToImage.tsx +2 -4
  185. package/src/shapes/Thread.tsx +2 -3
  186. package/src/shapes/Trigger.tsx +3 -4
  187. package/src/shapes/append-def.ts +8 -7
  188. package/src/shapes/array-def.ts +8 -8
  189. package/src/shapes/audio-def.ts +8 -7
  190. package/src/shapes/beacon-def.ts +9 -8
  191. package/src/shapes/chat-def.tsx +8 -8
  192. package/src/shapes/common/Box.tsx +7 -4
  193. package/src/shapes/common/FunctionBody.tsx +13 -26
  194. package/src/shapes/common/TextBox.tsx +137 -0
  195. package/src/shapes/common/index.ts +3 -1
  196. package/src/shapes/common/node-def.tsx +117 -0
  197. package/src/shapes/common/ports.ts +107 -0
  198. package/src/shapes/constant-def.tsx +8 -8
  199. package/src/shapes/database-def.ts +8 -8
  200. package/src/shapes/defs.ts +21 -6
  201. package/src/shapes/feed-def.ts +8 -7
  202. package/src/shapes/function-def.ts +8 -7
  203. package/src/shapes/gpt-def.ts +8 -7
  204. package/src/shapes/gpt-realtime-def.ts +10 -10
  205. package/src/shapes/json-def.ts +15 -13
  206. package/src/shapes/logic-def.ts +14 -11
  207. package/src/shapes/ports.test.ts +23 -0
  208. package/src/shapes/rng-def.ts +8 -7
  209. package/src/shapes/scope-def.ts +8 -7
  210. package/src/shapes/surface-def.ts +8 -8
  211. package/src/shapes/switch-def.ts +8 -7
  212. package/src/shapes/table-def.ts +7 -7
  213. package/src/shapes/template-def.ts +8 -7
  214. package/src/shapes/text-def.ts +8 -8
  215. package/src/shapes/text-to-image-def.ts +8 -8
  216. package/src/shapes/thread-def.ts +8 -7
  217. package/src/shapes/trigger-def.ts +11 -8
  218. package/src/testing/circuits.ts +21 -7
  219. package/src/types/canvas-board.test.ts +84 -0
  220. package/src/types/index.ts +7 -0
  221. package/src/types/model.ts +63 -0
  222. package/src/types/schema.ts +73 -0
  223. package/src/types/shapes.ts +73 -0
  224. package/dist/types/src/compute-layout.d.ts +0 -9
  225. package/dist/types/src/compute-layout.d.ts.map +0 -1
  226. package/dist/types/src/compute.stories.d.ts +0 -58
  227. package/dist/types/src/compute.stories.d.ts.map +0 -1
  228. package/dist/types/src/hooks/useComputeGraphController.d.ts +0 -10
  229. package/dist/types/src/hooks/useComputeGraphController.d.ts.map +0 -1
  230. package/dist/types/src/scene/NodeView.d.ts +0 -11
  231. package/dist/types/src/scene/NodeView.d.ts.map +0 -1
  232. package/dist/types/src/scene/defs.d.ts +0 -5
  233. package/dist/types/src/scene/defs.d.ts.map +0 -1
  234. package/dist/types/src/scene/ports.d.ts +0 -5
  235. package/dist/types/src/scene/ports.d.ts.map +0 -1
  236. package/dist/types/src/shapes/common/function-anchors.d.ts +0 -12
  237. package/dist/types/src/shapes/common/function-anchors.d.ts.map +0 -1
  238. package/src/compute-layout.ts +0 -37
  239. package/src/compute.stories.tsx +0 -302
  240. package/src/hooks/useComputeGraphController.ts +0 -65
  241. package/src/scene/NodeView.tsx +0 -42
  242. package/src/scene/defs.ts +0 -158
  243. package/src/scene/ports.ts +0 -30
  244. package/src/shapes/common/function-anchors.ts +0 -44
@@ -7,26 +7,21 @@ import { describe, test } from 'vitest';
7
7
 
8
8
  import * as GraphModel from '@dxos/graph/GraphModel';
9
9
  import * as GraphNode from '@dxos/graph/GraphNode';
10
- import {
11
- CanvasBoard,
12
- CanvasGraphModel,
13
- Polygon,
14
- createEllipse,
15
- createPath,
16
- createRectangle,
17
- isPath,
18
- isPolygon,
19
- } from '@dxos/react-ui-canvas-editor';
20
10
 
21
- import { ComputeShape, createFunction, createSwitch } from './shapes/index.ts';
11
+ import { ComputeShape, createReducer, createSwitch } from './shapes/index.ts';
12
+ import { CanvasBoard, CanvasGraphModel } from './types/index.ts';
22
13
 
23
14
  describe('compute', () => {
15
+ test('a reducer keeps the id it is created with', ({ expect }) => {
16
+ const reducer = createReducer({ id: 'reducer-1', center: { x: 0, y: 0 } });
17
+ expect(reducer.id).toBe('reducer-1');
18
+ });
19
+
24
20
  test('model', ({ expect }) => {
25
21
  const model = CanvasGraphModel.create<ComputeShape>();
26
22
  const node = createSwitch({ id: 'x', center: { x: 0, y: 0 }, size: { width: 80, height: 80 } });
27
23
  console.log(JSON.stringify(node, null, 2));
28
24
  expect(Schema.is(ComputeShape)(node)).toBe(true);
29
- expect(Schema.is(Polygon)(node)).toBe(true);
30
25
  expect(Schema.is(CanvasBoard.Shape)(node)).toBe(true);
31
26
  expect(Schema.is(GraphNode.GraphNode)(node)).toBe(true);
32
27
 
@@ -37,27 +32,3 @@ describe('compute', () => {
37
32
  console.log(JSON.stringify(model, null, 2));
38
33
  });
39
34
  });
40
-
41
- describe('schema', () => {
42
- test('basic types', ({ expect }) => {
43
- const shapes: CanvasBoard.Shape[] = [];
44
- shapes.push(createRectangle({ id: 'shape-1', center: { x: 0, y: 0 }, size: { width: 80, height: 80 } }));
45
- shapes.push(createEllipse({ id: 'shape-2', center: { x: 0, y: 0 }, size: { width: 80, height: 80 } }));
46
- shapes.push(createFunction({ id: 'shape-3', center: { x: 0, y: 0 } }));
47
- shapes.push(
48
- createPath({
49
- id: 'shape-4',
50
- points: [
51
- { x: 0, y: 0 },
52
- { x: 0, y: 0 },
53
- ],
54
- }),
55
- );
56
-
57
- const polygons = shapes.filter((shape) => isPolygon(shape)).map((shape) => shape.center);
58
- expect(polygons).to.have.length(3);
59
-
60
- const paths = shapes.filter((shape) => isPath(shape)).map((shape) => shape.path);
61
- expect(paths).to.have.length(1);
62
- });
63
- });
@@ -5,11 +5,10 @@
5
5
  import React from 'react';
6
6
 
7
7
  import { AppendInput } from '@dxos/conductor';
8
- import { type ShapeComponentProps } from '@dxos/react-ui-canvas-editor';
9
8
 
10
9
  import { type AppendShape } from './append-def.ts';
11
- import { FunctionBody } from './common/index.ts';
10
+ import { type ComputeNodeViewProps, FunctionBody } from './common/index.ts';
12
11
 
13
- export const AppendComponent = ({ shape }: ShapeComponentProps<AppendShape>) => {
12
+ export const AppendComponent = ({ node: shape }: ComputeNodeViewProps<AppendShape>) => {
14
13
  return <FunctionBody shape={shape} inputSchema={AppendInput} />;
15
14
  };
@@ -5,17 +5,16 @@
5
5
  import React from 'react';
6
6
 
7
7
  import { ReducerInput, ReducerOutput } from '@dxos/conductor';
8
- import { type ShapeComponentProps } from '@dxos/react-ui-canvas-editor';
9
8
 
10
9
  import { type ReducerShape } from './array-def.ts';
11
- import { FunctionBody } from './common/index.ts';
10
+ import { type ComputeNodeViewProps, FunctionBody } from './common/index.ts';
12
11
 
13
12
  //
14
13
  // Components
15
14
  //
16
15
 
17
- export type ReducerComponentProps = ShapeComponentProps<ReducerShape>;
16
+ export type ReducerComponentProps = ComputeNodeViewProps<ReducerShape>;
18
17
 
19
- export const ReducerComponent = ({ shape }: ReducerComponentProps) => {
18
+ export const ReducerComponent = ({ node: shape }: ReducerComponentProps) => {
20
19
  return <FunctionBody shape={shape} inputSchema={ReducerInput} outputSchema={ReducerOutput} />;
21
20
  };
@@ -5,13 +5,13 @@
5
5
  import React, { useEffect, useState } from 'react';
6
6
 
7
7
  import { DEFAULT_OUTPUT } from '@dxos/conductor';
8
- import { type ShapeComponentProps } from '@dxos/react-ui-canvas-editor';
9
8
  import * as Icon from '@dxos/react-ui/Icon';
10
9
 
11
10
  import { useComputeNodeState } from '../hooks/index.ts';
12
11
  import { type AudioShape } from './audio-def.ts';
12
+ import { type ComputeNodeViewProps } from './common/index.ts';
13
13
 
14
- export const AudioComponent = ({ shape }: ShapeComponentProps<AudioShape>) => {
14
+ export const AudioComponent = ({ node: shape }: ComputeNodeViewProps<AudioShape>) => {
15
15
  const { runtime } = useComputeNodeState(shape);
16
16
  const [active, setActive] = useState(false);
17
17
  useEffect(() => {
@@ -5,13 +5,13 @@
5
5
  import React from 'react';
6
6
 
7
7
  import { DEFAULT_INPUT, isTruthy } from '@dxos/conductor';
8
- import { type ShapeComponentProps } from '@dxos/react-ui-canvas-editor';
9
8
  import * as Icon from '@dxos/react-ui/Icon';
10
9
 
11
10
  import { useComputeNodeState } from '../hooks/index.ts';
12
11
  import { type BeaconShape } from './beacon-def.ts';
12
+ import { type ComputeNodeViewProps } from './common/index.ts';
13
13
 
14
- export const BeaconComponent = ({ shape }: ShapeComponentProps<BeaconShape>) => {
14
+ export const BeaconComponent = ({ node: shape }: ComputeNodeViewProps<BeaconShape>) => {
15
15
  const { runtime } = useComputeNodeState(shape);
16
16
  const input = runtime.inputs[DEFAULT_INPUT];
17
17
  const value = input?.type === 'executed' ? input.value : false;
@@ -6,10 +6,10 @@ import * as Schema from 'effect/Schema';
6
6
  import * as Struct from 'effect/Struct';
7
7
  import React, { type FC } from 'react';
8
8
 
9
- import { type ShapeDef, getAnchorPoints } from '@dxos/react-ui-canvas-editor';
10
- import { createAnchors } from '@dxos/react-ui-canvas-editor';
9
+ import { type NodeDef } from '@dxos/react-ui-canvas/scene';
11
10
 
12
- import { ComputeShape, type CreateShapeProps, createAnchorId, createShape } from './defs.ts';
11
+ import { createRowPorts, defineComputeNode, getRowPoints } from './common/index.ts';
12
+ import { ComputeShape, type CreateShapeProps, createAnchorId, createShape, withZ } from './defs.ts';
13
13
 
14
14
  //
15
15
  // Gate utils.
@@ -35,36 +35,39 @@ const createGate = (props: CreateGateProps): GateShape =>
35
35
  });
36
36
 
37
37
  // TODO(burdon): Create custom icons.
38
- const defineShape = <S extends GateShape>({
38
+ const defineGate = ({
39
39
  type,
40
40
  name,
41
41
  icon,
42
42
  symbol: Symbol,
43
- createShape,
43
+ create,
44
44
  inputs,
45
45
  outputs = [createAnchorId('output')],
46
46
  }: {
47
47
  type: GateType;
48
48
  symbol: FC<GateSymbolProps>;
49
- createShape: ShapeDef<S>['createShape'];
49
+ create: (props: Pick<GateShape, 'id' | 'center'>) => GateShape;
50
50
  inputs: string[];
51
51
  outputs?: string[];
52
- } & Pick<ShapeDef<GateShape>, 'name' | 'icon'>): ShapeDef<GateShape> => ({
53
- type,
54
- name,
55
- icon,
56
- // NOTE: Preact interprets captitalized properties as React components.
57
- // Be careful not to name component factories with a capital letter.
58
- component: () => {
59
- return (
60
- <div className='flex w-full justify-center items-center'>
61
- <Symbol />
62
- </div>
63
- );
64
- },
65
- createShape,
66
- getAnchors: (shape) => createAnchors({ shape, inputs, outputs }),
67
- });
52
+ } & Pick<NodeDef, 'name' | 'icon'>): NodeDef =>
53
+ defineComputeNode<GateShape>({
54
+ type,
55
+ name,
56
+ icon,
57
+ group: 'Operations',
58
+ schema: withZ(GateShape),
59
+ // NOTE: Preact interprets captitalized properties as React components.
60
+ // Be careful not to name component factories with a capital letter.
61
+ component: () => {
62
+ return (
63
+ <div className='flex w-full justify-center items-center'>
64
+ <Symbol />
65
+ </div>
66
+ );
67
+ },
68
+ create,
69
+ ports: (shape) => createRowPorts({ size: shape.size, inputs, outputs }),
70
+ });
68
71
 
69
72
  //
70
73
  // Symbols
@@ -97,7 +100,7 @@ const createSymbol =
97
100
  return (
98
101
  <svg viewBox={`0 0 ${width} ${height}`} className='dx-fill'>
99
102
  {/* Input line. */}
100
- {getAnchorPoints({ x: 0, y: centerY }, inputs).map(({ x, y }, i) => (
103
+ {getRowPoints({ x: 0, y: centerY }, inputs).map(({ x, y }, i) => (
101
104
  <line key={i} x1={x} y1={y} x2={startX * 1.3} y2={y} strokeWidth={strokeWidth} className={className} />
102
105
  ))}
103
106
 
@@ -135,12 +138,12 @@ export type AndShape = GateShape;
135
138
  export const createAnd = (props: Omit<CreateGateProps, 'type' | 'node'>) => {
136
139
  return createGate({ ...props, type: 'and' });
137
140
  };
138
- export const andShape = defineShape({
141
+ export const andNodeDef = defineGate({
139
142
  type: 'and',
140
143
  name: 'AND',
141
144
  icon: 'ph--intersection--regular',
142
145
  symbol: AndSymbol,
143
- createShape: createAnd,
146
+ create: createAnd,
144
147
  inputs: ['input.a', 'input.b'],
145
148
  });
146
149
 
@@ -169,12 +172,12 @@ export type OrShape = GateShape;
169
172
  export const createOr = (props: Omit<CreateGateProps, 'type' | 'node'>) => {
170
173
  return createGate({ ...props, type: 'or' });
171
174
  };
172
- export const orShape = defineShape({
175
+ export const orNodeDef = defineGate({
173
176
  type: 'or',
174
177
  name: 'OR',
175
178
  icon: 'ph--union--regular',
176
179
  symbol: OrSymbol,
177
- createShape: createOr,
180
+ create: createOr,
178
181
  inputs: ['input.a', 'input.b'],
179
182
  });
180
183
 
@@ -205,11 +208,11 @@ export type NotShape = GateShape;
205
208
  export const createNot = (props: Omit<CreateGateProps, 'type' | 'node'>) => {
206
209
  return createGate({ ...props, type: 'not' });
207
210
  };
208
- export const notShape = defineShape({
211
+ export const notNodeDef = defineGate({
209
212
  type: 'not',
210
213
  name: 'NOT',
211
214
  icon: 'ph--x--regular',
212
215
  symbol: NotSymbol,
213
- createShape: createNot,
216
+ create: createNot,
214
217
  inputs: [createAnchorId('input')],
215
218
  });
@@ -5,24 +5,19 @@
5
5
  import React, { useRef } from 'react';
6
6
 
7
7
  import { DEFAULT_OUTPUT } from '@dxos/conductor';
8
- import {
9
- type ShapeComponentProps,
10
- TextBox,
11
- type TextBoxControl,
12
- type TextBoxProps,
13
- } from '@dxos/react-ui-canvas-editor';
14
8
 
15
9
  import { useComputeNodeState } from '../hooks/index.ts';
16
10
  import { type ChatShape } from './chat-def.tsx';
17
- import { Box } from './common/index.ts';
11
+ import { Box, type ComputeNodeViewProps, TextBox, type TextBoxControl, type TextBoxProps } from './common/index.ts';
18
12
 
19
13
  //
20
14
  // Component
21
15
  //
22
16
 
23
- export type TextInputComponentProps = ShapeComponentProps<ChatShape> & TextBoxProps & { title?: string };
17
+ export type TextInputComponentProps = ComputeNodeViewProps<ChatShape> &
18
+ Pick<TextBoxProps, 'placeholder'> & { title?: string };
24
19
 
25
- export const TextInputComponent = ({ shape, title, ...props }: TextInputComponentProps) => {
20
+ export const TextInputComponent = ({ node: shape, title, placeholder }: TextInputComponentProps) => {
26
21
  const { runtime } = useComputeNodeState(shape);
27
22
  const inputRef = useRef<TextBoxControl>(null);
28
23
 
@@ -36,7 +31,7 @@ export const TextInputComponent = ({ shape, title, ...props }: TextInputComponen
36
31
 
37
32
  return (
38
33
  <Box shape={shape} title={title}>
39
- <TextBox ref={inputRef} onEnter={handleEnter} {...props} />
34
+ <TextBox ref={inputRef} onEnter={handleEnter} placeholder={placeholder} />
40
35
  </Box>
41
36
  );
42
37
  };
@@ -5,26 +5,27 @@
5
5
  import React, { useCallback, useRef, useState } from 'react';
6
6
 
7
7
  import { ComputeValueType } from '@dxos/conductor';
8
- import {
9
- type ShapeComponentProps,
10
- TextBox,
11
- type TextBoxControl,
12
- type TextBoxProps,
13
- } from '@dxos/react-ui-canvas-editor';
14
8
  import * as Field from '@dxos/react-ui/Field';
15
9
  import * as Input from '@dxos/react-ui/Input';
16
10
  import { safeParseJson } from '@dxos/util';
17
11
 
18
12
  import { useComputeNodeState } from '../hooks/index.ts';
19
- import { Box, TypeSelect } from './common/index.ts';
13
+ import {
14
+ Box,
15
+ type ComputeNodeViewProps,
16
+ TextBox,
17
+ type TextBoxControl,
18
+ type TextBoxProps,
19
+ TypeSelect,
20
+ } from './common/index.ts';
20
21
  import { type ConstantShape } from './constant-def.tsx';
21
22
 
22
23
  //
23
24
  // Component
24
25
  //
25
26
 
26
- export type ConstantComponentProps = ShapeComponentProps<ConstantShape> &
27
- TextBoxProps & { title?: string; chat?: boolean };
27
+ export type ConstantComponentProps = ComputeNodeViewProps<ConstantShape> &
28
+ Pick<TextBoxProps, 'placeholder'> & { title?: string };
28
29
 
29
30
  const inferType = (value: any): ComputeValueType | undefined => {
30
31
  if (typeof value === 'string') {
@@ -38,7 +39,7 @@ const inferType = (value: any): ComputeValueType | undefined => {
38
39
  }
39
40
  };
40
41
 
41
- export const ConstantComponent = ({ shape, title, chat, ...props }: ConstantComponentProps) => {
42
+ export const ConstantComponent = ({ node: shape, title, placeholder }: ConstantComponentProps) => {
42
43
  const { node } = useComputeNodeState(shape);
43
44
  const [type, setType] = useState(inferType(node.value) ?? ComputeValueType.literals[0]);
44
45
  const inputRef = useRef<TextBoxControl>(null);
@@ -68,10 +69,16 @@ export const ConstantComponent = ({ shape, title, chat, ...props }: ConstantComp
68
69
  return (
69
70
  <Box shape={shape} title={title} status={<TypeSelect value={type} onValueChange={setType} />}>
70
71
  {(type === 'string' || type === 'number') && (
71
- <TextBox {...props} ref={inputRef} value={node.value} onEnter={handleEnter} />
72
+ <TextBox placeholder={placeholder} ref={inputRef} value={node.value} onEnter={handleEnter} />
72
73
  )}
73
74
  {type === 'object' && (
74
- <TextBox {...props} ref={inputRef} value={JSON.stringify(node.value, null, 2)} language={'json'} />
75
+ <TextBox
76
+ placeholder={placeholder}
77
+ ref={inputRef}
78
+ value={JSON.stringify(node.value, null, 2)}
79
+ language={'json'}
80
+ onEnter={handleEnter}
81
+ />
75
82
  )}
76
83
  {type === 'boolean' && (
77
84
  <div className='flex grow justify-center items-center'>
@@ -4,11 +4,9 @@
4
4
 
5
5
  import React from 'react';
6
6
 
7
- import { type ShapeComponentProps } from '@dxos/react-ui-canvas-editor';
8
-
9
- import { Box } from './common/index.ts';
7
+ import { Box, type ComputeNodeViewProps } from './common/index.ts';
10
8
  import { type DatabaseShape } from './database-def.ts';
11
9
 
12
- export const DatabaseComponent = ({ shape }: ShapeComponentProps<DatabaseShape>) => {
10
+ export const DatabaseComponent = ({ node: shape }: ComputeNodeViewProps<DatabaseShape>) => {
13
11
  return <Box shape={shape} />;
14
12
  };
@@ -5,16 +5,15 @@
5
5
  import React, { Fragment } from 'react';
6
6
 
7
7
  import { DEFAULT_OUTPUT } from '@dxos/conductor';
8
- import { type ShapeComponentProps } from '@dxos/react-ui-canvas-editor';
9
8
  import * as ScrollArea from '@dxos/react-ui/ScrollArea';
10
9
  import type * as Util from '@dxos/react-ui/Util';
11
10
  import { mx } from '@dxos/ui-theme';
12
11
 
13
12
  import { useComputeNodeState } from '../hooks/index.ts';
14
- import { Box } from './common/index.ts';
13
+ import { Box, type ComputeNodeViewProps } from './common/index.ts';
15
14
  import { type FeedShape } from './feed-def.ts';
16
15
 
17
- export const FeedComponent = ({ shape }: ShapeComponentProps<FeedShape>) => {
16
+ export const FeedComponent = ({ node: shape }: ComputeNodeViewProps<FeedShape>) => {
18
17
  const { runtime } = useComputeNodeState(shape);
19
18
  const items = runtime.outputs[DEFAULT_OUTPUT]?.type === 'executed' ? runtime.outputs[DEFAULT_OUTPUT].value : [];
20
19
 
@@ -9,24 +9,18 @@ import * as Script from '@dxos/compute/Script';
9
9
  import { Filter, Obj, Ref } from '@dxos/echo';
10
10
  import { parseId } from '@dxos/keys';
11
11
  import { useClient } from '@dxos/react-client';
12
- import {
13
- type ShapeComponentProps,
14
- TextBox,
15
- type TextBoxControl,
16
- type TextBoxProps,
17
- } from '@dxos/react-ui-canvas-editor';
18
12
 
19
13
  import { useComputeNodeState } from '../hooks/index.ts';
20
- import { Box } from './common/index.ts';
14
+ import { Box, type ComputeNodeViewProps, TextBox, type TextBoxControl, type TextBoxProps } from './common/index.ts';
21
15
  import { type FunctionShape } from './function-def.ts';
22
16
 
23
17
  //
24
18
  // Component
25
19
  //
26
20
 
27
- type FunctionShapeComponentProps = ShapeComponentProps<FunctionShape> & TextBoxProps & { title?: string };
21
+ type FunctionShapeComponentProps = ComputeNodeViewProps<FunctionShape> & Pick<TextBoxProps, 'placeholder'>;
28
22
 
29
- export const FunctionShapeComponent = ({ shape, title, ...props }: FunctionShapeComponentProps) => {
23
+ export const FunctionShapeComponent = ({ node: shape, placeholder }: FunctionShapeComponentProps) => {
30
24
  const client = useClient();
31
25
  const { node, runtime } = useComputeNodeState(shape);
32
26
  const inputRef = useRef<TextBoxControl>(null);
@@ -72,7 +66,7 @@ export const FunctionShapeComponent = ({ shape, title, ...props }: FunctionShape
72
66
  return (
73
67
  <Box shape={shape} title='Function' onAction={handleAction}>
74
68
  <TextBox
75
- {...props}
69
+ placeholder={placeholder}
76
70
  ref={inputRef}
77
71
  value={node.value}
78
72
  language={node.valueType === 'object' ? 'json' : undefined}
@@ -4,14 +4,13 @@
4
4
 
5
5
  import React, { useEffect, useState } from 'react';
6
6
 
7
- import { type ShapeComponentProps } from '@dxos/react-ui-canvas-editor';
8
7
  import * as ScrollArea from '@dxos/react-ui/ScrollArea';
9
8
 
10
9
  import { useComputeNodeState } from '../hooks/index.ts';
11
- import { FunctionBody } from './common/index.ts';
10
+ import { type ComputeNodeViewProps, FunctionBody } from './common/index.ts';
12
11
  import { type GptShape } from './gpt-def.ts';
13
12
 
14
- export const GptComponent = ({ shape }: ShapeComponentProps<GptShape>) => {
13
+ export const GptComponent = ({ node: shape }: ComputeNodeViewProps<GptShape>) => {
15
14
  const { meta, runtime } = useComputeNodeState(shape);
16
15
  const [text, setText] = useState('');
17
16
  const [tokens, setTokens] = useState(0);
@@ -6,12 +6,12 @@ import React, { useState } from 'react';
6
6
 
7
7
  import { log } from '@dxos/log';
8
8
  import { useConfig } from '@dxos/react-client';
9
- import { type ShapeComponentProps } from '@dxos/react-ui-canvas-editor';
10
9
  import * as Icon from '@dxos/react-ui/Icon';
11
10
 
11
+ import { type ComputeNodeViewProps } from './common/index.ts';
12
12
  import { type GptRealtimeShape } from './gpt-realtime-def.ts';
13
13
 
14
- export const GptRealtimeComponent = ({ shape }: ShapeComponentProps<GptRealtimeShape>) => {
14
+ export const GptRealtimeComponent = ({ node: shape }: ComputeNodeViewProps<GptRealtimeShape>) => {
15
15
  const [isLive, setIsLive] = useState(false);
16
16
  const [isReady, setIsReady] = useState(false);
17
17
  const config = useConfig();
@@ -5,20 +5,19 @@
5
5
  import React from 'react';
6
6
 
7
7
  import { DEFAULT_INPUT } from '@dxos/conductor';
8
- import { type ShapeComponentProps } from '@dxos/react-ui-canvas-editor';
9
8
  import { Syntax } from '@dxos/react-ui-syntax-highlighter';
10
9
 
11
10
  import { useComputeNodeState } from '../hooks/index.ts';
12
- import { Box } from './common/index.ts';
11
+ import { Box, type ComputeNodeViewProps } from './common/index.ts';
13
12
  import { type JsonShape, type JsonTransformShape } from './json-def.ts';
14
13
 
15
14
  //
16
15
  // Component
17
16
  //
18
17
 
19
- export type JsonComponentProps = ShapeComponentProps<JsonShape>;
18
+ export type JsonComponentProps = ComputeNodeViewProps<JsonShape>;
20
19
 
21
- export const JsonComponent = ({ shape, ...props }: JsonComponentProps) => {
20
+ export const JsonComponent = ({ node: shape }: JsonComponentProps) => {
22
21
  const { runtime } = useComputeNodeState(shape);
23
22
  const input = runtime.inputs[DEFAULT_INPUT];
24
23
  const value = input?.type === 'executed' ? input.value : undefined;
@@ -37,8 +36,8 @@ export const JsonComponent = ({ shape, ...props }: JsonComponentProps) => {
37
36
  );
38
37
  };
39
38
 
40
- export type JsonTransformComponentProps = ShapeComponentProps<JsonTransformShape>;
39
+ export type JsonTransformComponentProps = ComputeNodeViewProps<JsonTransformShape>;
41
40
 
42
- export const JsonTransformComponent = ({ shape, ...props }: JsonTransformComponentProps) => {
41
+ export const JsonTransformComponent = ({ node: shape }: JsonTransformComponentProps) => {
43
42
  return <Box shape={shape} />;
44
43
  };
@@ -5,23 +5,22 @@
5
5
  import React from 'react';
6
6
 
7
7
  import { IfElseInput, IfElseOutput, IfInput, IfOutput } from '@dxos/conductor';
8
- import { type ShapeComponentProps } from '@dxos/react-ui-canvas-editor';
9
8
 
10
- import { FunctionBody } from './common/index.ts';
9
+ import { type ComputeNodeViewProps, FunctionBody } from './common/index.ts';
11
10
  import { type IfElseShape, type IfShape } from './logic-def.ts';
12
11
 
13
12
  //
14
13
  // Components
15
14
  //
16
15
 
17
- export type IfComponentProps = ShapeComponentProps<IfShape>;
16
+ export type IfComponentProps = ComputeNodeViewProps<IfShape>;
18
17
 
19
- export const IfComponent = ({ shape, ...props }: IfComponentProps) => {
18
+ export const IfComponent = ({ node: shape }: IfComponentProps) => {
20
19
  return <FunctionBody shape={shape} inputSchema={IfInput} outputSchema={IfOutput} />;
21
20
  };
22
21
 
23
- export type IfElseComponentProps = ShapeComponentProps<IfElseShape>;
22
+ export type IfElseComponentProps = ComputeNodeViewProps<IfElseShape>;
24
23
 
25
- export const IfElseComponent = ({ shape, ...props }: IfElseComponentProps) => {
24
+ export const IfElseComponent = ({ node: shape }: IfElseComponentProps) => {
26
25
  return <FunctionBody shape={shape} inputSchema={IfElseInput} outputSchema={IfElseOutput} />;
27
26
  };
@@ -5,10 +5,10 @@
5
5
  import React, { useEffect, useState } from 'react';
6
6
 
7
7
  import { DEFAULT_OUTPUT } from '@dxos/conductor';
8
- import { type ShapeComponentProps } from '@dxos/react-ui-canvas-editor';
9
8
  import * as Icon from '@dxos/react-ui/Icon';
10
9
 
11
10
  import { useComputeNodeState } from '../hooks/index.ts';
11
+ import { type ComputeNodeViewProps } from './common/index.ts';
12
12
  import { type RandomShape } from './rng-def.ts';
13
13
 
14
14
  const icons = [
@@ -23,7 +23,7 @@ const icons = [
23
23
  const pickIcon = () => icons[Math.floor(Math.random() * icons.length)];
24
24
 
25
25
  // TODO(burdon): Optional range.
26
- export const RandomComponent = ({ shape }: ShapeComponentProps<RandomShape>) => {
26
+ export const RandomComponent = ({ node: shape }: ComputeNodeViewProps<RandomShape>) => {
27
27
  const { runtime } = useComputeNodeState(shape);
28
28
 
29
29
  const [spin, setSpin] = useState(false);
@@ -6,13 +6,13 @@ import React from 'react';
6
6
 
7
7
  import { DEFAULT_INPUT } from '@dxos/conductor';
8
8
  import { useAudioStream } from '@dxos/react-ui-audio';
9
- import { type ShapeComponentProps } from '@dxos/react-ui-canvas-editor';
10
9
  import { Chaos, shaderPresets } from '@dxos/react-ui-experimental';
11
10
 
12
11
  import { useComputeNodeState } from '../hooks/index.ts';
12
+ import { type ComputeNodeViewProps } from './common/index.ts';
13
13
  import { type ScopeShape } from './scope-def.ts';
14
14
 
15
- export const ScopeComponent = ({ shape }: ShapeComponentProps<ScopeShape>) => {
15
+ export const ScopeComponent = ({ node: shape }: ComputeNodeViewProps<ScopeShape>) => {
16
16
  const { runtime } = useComputeNodeState(shape);
17
17
  const input = runtime.inputs[DEFAULT_INPUT];
18
18
  const active = input?.type === 'executed' ? input.value : false;
@@ -7,14 +7,13 @@ import React from 'react';
7
7
  import * as Surface from '@dxos/app-framework/Surface';
8
8
  import * as AppSurface from '@dxos/app-toolkit/AppSurface';
9
9
  import { DEFAULT_INPUT } from '@dxos/conductor';
10
- import { type ShapeComponentProps } from '@dxos/react-ui-canvas-editor';
11
10
  import * as Card from '@dxos/react-ui/Card';
12
11
 
13
12
  import { useComputeNodeState } from '../hooks/index.ts';
14
- import { Box } from './common/index.ts';
13
+ import { Box, type ComputeNodeViewProps } from './common/index.ts';
15
14
  import { type SurfaceShape } from './surface-def.ts';
16
15
 
17
- export const SurfaceComponent = ({ shape }: ShapeComponentProps<SurfaceShape>) => {
16
+ export const SurfaceComponent = ({ node: shape }: ComputeNodeViewProps<SurfaceShape>) => {
18
17
  const { runtime } = useComputeNodeState(shape);
19
18
  const input = runtime.inputs[DEFAULT_INPUT];
20
19
  const value = input?.type === 'executed' ? input.value : null;
@@ -22,9 +21,13 @@ export const SurfaceComponent = ({ shape }: ShapeComponentProps<SurfaceShape>) =
22
21
  // TODO(burdon): Subject property?
23
22
  return (
24
23
  <Box shape={shape}>
25
- <Card.Root grid>
26
- {value !== null && <Surface.Surface type={AppSurface.CardContent} data={{ subject: value }} limit={1} />}
27
- </Card.Root>
24
+ {/* No card until the input has a value: an empty one is a bare frame with nothing in it. */}
25
+ {value !== null && (
26
+ // The shape's frame already frames it, so the card fills the body without a border of its own.
27
+ <Card.Root grid border={false} classNames='dx-grow'>
28
+ <Surface.Surface type={AppSurface.CardContent} data={{ subject: value }} limit={1} />
29
+ </Card.Root>
30
+ )}
28
31
  </Box>
29
32
  );
30
33
  };
@@ -5,15 +5,15 @@
5
5
  import React, { useEffect, useState } from 'react';
6
6
 
7
7
  import { DEFAULT_OUTPUT } from '@dxos/conductor';
8
- import { type ShapeComponentProps } from '@dxos/react-ui-canvas-editor';
9
8
  import * as Field from '@dxos/react-ui/Field';
10
9
  import * as Input from '@dxos/react-ui/Input';
11
10
 
12
11
  import { useComputeNodeState } from '../hooks/index.ts';
12
+ import { type ComputeNodeViewProps } from './common/index.ts';
13
13
  import { type SwitchShape } from './switch-def.ts';
14
14
 
15
15
  // TODO(burdon): Should model as a constant.
16
- export const SwitchComponent = ({ shape }: ShapeComponentProps<SwitchShape>) => {
16
+ export const SwitchComponent = ({ node: shape }: ComputeNodeViewProps<SwitchShape>) => {
17
17
  const { runtime } = useComputeNodeState(shape);
18
18
  const [value, setValue] = useState(false);
19
19
  useEffect(() => {
@@ -21,16 +21,14 @@ export const SwitchComponent = ({ shape }: ShapeComponentProps<SwitchShape>) =>
21
21
  }, [value]);
22
22
 
23
23
  return (
24
- // The node frame would otherwise take the press as select-and-drag and capture the pointer, so the
25
- // switch never sees the click.
26
- <div
27
- className='flex w-full justify-center items-center'
28
- onPointerDown={(ev) => ev.stopPropagation()}
29
- onClick={(ev) => ev.stopPropagation()}
30
- >
31
- <Field.Root>
32
- <Input.Switch checked={value} onCheckedChange={({ checked: value }) => setValue(value)} />
33
- </Field.Root>
24
+ <div className='flex w-full justify-center items-center'>
25
+ {/* Only the switch keeps the press from the node frame (which would take it as select-and-drag and capture
26
+ the pointer, so the switch never saw the click); the rest of the shape drags as any node does. */}
27
+ <div className='inline-flex' onPointerDown={(ev) => ev.stopPropagation()} onClick={(ev) => ev.stopPropagation()}>
28
+ <Field.Root>
29
+ <Input.Switch checked={value} onCheckedChange={({ checked: value }) => setValue(value)} />
30
+ </Field.Root>
31
+ </div>
34
32
  </div>
35
33
  );
36
34
  };