refactor(core): use node lookup map internally (#1450)

* refactor(core): use node lookup map internally

* chore(changeset): add
This commit is contained in:
Braks
2024-06-06 10:45:38 +02:00
parent faf67c2b55
commit a592fbd78a
5 changed files with 39 additions and 45 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"@vue-flow/core": minor
---
Replace internally nodeIds/edgeIds array with nodeLookup/edgeLookup map
+8 -16
View File
@@ -8,6 +8,7 @@ import type {
Edge, Edge,
EdgeAddChange, EdgeAddChange,
EdgeChange, EdgeChange,
EdgeLookup,
EdgeRemoveChange, EdgeRemoveChange,
EdgeSelectionChange, EdgeSelectionChange,
Elements, Elements,
@@ -18,6 +19,7 @@ import type {
NodeAddChange, NodeAddChange,
NodeChange, NodeChange,
NodeDimensionChange, NodeDimensionChange,
NodeLookup,
NodePositionChange, NodePositionChange,
NodeRemoveChange, NodeRemoveChange,
NodeSelectionChange, NodeSelectionChange,
@@ -55,15 +57,13 @@ import { storeOptionsToSkip, useState } from './state'
export function useActions( export function useActions(
id: string, id: string,
state: State, state: State,
// todo: change to a Set nodeLookup: ComputedRef<NodeLookup>,
nodeIds: ComputedRef<string[]>, edgeLookup: ComputedRef<EdgeLookup>,
// todo: change to a Set
edgeIds: ComputedRef<string[]>,
): Actions { ): Actions {
const viewportHelper = useViewportHelper(state) const viewportHelper = useViewportHelper(state)
const updateNodeInternals: Actions['updateNodeInternals'] = (ids) => { const updateNodeInternals: Actions['updateNodeInternals'] = (ids) => {
const updateIds = ids ?? nodeIds.value ?? [] const updateIds = ids ?? state.nodes.map((n) => n.id) ?? []
state.hooks.updateNodeInternals.trigger(updateIds) state.hooks.updateNodeInternals.trigger(updateIds)
} }
@@ -85,11 +85,7 @@ export function useActions(
return return
} }
if (state.nodes && !nodeIds.value.length) { return nodeLookup.value.get(id)
return state.nodes.find((node) => node.id === id)
}
return state.nodes[nodeIds.value.indexOf(id)]
} }
const findEdge: Actions['findEdge'] = (id) => { const findEdge: Actions['findEdge'] = (id) => {
@@ -97,11 +93,7 @@ export function useActions(
return return
} }
if (state.edges && !edgeIds.value.length) { return edgeLookup.value.get(id)
return state.edges.find((edge) => edge.id === id)
}
return state.edges[edgeIds.value.indexOf(id)]
} }
const updateNodePositions: Actions['updateNodePositions'] = (dragItems, changed, dragging) => { const updateNodePositions: Actions['updateNodePositions'] = (dragItems, changed, dragging) => {
@@ -370,7 +362,7 @@ export function useActions(
const setNodeExtent: Actions['setNodeExtent'] = (nodeExtent) => { const setNodeExtent: Actions['setNodeExtent'] = (nodeExtent) => {
state.nodeExtent = nodeExtent state.nodeExtent = nodeExtent
updateNodeInternals(nodeIds.value) updateNodeInternals()
} }
const setInteractive: Actions['setInteractive'] = (isInteractive) => { const setInteractive: Actions['setInteractive'] = (isInteractive) => {
+10 -18
View File
@@ -1,31 +1,23 @@
import type { ComputedRef } from 'vue' import type { ComputedRef } from 'vue'
import { computed } from 'vue' import { computed } from 'vue'
import type { ComputedGetters, GraphEdge, GraphNode, State } from '../types' import type { ComputedGetters, EdgeLookup, GraphEdge, GraphNode, NodeLookup, State } from '../types'
import { getNodesInside, isEdgeVisible } from '../utils' import { getNodesInside, isEdgeVisible } from '../utils'
import { defaultEdgeTypes, defaultNodeTypes } from '../utils/defaultNodesEdges' import { defaultEdgeTypes, defaultNodeTypes } from '../utils/defaultNodesEdges'
export function useGetters(state: State, nodeIds: ComputedRef<string[]>, edgeIds: ComputedRef<string[]>): ComputedGetters { export function useGetters(
state: State,
nodeLookup: ComputedRef<NodeLookup>,
edgeLookup: ComputedRef<EdgeLookup>,
): ComputedGetters {
/** /**
* @deprecated will be removed in next major version; use findNode instead * @deprecated will be removed in next major version; use findNode instead
*/ */
const getNode: ComputedGetters['getNode'] = computed(() => (id: string) => { const getNode: ComputedGetters['getNode'] = computed(() => (id) => nodeLookup.value.get(id))
if (state.nodes && !nodeIds.value.length) {
return state.nodes.find((node) => node.id === id)
}
return state.nodes[nodeIds.value.indexOf(id)]
})
/** /**
* @deprecated will be removed in next major version; use findEdge instead * @deprecated will be removed in next major version; use findEdge instead
*/ */
const getEdge: ComputedGetters['getEdge'] = computed(() => (id: string) => { const getEdge: ComputedGetters['getEdge'] = computed(() => (id) => edgeLookup.value.get(id))
if (state.edges && !edgeIds.value.length) {
return state.edges.find((edge) => edge.id === id)
}
return state.edges[edgeIds.value.indexOf(id)]
})
const getEdgeTypes: ComputedGetters['getEdgeTypes'] = computed(() => { const getEdgeTypes: ComputedGetters['getEdgeTypes'] = computed(() => {
const edgeTypes: Record<string, any> = { const edgeTypes: Record<string, any> = {
@@ -80,8 +72,8 @@ export function useGetters(state: State, nodeIds: ComputedRef<string[]>, edgeIds
const visibleEdges: GraphEdge[] = [] const visibleEdges: GraphEdge[] = []
for (const edge of state.edges) { for (const edge of state.edges) {
const source = getNode.value(edge.source)! const source = nodeLookup.value.get(edge.source)!
const target = getNode.value(edge.target)! const target = nodeLookup.value.get(edge.target)!
if ( if (
isEdgeVisible({ isEdgeVisible({
+4
View File
@@ -31,6 +31,10 @@ import type { CustomEvent, FlowHooks, FlowHooksEmit, FlowHooksOn } from './hooks
import type { EdgeChange, NodeChange, NodeDragItem } from './changes' import type { EdgeChange, NodeChange, NodeDragItem } from './changes'
import type { ConnectingHandle, ValidConnectionFunc } from './handle' import type { ConnectingHandle, ValidConnectionFunc } from './handle'
export type NodeLookup = Map<string, GraphNode>
export type EdgeLookup = Map<string, GraphEdge>
export interface UpdateNodeDimensionsParams { export interface UpdateNodeDimensionsParams {
id: string id: string
nodeElement: HTMLDivElement nodeElement: HTMLDivElement
+12 -11
View File
@@ -1,6 +1,6 @@
import { toRefs } from '@vueuse/core' import { toRefs } from '@vueuse/core'
import { computed, getCurrentInstance, reactive } from 'vue' import { computed, getCurrentInstance, reactive } from 'vue'
import type { FlowOptions, VueFlowStore } from '../types' import type { FlowOptions, GraphEdge, GraphNode, VueFlowStore } from '../types'
import { useActions, useGetters, useState } from '../store' import { useActions, useGetters, useState } from '../store'
/** /**
@@ -57,27 +57,28 @@ export class Storage {
} }
// for lookup purposes // for lookup purposes
const nodeIds = computed(() => { const nodeLookup = computed(() => {
const ids: string[] = [] const nodesMap = new Map<string, GraphNode>()
for (const node of reactiveState.nodes) { for (const node of reactiveState.nodes) {
ids.push(node.id) nodesMap.set(node.id, node)
} }
return ids return nodesMap
}) })
const edgeIds = computed(() => { const edgeLookup = computed(() => {
const ids: string[] = [] const edgesMap = new Map<string, GraphEdge>()
for (const edge of reactiveState.edges) { for (const edge of reactiveState.edges) {
ids.push(edge.id) edgesMap.set(edge.id, edge)
} }
return ids return edgesMap
}) })
const getters = useGetters(reactiveState, nodeIds, edgeIds) const getters = useGetters(reactiveState, nodeLookup, edgeLookup)
const actions = useActions(id, reactiveState, nodeIds, edgeIds) const actions = useActions(id, reactiveState, nodeLookup, edgeLookup)
actions.setState({ ...reactiveState, ...preloadedState }) actions.setState({ ...reactiveState, ...preloadedState })