@difizen/ai-flow
Version:
Scalable, out-of-the-box, agent-oriented flow
370 lines (368 loc) • 15.1 kB
JavaScript
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
import { ControlMode } from "../../interfaces/flow";
import { useFlowsManagerStore } from "../../stores/flowsManagerStore";
import { useFlowStore } from "../../stores/flowStore";
import { useShortcutsStore } from "../../stores/useShortcutsStore";
import { getNodeId } from "../../utils/reactflowUtils";
import isWrappedWithClass from "../../utils/wrappedClass";
import React from 'react';
import { Background, MiniMap, ReactFlow } from '@xyflow/react';
import _ from 'lodash';
import { useCallback, useEffect, useRef, useState } from 'react';
import { useHotkeys } from 'react-hotkeys-hook';
import CustomConnectionLine from "../CustomEdge/costom-connection-line";
import CustomEdge from "../CustomEdge/index";
import { Operator } from "../FlowController/operator";
import { EventEmitterContextProvider } from "../../context/event-emitter";
import { useNodeInteractions } from "../../stores/nodeInteractions";
import '@xyflow/react/dist/style.css';
import { Header } from "../Header";
import HelpLine from "../HelpLine";
import { NodeComponentMap } from "../Node";
import { Panel } from "../Panel";
import { jsx as _jsx } from "react/jsx-runtime";
import { jsxs as _jsxs } from "react/jsx-runtime";
var edgeTypes = {
custom: CustomEdge
};
function Flow(props) {
var _props$miniMap = props.miniMap,
miniMap = _props$miniMap === void 0 ? true : _props$miniMap,
classNames = props.classNames,
_props$nodeTypes = props.nodeTypes,
nodeTypes = _props$nodeTypes === void 0 ? NodeComponentMap : _props$nodeTypes,
initialGraph = props.initialGraph,
toolbar = props.toolbar;
var position = useRef({
x: 0,
y: 0
});
var _useState = useState(null),
_useState2 = _slicedToArray(_useState, 2),
lastSelection = _useState2[0],
setLastSelection = _useState2[1];
var controlMode = useFlowStore(function (state) {
return state.controlMode;
});
var nodes = useFlowStore(function (state) {
return state.nodes;
});
var handleNodeEdited = useFlowStore(function (state) {
return state.handleNodeEdited;
});
var edges = useFlowStore(function (state) {
return state.edges;
});
var onNodesChange = useFlowStore(function (state) {
return state.onNodesChange;
});
var onEdgesChange = useFlowStore(function (state) {
return state.onEdgesChange;
});
var initFlow = useFlowStore(function (state) {
return state.initFlow;
});
var _onNodeDrag = useNodeInteractions(function (state) {
return state.onNodeDrag;
});
var onNodeDragEnd = useNodeInteractions(function (state) {
return state.onNodeDragEnd;
});
var setReactFlowInstance = useFlowStore(function (state) {
return state.setReactFlowInstance;
});
var deleteNode = useFlowStore(function (state) {
return state.deleteNode;
});
var deleteEdge = useFlowStore(function (state) {
return state.deleteEdge;
});
var onConnect = useFlowStore(function (state) {
return state.onConnect;
});
var setLastCopiedSelection = useFlowStore(function (state) {
return state.setLastCopiedSelection;
});
var lastCopiedSelection = useFlowStore(function (state) {
return state.lastCopiedSelection;
});
var paste = useFlowStore(function (state) {
return state.paste;
});
var undo = useFlowsManagerStore(function (state) {
return state.undo;
});
var redo = useFlowsManagerStore(function (state) {
return state.redo;
});
var takeSnapshot = useFlowsManagerStore(function (state) {
return state.takeSnapshot;
});
// Hot keys
var undoAction = useShortcutsStore(function (state) {
return state.undo;
});
var redoAction = useShortcutsStore(function (state) {
return state.redo;
});
var copyAction = useShortcutsStore(function (state) {
return state.copy;
});
var duplicate = useShortcutsStore(function (state) {
return state.duplicate;
});
var deleteAction = useShortcutsStore(function (state) {
return state.delete;
});
var cutAction = useShortcutsStore(function (state) {
return state.cut;
});
var pasteAction = useShortcutsStore(function (state) {
return state.paste;
});
function handleUndo(e) {
if (!isWrappedWithClass(e, 'noflow')) {
e.preventDefault();
e.stopImmediatePropagation();
undo();
}
}
function handleRedo(e) {
if (!isWrappedWithClass(e, 'noflow')) {
e.preventDefault();
e.stopImmediatePropagation();
redo();
}
}
function handleDuplicate(e) {
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();
var selectedNode = nodes.filter(function (obj) {
return obj.selected;
});
console.log('🚀 ~ handleDuplicate ~ selectedNode:', selectedNode);
if (selectedNode.length > 0) {
paste({
nodes: selectedNode,
edges: []
}, {
x: position.current.x,
y: position.current.y
});
}
}
function handleCopy(e) {
var multipleSelection = lastSelection !== null && lastSelection !== void 0 && lastSelection.nodes ? (lastSelection === null || lastSelection === void 0 ? void 0 : lastSelection.nodes.length) > 0 : false;
if (!isWrappedWithClass(e, 'noflow') && (isWrappedWithClass(e, 'react-flow__node') || multipleSelection)) {
var _window$getSelection;
e.preventDefault();
e.stopImmediatePropagation();
if (((_window$getSelection = window.getSelection()) === null || _window$getSelection === void 0 ? void 0 : _window$getSelection.toString().length) === 0 && lastSelection) {
setLastCopiedSelection(_.cloneDeep(lastSelection));
}
}
}
function handleCut(e) {
if (!isWrappedWithClass(e, 'noflow')) {
var _window$getSelection2;
e.preventDefault();
e.stopImmediatePropagation();
if (((_window$getSelection2 = window.getSelection()) === null || _window$getSelection2 === void 0 ? void 0 : _window$getSelection2.toString().length) === 0 && lastSelection) {
setLastCopiedSelection(_.cloneDeep(lastSelection), true);
}
}
}
function handlePaste(e) {
if (!isWrappedWithClass(e, 'noflow')) {
var _window$getSelection3;
e.preventDefault();
e.stopImmediatePropagation();
if (((_window$getSelection3 = window.getSelection()) === null || _window$getSelection3 === void 0 ? void 0 : _window$getSelection3.toString().length) === 0 && lastCopiedSelection) {
takeSnapshot();
paste(lastCopiedSelection, {
x: position.current.x,
y: position.current.y
});
}
}
}
function handleDelete(e) {
if (!isWrappedWithClass(e, 'nodelete') && lastSelection) {
e.preventDefault();
e.stopImmediatePropagation();
takeSnapshot();
deleteNode(lastSelection.nodes.map(function (node) {
return node.id;
}));
deleteEdge(lastSelection.edges.map(function (edge) {
return edge.id;
}));
}
}
useHotkeys(undoAction, handleUndo);
useHotkeys(redoAction, handleRedo);
useHotkeys(duplicate, handleDuplicate);
useHotkeys(copyAction, handleCopy);
useHotkeys(cutAction, handleCut);
useHotkeys(pasteAction, handlePaste);
useHotkeys(deleteAction, handleDelete);
useHotkeys('delete', handleDelete);
var onConnectMod = useCallback(function (params) {
takeSnapshot();
onConnect(params);
}, [takeSnapshot, onConnect]);
var onDrop = useCallback(function (event) {
event.preventDefault();
if (event.dataTransfer.types.some(function (types) {
return types === 'nodedata';
})) {
takeSnapshot();
try {
// Extract the data from the drag event and parse it as a JSON object
var data = JSON.parse(event.dataTransfer.getData('nodedata'));
var newId = getNodeId(data.type);
var newNode = {
id: newId,
type: data.type,
position: {
x: 0,
y: 0
},
data: _objectSpread(_objectSpread({}, data.node), {}, {
id: newId,
folded: false
})
};
paste({
nodes: [newNode],
edges: []
}, {
x: event.clientX,
y: event.clientY
});
} catch (error) {
console.error(error);
}
}
},
// Specify dependencies for useCallback
[takeSnapshot, paste]);
var onDragOver = useCallback(function (event) {
event.preventDefault();
if (event.dataTransfer.types.some(function (types) {
return types === 'nodedata';
})) {
event.dataTransfer.dropEffect = 'move';
} else {
event.dataTransfer.dropEffect = 'copy';
}
}, []);
var onNodeDragStart = useCallback(function () {
// 👇 make dragging a node undoable
takeSnapshot();
// 👉 you can place your event handlers here
}, [takeSnapshot]);
var onSelectionChange = useCallback(function (flow) {
setLastSelection(flow);
}, []);
var onSelectionDragStart = useCallback(function () {
// 👇 make dragging a selection undoable
takeSnapshot();
}, [takeSnapshot]);
// get current mouse position for paste node
useEffect(function () {
var handleMouseMove = function handleMouseMove(event) {
position.current = {
x: event.clientX,
y: event.clientY
};
};
document.addEventListener('mousemove', handleMouseMove);
return function () {
document.removeEventListener('mousemove', handleMouseMove);
};
}, [lastCopiedSelection, lastSelection, takeSnapshot]);
var autoSaving = useFlowsManagerStore(function (state) {
return state.autoSaving;
});
var initializeAutoSaveFlow = useFlowsManagerStore(function (state) {
return state.initializeAutoSaveFlow;
});
useEffect(function () {
if (initialGraph) {
initFlow(initialGraph);
}
if (autoSaving) {
initializeAutoSaveFlow();
}
}, []);
var handleNodeClick = useCallback(function (_, node) {
return handleNodeEdited(node.id);
}, [handleNodeEdited]);
return /*#__PURE__*/_jsx(EventEmitterContextProvider, {
children: /*#__PURE__*/_jsx("div", {
style: {
height: '100%',
width: '100%'
},
className: classNames,
children: /*#__PURE__*/_jsxs(ReactFlow, {
nodes: nodes,
edges: edges,
onInit: setReactFlowInstance,
onNodesChange: onNodesChange,
onNodeDrag: function onNodeDrag(_, node) {
return _onNodeDrag(node);
},
onNodeDragStop: function onNodeDragStop(_, node) {
return onNodeDragEnd(node);
},
onEdgesChange: onEdgesChange,
onNodeDragStart: onNodeDragStart,
onSelectionChange: onSelectionChange,
onSelectionDragStart: onSelectionDragStart,
onConnect: onConnectMod,
onNodeClick: handleNodeClick,
nodeTypes: nodeTypes,
edgeTypes: edgeTypes,
disableKeyboardA11y: true,
connectionLineComponent: CustomConnectionLine,
onDrop: onDrop,
onDragOver: onDragOver,
maxZoom: 2,
minZoom: 0.25,
panOnDrag: controlMode === ControlMode.Hand,
selectionOnDrag: controlMode === ControlMode.Pointer,
fitView: true,
children: [/*#__PURE__*/_jsx(Background, {
gap: [24, 24],
size: 4,
color: "#f1f1f1"
}), miniMap && /*#__PURE__*/_jsx(MiniMap, {
style: {
width: 102,
height: 72
},
className: "!absolute !left-4 !bottom-14 z-[9] !m-0 !w-[102px] !h-[72px] !border-[0.5px] !border-black/8 !rounded-lg !shadow-lg"
}), /*#__PURE__*/_jsx(Operator, {}), /*#__PURE__*/_jsx(Panel, {
className: toolbar ? '' : 'top-2'
}), /*#__PURE__*/_jsx(Header, {
toolbar: toolbar
}), /*#__PURE__*/_jsx(HelpLine, {})]
})
})
});
}
export default Flow;