67 lines
1.6 KiB
TypeScript
67 lines
1.6 KiB
TypeScript
/**
|
|
* Flow Bridge — bridges arrow data pipes with LayerFlow entries in Automerge.
|
|
*
|
|
* When an arrow pipe connects two folk-rapp shapes, a LayerFlow is auto-created
|
|
* in the Automerge doc. Deleting the arrow removes the LayerFlow.
|
|
*/
|
|
|
|
import { inferFlowKind } from "./data-types";
|
|
import type { LayerFlow, Layer } from "./layer-types";
|
|
|
|
interface SyncLike {
|
|
getLayers(): Layer[];
|
|
addFlow(flow: LayerFlow): void;
|
|
removeFlow(flowId: string): void;
|
|
}
|
|
|
|
/**
|
|
* Create a LayerFlow when an arrow pipe is created between two folk-rapp shapes.
|
|
* Returns the new flowId, or null if layers couldn't be matched.
|
|
*/
|
|
export function onArrowPipeCreated(
|
|
arrowId: string,
|
|
sourcePort: string,
|
|
targetPort: string,
|
|
srcModuleId: string,
|
|
tgtModuleId: string,
|
|
sync: SyncLike,
|
|
): string | null {
|
|
const layers = sync.getLayers();
|
|
|
|
// Find layers matching the source and target modules
|
|
const srcLayer = layers.find(l => l.moduleId === srcModuleId);
|
|
const tgtLayer = layers.find(l => l.moduleId === tgtModuleId);
|
|
|
|
if (!srcLayer || !tgtLayer) return null;
|
|
|
|
const flowKind = inferFlowKind(sourcePort);
|
|
const flowId = `flow-${arrowId}`;
|
|
|
|
const flow: LayerFlow = {
|
|
id: flowId,
|
|
kind: flowKind,
|
|
sourceLayerId: srcLayer.id,
|
|
targetLayerId: tgtLayer.id,
|
|
label: `${srcModuleId} → ${tgtModuleId}`,
|
|
strength: 1,
|
|
active: true,
|
|
meta: {
|
|
arrowId,
|
|
sourcePort,
|
|
targetPort,
|
|
},
|
|
};
|
|
|
|
sync.addFlow(flow);
|
|
return flowId;
|
|
}
|
|
|
|
/**
|
|
* Remove a LayerFlow when the corresponding arrow is deleted.
|
|
*/
|
|
export function onArrowRemoved(flowId: string, sync: SyncLike): void {
|
|
if (flowId) {
|
|
sync.removeFlow(flowId);
|
|
}
|
|
}
|