rspace-online/lib/flow-bridge.ts

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);
}
}