Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 18 additions & 28 deletions packages/project/src/merge/map-uuids.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,41 +12,33 @@ import { Job } from '@openfn/lexicon';
import { Project } from '../Project';
import Workflow from '../Workflow';

// changing parent and changing id is probably a new node
// changing id but preserving parent should map
// adding a new node an changing the id... an we track this?

// null: this item does not exist in B
// string: this item maps to this ID in B (could be the same)
// true: this item needs a new UUID in B

// detecting nodes in b that were in a via heuristics
// what are the possible changes that will happen to a node.
// - change of properties (name, adaptor-type) [note: name affects id]
// - change of position (parent, children)
// - change of properties & position -> though one

// passes to pick solid nodes
// 1. properties & position match - solid node!

// passes to predict nodes
// 1. check what node was in that position originally (use parent when parent is a solid node, else use sibling if it's solid, else if all children are solid)
// 2. if the original node isn't a solid node, then it might be it. (when same parent and children)

export interface MappingResults {
nodes: Record<string, string>;
edges: Record<string, string>;
}

type EdgesType = Record<string, string[]>;

/**
* Compare two Workflows and identify matching nodes across them.
*
* This is designed to help merging two workflows together, ensuring that
* as many UUIDs are preserved in the target workflow as possible.
*
* Returns node and edge maps, where the key is the id in the source, and the
* value is the corresponding UUID in the target,
* ie: `{
* // source id: target UUID
* a: '851341-1234124-1512'
* }
*/
export default (source: Workflow, target: Workflow): MappingResults => {
const edgeMapping: MappingResults['edges'] = {};

const targetEdges = target.getAllEdges();
const sourceEdges = source.getAllEdges();

// Map by id
// First, simply map nodes with the same id
let {
mapping: nodeMapping,
pool,
Expand All @@ -58,6 +50,7 @@ export default (source: Workflow, target: Workflow): MappingResults => {
return id;
};

// Now, for any nodes that weren't mapped, try and find a suitable mapping
for (const source_step of pool.source) {
if (!source_step.id) continue; // yh. we'll always have it.

Expand Down Expand Up @@ -86,7 +79,7 @@ export default (source: Workflow, target: Workflow): MappingResults => {
continue;
}

// Children
// Is there an unmapped node with the same children?
result = mapStepByChildren(
source_step,
candidates,
Expand All @@ -104,7 +97,7 @@ export default (source: Workflow, target: Workflow): MappingResults => {
continue;
}

// Expression
// Is there an unmapped node with the same expression?
result = mapStepByExpression(source_step, candidates);
if (result.length) candidates = result;
if (candidates.length === 1) {
Expand Down Expand Up @@ -297,7 +290,4 @@ function mapStepByExpression(
candidates: Workflow['steps']
) {
return findByExpression((source_step as Job).expression, candidates);
}

// Get an array of all UUIDS
const extractUUIDS = (p: Project) => {};
}