From 4d5bbab50690fd8b2ab0072e4e69bd1ed5a4bce1 Mon Sep 17 00:00:00 2001 From: braks <78412429+bcakmakoglu@users.noreply.github.com> Date: Mon, 17 Jul 2023 22:10:03 +0200 Subject: [PATCH] fix(core): use noop viewport operations instead of waiting for promise --- packages/core/src/composables/useViewport.ts | 9 +- packages/core/src/composables/useVueFlow.ts | 14 +-- .../core/src/container/Viewport/Transform.vue | 17 +--- packages/core/src/store/actions.ts | 98 +++++++------------ 4 files changed, 46 insertions(+), 92 deletions(-) diff --git a/packages/core/src/composables/useViewport.ts b/packages/core/src/composables/useViewport.ts index 182ee316..636af28a 100644 --- a/packages/core/src/composables/useViewport.ts +++ b/packages/core/src/composables/useViewport.ts @@ -36,14 +36,7 @@ export function useViewport(state: State, getters: ComputedGetters) { nodesInitialized.value = true }) - const isReady = computed( - () => - !!d3Zoom && - !!d3Selection && - !!dimensions.width && - !!dimensions.height && - (getNodes.value.length ? nodesInitialized.value : true), - ) + const isReady = computed(() => !!d3Zoom && !!d3Selection && !!dimensions.width && !!dimensions.height && nodesInitialized.value) function zoom(scale: number, duration?: number) { if (d3Selection && d3Zoom) { diff --git a/packages/core/src/composables/useVueFlow.ts b/packages/core/src/composables/useVueFlow.ts index 74145fc7..25642b3f 100644 --- a/packages/core/src/composables/useVueFlow.ts +++ b/packages/core/src/composables/useVueFlow.ts @@ -39,13 +39,6 @@ export class Storage { const reactiveState = reactive(state) - const nodeIds = computed(() => reactiveState.nodes.map((n) => n.id)) - const edgeIds = computed(() => reactiveState.edges.map((e) => e.id)) - - const getters = useGetters(reactiveState, nodeIds, edgeIds) - - const actions = useActions(reactiveState, getters, nodeIds, edgeIds) - const hooksOn = {} Object.entries(reactiveState.hooks).forEach(([n, h]) => { const name = `on${n.charAt(0).toUpperCase() + n.slice(1)}` @@ -57,6 +50,13 @@ export class Storage { emits[n] = h.trigger }) + const nodeIds = computed(() => reactiveState.nodes.map((n) => n.id)) + const edgeIds = computed(() => reactiveState.edges.map((e) => e.id)) + + const getters = useGetters(reactiveState, nodeIds, edgeIds) + + const actions = useActions(id, emits, hooksOn, reactiveState, getters, nodeIds, edgeIds) + actions.setState(reactiveState) const flow: VueFlowStore = { diff --git a/packages/core/src/container/Viewport/Transform.vue b/packages/core/src/container/Viewport/Transform.vue index a5bd23f7..ea7d9746 100644 --- a/packages/core/src/container/Viewport/Transform.vue +++ b/packages/core/src/container/Viewport/Transform.vue @@ -5,27 +5,16 @@ import { useVueFlow } from '../../composables' import NodeRenderer from '../NodeRenderer/NodeRenderer.vue' import EdgeRenderer from '../EdgeRenderer/EdgeRenderer.vue' -const { id, viewport, emits, d3Zoom, d3Selection, dimensions, ...rest } = useVueFlow() +const { id, viewport, d3Zoom, d3Selection, dimensions } = useVueFlow() const viewportReady = ref(!isClient) until(() => d3Zoom.value && d3Selection.value && dimensions.value.width > 0 && dimensions.value.height > 0) - .toBeTruthy() + .toBe(true) .then(() => { - // emit pane ready event - emits.paneReady({ - id, - viewport, - emits, - d3Zoom, - d3Selection, - dimensions, - ...rest, - }) - setTimeout(() => { viewportReady.value = true - }, 0) + }, 1) }) diff --git a/packages/core/src/store/actions.ts b/packages/core/src/store/actions.ts index 1540afab..1621f714 100644 --- a/packages/core/src/store/actions.ts +++ b/packages/core/src/store/actions.ts @@ -48,14 +48,15 @@ import { } from '~/utils' export function useActions( + id: string, + emits: any, + hooksOn: any, state: State, getters: ComputedGetters, nodeIds: ComputedRef, edgeIds: ComputedRef, ): Actions { - let fitViewOnInitDone = false - - const viewportHelper = $(useViewport(state, getters)) + const viewportHelper = useViewport(state, getters) const updateNodeInternals: Actions['updateNodeInternals'] = (ids) => { const updateIds = ids ?? nodeIds.value ?? [] @@ -190,16 +191,6 @@ export function useActions( return res }, []) - if (state.fitViewOnInit && !fitViewOnInitDone) { - until(() => viewportHelper.initialized) - .toBe(true) - .then(() => { - viewportHelper.fitView() - }) - - fitViewOnInitDone = true - } - if (changes.length) { state.hooks.nodesChange.trigger(changes) } @@ -783,45 +774,6 @@ export function useActions( } } - const fitView: Actions['fitView'] = async (params = { padding: 0.1 }) => { - await until(() => viewportHelper.initialized).toBe(true) - viewportHelper.fitView(params) - } - - const zoomIn: Actions['zoomIn'] = async (options) => { - await until(() => viewportHelper.initialized).toBe(true) - viewportHelper.zoomIn(options) - } - - const zoomOut: Actions['zoomOut'] = async (options) => { - await until(() => viewportHelper.initialized).toBe(true) - viewportHelper.zoomOut(options) - } - - const zoomTo: Actions['zoomTo'] = async (zoomLevel, options) => { - await until(() => viewportHelper.initialized).toBe(true) - viewportHelper.zoomTo(zoomLevel, options) - } - - const setTransform: Actions['setTransform'] = async (transform, options) => { - await until(() => viewportHelper.initialized).toBe(true) - viewportHelper.setTransform(transform, options) - } - - const getTransform: Actions['getTransform'] = () => viewportHelper.getTransform() - - const setCenter: Actions['setCenter'] = async (x, y, options) => { - await until(() => viewportHelper.initialized).toBe(true) - viewportHelper.setCenter(x, y, options) - } - - const fitBounds: Actions['fitBounds'] = async (bounds, options) => { - await until(() => viewportHelper.initialized).toBe(true) - viewportHelper.fitBounds(bounds, options) - } - - const project: Actions['project'] = (position) => viewportHelper.project(position) - const toObject: Actions['toObject'] = () => { // we have to stringify/parse so objects containing refs (like nodes and edges) can potentially be saved in a storage return JSON.parse( @@ -866,7 +818,7 @@ export function useActions( } if (position) { - setTransform({ x: position[0], y: position[1], zoom: zoom || 1 }) + viewportHelper.value.setTransform({ x: position[0], y: position[1], zoom: zoom || 1 }) } } @@ -896,7 +848,7 @@ export function useActions( setState(resetState) } - return { + const actions: Actions = { updateNodePositions, updateNodeDimensions, setElements, @@ -929,19 +881,39 @@ export function useActions( getIntersectingNodes, isNodeIntersecting, panBy, - fitView, - zoomIn, - zoomOut, - zoomTo, - setTransform, - getTransform, - setCenter, - fitBounds, - project, + fitView: (params) => viewportHelper.value.fitView(params), + zoomIn: (transitionOpts) => viewportHelper.value.zoomIn(transitionOpts), + zoomOut: (transitionOpts) => viewportHelper.value.zoomOut(transitionOpts), + zoomTo: (zoomLevel, transitionOpts) => viewportHelper.value.zoomTo(zoomLevel, transitionOpts), + setTransform: (params, transitionOpts) => viewportHelper.value.setTransform(params, transitionOpts), + getTransform: () => viewportHelper.value.getTransform(), + setCenter: (x, y, opts) => viewportHelper.value.setCenter(x, y, opts), + fitBounds: (params, opts) => viewportHelper.value.fitBounds(params, opts), + project: (params) => viewportHelper.value.project(params), toObject, fromObject, updateNodeInternals, $reset, $destroy: () => {}, } + + until(() => viewportHelper.value.initialized) + .toBe(true, { flush: 'pre' }) + .then(() => { + if (state.fitViewOnInit) { + viewportHelper.value.fitView() + } + + state.hooks.paneReady.trigger({ + id, + emits, + vueFlowVersion: typeof __VUE_FLOW_VERSION__ !== 'undefined' ? __VUE_FLOW_VERSION__ : 'UNKNOWN', + ...hooksOn, + ...state, + ...getters, + ...actions, + }) + }) + + return actions }