merge useNodeConnections
This commit is contained in:
@@ -92,7 +92,7 @@
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
||||
store.edges;
|
||||
if (onconnect || ondisconnect) {
|
||||
let connections = store.connectionLookup.get(`${nodeId}-${type}-${handleId}`);
|
||||
let connections = store.connectionLookup.get(`${nodeId}-${type}${id ? `-${id}` : ''}`);
|
||||
|
||||
if (prevConnections && !areConnectionMapsEqual(connections, prevConnections)) {
|
||||
const _connections = connections ?? new Map();
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
return (item: Item) => {
|
||||
const isSelected = ids.has(item.id);
|
||||
|
||||
if (item.selected !== isSelected) {
|
||||
if (!!item.selected !== isSelected) {
|
||||
return { ...item, selected: isSelected };
|
||||
}
|
||||
|
||||
@@ -23,8 +23,7 @@
|
||||
};
|
||||
}
|
||||
|
||||
// TODO: maybe replace with set.intersection?
|
||||
function setEq(a: Set<string>, b: Set<string>) {
|
||||
function isSetEqual(a: Set<string>, b: Set<string>) {
|
||||
if (a.size !== b.size) {
|
||||
return false;
|
||||
}
|
||||
@@ -57,7 +56,6 @@
|
||||
// svelte-ignore non_reactive_update
|
||||
let container: HTMLDivElement;
|
||||
let containerBounds: DOMRect | null = null;
|
||||
// let selectedNodes: InternalNode[] = [];
|
||||
|
||||
let selectedNodeIds: Set<string> = new Set();
|
||||
let selectedEdgeIds: Set<string> = new Set();
|
||||
@@ -149,25 +147,27 @@
|
||||
).map((n) => n.id)
|
||||
);
|
||||
|
||||
// TODO: replace with extended connectionLookup
|
||||
let edgesSelectable = store.defaultEdgeOptions.selectable ?? true;
|
||||
selectedEdgeIds = new Set();
|
||||
store.edges.forEach((edge) => {
|
||||
if (
|
||||
selectedNodeIds.has(edge.source) &&
|
||||
selectedNodeIds.has(edge.target) &&
|
||||
(edge.selectable ?? edgesSelectable)
|
||||
) {
|
||||
selectedEdgeIds.add(edge.id);
|
||||
|
||||
// We look for all edges connected to the selected nodes
|
||||
for (let nodeId of selectedNodeIds) {
|
||||
let connections = store.connectionLookup.get(nodeId);
|
||||
if (!connections) continue;
|
||||
for (let { edgeId } of connections.values()) {
|
||||
let edge = store.edgeLookup.get(edgeId);
|
||||
if (edge && (edge.selectable ?? edgesSelectable)) {
|
||||
selectedEdgeIds.add(edgeId);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// this prevents unnecessary updates while updating the selection rectangle
|
||||
if (setEq(prevSelectedNodeIds, selectedNodeIds)) {
|
||||
if (isSetEqual(prevSelectedNodeIds, selectedNodeIds)) {
|
||||
store.nodes = store.nodes.map(toggleSelected(selectedNodeIds));
|
||||
}
|
||||
|
||||
if (setEq(prevSelectedEdgeIds, selectedEdgeIds)) {
|
||||
if (isSetEqual(prevSelectedEdgeIds, selectedEdgeIds)) {
|
||||
store.edges = store.edges.map(toggleSelected(selectedEdgeIds));
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import { getContext } from 'svelte';
|
||||
* @param functionName - The name of the function that is being called
|
||||
* @param force - If true, the warning will be shown regardless if child of <SvelteFlowFlow />
|
||||
*/
|
||||
export function derivedWarning(functionName: string, force?: boolean) {
|
||||
export function derivedWarning(functionName: string) {
|
||||
const storeContext = getContext<StoreContext>(key);
|
||||
|
||||
if (!storeContext) {
|
||||
@@ -18,7 +18,7 @@ export function derivedWarning(functionName: string, force?: boolean) {
|
||||
);
|
||||
}
|
||||
|
||||
if ((force || storeContext.provider) && !$effect.tracking()) {
|
||||
if (storeContext.provider && typeof window === 'object' && !$effect.tracking()) {
|
||||
console.warn(`Use $derived(${functionName}()) to receive updates when values change.`);
|
||||
console.trace(functionName);
|
||||
}
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
import { areConnectionMapsEqual, type HandleConnection, type HandleType } from '@xyflow/system';
|
||||
|
||||
import { useStore } from '$lib/store';
|
||||
import { getContext } from 'svelte';
|
||||
|
||||
export type useHandleConnectionsParams = {
|
||||
type: HandleType;
|
||||
nodeId?: string;
|
||||
id?: string | null;
|
||||
};
|
||||
|
||||
const initialConnections: HandleConnection[] = [];
|
||||
|
||||
/**
|
||||
* Hook to check if a <Handle /> is connected to another <Handle /> and get the connections.
|
||||
*
|
||||
* @public
|
||||
* @param param.nodeId
|
||||
* @param param.type - handle type 'source' or 'target'
|
||||
* @param param.id - the handle id (this is only needed if the node has multiple handles of the same type)
|
||||
* @returns an array with connections
|
||||
*/
|
||||
export function useHandleConnections({
|
||||
type,
|
||||
nodeId: _nodeId,
|
||||
id = null
|
||||
}: useHandleConnectionsParams) {
|
||||
const { edges, connectionLookup } = $derived(useStore());
|
||||
|
||||
const contextNodeId = getContext<string>('svelteflow__node_id');
|
||||
const nodeId = _nodeId ?? contextNodeId;
|
||||
|
||||
let prevConnections: Map<string, HandleConnection> | undefined = new Map();
|
||||
let connectionsArray: HandleConnection[] = initialConnections;
|
||||
|
||||
const connections = $derived.by(() => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
||||
edges;
|
||||
const nextConnections = connectionLookup.get(`${nodeId}-${type}-${id || null}`);
|
||||
if (!areConnectionMapsEqual(nextConnections, prevConnections)) {
|
||||
prevConnections = nextConnections;
|
||||
connectionsArray = Array.from(nextConnections?.values() || initialConnections);
|
||||
}
|
||||
return connectionsArray;
|
||||
});
|
||||
|
||||
return {
|
||||
get current() {
|
||||
return connections;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
import { areConnectionMapsEqual, type NodeConnection, type HandleType } from '@xyflow/system';
|
||||
|
||||
import { useStore } from '$lib/store';
|
||||
import { getContext } from 'svelte';
|
||||
|
||||
type UseNodeConnectionsParams = {
|
||||
type?: HandleType;
|
||||
handleId?: string;
|
||||
nodeId?: string;
|
||||
// TODO: Svelte 5
|
||||
// onConnect?: (connections: Connection[]) => void;
|
||||
// onDisconnect?: (connections: Connection[]) => void;
|
||||
};
|
||||
|
||||
const initialConnections: NodeConnection[] = [];
|
||||
|
||||
/**
|
||||
* Hook to retrieve all edges connected to a node. Can be filtered by handle type and id.
|
||||
*
|
||||
* @public
|
||||
* @param param.nodeId - node id - optional if called inside a custom node
|
||||
* @param param.type - filter by handle type 'source' or 'target'
|
||||
* @param param.handleId - filter by handle id (this is only needed if the node has multiple handles of the same type)
|
||||
* @todo @param param.onConnect - gets called when a connection is established
|
||||
* @todo @param param.onDisconnect - gets called when a connection is removed
|
||||
* @returns an array with connections
|
||||
*/
|
||||
export function useNodeConnections({
|
||||
type,
|
||||
nodeId: _nodeId,
|
||||
handleId
|
||||
}: UseNodeConnectionsParams = {}) {
|
||||
const { edges, connectionLookup } = $derived(useStore());
|
||||
|
||||
const contextNodeId = getContext<string>('svelteflow__node_id');
|
||||
const nodeId = _nodeId ?? contextNodeId;
|
||||
|
||||
let prevConnections: Map<string, NodeConnection> | undefined = new Map();
|
||||
let connectionsArray: NodeConnection[] = initialConnections;
|
||||
|
||||
const connections = $derived.by(() => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
||||
edges;
|
||||
const nextConnections = connectionLookup.get(
|
||||
`${nodeId}-${type}${handleId ? `-${handleId}` : ''}`
|
||||
);
|
||||
if (!areConnectionMapsEqual(nextConnections, prevConnections)) {
|
||||
prevConnections = nextConnections;
|
||||
connectionsArray = Array.from(nextConnections?.values() || initialConnections);
|
||||
}
|
||||
return connectionsArray;
|
||||
});
|
||||
|
||||
return {
|
||||
get current() {
|
||||
return connections;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -35,7 +35,7 @@ export * from '$lib/hooks/useSvelteFlow.svelte';
|
||||
export * from '$lib/hooks/useUpdateNodeInternals.svelte';
|
||||
export * from '$lib/hooks/useConnection.svelte';
|
||||
export * from '$lib/hooks/useNodesEdgesViewport.svelte';
|
||||
export * from '$lib/hooks/useHandleConnections.svelte';
|
||||
export * from '$lib/hooks/useNodeConnections.svelte';
|
||||
export * from '$lib/hooks/useNodesData.svelte';
|
||||
export * from '$lib/hooks/useInternalNode.svelte';
|
||||
export { useInitialized, useNodesInitialized } from '$lib/hooks/useInitialized.svelte';
|
||||
|
||||
Reference in New Issue
Block a user