578 lines
15 KiB
JavaScript
578 lines
15 KiB
JavaScript
|
|
"use strict";
|
||
|
|
var __create = Object.create;
|
||
|
|
var __defProp = Object.defineProperty;
|
||
|
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||
|
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||
|
|
var __getProtoOf = Object.getPrototypeOf;
|
||
|
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||
|
|
var __export = (target, all) => {
|
||
|
|
for (var name in all)
|
||
|
|
__defProp(target, name, { get: all[name], enumerable: true });
|
||
|
|
};
|
||
|
|
var __copyProps = (to, from, except, desc) => {
|
||
|
|
if (from && typeof from === "object" || typeof from === "function") {
|
||
|
|
for (let key of __getOwnPropNames(from))
|
||
|
|
if (!__hasOwnProp.call(to, key) && key !== except)
|
||
|
|
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||
|
|
}
|
||
|
|
return to;
|
||
|
|
};
|
||
|
|
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||
|
|
// If the importer is in node compatibility mode or this is not an ESM
|
||
|
|
// file that has been converted to a CommonJS file using a Babel-
|
||
|
|
// compatible transform (i.e. "__esModule" has not been set), then set
|
||
|
|
// "default" to the CommonJS "module.exports" for node compatibility.
|
||
|
|
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||
|
|
mod
|
||
|
|
));
|
||
|
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||
|
|
|
||
|
|
// src/utils/index.ts
|
||
|
|
var index_exports = {};
|
||
|
|
__export(index_exports, {
|
||
|
|
FitToBoundsMode: () => FitToBoundsMode,
|
||
|
|
areNodesClose: () => areNodesClose,
|
||
|
|
bezierHorizontal: () => bezierHorizontal,
|
||
|
|
bezierSmart: () => bezierSmart,
|
||
|
|
bezierVertical: () => bezierVertical,
|
||
|
|
calculateBounds: () => calculateBounds,
|
||
|
|
checkNodesOverlap: () => checkNodesOverlap,
|
||
|
|
clearCustomEdgePathCalculators: () => clearCustomEdgePathCalculators,
|
||
|
|
clearPendingState: () => clearPendingState,
|
||
|
|
createComponentRegistry: () => createComponentRegistry,
|
||
|
|
createDebug: () => createDebug,
|
||
|
|
createFallbackComponent: () => createFallbackComponent,
|
||
|
|
debug: () => debug,
|
||
|
|
defaultEdgePathCalculator: () => defaultEdgePathCalculator,
|
||
|
|
getCustomEdgePathCalculatorNames: () => getCustomEdgePathCalculatorNames,
|
||
|
|
getEdgePathCalculator: () => getEdgePathCalculator,
|
||
|
|
getNodeBounds: () => getNodeBounds,
|
||
|
|
getNodeCenter: () => getNodeCenter,
|
||
|
|
getNodeGestureConfig: () => getNodeGestureConfig,
|
||
|
|
getPendingState: () => getPendingState,
|
||
|
|
getViewportGestureConfig: () => getViewportGestureConfig,
|
||
|
|
hasCustomEdgePathCalculator: () => hasCustomEdgePathCalculator,
|
||
|
|
hasPendingMutations: () => hasPendingMutations,
|
||
|
|
hitTestNode: () => hitTestNode,
|
||
|
|
hitTestPort: () => hitTestPort,
|
||
|
|
pendingNodeMutations: () => pendingNodeMutations,
|
||
|
|
registerEdgePathCalculator: () => registerEdgePathCalculator,
|
||
|
|
resolveEdgePathCalculator: () => resolveEdgePathCalculator,
|
||
|
|
setHitTestProvider: () => setHitTestProvider,
|
||
|
|
setNodeCenter: () => setNodeCenter,
|
||
|
|
smoothStep: () => smoothStep,
|
||
|
|
stepHorizontal: () => stepHorizontal,
|
||
|
|
stepSmart: () => stepSmart,
|
||
|
|
stepVertical: () => stepVertical,
|
||
|
|
straight: () => straight,
|
||
|
|
unregisterEdgePathCalculator: () => unregisterEdgePathCalculator
|
||
|
|
});
|
||
|
|
module.exports = __toCommonJS(index_exports);
|
||
|
|
|
||
|
|
// src/utils/debug.ts
|
||
|
|
var import_debug = __toESM(require("debug"));
|
||
|
|
var NAMESPACE = "canvas";
|
||
|
|
function createDebug(module2) {
|
||
|
|
const base = (0, import_debug.default)(`${NAMESPACE}:${module2}`);
|
||
|
|
const warn = (0, import_debug.default)(`${NAMESPACE}:${module2}:warn`);
|
||
|
|
const error = (0, import_debug.default)(`${NAMESPACE}:${module2}:error`);
|
||
|
|
warn.enabled = true;
|
||
|
|
error.enabled = true;
|
||
|
|
warn.log = console.warn.bind(console);
|
||
|
|
error.log = console.error.bind(console);
|
||
|
|
const debugFn = Object.assign(base, {
|
||
|
|
warn,
|
||
|
|
error
|
||
|
|
});
|
||
|
|
return debugFn;
|
||
|
|
}
|
||
|
|
var debug = {
|
||
|
|
graph: {
|
||
|
|
node: createDebug("graph:node"),
|
||
|
|
edge: createDebug("graph:edge"),
|
||
|
|
sync: createDebug("graph:sync")
|
||
|
|
},
|
||
|
|
ui: {
|
||
|
|
selection: createDebug("ui:selection"),
|
||
|
|
drag: createDebug("ui:drag"),
|
||
|
|
resize: createDebug("ui:resize")
|
||
|
|
},
|
||
|
|
sync: {
|
||
|
|
status: createDebug("sync:status"),
|
||
|
|
mutations: createDebug("sync:mutations"),
|
||
|
|
queue: createDebug("sync:queue")
|
||
|
|
},
|
||
|
|
viewport: createDebug("viewport")
|
||
|
|
};
|
||
|
|
|
||
|
|
// src/utils/gesture-configs.ts
|
||
|
|
var fingerGestureConfig = {
|
||
|
|
eventOptions: {
|
||
|
|
passive: false,
|
||
|
|
capture: false
|
||
|
|
},
|
||
|
|
drag: {
|
||
|
|
pointer: {
|
||
|
|
touch: true,
|
||
|
|
keys: false,
|
||
|
|
capture: false,
|
||
|
|
buttons: -1
|
||
|
|
},
|
||
|
|
filterTaps: true,
|
||
|
|
tapsThreshold: 10,
|
||
|
|
// Was 3 — too strict for fingers
|
||
|
|
threshold: 10
|
||
|
|
// Was 3 — needs larger dead zone
|
||
|
|
}
|
||
|
|
};
|
||
|
|
var pencilGestureConfig = {
|
||
|
|
eventOptions: {
|
||
|
|
passive: false,
|
||
|
|
capture: false
|
||
|
|
},
|
||
|
|
drag: {
|
||
|
|
pointer: {
|
||
|
|
touch: true,
|
||
|
|
keys: false,
|
||
|
|
capture: false,
|
||
|
|
buttons: -1
|
||
|
|
},
|
||
|
|
filterTaps: true,
|
||
|
|
tapsThreshold: 3,
|
||
|
|
threshold: 2
|
||
|
|
// Very precise — small dead zone
|
||
|
|
}
|
||
|
|
};
|
||
|
|
var mouseGestureConfig = {
|
||
|
|
eventOptions: {
|
||
|
|
passive: false,
|
||
|
|
capture: false
|
||
|
|
},
|
||
|
|
drag: {
|
||
|
|
pointer: {
|
||
|
|
touch: true,
|
||
|
|
keys: false,
|
||
|
|
capture: false,
|
||
|
|
buttons: -1
|
||
|
|
},
|
||
|
|
filterTaps: true,
|
||
|
|
tapsThreshold: 5,
|
||
|
|
// Was 3
|
||
|
|
threshold: 3
|
||
|
|
}
|
||
|
|
};
|
||
|
|
function getNodeGestureConfig(source) {
|
||
|
|
switch (source) {
|
||
|
|
case "finger":
|
||
|
|
return fingerGestureConfig;
|
||
|
|
case "pencil":
|
||
|
|
return pencilGestureConfig;
|
||
|
|
case "mouse":
|
||
|
|
return mouseGestureConfig;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
function getViewportGestureConfig(source) {
|
||
|
|
const base = getNodeGestureConfig(source);
|
||
|
|
return {
|
||
|
|
...base,
|
||
|
|
eventOptions: {
|
||
|
|
passive: false
|
||
|
|
},
|
||
|
|
pinch: {
|
||
|
|
pointer: {
|
||
|
|
touch: true
|
||
|
|
}
|
||
|
|
},
|
||
|
|
wheel: {
|
||
|
|
eventOptions: {
|
||
|
|
passive: false
|
||
|
|
}
|
||
|
|
}
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
// src/utils/mutation-queue.ts
|
||
|
|
var pendingNodeMutations = /* @__PURE__ */ new Map();
|
||
|
|
function getPendingState(nodeId) {
|
||
|
|
let state = pendingNodeMutations.get(nodeId);
|
||
|
|
if (!state) {
|
||
|
|
state = {
|
||
|
|
inFlight: false,
|
||
|
|
queuedPosition: null,
|
||
|
|
queuedUiProperties: null,
|
||
|
|
graphId: null
|
||
|
|
};
|
||
|
|
pendingNodeMutations.set(nodeId, state);
|
||
|
|
}
|
||
|
|
return state;
|
||
|
|
}
|
||
|
|
function clearPendingState(nodeId) {
|
||
|
|
pendingNodeMutations.delete(nodeId);
|
||
|
|
}
|
||
|
|
function hasPendingMutations() {
|
||
|
|
for (const state of pendingNodeMutations.values()) {
|
||
|
|
if (state.inFlight || state.queuedPosition !== null || state.queuedUiProperties !== null) {
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
// src/utils/component-registry.tsx
|
||
|
|
var import_compiler_runtime = require("react/compiler-runtime");
|
||
|
|
var import_react = __toESM(require("react"));
|
||
|
|
var import_jsx_runtime = require("react/jsx-runtime");
|
||
|
|
function createComponentRegistry({
|
||
|
|
registry,
|
||
|
|
fallback,
|
||
|
|
getDisplayName = (type) => `Memoized${type}Component`
|
||
|
|
}) {
|
||
|
|
const memoizedCache = /* @__PURE__ */ new Map();
|
||
|
|
const getComponent = (type) => {
|
||
|
|
if (memoizedCache.has(type)) {
|
||
|
|
return memoizedCache.get(type);
|
||
|
|
}
|
||
|
|
const LazyComponent = registry[type];
|
||
|
|
if (!LazyComponent) {
|
||
|
|
return fallback || null;
|
||
|
|
}
|
||
|
|
function RegistryComponent(props) {
|
||
|
|
const $ = (0, import_compiler_runtime.c)(2);
|
||
|
|
let t0;
|
||
|
|
if ($[0] !== props) {
|
||
|
|
t0 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LazyComponent, {
|
||
|
|
...props
|
||
|
|
});
|
||
|
|
$[0] = props;
|
||
|
|
$[1] = t0;
|
||
|
|
} else {
|
||
|
|
t0 = $[1];
|
||
|
|
}
|
||
|
|
return t0;
|
||
|
|
}
|
||
|
|
RegistryComponent.displayName = getDisplayName(type);
|
||
|
|
memoizedCache.set(type, RegistryComponent);
|
||
|
|
return RegistryComponent;
|
||
|
|
};
|
||
|
|
const getTypes = () => Object.keys(registry);
|
||
|
|
const hasType = (type) => type in registry;
|
||
|
|
return {
|
||
|
|
getComponent,
|
||
|
|
getTypes,
|
||
|
|
hasType,
|
||
|
|
Fallback: fallback || null
|
||
|
|
};
|
||
|
|
}
|
||
|
|
function createFallbackComponent(getMessage) {
|
||
|
|
return function FallbackComponent(props) {
|
||
|
|
const message = getMessage ? getMessage(props) : `Unsupported type: "${props.nodeData?.dbData?.node_type || "Unknown"}"`;
|
||
|
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
||
|
|
style: {
|
||
|
|
padding: "10px",
|
||
|
|
color: "orange"
|
||
|
|
},
|
||
|
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
||
|
|
children: message
|
||
|
|
})
|
||
|
|
});
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
// src/utils/edge-path-calculators.ts
|
||
|
|
var bezierHorizontal = ({
|
||
|
|
x1,
|
||
|
|
y1,
|
||
|
|
x2,
|
||
|
|
y2
|
||
|
|
}) => {
|
||
|
|
const dist = Math.abs(x2 - x1);
|
||
|
|
const offset = Math.max(dist * 0.5, 50);
|
||
|
|
const cp1x = x1 + offset;
|
||
|
|
const cp1y = y1;
|
||
|
|
const cp2x = x2 - offset;
|
||
|
|
const cp2y = y2;
|
||
|
|
const path = `M ${x1} ${y1} C ${cp1x} ${cp1y}, ${cp2x} ${cp2y}, ${x2} ${y2}`;
|
||
|
|
const labelX = (x1 + x2) / 2;
|
||
|
|
const labelY = (y1 + y2) / 2;
|
||
|
|
return {
|
||
|
|
path,
|
||
|
|
labelX,
|
||
|
|
labelY
|
||
|
|
};
|
||
|
|
};
|
||
|
|
var bezierVertical = ({
|
||
|
|
x1,
|
||
|
|
y1,
|
||
|
|
x2,
|
||
|
|
y2
|
||
|
|
}) => {
|
||
|
|
const dist = Math.abs(y2 - y1);
|
||
|
|
const offset = Math.max(dist * 0.5, 50);
|
||
|
|
const cp1x = x1;
|
||
|
|
const cp1y = y1 + offset;
|
||
|
|
const cp2x = x2;
|
||
|
|
const cp2y = y2 - offset;
|
||
|
|
const path = `M ${x1} ${y1} C ${cp1x} ${cp1y}, ${cp2x} ${cp2y}, ${x2} ${y2}`;
|
||
|
|
const labelX = (x1 + x2) / 2;
|
||
|
|
const labelY = (y1 + y2) / 2;
|
||
|
|
return {
|
||
|
|
path,
|
||
|
|
labelX,
|
||
|
|
labelY
|
||
|
|
};
|
||
|
|
};
|
||
|
|
var bezierSmart = (input) => {
|
||
|
|
const {
|
||
|
|
x1,
|
||
|
|
y1,
|
||
|
|
x2,
|
||
|
|
y2
|
||
|
|
} = input;
|
||
|
|
const dx = Math.abs(x2 - x1);
|
||
|
|
const dy = Math.abs(y2 - y1);
|
||
|
|
return dx > dy ? bezierHorizontal(input) : bezierVertical(input);
|
||
|
|
};
|
||
|
|
var straight = ({
|
||
|
|
x1,
|
||
|
|
y1,
|
||
|
|
x2,
|
||
|
|
y2
|
||
|
|
}) => {
|
||
|
|
const path = `M ${x1} ${y1} L ${x2} ${y2}`;
|
||
|
|
const labelX = (x1 + x2) / 2;
|
||
|
|
const labelY = (y1 + y2) / 2;
|
||
|
|
return {
|
||
|
|
path,
|
||
|
|
labelX,
|
||
|
|
labelY
|
||
|
|
};
|
||
|
|
};
|
||
|
|
var stepHorizontal = ({
|
||
|
|
x1,
|
||
|
|
y1,
|
||
|
|
x2,
|
||
|
|
y2
|
||
|
|
}) => {
|
||
|
|
const midX = (x1 + x2) / 2;
|
||
|
|
const path = `M ${x1} ${y1} L ${midX} ${y1} L ${midX} ${y2} L ${x2} ${y2}`;
|
||
|
|
const labelX = midX;
|
||
|
|
const labelY = (y1 + y2) / 2;
|
||
|
|
return {
|
||
|
|
path,
|
||
|
|
labelX,
|
||
|
|
labelY
|
||
|
|
};
|
||
|
|
};
|
||
|
|
var stepVertical = ({
|
||
|
|
x1,
|
||
|
|
y1,
|
||
|
|
x2,
|
||
|
|
y2
|
||
|
|
}) => {
|
||
|
|
const midY = (y1 + y2) / 2;
|
||
|
|
const path = `M ${x1} ${y1} L ${x1} ${midY} L ${x2} ${midY} L ${x2} ${y2}`;
|
||
|
|
const labelX = (x1 + x2) / 2;
|
||
|
|
const labelY = midY;
|
||
|
|
return {
|
||
|
|
path,
|
||
|
|
labelX,
|
||
|
|
labelY
|
||
|
|
};
|
||
|
|
};
|
||
|
|
var stepSmart = (input) => {
|
||
|
|
const {
|
||
|
|
x1,
|
||
|
|
y1,
|
||
|
|
x2,
|
||
|
|
y2
|
||
|
|
} = input;
|
||
|
|
const dx = Math.abs(x2 - x1);
|
||
|
|
const dy = Math.abs(y2 - y1);
|
||
|
|
return dx > dy ? stepHorizontal(input) : stepVertical(input);
|
||
|
|
};
|
||
|
|
var smoothStep = ({
|
||
|
|
x1,
|
||
|
|
y1,
|
||
|
|
x2,
|
||
|
|
y2
|
||
|
|
}) => {
|
||
|
|
const midX = (x1 + x2) / 2;
|
||
|
|
const radius = Math.min(20, Math.abs(x2 - x1) / 4, Math.abs(y2 - y1) / 2);
|
||
|
|
if (radius < 5 || Math.abs(y2 - y1) < radius * 2) {
|
||
|
|
return stepHorizontal({
|
||
|
|
x1,
|
||
|
|
y1,
|
||
|
|
x2,
|
||
|
|
y2,
|
||
|
|
sourceWidth: 0,
|
||
|
|
sourceHeight: 0,
|
||
|
|
targetWidth: 0,
|
||
|
|
targetHeight: 0
|
||
|
|
});
|
||
|
|
}
|
||
|
|
const yDir = y2 > y1 ? 1 : -1;
|
||
|
|
const path = `
|
||
|
|
M ${x1} ${y1}
|
||
|
|
L ${midX - radius} ${y1}
|
||
|
|
Q ${midX} ${y1}, ${midX} ${y1 + radius * yDir}
|
||
|
|
L ${midX} ${y2 - radius * yDir}
|
||
|
|
Q ${midX} ${y2}, ${midX + radius} ${y2}
|
||
|
|
L ${x2} ${y2}
|
||
|
|
`.replace(/\s+/g, " ").trim();
|
||
|
|
const labelX = midX;
|
||
|
|
const labelY = (y1 + y2) / 2;
|
||
|
|
return {
|
||
|
|
path,
|
||
|
|
labelX,
|
||
|
|
labelY
|
||
|
|
};
|
||
|
|
};
|
||
|
|
function getEdgePathCalculator(type) {
|
||
|
|
switch (type) {
|
||
|
|
case "bezier":
|
||
|
|
return bezierHorizontal;
|
||
|
|
case "bezier-vertical":
|
||
|
|
return bezierVertical;
|
||
|
|
case "bezier-smart":
|
||
|
|
return bezierSmart;
|
||
|
|
case "straight":
|
||
|
|
return straight;
|
||
|
|
case "step":
|
||
|
|
return stepHorizontal;
|
||
|
|
case "step-vertical":
|
||
|
|
return stepVertical;
|
||
|
|
case "step-smart":
|
||
|
|
return stepSmart;
|
||
|
|
case "smooth-step":
|
||
|
|
return smoothStep;
|
||
|
|
default:
|
||
|
|
return bezierHorizontal;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
var defaultEdgePathCalculator = bezierHorizontal;
|
||
|
|
|
||
|
|
// src/utils/layout.ts
|
||
|
|
var FitToBoundsMode = /* @__PURE__ */ (function(FitToBoundsMode2) {
|
||
|
|
FitToBoundsMode2["Graph"] = "graph";
|
||
|
|
FitToBoundsMode2["Selection"] = "selection";
|
||
|
|
return FitToBoundsMode2;
|
||
|
|
})({});
|
||
|
|
var calculateBounds = (nodes) => {
|
||
|
|
if (nodes.length === 0) {
|
||
|
|
return {
|
||
|
|
x: 0,
|
||
|
|
y: 0,
|
||
|
|
width: 0,
|
||
|
|
height: 0
|
||
|
|
};
|
||
|
|
}
|
||
|
|
const minX = Math.min(...nodes.map((node) => node.x));
|
||
|
|
const minY = Math.min(...nodes.map((node) => node.y));
|
||
|
|
const maxX = Math.max(...nodes.map((node) => node.x + node.width));
|
||
|
|
const maxY = Math.max(...nodes.map((node) => node.y + node.height));
|
||
|
|
return {
|
||
|
|
x: minX,
|
||
|
|
y: minY,
|
||
|
|
width: maxX - minX,
|
||
|
|
height: maxY - minY
|
||
|
|
};
|
||
|
|
};
|
||
|
|
function getNodeCenter(node) {
|
||
|
|
return {
|
||
|
|
x: node.x + node.width / 2,
|
||
|
|
y: node.y + node.height / 2
|
||
|
|
};
|
||
|
|
}
|
||
|
|
function setNodeCenter(node, centerX, centerY) {
|
||
|
|
return {
|
||
|
|
...node,
|
||
|
|
x: centerX - node.width / 2,
|
||
|
|
y: centerY - node.height / 2
|
||
|
|
};
|
||
|
|
}
|
||
|
|
function checkNodesOverlap(node1, node2) {
|
||
|
|
const center1 = getNodeCenter(node1);
|
||
|
|
const center2 = getNodeCenter(node2);
|
||
|
|
const dx = Math.abs(center1.x - center2.x);
|
||
|
|
const dy = Math.abs(center1.y - center2.y);
|
||
|
|
const minDistanceX = (node1.width + node2.width) / 2;
|
||
|
|
const minDistanceY = (node1.height + node2.height) / 2;
|
||
|
|
return dx < minDistanceX && dy < minDistanceY;
|
||
|
|
}
|
||
|
|
function getNodeBounds(node) {
|
||
|
|
return {
|
||
|
|
x: node.x,
|
||
|
|
y: node.y,
|
||
|
|
width: node.width,
|
||
|
|
height: node.height,
|
||
|
|
left: node.x,
|
||
|
|
right: node.x + node.width,
|
||
|
|
top: node.y,
|
||
|
|
bottom: node.y + node.height
|
||
|
|
};
|
||
|
|
}
|
||
|
|
function areNodesClose(node1, node2, threshold = 200) {
|
||
|
|
const center1 = getNodeCenter(node1);
|
||
|
|
const center2 = getNodeCenter(node2);
|
||
|
|
const distance = Math.sqrt(Math.pow(center1.x - center2.x, 2) + Math.pow(center1.y - center2.y, 2));
|
||
|
|
return distance <= threshold;
|
||
|
|
}
|
||
|
|
|
||
|
|
// src/utils/hit-test.ts
|
||
|
|
var defaultProvider = {
|
||
|
|
elementFromPoint: (x, y) => document.elementFromPoint(x, y),
|
||
|
|
elementsFromPoint: (x, y) => document.elementsFromPoint(x, y)
|
||
|
|
};
|
||
|
|
var _provider = defaultProvider;
|
||
|
|
function setHitTestProvider(provider) {
|
||
|
|
_provider = provider ?? defaultProvider;
|
||
|
|
}
|
||
|
|
function hitTestNode(screenX, screenY) {
|
||
|
|
const element = _provider.elementFromPoint(screenX, screenY);
|
||
|
|
const nodeElement = element?.closest("[data-node-id]") ?? null;
|
||
|
|
const nodeId = nodeElement?.getAttribute("data-node-id") ?? null;
|
||
|
|
return {
|
||
|
|
nodeId,
|
||
|
|
element: nodeElement
|
||
|
|
};
|
||
|
|
}
|
||
|
|
function hitTestPort(screenX, screenY) {
|
||
|
|
const elements = _provider.elementsFromPoint(screenX, screenY);
|
||
|
|
for (const el of elements) {
|
||
|
|
const portElement = el.closest("[data-drag-port-id]");
|
||
|
|
if (portElement) {
|
||
|
|
const portId = portElement.dataset.dragPortId;
|
||
|
|
const portBar = portElement.closest("[data-port-bar]");
|
||
|
|
const nodeId = portBar?.dataset.nodeId;
|
||
|
|
if (portId && nodeId) {
|
||
|
|
return {
|
||
|
|
nodeId,
|
||
|
|
portId
|
||
|
|
};
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
|
||
|
|
// src/utils/edge-path-registry.ts
|
||
|
|
var customCalculators = /* @__PURE__ */ new Map();
|
||
|
|
function registerEdgePathCalculator(name, calculator) {
|
||
|
|
customCalculators.set(name, calculator);
|
||
|
|
}
|
||
|
|
function unregisterEdgePathCalculator(name) {
|
||
|
|
return customCalculators.delete(name);
|
||
|
|
}
|
||
|
|
function resolveEdgePathCalculator(name) {
|
||
|
|
return customCalculators.get(name) ?? getEdgePathCalculator(name);
|
||
|
|
}
|
||
|
|
function hasCustomEdgePathCalculator(name) {
|
||
|
|
return customCalculators.has(name);
|
||
|
|
}
|
||
|
|
function getCustomEdgePathCalculatorNames() {
|
||
|
|
return Array.from(customCalculators.keys());
|
||
|
|
}
|
||
|
|
function clearCustomEdgePathCalculators() {
|
||
|
|
customCalculators.clear();
|
||
|
|
}
|
||
|
|
//# sourceMappingURL=index.js.map
|