-
+
-
+
@@ -249,8 +244,8 @@ export default {
-
-
+
+
diff --git a/src/store/actions.ts b/src/store/actions.ts
new file mode 100644
index 00000000..c8165d29
--- /dev/null
+++ b/src/store/actions.ts
@@ -0,0 +1,169 @@
+import microDiff from 'microdiff'
+import { Elements, FlowActions, FlowGetters, FlowState } from '~/types'
+import { getConnectedEdges, getNodesInside, getRectOfNodes, parseElements, processElements } from '~/utils'
+
+export default (state: FlowState, getters: FlowGetters): FlowActions => {
+ const setElements: FlowActions['setElements'] = async (elements, force = true) => {
+ const { nodes, edges } = parseElements(elements, state.elements, state.nodeExtent)
+ if (force) state.elements = []
+ await processElements([...nodes, ...edges], (processed) => {
+ state.elements = [...state.elements, ...processed]
+ })
+ state.hooks.elementsProcessed.trigger(state.elements)
+ }
+ const setUserSelection: FlowActions['setUserSelection'] = (mousePos) => {
+ state.selectionActive = true
+ state.userSelectionRect = {
+ width: 0,
+ height: 0,
+ startX: mousePos.x,
+ startY: mousePos.y,
+ x: mousePos.x,
+ y: mousePos.y,
+ draw: true,
+ }
+ }
+ const updateUserSelection: FlowActions['updateUserSelection'] = (mousePos) => {
+ const startX = state.userSelectionRect.startX
+ const startY = state.userSelectionRect.startY
+
+ const nextUserSelectRect: FlowState['userSelectionRect'] = {
+ ...state.userSelectionRect,
+ x: mousePos.x < startX ? mousePos.x : state.userSelectionRect.x,
+ y: mousePos.y < startY ? mousePos.y : state.userSelectionRect.y,
+ width: Math.abs(mousePos.x - startX),
+ height: Math.abs(mousePos.y - startY),
+ }
+ const selectedNodes = getNodesInside(getters.getNodes.value, state.userSelectionRect, state.transform)
+ const selectedEdges = getConnectedEdges(selectedNodes, getters.getEdges.value)
+
+ const nextSelectedElements = [...selectedNodes, ...selectedEdges]
+ state.userSelectionRect = nextUserSelectRect
+ state.selectedElements = nextSelectedElements
+ }
+ const unsetUserSelection: FlowActions['unsetUserSelection'] = () => {
+ state.selectionActive = false
+ state.userSelectionRect.draw = false
+
+ if (!getters.getSelectedNodes || getters.getSelectedNodes.value.length === 0) {
+ state.selectedElements = undefined
+ state.hooks.selectionChange.trigger(undefined)
+ state.nodesSelectionActive = false
+ } else {
+ state.selectedNodesBbox = getRectOfNodes(getters.getSelectedNodes.value)
+ state.nodesSelectionActive = true
+ }
+ }
+ const addSelectedElements: FlowActions['addSelectedElements'] = (elements: any) => {
+ const selectedElementsArr = Array.isArray(elements) ? elements : [elements]
+ const selectedElementsUpdated = microDiff(selectedElementsArr, state.selectedElements ?? []).length
+ state.selectedElements = selectedElementsUpdated ? selectedElementsArr : state.selectedElements
+ if (selectedElementsUpdated) state.hooks.selectionChange.trigger(selectedElementsArr)
+ }
+ const initD3Zoom: FlowActions['initD3Zoom'] = ({ d3ZoomHandler, d3Zoom, d3Selection }) => {
+ state.d3Zoom = d3Zoom
+ state.d3Selection = d3Selection
+ state.d3ZoomHandler = d3ZoomHandler
+ }
+ const setMinZoom: FlowActions['setMinZoom'] = (minZoom: any) => {
+ state.d3Zoom?.scaleExtent([minZoom, state.maxZoom])
+ state.minZoom = minZoom
+ }
+ const setMaxZoom: FlowActions['setMaxZoom'] = (maxZoom: any) => {
+ state.d3Zoom?.scaleExtent([state.minZoom, maxZoom])
+ state.maxZoom = maxZoom
+ }
+ const setTranslateExtent: FlowActions['setTranslateExtent'] = (translateExtent: any) => {
+ state.d3Zoom?.translateExtent(translateExtent)
+ state.translateExtent = translateExtent
+ }
+ const resetSelectedElements: FlowActions['resetSelectedElements'] = () => {
+ state.selectedElements = undefined
+ }
+ const unsetNodesSelection: FlowActions['unsetNodesSelection'] = () => {
+ state.nodesSelectionActive = false
+ }
+ const updateSize: FlowActions['updateSize'] = (size) => {
+ state.dimensions = size
+ }
+ const setConnectionNodeId: FlowActions['setConnectionNodeId'] = ({
+ connectionHandleId,
+ connectionHandleType,
+ connectionNodeId,
+ }) => {
+ state.connectionNodeId = connectionNodeId
+ state.connectionHandleId = connectionHandleId
+ state.connectionHandleType = connectionHandleType
+ }
+ const setInteractive: FlowActions['setInteractive'] = (isInteractive) => {
+ state.nodesDraggable = isInteractive
+ state.nodesConnectable = isInteractive
+ state.elementsSelectable = isInteractive
+ }
+ const addElements: FlowActions['addElements'] = (elements: Elements) => {
+ setElements(elements, false)
+ }
+ const setState: FlowActions['setState'] = (newState) => {
+ if (typeof newState.loading !== 'undefined') state.loading = newState.loading
+ if (typeof newState.panOnScroll !== 'undefined') state.panOnScroll = newState.panOnScroll
+ if (typeof newState.panOnScrollMode !== 'undefined') state.panOnScrollMode = newState.panOnScrollMode
+ if (typeof newState.panOnScrollSpeed !== 'undefined') state.panOnScrollSpeed = newState.panOnScrollSpeed
+ if (typeof newState.paneMoveable !== 'undefined') state.paneMoveable = newState.paneMoveable
+ if (typeof newState.zoomOnScroll !== 'undefined') state.zoomOnScroll = newState.zoomOnScroll
+ if (typeof newState.preventScrolling !== 'undefined') state.preventScrolling = newState.preventScrolling
+ if (typeof newState.zoomOnDoubleClick !== 'undefined') state.zoomOnDoubleClick = newState.zoomOnDoubleClick
+ if (typeof newState.zoomOnPinch !== 'undefined') state.zoomOnPinch = newState.zoomOnPinch
+ if (typeof newState.defaultZoom !== 'undefined') state.defaultZoom = newState.defaultZoom
+ if (typeof newState.defaultPosition !== 'undefined') state.defaultPosition = newState.defaultPosition
+ if (typeof newState.edgeTypes !== 'undefined') state.edgeTypes = newState.edgeTypes
+ if (typeof newState.nodeTypes !== 'undefined') state.nodeTypes = newState.nodeTypes
+ if (typeof newState.storageKey !== 'undefined') state.storageKey = newState.storageKey
+ if (typeof newState.edgeUpdaterRadius !== 'undefined') state.edgeUpdaterRadius = newState.edgeUpdaterRadius
+ if (typeof newState.elementsSelectable !== 'undefined') state.elementsSelectable = newState.elementsSelectable
+ if (typeof newState.onlyRenderVisibleElements !== 'undefined')
+ state.onlyRenderVisibleElements = newState.onlyRenderVisibleElements
+ if (typeof newState.edgesUpdatable !== 'undefined') state.edgesUpdatable = newState.edgesUpdatable
+ if (typeof newState.nodesConnectable !== 'undefined') state.nodesConnectable = newState.nodesConnectable
+ if (typeof newState.nodesDraggable !== 'undefined') state.nodesDraggable = newState.nodesDraggable
+ if (typeof newState.arrowHeadColor !== 'undefined') state.arrowHeadColor = newState.arrowHeadColor
+ if (typeof newState.markerEndId !== 'undefined') state.markerEndId = newState.markerEndId
+ if (typeof newState.deleteKeyCode !== 'undefined') state.deleteKeyCode = newState.deleteKeyCode
+ if (typeof newState.selectionKeyCode !== 'undefined') state.selectionKeyCode = newState.selectionKeyCode
+ if (typeof newState.zoomActivationKeyCode !== 'undefined') state.zoomActivationKeyCode = newState.zoomActivationKeyCode
+ if (typeof newState.multiSelectionKeyCode !== 'undefined') state.multiSelectionKeyCode = newState.multiSelectionKeyCode
+ if (typeof newState.snapToGrid !== 'undefined') state.snapToGrid = newState.snapToGrid
+ if (typeof newState.snapGrid !== 'undefined') state.snapGrid = newState.snapGrid
+ if (typeof newState.nodeExtent !== 'undefined') state.nodeExtent = newState.nodeExtent
+ if (!state.isReady)
+ until(() => state.d3Zoom)
+ .not.toBeUndefined()
+ .then(() => {
+ if (typeof newState.maxZoom !== 'undefined') setMaxZoom(newState.maxZoom)
+ if (typeof newState.minZoom !== 'undefined') setMinZoom(newState.minZoom)
+ if (typeof newState.translateExtent !== 'undefined') setTranslateExtent(newState.translateExtent)
+ })
+ else {
+ if (typeof newState.maxZoom !== 'undefined') setMaxZoom(newState.maxZoom)
+ if (typeof newState.minZoom !== 'undefined') setMinZoom(newState.minZoom)
+ if (typeof newState.translateExtent !== 'undefined') setTranslateExtent(newState.translateExtent)
+ }
+ }
+ return {
+ setElements,
+ setUserSelection,
+ updateUserSelection,
+ unsetUserSelection,
+ addSelectedElements,
+ initD3Zoom,
+ setMinZoom,
+ setMaxZoom,
+ setTranslateExtent,
+ resetSelectedElements,
+ unsetNodesSelection,
+ updateSize,
+ setConnectionNodeId,
+ setInteractive,
+ addElements,
+ setState,
+ }
+}
diff --git a/src/store/getters.ts b/src/store/getters.ts
new file mode 100644
index 00000000..cfcac746
--- /dev/null
+++ b/src/store/getters.ts
@@ -0,0 +1,73 @@
+import { FlowGetters, FlowState, GraphEdge, GraphNode } from '~/types'
+import { defaultEdgeTypes, defaultNodeTypes, getNodesInside, getSourceTargetNodes, isEdge, isGraphNode } from '~/utils'
+
+export default (state: FlowState): FlowGetters => {
+ const getEdgeTypes = computed(() => {
+ const edgeTypes: Record = {
+ ...defaultEdgeTypes,
+ }
+ state.edgeTypes?.forEach((n) => (edgeTypes[n] = n))
+ return edgeTypes
+ })
+
+ const getNodeTypes = computed(() => {
+ const nodeTypes: Record = {
+ ...defaultNodeTypes,
+ }
+ state.nodeTypes?.forEach((n) => (nodeTypes[n] = n))
+ return nodeTypes
+ })
+
+ const getNodes = computed(() => {
+ if (state.isReady) {
+ const nodes = state.elements.filter((n) => isGraphNode(n) && !n.isHidden) as GraphNode[]
+ return state.onlyRenderVisibleElements
+ ? nodes &&
+ getNodesInside(
+ nodes,
+ {
+ x: 0,
+ y: 0,
+ width: state.dimensions.width,
+ height: state.dimensions.height,
+ },
+ state.transform,
+ true,
+ )
+ : nodes ?? []
+ }
+ return []
+ })
+
+ const getEdges = computed(() => {
+ const edges = state.elements.filter((e) => isEdge(e) && !e.isHidden) as GraphEdge[]
+ if (state.isReady) {
+ return (
+ edges
+ .map((edge) => {
+ const { sourceNode, targetNode } = getSourceTargetNodes(edge, getNodes.value)
+ if (!sourceNode) console.warn(`couldn't create edge for source id: ${edge.source}; edge id: ${edge.id}`)
+ if (!targetNode) console.warn(`couldn't create edge for target id: ${edge.target}; edge id: ${edge.id}`)
+
+ return {
+ ...edge,
+ sourceNode,
+ targetNode,
+ }
+ })
+ .filter(({ sourceNode, targetNode }) => !!(sourceNode && targetNode)) ?? []
+ )
+ }
+ return []
+ })
+
+ const getSelectedNodes = computed(() => state.selectedElements?.filter(isGraphNode) ?? [])
+
+ return {
+ getEdgeTypes,
+ getNodeTypes,
+ getEdges,
+ getNodes,
+ getSelectedNodes,
+ }
+}
diff --git a/src/store/index.ts b/src/store/index.ts
index 7431fd5a..f1689b55 100644
--- a/src/store/index.ts
+++ b/src/store/index.ts
@@ -1 +1 @@
-export { default as useStateStore } from './stateStore'
+export { default as useNewStore } from './store'
diff --git a/src/store/state.ts b/src/store/state.ts
new file mode 100644
index 00000000..561c1eaa
--- /dev/null
+++ b/src/store/state.ts
@@ -0,0 +1,5 @@
+import { FlowState } from '~/types'
+
+export default (preloadedState: FlowState) => ({
+ ...preloadedState,
+})
diff --git a/src/store/stateStore.ts b/src/store/stateStore.ts
deleted file mode 100644
index 97f8f0c3..00000000
--- a/src/store/stateStore.ts
+++ /dev/null
@@ -1,241 +0,0 @@
-import microDiff from 'microdiff'
-import { setActivePinia, createPinia, defineStore, StoreDefinition, acceptHMRUpdate, getActivePinia } from 'pinia'
-import { FlowState, FlowActions, Elements, FlowGetters, GraphNode, GraphEdge } from '~/types'
-import {
- getConnectedEdges,
- getNodesInside,
- getRectOfNodes,
- defaultNodeTypes,
- defaultEdgeTypes,
- isGraphNode,
- getSourceTargetNodes,
- isEdge,
- parseElements,
- processElements,
-} from '~/utils'
-
-const pinia = createPinia()
-
-export default (id: string, preloadedState: FlowState) => {
- setActivePinia(getActivePinia() ?? pinia)
-
- const store: StoreDefinition = defineStore({
- id: id ?? 'vue-flow',
- state: () => ({
- ...preloadedState,
- }),
- getters: {
- getEdgeTypes() {
- const edgeTypes: Record = {
- ...defaultEdgeTypes,
- }
- this.edgeTypes?.forEach((n) => (edgeTypes[n] = n))
- return edgeTypes
- },
- getNodeTypes() {
- const nodeTypes: Record = {
- ...defaultNodeTypes,
- }
- this.nodeTypes?.forEach((n) => (nodeTypes[n] = n))
- return nodeTypes
- },
- getNodes(): GraphNode[] {
- if (this.isReady) {
- const nodes = this.elements.filter((n) => isGraphNode(n) && !n.isHidden) as GraphNode[]
- return this.onlyRenderVisibleElements
- ? nodes &&
- getNodesInside(
- nodes,
- {
- x: 0,
- y: 0,
- width: this.dimensions.width,
- height: this.dimensions.height,
- },
- this.transform,
- true,
- )
- : nodes ?? []
- }
- return []
- },
- getEdges(): GraphEdge[] {
- const edges = this.elements.filter((e) => isEdge(e) && !e.isHidden) as GraphEdge[]
- if (this.isReady) {
- return (
- edges
- .map((edge) => {
- const { sourceNode, targetNode } = getSourceTargetNodes(edge, this.getNodes)
- if (!sourceNode) console.warn(`couldn't create edge for source id: ${edge.source}; edge id: ${edge.id}`)
- if (!targetNode) console.warn(`couldn't create edge for target id: ${edge.target}; edge id: ${edge.id}`)
-
- return {
- ...edge,
- sourceNode,
- targetNode,
- }
- })
- .filter(({ sourceNode, targetNode }) => !!(sourceNode && targetNode)) ?? []
- )
- }
- return []
- },
- getSelectedNodes(): GraphNode[] {
- return this.selectedElements?.filter(isGraphNode) ?? []
- },
- },
- actions: {
- async setElements(elements, force = true) {
- const { nodes, edges } = parseElements(elements, this.elements, this.nodeExtent)
- if (force) this.elements = []
- await processElements([...nodes, ...edges], (processed) => {
- this.elements = [...this.elements, ...processed]
- })
- this.hooks.elementsProcessed.trigger(this.elements)
- },
- setUserSelection(mousePos) {
- this.selectionActive = true
- this.userSelectionRect = {
- width: 0,
- height: 0,
- startX: mousePos.x,
- startY: mousePos.y,
- x: mousePos.x,
- y: mousePos.y,
- draw: true,
- }
- },
- updateUserSelection(mousePos) {
- const startX = this.userSelectionRect.startX
- const startY = this.userSelectionRect.startY
-
- const nextUserSelectRect: FlowState['userSelectionRect'] = {
- ...this.userSelectionRect,
- x: mousePos.x < startX ? mousePos.x : this.userSelectionRect.x,
- y: mousePos.y < startY ? mousePos.y : this.userSelectionRect.y,
- width: Math.abs(mousePos.x - startX),
- height: Math.abs(mousePos.y - startY),
- }
- const selectedNodes = getNodesInside(this.getNodes, this.userSelectionRect, this.transform)
- const selectedEdges = getConnectedEdges(selectedNodes, this.getEdges)
-
- const nextSelectedElements = [...selectedNodes, ...selectedEdges]
- this.userSelectionRect = nextUserSelectRect
- this.selectedElements = nextSelectedElements
- },
- unsetUserSelection() {
- this.selectionActive = false
- this.userSelectionRect.draw = false
-
- if (!this.getSelectedNodes || this.getSelectedNodes.length === 0) {
- this.selectedElements = undefined
- this.hooks.selectionChange.trigger(undefined)
- this.nodesSelectionActive = false
- } else {
- this.selectedNodesBbox = getRectOfNodes(this.getSelectedNodes)
- this.nodesSelectionActive = true
- }
- },
- addSelectedElements(elements) {
- const selectedElementsArr = Array.isArray(elements) ? elements : [elements]
- const selectedElementsUpdated = microDiff(selectedElementsArr, this.selectedElements ?? []).length
- this.selectedElements = selectedElementsUpdated ? selectedElementsArr : this.selectedElements
- if (selectedElementsUpdated) this.hooks.selectionChange.trigger(selectedElementsArr)
- },
- initD3Zoom({ d3ZoomHandler, d3Zoom, d3Selection }) {
- this.d3Zoom = d3Zoom
- this.d3Selection = d3Selection
- this.d3ZoomHandler = d3ZoomHandler
- },
- setMinZoom(minZoom) {
- this.d3Zoom?.scaleExtent([minZoom, this.maxZoom])
- this.minZoom = minZoom
- },
- setMaxZoom(maxZoom) {
- this.d3Zoom?.scaleExtent([this.minZoom, maxZoom])
- this.maxZoom = maxZoom
- },
- setTranslateExtent(translateExtent) {
- this.d3Zoom?.translateExtent(translateExtent)
- this.translateExtent = translateExtent
- },
- setNodeExtent(nodeExtent) {
- this.nodeExtent = nodeExtent
- },
- resetSelectedElements() {
- this.selectedElements = undefined
- },
- unsetNodesSelection() {
- this.nodesSelectionActive = false
- },
- updateSize(size) {
- this.dimensions = size
- },
- setConnectionNodeId({ connectionHandleId, connectionHandleType, connectionNodeId }) {
- this.connectionNodeId = connectionNodeId
- this.connectionHandleId = connectionHandleId
- this.connectionHandleType = connectionHandleType
- },
- setInteractive(isInteractive) {
- this.nodesDraggable = isInteractive
- this.nodesConnectable = isInteractive
- this.elementsSelectable = isInteractive
- },
- addElements(elements: Elements) {
- this.setElements(elements, false)
- },
- setState(state) {
- if (typeof state.loading !== 'undefined') this.loading = state.loading
- if (typeof state.panOnScroll !== 'undefined') this.panOnScroll = state.panOnScroll
- if (typeof state.panOnScrollMode !== 'undefined') this.panOnScrollMode = state.panOnScrollMode
- if (typeof state.panOnScrollSpeed !== 'undefined') this.panOnScrollSpeed = state.panOnScrollSpeed
- if (typeof state.paneMoveable !== 'undefined') this.paneMoveable = state.paneMoveable
- if (typeof state.zoomOnScroll !== 'undefined') this.zoomOnScroll = state.zoomOnScroll
- if (typeof state.preventScrolling !== 'undefined') this.preventScrolling = state.preventScrolling
- if (typeof state.zoomOnDoubleClick !== 'undefined') this.zoomOnDoubleClick = state.zoomOnDoubleClick
- if (typeof state.zoomOnPinch !== 'undefined') this.zoomOnPinch = state.zoomOnPinch
- if (typeof state.defaultZoom !== 'undefined') this.defaultZoom = state.defaultZoom
- if (typeof state.defaultPosition !== 'undefined') this.defaultPosition = state.defaultPosition
- if (typeof state.edgeTypes !== 'undefined') this.edgeTypes = state.edgeTypes
- if (typeof state.nodeTypes !== 'undefined') this.nodeTypes = state.nodeTypes
- if (typeof state.storageKey !== 'undefined') this.storageKey = state.storageKey
- if (typeof state.edgeUpdaterRadius !== 'undefined') this.edgeUpdaterRadius = state.edgeUpdaterRadius
- if (typeof state.elementsSelectable !== 'undefined') this.elementsSelectable = state.elementsSelectable
- if (typeof state.onlyRenderVisibleElements !== 'undefined')
- this.onlyRenderVisibleElements = state.onlyRenderVisibleElements
- if (typeof state.edgesUpdatable !== 'undefined') this.edgesUpdatable = state.edgesUpdatable
- if (typeof state.nodesConnectable !== 'undefined') this.nodesConnectable = state.nodesConnectable
- if (typeof state.nodesDraggable !== 'undefined') this.nodesDraggable = state.nodesDraggable
- if (typeof state.arrowHeadColor !== 'undefined') this.arrowHeadColor = state.arrowHeadColor
- if (typeof state.markerEndId !== 'undefined') this.markerEndId = state.markerEndId
- if (typeof state.deleteKeyCode !== 'undefined') this.deleteKeyCode = state.deleteKeyCode
- if (typeof state.selectionKeyCode !== 'undefined') this.selectionKeyCode = state.selectionKeyCode
- if (typeof state.zoomActivationKeyCode !== 'undefined') this.zoomActivationKeyCode = state.zoomActivationKeyCode
- if (typeof state.multiSelectionKeyCode !== 'undefined') this.multiSelectionKeyCode = state.multiSelectionKeyCode
- if (typeof state.snapToGrid !== 'undefined') this.snapToGrid = state.snapToGrid
- if (typeof state.snapGrid !== 'undefined') this.snapGrid = state.snapGrid
- if (!this.isReady)
- until(() => this.d3Zoom)
- .not.toBeUndefined()
- .then(() => {
- if (typeof state.maxZoom !== 'undefined') this.setMaxZoom(state.maxZoom)
- if (typeof state.minZoom !== 'undefined') this.setMinZoom(state.minZoom)
- if (typeof state.translateExtent !== 'undefined') this.setTranslateExtent(state.translateExtent)
- if (typeof state.nodeExtent !== 'undefined') this.setNodeExtent(state.nodeExtent)
- })
- else {
- if (typeof state.maxZoom !== 'undefined') this.setMaxZoom(state.maxZoom)
- if (typeof state.minZoom !== 'undefined') this.setMinZoom(state.minZoom)
- if (typeof state.translateExtent !== 'undefined') this.setTranslateExtent(state.translateExtent)
- if (typeof state.nodeExtent !== 'undefined') this.setNodeExtent(state.nodeExtent)
- }
- },
- },
- })
-
- if (import.meta.hot) {
- import.meta.hot.accept(acceptHMRUpdate(store, import.meta.hot))
- }
-
- return store
-}
diff --git a/src/store/store.ts b/src/store/store.ts
new file mode 100644
index 00000000..b50f25aa
--- /dev/null
+++ b/src/store/store.ts
@@ -0,0 +1,16 @@
+import useState from './state'
+import useActions from './actions'
+import useGetters from './getters'
+import { FlowState, FlowStore } from '~/types'
+
+export default (id: string, preloadedState: FlowState): FlowStore => {
+ const state = reactive(useState(preloadedState))
+ const getters = useGetters(state)
+ const actions = useActions(state, getters)
+ return {
+ state,
+ ...toRefs(state),
+ ...getters,
+ ...actions,
+ }
+}
diff --git a/src/types/connection.ts b/src/types/connection.ts
index 70651f97..2e74a558 100644
--- a/src/types/connection.ts
+++ b/src/types/connection.ts
@@ -32,9 +32,6 @@ export type OnConnectStartParams = {
handleId?: ElementId
handleType?: HandleType
}
-export type OnConnectStartFunc = (event: MouseEvent, params: OnConnectStartParams) => void
-export type OnConnectStopFunc = (event: MouseEvent) => void
-export type OnConnectEndFunc = (event: MouseEvent) => void
export enum ConnectionMode {
Strict = 'strict',
diff --git a/src/types/store.ts b/src/types/store.ts
index 63a91052..f12848d9 100644
--- a/src/types/store.ts
+++ b/src/types/store.ts
@@ -1,4 +1,5 @@
-import { Store } from 'pinia'
+import { ComputedRef, ToRefs } from 'vue'
+import { UnwrapNestedRefs } from '@vue/reactivity'
import {
Dimensions,
ElementId,
@@ -13,14 +14,7 @@ import {
XYPosition,
} from './flow'
import { HandleType, EdgeComponent, NodeComponent } from './components'
-import {
- ConnectionMode,
- OnConnectEndFunc,
- OnConnectFunc,
- OnConnectStartFunc,
- OnConnectStopFunc,
- SetConnectionId,
-} from './connection'
+import { ConnectionMode, SetConnectionId } from './connection'
import { GraphEdge } from './edge'
import { NodeExtent, GraphNode, TranslateExtent } from './node'
import { D3Selection, D3Zoom, D3ZoomHandler, InitD3ZoomPayload } from './zoom'
@@ -28,13 +22,13 @@ import { FlowHooks } from './hooks'
export interface FlowState extends Omit {
hooks: FlowHooks
- instance?: FlowInstance
+ instance: FlowInstance | undefined
elements: FlowElements
- d3Zoom?: D3Zoom
- d3Selection?: D3Selection
- d3ZoomHandler?: D3ZoomHandler
+ d3Zoom: D3Zoom | undefined
+ d3Selection: D3Selection | undefined
+ d3ZoomHandler: D3ZoomHandler | undefined
minZoom: number
maxZoom: number
translateExtent: TranslateExtent
@@ -42,16 +36,16 @@ export interface FlowState extends Omit {
dimensions: Dimensions
transform: Transform
- selectedElements?: FlowElements
- selectedNodesBbox?: Rect
+ selectedElements: FlowElements | undefined
+ selectedNodesBbox: Rect | undefined
nodesSelectionActive: boolean
selectionActive: boolean
userSelectionRect: SelectionRect
multiSelectionActive: boolean
- connectionNodeId?: ElementId
- connectionHandleId?: ElementId
- connectionHandleType?: HandleType
+ connectionNodeId: ElementId | undefined
+ connectionHandleId: ElementId | undefined
+ connectionHandleType: HandleType | undefined
connectionPosition: XYPosition
connectionMode: ConnectionMode
@@ -63,11 +57,6 @@ export interface FlowState extends Omit {
nodesConnectable: boolean
elementsSelectable: boolean
- onConnect?: OnConnectFunc
- onConnectStart?: OnConnectStartFunc
- onConnectStop?: OnConnectStopFunc
- onConnectEnd?: OnConnectEndFunc
-
isReady: boolean
vueFlowVersion: string
@@ -83,22 +72,22 @@ export interface FlowActions {
setMinZoom: (zoom: number) => void
setMaxZoom: (zoom: number) => void
setTranslateExtent: (translateExtent: TranslateExtent) => void
- setNodeExtent: (nodeExtent: NodeExtent) => void
resetSelectedElements: () => void
unsetNodesSelection: () => void
updateSize: (size: Dimensions) => void
setConnectionNodeId: (payload: SetConnectionId) => void
setInteractive: (isInteractive: boolean) => void
addElements: (elements: Elements) => void
- setState: (state: FlowOptions) => void
+ setState: (state: Partial) => void
}
export interface FlowGetters {
- getEdgeTypes: () => Record
- getNodeTypes: () => Record
- getNodes: () => GraphNode[]
- getEdges: () => GraphEdge[]
- getSelectedNodes: () => GraphNode[]
+ getEdgeTypes: ComputedRef>
+ getNodeTypes: ComputedRef>
+ getNodes: ComputedRef
+ getEdges: ComputedRef
+ getSelectedNodes: ComputedRef
}
-export type FlowStore = Store
+export type FlowStore = { state: FlowState } & ToRefs & FlowActions & FlowGetters
+export type ReactiveFlowStore = UnwrapNestedRefs
diff --git a/src/utils/edge.ts b/src/utils/edge.ts
index 9843edfc..ccbec3f8 100644
--- a/src/utils/edge.ts
+++ b/src/utils/edge.ts
@@ -15,8 +15,8 @@ import {
export function getHandlePosition(position: Position, node: GraphNode, handle?: HandleElement): XYPosition {
const x = (handle?.x ?? 0) + node.position.x
const y = (handle?.y ?? 0) + node.position.y
- const width = handle?.width || node.__vf.width
- const height = handle?.height || node.__vf.height
+ const width = handle?.width ?? node.__vf.width
+ const height = handle?.height ?? node.__vf.height
switch (position) {
case Position.Top:
@@ -48,7 +48,7 @@ export function getHandle(bounds: HandleElement[], handleId?: ElementId): Handle
// there is no handleId when there are no multiple handles/ handles with ids
// so we just pick the first one
let handle
- if (bounds.length === 1 || !handleId) {
+ if (bounds.length === 1 ?? !handleId) {
handle = bounds[0]
} else if (handleId) {
handle = bounds.find((d) => d.id === handleId)
diff --git a/src/utils/graph.ts b/src/utils/graph.ts
index 7608f9f1..837ca704 100644
--- a/src/utils/graph.ts
+++ b/src/utils/graph.ts
@@ -16,6 +16,8 @@ import {
FlowElements,
GraphEdge,
NextElements,
+ ReactiveFlowStore,
+ FlowState,
} from '~/types'
import { useWindow } from '~/composables'
import { getSourceTargetNodes } from '~/utils/edge'
@@ -161,7 +163,7 @@ export const pointToRendererPoint = (
return position
}
-export const onLoadProject = (currentStore: FlowStore) => (position: XYPosition) =>
+export const onLoadProject = (currentStore: ReactiveFlowStore) => (position: XYPosition) =>
pointToRendererPoint(position, currentStore.transform, currentStore.snapToGrid, currentStore.snapGrid)
export const parseNode = (node: Node, nodeExtent: NodeExtent): GraphNode => ({
@@ -276,9 +278,9 @@ export const getConnectedEdges = (nodes: GraphNode[], edges: GraphEdge[]) => {
return edges.filter((edge) => nodeIds.includes(edge.source) || nodeIds.includes(edge.target))
}
-export const onLoadGetElements = (currentStore: FlowStore) => (): FlowElements => currentStore.elements
+export const onLoadGetElements = (currentStore: ReactiveFlowStore) => (): FlowElements => currentStore.elements
-export const onLoadToObject = (currentStore: FlowStore) => (): FlowExportObject => {
+export const onLoadToObject = (currentStore: FlowState) => (): FlowExportObject => {
// we have to stringify/parse so objects containing refs (like nodes and edges) can potentially be saved in a storage
return JSON.parse(
JSON.stringify({
diff --git a/src/utils/store.ts b/src/utils/store.ts
index 8bdef8fd..8c358810 100644
--- a/src/utils/store.ts
+++ b/src/utils/store.ts
@@ -16,6 +16,8 @@ export const defaultEdgeTypes: DefaultEdgeTypes = {
}
export const initialState = (): FlowState => ({
+ isReady: false,
+ instance: undefined,
dimensions: {
width: 0,
height: 0,
@@ -50,6 +52,9 @@ export const initialState = (): FlowState => ({
panOnScrollMode: PanOnScrollMode.Free,
paneMoveable: true,
edgeUpdaterRadius: 10,
+ onlyRenderVisibleElements: undefined,
+ defaultZoom: undefined,
+ defaultPosition: undefined,
nodesSelectionActive: false,
selectionActive: false,
@@ -65,6 +70,8 @@ export const initialState = (): FlowState => ({
},
arrowHeadColor: '#b1b1b7',
+ connectionLineStyle: {},
+ connectionLineType: undefined,
connectionNodeId: undefined,
connectionHandleId: undefined,
connectionHandleType: 'source',
@@ -78,12 +85,18 @@ export const initialState = (): FlowState => ({
nodesDraggable: true,
nodesConnectable: true,
elementsSelectable: true,
-
+ selectNodesOnDrag: undefined,
multiSelectionActive: false,
+ deleteKeyCode: undefined,
+ selectionKeyCode: undefined,
+ multiSelectionKeyCode: undefined,
+ zoomActivationKeyCode: undefined,
- isReady: false,
hooks: createHooks(),
loading: false,
+ markerEndId: undefined,
+ storageKey: undefined,
+
vueFlowVersion: typeof __VUE_FLOW_VERSION__ !== 'undefined' ? __VUE_FLOW_VERSION__ : '-',
})