All files workflowHydration.js

100% Statements 82/82
73.52% Branches 25/34
100% Functions 5/5
100% Lines 82/82

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 832x 2x 2x 7x 7x 7x 7x 7x 2x 5x 5x 5x 5x 5x 2x 7x 7x 7x 7x 7x 7x 2x 7x 7x 7x 7x 5x 5x 3x 3x 7x 7x 7x 7x 2x 2x 6x 6x 6x 6x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x  
import { sortNodesForParentOrder } from './nodeHierarchy.js';
import { sanitizeRuntimeValuesForPersistence } from './runtimeValuePersistence.js';
 
function mergeDefinition(nodeData, defs) {
  const savedData = nodeData || {};
  const registryDefinition = savedData.className ? defs[savedData.className] : null;
  return registryDefinition || null;
}
 
function getSocketType(inputDef) {
  if (!inputDef) return null;
  const [type] = Array.isArray(inputDef) ? inputDef : [inputDef];
  return Array.isArray(type) ? type[0] : type;
}
 
function getInputEntries(definition) {
  return [
    ...Object.entries(definition?.input?.required || {}),
    ...Object.entries(definition?.input?.optional || {}),
  ];
}
 
function sanitizeWidgetValues(widgetValues, definition) {
  const nextValues = { ...(widgetValues || {}) };
 
  getInputEntries(definition).forEach(([inputName, inputDef]) => {
    const type = getSocketType(inputDef);
    if (type === 'FILE_PICKER' || type === 'FOLDER_PICKER') {
      nextValues[inputName] = '';
    }
  });
 
  return nextValues;
}
 
export function hydrateWorkflowState(data, defs = {}) {
  const loadedNodes = Array.isArray(data?.nodes) ? data.nodes : [];
  const loadedEdges = Array.isArray(data?.edges) ? data.edges : [];
 
  const nodes = sortNodesForParentOrder(loadedNodes.map((node) => {
    const definition = mergeDefinition(node.data, defs);
 
    return {
      ...node,
      type: node.type || 'custom',
      className: node.className,
      parentId: node.parentId,
      extent: node.extent,
      hidden: !!node.hidden,
      style: node.style,
      dragHandle: node.dragHandle || '.drag-handle',
      data: {
        ...node.data,
        label: node.data?.label || node.data?.className || 'Node',
        widgetValues: sanitizeWidgetValues(node.data?.widgetValues, definition),
        runtimeValues: sanitizeRuntimeValuesForPersistence(
          node.data?.className,
          node.data?.runtimeValues,
        ),
        ...(node.data?.extraData || {}),
        definition,
        previewImage: null,
        tableRows: null,
        meshData: null,
        overlay: null,
        scalarValue: null,
        processingTimeMs: null,
        warning: null,
      },
    };
  }));
 
  const edges = loadedEdges.map((edge) => ({ ...edge }));
 
  const nextNodeId = Math.max(0, ...loadedNodes.map((node) => parseInt(node.id, 10) || 0)) + 1;
 
  return {
    nodes,
    edges,
    nextNodeId,
  };
}