MCPcopy Create free account
hub / github.com/ForestHubAI/edge-agents / pasteToStore

Function pasteToStore

ts/workflow-builder/src/utils/graphOperations.ts:388–488  ·  view source on GitHub ↗
(
  store: CanvasStore,
  clipboard: Clipboard,
  offset: { x: number; y: number } = { x: 50, y: 50 },
  getNodeDefinition?: (node: NodeData) => NodeDefinition | undefined,
)

Source from the content-addressed store, hash-verified

386
387/** Paste clipboard contents into the store with new IDs and optional position offset. */
388export function pasteToStore(
389 store: CanvasStore,
390 clipboard: Clipboard,
391 offset: { x: number; y: number } = { x: 50, y: 50 },
392 getNodeDefinition?: (node: NodeData) => NodeDefinition | undefined,
393): PasteResult {
394 const empty: PasteResult = { pasted: false, skippedLabels: [] };
395 if (clipboard.nodes.length === 0) return empty;
396
397 const { setNodes, setEdges, setVariables } = store.getState();
398
399 // Filter out nodes that cannot be pasted (unremovable or singleton already on canvas)
400 const skippedLabels: string[] = [];
401 const pastableNodes = clipboard.nodes.filter((node) => {
402 if (!getNodeDefinition) return true;
403 const def = getNodeDefinition(node.data);
404 if (!def) return true;
405 if (!canAddNode(store, def)) {
406 skippedLabels.push(def.label);
407 return false;
408 }
409 return true;
410 });
411
412 if (pastableNodes.length === 0) return { pasted: false, skippedLabels };
413
414 // Build old ID -> new ID mapping (only for pastable nodes)
415 const idMap = new Map<string, string>();
416 pastableNodes.forEach((node) => {
417 const newId = generateId();
418 idMap.set(node.id, newId);
419 });
420
421 // Create new nodes with updated IDs and positions
422 const newNodes: Node<NodeData>[] = pastableNodes.map((node) => {
423 const newId = idMap.get(node.id)!;
424
425 // Deep copy and update node data
426 const newData = JSON.parse(JSON.stringify(node.data)) as NodeData;
427 newData.id = newId;
428
429 // Update expression references to point to new node IDs
430 newData.arguments = updateExpressionsInArgs(getArguments(newData), idMap) as typeof newData.arguments;
431
432 return {
433 ...node,
434 id: newId,
435 position: {
436 x: node.position.x + offset.x,
437 y: node.position.y + offset.y,
438 },
439 data: newData,
440 selected: true,
441 };
442 });
443
444 // Dedupe emit binding names on pasted nodes against existing variables.
445 // (Pasted nodes come from JSON.parse(JSON.stringify(...)) of live nodes, so

Callers 1

useGraphFunction · 0.90

Calls 8

generateIdFunction · 0.90
getArgumentsFunction · 0.90
isExpressionFunction · 0.90
canAddNodeFunction · 0.85
updateExpressionsInArgsFunction · 0.85
collectVariableNamesFunction · 0.85
deduplicateEmitNamesFunction · 0.85

Tested by

no test coverage detected