Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Feature seperate out engines in the graph engine to support dataflow and behaviour flow #666

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
5 changes: 5 additions & 0 deletions .changeset/brown-melons-fetch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@tokens-studio/graph-editor": major
---

Removes the debugger and any reference to it. It was error prone and required patches to get it to compile correctly due to a problem with react-virtualized. A new debugger as a standalone package for testing and development will be created
5 changes: 5 additions & 0 deletions .changeset/curvy-ghosts-love.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@tokens-studio/graph-engine": major
---

Removed the COLOR_OBJECT, VEC3, DIMENSION schemas
5 changes: 5 additions & 0 deletions .changeset/cyan-wombats-drum.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@tokens-studio/graph-engine": major
---

Removed the `checkCapabilitites` function on the Graph.
5 changes: 5 additions & 0 deletions .changeset/fluffy-dragons-matter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@tokens-studio/graph-editor": patch
---

Adds a shortcut panel to visualize the shortcuts
5 changes: 5 additions & 0 deletions .changeset/foo-bar.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@tokens-studio/graph-editor": major
---

Editor now accepts a `nodeLoader` which handles loading nodes instead of a static lookup
6 changes: 6 additions & 0 deletions .changeset/giant-steaks-jump.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@tokens-studio/graph-editor": major
---

Removed `initialGraph` from the editor. This can now be passed through with the Frame.graph option instead

5 changes: 5 additions & 0 deletions .changeset/green-ladybugs-warn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@tokens-studio/graph-engine": major
---

Removed the setNode method on the Port
5 changes: 5 additions & 0 deletions .changeset/hot-feet-do.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@tokens-studio/graph-engine": major
---

Changed the Changed the internal conversion of the engine to no longer attempt to convert types. This should be handle in the editor rather
5 changes: 5 additions & 0 deletions .changeset/hot-swans-hug.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@tokens-studio/graph-engine": major
---

.predecessors is no longer a method on the Graph object, but is instead exported as a standalone function
5 changes: 5 additions & 0 deletions .changeset/khaki-timers-brush.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@tokens-studio/graph-engine": patch
---

Removed the .load method from Nodes, the .loadResource method from the Graph object and the externalLoader from the graph
5 changes: 5 additions & 0 deletions .changeset/lemon-clocks-double.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@tokens-studio/graph-engine": major
---

.update, .propagate, and .execute are now no longer methods on the Graph object and instead belong to the dataflow capability
5 changes: 5 additions & 0 deletions .changeset/light-avocados-hammer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@tokens-studio/graph-engine": major
---

The engine now allows for async node loading during deserialization using a nodeLoader instead of a static lookup
5 changes: 5 additions & 0 deletions .changeset/light-donkeys-lie.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@tokens-studio/graph-engine": major
---

The groups property on the node base class has been removed
5 changes: 5 additions & 0 deletions .changeset/long-shoes-occur.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@tokens-studio/graph-engine": major
---

Removed .start, .stop, .pause, .resume from the graph and instead created a new ControlFlow class which can be added to a graph as a capability
5 changes: 5 additions & 0 deletions .changeset/old-birds-attend.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@tokens-studio/graph-engine": major
---

extractTypes no longer exists as a static method on the Graph class and can instead be imported as a standalone function
5 changes: 5 additions & 0 deletions .changeset/poor-glasses-greet.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@tokens-studio/graph-engine": major
---

Removes the `visible` value in the edge. This should be handled in an editor and is not important to the the core engine
5 changes: 5 additions & 0 deletions .changeset/popular-seas-pretend.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@tokens-studio/graph-engine": major
---

hasConnectedInput has been removed as a method on the graph. It can be imported now as a standalone function
5 changes: 5 additions & 0 deletions .changeset/quick-jeans-hammer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@tokens-studio/graph-editor": patch
---

Made the context menu styling consistent
5 changes: 5 additions & 0 deletions .changeset/silver-dolls-joke.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@tokens-studio/graph-engine": major
---

Capabilities are now no longer shared by default and are instead registered again on any cloned graphs
5 changes: 5 additions & 0 deletions .changeset/slow-humans-fold.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@tokens-studio/graph-engine": major
---

Remove the clearOutputs method on Node
5 changes: 5 additions & 0 deletions .changeset/tame-queens-relate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@tokens-studio/graph-engine": major
---

Removed the `groups` property on the Node object
5 changes: 5 additions & 0 deletions .changeset/thin-files-beg.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@tokens-studio/graph-engine": major
---

Removed the buffer type and schema from the engine
16 changes: 16 additions & 0 deletions .changeset/wild-cars-kiss.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
"@tokens-studio/graph-editor": major
---

Removes the External Loader from the editor as this will likely be scoped per Frame

You should instead attach your external loader directly to the graph you created when creating a frame

```ts
const graph = new Graph();

graph.externaloLoader = myExternalLoader;

const Frame = new Frame({ graph , ...etc})

```
5 changes: 5 additions & 0 deletions .changeset/yellow-carrots-tan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@tokens-studio/graph-editor": major
---

