Skip to content

Commit

Permalink
Fork nodes (#179)
Browse files Browse the repository at this point in the history
  • Loading branch information
GabiGrin authored Jan 7, 2025
1 parent 8d66721 commit 948252d
Show file tree
Hide file tree
Showing 136 changed files with 2,782 additions and 1,680 deletions.
28 changes: 23 additions & 5 deletions core/src/misc/custom-code-node-from-code.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { isCodeNode, isMacroNode, MacroNode, Node } from "../";
import { transpileFile } from "./transpile-file/transpile-file";
import { processImprovedMacro } from "../improved-macros/improved-macros";
import {
ImprovedMacroNode,
processImprovedMacro,
} from "../improved-macros/improved-macros";

export function customCodeNodeFromCode(
code: string,
Expand All @@ -18,13 +21,28 @@ export function customCodeNodeFromCode(

const result = new Function(wrappedCode)(imports);

if (isCodeNode(result.default) || isMacroNode(result.default)) {
if (result.default.icon) {
const macro = processImprovedMacro(result.default) as MacroNode<any>;
const validNodes = Object.values(result).filter(
(node) => isCodeNode(node) || isMacroNode(node)
);

if (validNodes.length === 0) {
throw new Error("No valid nodes found");
}

if (validNodes.length > 1) {
throw new Error("Multiple valid nodes found");
}

const node = validNodes[0];

if (isCodeNode(node) || isMacroNode(node)) {
if ((node as ImprovedMacroNode).icon) {
const macro = processImprovedMacro(
node as ImprovedMacroNode
) as MacroNode<any>;
macro.id = `${macro.id}${suffixId ? `-${suffixId}` : ""}`;
return macro;
}
const node = result.default as Node;
node.id = `${node.id}${suffixId ? `-${suffixId}` : ""}`;
return node;
} else {
Expand Down
1 change: 1 addition & 0 deletions core/src/node/macro-node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ export type MacroNodeDefinition<T> = Omit<
* Resolver will use this to load the editor component bundle into the editor
*/
editorConfig: MacroEditorConfigDefinition;
sourceCode?: string;
};

export interface MacroEditorCompProps<T> {
Expand Down
8 changes: 6 additions & 2 deletions core/src/node/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,12 +193,16 @@ export type Node = CodeNode | CustomNode;
export type ImportableSource = {
module: string;
node: ImportedNode;
implicit?: boolean;
};

export type CustomNode = VisualNode;

export type CodeNodeDefinition = Omit<CodeNode, "run">;
export type CodeNodeDefinition = Omit<CodeNode, "run"> & {
/**
* The source code of the node, if available. Used for editing and forking nodes in the editor.
*/
sourceCode?: string;
};

export type NodeDefinition = CustomNode | CodeNodeDefinition;
export type NodeOrMacroDefinition = NodeDefinition | MacroNodeDefinition<any>;
Expand Down
4 changes: 3 additions & 1 deletion flow-editor/src/flow-editor/ports/ports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,9 @@ export const defaultPorts: EditorPorts = {
getLibraryData: () => Promise.resolve({ groups: [] }),
onRequestSiblingNodes: () => Promise.resolve([]),
onCreateCustomNode: toastNotImplemented("onCreateCustomNode"),
onRequestNodeSource: toastNotImplemented("getNodeSource"),
onRequestNodeSource: () => {
throw new Error("Not implemented");
},
};

export const PortsContext = createContext<EditorPorts>(defaultPorts);
Expand Down
8 changes: 6 additions & 2 deletions flow-editor/src/types/@flyde-core.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -672,10 +672,14 @@ declare module '@flyde/core/node/node' {
export type ImportableSource = {
module: string;
node: ImportedNode;
implicit?: boolean;
};
export type CustomNode = VisualNode;
export type CodeNodeDefinition = Omit<CodeNode, "run">;
export type CodeNodeDefinition = Omit<CodeNode, "run"> & {
/**
* The source code of the node, if available. Used for editing and forking nodes in the editor.
*/
sourceCode?: string;
};
export type NodeDefinition = CustomNode | CodeNodeDefinition;
export type NodeOrMacroDefinition = NodeDefinition | MacroNodeDefinition<any>;
export type NodeModuleMetaData = {
Expand Down
8 changes: 6 additions & 2 deletions flow-editor/src/types/flyde-core-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -673,10 +673,14 @@ declare module '@flyde/core/node/node' {
export type ImportableSource = {
module: string;
node: ImportedNode;
implicit?: boolean;
};
export type CustomNode = VisualNode;
export type CodeNodeDefinition = Omit<CodeNode, "run">;
export type CodeNodeDefinition = Omit<CodeNode, "run"> & {
/**
* The source code of the node, if available. Used for editing and forking nodes in the editor.
*/
sourceCode?: string;
};
export type NodeDefinition = CustomNode | CodeNodeDefinition;
export type NodeOrMacroDefinition = NodeDefinition | MacroNodeDefinition<any>;
export type NodeModuleMetaData = {
Expand Down
34 changes: 33 additions & 1 deletion flow-editor/src/visual-node-editor/VisualNodeEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import {
ResolvedMacroNodeInstance,
ImportedNode,
MacroNodeDefinition,
NodeOrMacroDefinition,
CodeNodeDefinition,
} from "@flyde/core";

import { InstanceView, InstanceViewProps } from "./instance-view/InstanceView";
Expand Down Expand Up @@ -257,6 +259,10 @@ export const VisualNodeEditor: React.FC<VisualNodeEditorProps & { ref?: any }> =
}>();

const [isAddingCustomNode, setIsAddingCustomNode] = useState(false);
const [customNodeForkData, setCustomNodeForkData] = useState<{
node: NodeOrMacroDefinition;
initialCode: string;
}>();

const inlineEditorPortalRootRef = useRef();

Expand Down Expand Up @@ -1482,6 +1488,27 @@ export const VisualNodeEditor: React.FC<VisualNodeEditorProps & { ref?: any }> =
: "grab"
: "default";

const onViewForkCode = React.useCallback(
async (instance: NodeInstance) => {
const nodeDef = safelyGetNodeDef(
instance,
currResolvedDeps
) as CodeNodeDefinition;
try {
const code = nodeDef.sourceCode;
if (!code) {
toastMsg("No source code found");
return;
}
setCustomNodeForkData({ node: nodeDef, initialCode: code });
setIsAddingCustomNode(true);
} catch (e) {
console.error("Failed to get node source:", e);
}
},
[currResolvedDeps]
);

try {
return (
<ContextMenu
Expand Down Expand Up @@ -1616,6 +1643,7 @@ export const VisualNodeEditor: React.FC<VisualNodeEditorProps & { ref?: any }> =
onGroupSelected={onGroupSelectedInternal}
onPinMouseDown={onPinMouseDown}
onPinMouseUp={onPinMouseUp}
onViewForkCode={onViewForkCode}
hadError={
props.instancesWithErrors?.has(fullInsIdPath(ins.id)) ??
false
Expand Down Expand Up @@ -1687,8 +1715,12 @@ export const VisualNodeEditor: React.FC<VisualNodeEditorProps & { ref?: any }> =
{isAddingCustomNode ? (
<CustomNodeModal
isOpen={isAddingCustomNode}
onClose={() => setIsAddingCustomNode(false)}
onClose={() => {
setIsAddingCustomNode(false);
setCustomNodeForkData(undefined);
}}
onSave={onSaveCustomNode}
forkMode={customNodeForkData}
/>
) : null}
<div className="run-btn-container">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,8 @@ export interface InstanceViewProps {
onDeleteInstance: (ins: NodeInstance) => void;
onSetDisplayName: (ins: NodeInstance, view: string | undefined) => void;

onViewForkCode?: (ins: NodeInstance) => void;

displayMode?: true;

forceShowMinimized?: PinType | "both";
Expand Down Expand Up @@ -615,7 +617,10 @@ export const InstanceView: React.FC<InstanceViewProps> =
{ text: "Reorder outputs", onClick: _onChangeVisibleOutputs },
{ text: `Set display name`, onClick: _onSetDisplayName },
{ text: "Group selected instances", onClick: onGroupSelected },

{
text: "View/fork code",
onClick: () => props.onViewForkCode(instance),
},
{
text: "Delete instance",
intent: "danger",
Expand Down
2 changes: 1 addition & 1 deletion playground/stdlib-bundle/inline-macros.ts

Large diffs are not rendered by default.

8 changes: 6 additions & 2 deletions playground/types/@flyde-core.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -672,10 +672,14 @@ declare module '@flyde/core/node/node' {
export type ImportableSource = {
module: string;
node: ImportedNode;
implicit?: boolean;
};
export type CustomNode = VisualNode;
export type CodeNodeDefinition = Omit<CodeNode, "run">;
export type CodeNodeDefinition = Omit<CodeNode, "run"> & {
/**
* The source code of the node, if available. Used for editing and forking nodes in the editor.
*/
sourceCode?: string;
};
export type NodeDefinition = CustomNode | CodeNodeDefinition;
export type NodeOrMacroDefinition = NodeDefinition | MacroNodeDefinition<any>;
export type NodeModuleMetaData = {
Expand Down
Loading

0 comments on commit 948252d

Please sign in to comment.