Removed the Vec3 Control
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@ export default class MyCustomNode extends Node {
//You will likely want to expose input and output ports for the node
constructor(props: INodeDefinition) {
super(props);
this.addInput("a", {
this.dataflow.addInput("a", {
type: NumberSchema,
});
this.addInput("b", {
this.dataflow.addInput("b", {
type: NumberSchema,
});
this.addOutput("value", {
this.dataflow.addOutput("value", {
type: NumberSchema,
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,6 @@ const output = new Output({ graph });
const add = new Add({ graph });
const div = new Divide({ graph });

//Lets add the nodes explicitly. This makes sure if they apply side effects to the graph on entry that they are seperated from being defined
graph.addNode(input);
graph.addNode(output);
graph.addNode(add);
graph.addNode(div);

//Create an input port on the input. This would be a dynamic property
input.addInput("y", {
Expand Down
5 changes: 3 additions & 2 deletions packages/graph-editor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"format": "npm run format:eslint && npm run format:prettier",
"format:eslint": "eslint . --fix",
"format:prettier": "prettier \"**/*.{tsx,ts,js,md,json}\" --write",
"test": "vitest run",
"test:e2e": "cypress run",
"test:e2e:manual": "cypress open",
"lint": "npm run lint:prettier && npm run lint:eslint",
Expand All @@ -59,7 +60,6 @@
"@tokens-studio/tokens": "^0.3.7",
"@tokens-studio/types": "^0.5.1",
"@tokens-studio/ui": "^1.0.13",
"@xzdarcy/react-timeline-editor": "^0.1.9",
"array-move": "^4.0.0",
"clsx": "^2.1.1",
"cmdk": "^0.2.0",
Expand Down Expand Up @@ -89,7 +89,7 @@
"reselect": "^4.1.8",
"sentence-case": "^3.0.4",
"undo-manager": "^1.1.1",
"uuid": "^9.0.0"
"nanoid": "^5.0.7"
},
"peerDependencies": {
"react": "^18.2.0",
Expand Down Expand Up @@ -121,6 +121,7 @@
"cypress": "^13.9.0",
"cypress-react-selector": "^3.0.0",
"glob": "^11.0.0",
"happy-dom": "^16.3.0",
"postcss": "^8.4.47",
"postcss-cli": "^11.0.0",
"postcss-css-variables": "^0.19.0",
Expand Down
4 changes: 4 additions & 0 deletions packages/graph-editor/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,7 @@ In the example above, we use the useRef hook to create a reference to the Editor
## Development

We need to force the cypress react selector to use a version of `resq` that supports 18.2.0. This is done through resolutions and by manually adding it as a dev dependency

## Notes

This project uses [CSS modules](https://github.com/css-modules/css-modules) to handle encapsulating css. We distribute this in the dist with imports to `*.module.css` files still remaining without transformation to the css files. We assume that the implementing system will handle this transformation and export of the mangled css classnames if needed.
33 changes: 19 additions & 14 deletions packages/graph-editor/src/components/commandPalette/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,19 @@ import { observer } from 'mobx-react-lite';
import { showNodesCmdPaletteSelector } from '@/redux/selectors/ui.js';
import { useDispatch, useSelector } from 'react-redux';
import { useSelectAddedNodes } from '@/hooks/useSelectAddedNodes.js';
import React from 'react';
import React, { useCallback } from 'react';
import Search from '@tokens-studio/icons/Search.js';
import styles from './index.module.css';

export interface ICommandMenu {
items: DropPanelStore;
handleSelectNewNodeType: (node: NodeRequest) =>
handleSelectNewNodeType: (node: NodeRequest) => Promise<
| {
graphNode: Node;
flowNode: ReactFlowNode;
}
| undefined;
| undefined
>;
}

const CommandItem = observer(
Expand Down Expand Up @@ -80,7 +81,10 @@ const CommandMenuGroup = observer(
},
);

const CommandMenu = ({ items, handleSelectNewNodeType }: ICommandMenu) => {
export const CommandMenu = ({
items,
handleSelectNewNodeType,
}: ICommandMenu) => {
const showNodesCmdPalette = useSelector(showNodesCmdPaletteSelector);
const dispatch = useDispatch();
const cursorPositionRef = React.useRef<{ x: number; y: number }>({
Expand All @@ -91,8 +95,8 @@ const CommandMenu = ({ items, handleSelectNewNodeType }: ICommandMenu) => {
const reactflow = useReactFlow();
const selectAddedNodes = useSelectAddedNodes();

const handleSelectItem = (item) => {
const newNode = handleSelectNewNodeType({
const handleSelectItem = async (item) => {
const newNode = await handleSelectNewNodeType({
position: reactflow.screenToFlowPosition(cursorPositionRef.current),
...item,
});
Expand Down Expand Up @@ -132,13 +136,16 @@ const CommandMenu = ({ items, handleSelectNewNodeType }: ICommandMenu) => {
}, [dispatch.ui, showNodesCmdPalette]);

// Close the menu when Escape key is pressed inside the input
const handleKeyDown = (e) => {
if (e.key === 'Escape') {
e.preventDefault();
const handleKeyDown = useCallback(
(e) => {
if (e.key === 'Escape') {
e.preventDefault();

dispatch.ui.setShowNodesCmdPalette(false);
}
};
dispatch.ui.setShowNodesCmdPalette(false);
}
},
[dispatch.ui],
);

return (
<Command.Dialog
Expand Down Expand Up @@ -216,5 +223,3 @@ function NodePreview({ title, description, docs }) {
</Stack>
);
}

export { CommandMenu };
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { ContextMenuItem } from './ContextMenuStyles.js';
import { DataflowNode } from '@tokens-studio/graph-engine';
import { Graph } from 'graphlib';
import { Item, Menu, Separator } from 'react-contexify';
import { Menu, Separator } from 'react-contexify';
import { Node, ReactFlowInstance, useReactFlow } from 'reactflow';
import { useAction } from '@/editor/actions/provider.js';
import { useCanDeleteNode } from '@/hooks/useCanDeleteNode.js';
Expand Down Expand Up @@ -153,7 +155,7 @@ export const NodeContextMenu = ({ id, nodes }: INodeContextMenuProps) => {
nodes.forEach((node) => {
const graphNode = graph.getNode(node.id);
if (graphNode) {
graphNode.run();
(graphNode as DataflowNode).dataflow?.run();
}
});
}
Expand All @@ -167,11 +169,15 @@ export const NodeContextMenu = ({ id, nodes }: INodeContextMenuProps) => {
<Separator />
{nodes?.length == 1 && (
<>
<Item onClick={onTraceSource}>Trace Upstream</Item>
<Item onClick={onTraceTarget}>Trace Downstream</Item>
<ContextMenuItem onClick={onTraceSource}>
Trace Upstream
</ContextMenuItem>
<ContextMenuItem onClick={onTraceTarget}>
Trace Downstream
</ContextMenuItem>
</>
)}
<Item onClick={onResetTrace}>Reset Trace</Item>
<ContextMenuItem onClick={onResetTrace}>Reset Trace</ContextMenuItem>
<Separator />
<Item disabled={!isDeletable} onClick={deleteEl}>
Delete
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { ContextMenuItem } from './ContextMenuStyles.js';
import { Menu, Separator } from 'react-contexify';
import { clear } from '../../editor/actions/clear.js';
import { showGrid, snapGrid } from '@/redux/selectors/settings.js';
import { useAction } from '@/editor/actions/provider.js';
import { useAutoLayout } from '../../editor/hooks/useAutolayout.js';
import { useDispatch } from '@/hooks/index.js';
import { useFrame } from '@/system/frame/hook.js';
import { useLocalGraph } from '@/context/graph.js';
import { useReactFlow } from 'reactflow';
import { useSelector } from 'react-redux';
import React, { useCallback } from 'react';

export interface IPaneContextMenu<T = unknown> {
Expand All @@ -17,8 +16,8 @@ export interface IPaneContextMenu<T = unknown> {

export const PaneContextMenu = <T = unknown,>({ id }: IPaneContextMenu<T>) => {
const reactFlowInstance = useReactFlow();
const showGridValue = useSelector(showGrid);
const snapGridValue = useSelector(snapGrid);

const frame = useFrame();
const dispatch = useDispatch();
const graph = useLocalGraph();
const createNode = useAction('createNode');
Expand Down Expand Up @@ -51,12 +50,12 @@ export const PaneContextMenu = <T = unknown,>({ id }: IPaneContextMenu<T>) => {
}, [reactFlowInstance]);

const setShowGrid = useCallback(() => {
dispatch.settings.setShowGrid(!showGridValue);
}, [dispatch.settings, showGridValue]);
frame.settings.setShowGrid(!frame.settings.showGrid);
}, [frame.settings]);

const setSnapGrid = useCallback(() => {
dispatch.settings.setSnapGrid(!snapGridValue);
}, [dispatch.settings, snapGridValue]);
frame.settings.setSnapGrid(!frame.settings.snapGrid);
}, [frame.settings]);

const clearCallback = useCallback(() => {
clear(reactFlowInstance, graph);
Expand All @@ -70,7 +69,7 @@ export const PaneContextMenu = <T = unknown,>({ id }: IPaneContextMenu<T>) => {
<Separator />
<ContextMenuItem onClick={layout}>Apply Layout</ContextMenuItem>
<ContextMenuItem onClick={setShowGrid}>
{showGridValue ? 'Hide' : 'Show'} Grid
{frame.settings.showGrid ? 'Hide' : 'Show'} Grid
</ContextMenuItem>
<ContextMenuItem onClick={recenter}>Recenter</ContextMenuItem>
<Separator />
Expand Down
Loading