feat: use a storage class to map flow instances
* improves cleanup of instances
This commit is contained in:
@@ -1,8 +1,5 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { VueFlow, MiniMap, Controls, useVueFlow, useWindow } from '~/index'
|
import { VueFlow, MiniMap, Controls, useVueFlow } from '~/index'
|
||||||
|
|
||||||
const window: any = useWindow()
|
|
||||||
const isWindows = window.navigator.oscpu.includes('Windows')
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
nodesDraggable,
|
nodesDraggable,
|
||||||
|
|||||||
@@ -1,32 +1,74 @@
|
|||||||
import { EffectScope } from 'vue'
|
import { EffectScope } from 'vue'
|
||||||
import { FlowOptions, UseVueFlow, Store } from '~/types'
|
import { FlowOptions, UseVueFlow } from '~/types'
|
||||||
import { VueFlow } from '~/context'
|
import { VueFlow } from '~/context'
|
||||||
import { useStore } from '~/store'
|
import { useStore } from '~/store'
|
||||||
|
|
||||||
let id = 0
|
export class Storage {
|
||||||
|
public flows = new Map<string, UseVueFlow>()
|
||||||
|
static instance: Storage
|
||||||
|
|
||||||
type Scope = EffectScope & { vueFlow: UseVueFlow }
|
public static getInstance(): Storage {
|
||||||
export default <N = any, E = N>(options?: Partial<FlowOptions<N, E>>): UseVueFlow<N, E> => {
|
if (!Storage.instance) {
|
||||||
const scope = getCurrentScope() as Scope
|
Storage.instance = new Storage()
|
||||||
let vueFlow: UseVueFlow | null = scope ? inject(VueFlow, null) ?? (scope.vueFlow as UseVueFlow) : null
|
}
|
||||||
if (!vueFlow || (vueFlow && options?.id && options.id !== vueFlow.id)) {
|
|
||||||
const name = options?.id ?? `vue-flow-${id++}`
|
return Storage.instance
|
||||||
const store: Store = useStore(options)
|
}
|
||||||
vueFlow = {
|
|
||||||
id: name,
|
public set(id: string, flow: UseVueFlow) {
|
||||||
|
this.flows.set(id, flow)
|
||||||
|
}
|
||||||
|
|
||||||
|
public get(id: string) {
|
||||||
|
return this.flows.get(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
public remove(id: string) {
|
||||||
|
this.flows.delete(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
public create(id: string, options?: Partial<FlowOptions>) {
|
||||||
|
const store = useStore(options)
|
||||||
|
const flow = {
|
||||||
|
id,
|
||||||
store: reactive(store),
|
store: reactive(store),
|
||||||
...toRefs(store.state),
|
...toRefs(store.state),
|
||||||
...store.getters,
|
...store.getters,
|
||||||
...store.actions,
|
...store.actions,
|
||||||
...store.hooksOn,
|
...store.hooksOn,
|
||||||
} as unknown as UseVueFlow
|
} as unknown as UseVueFlow
|
||||||
|
this.set(id, flow)
|
||||||
|
return flow
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let id = 0
|
||||||
|
|
||||||
|
type Scope = EffectScope & { vueFlowId: string }
|
||||||
|
export default <N = any, E = N>(options?: Partial<FlowOptions<N, E>>): UseVueFlow<N, E> => {
|
||||||
|
const storage = Storage.getInstance()
|
||||||
|
const scope = getCurrentScope() as Scope
|
||||||
|
let vueFlow =
|
||||||
|
typeof inject(VueFlow, undefined) !== 'undefined'
|
||||||
|
? inject(VueFlow, undefined)!
|
||||||
|
: scope && scope.vueFlowId
|
||||||
|
? storage.get(scope.vueFlowId)
|
||||||
|
: undefined
|
||||||
|
if (!vueFlow || (vueFlow && options?.id && options.id !== vueFlow.id)) {
|
||||||
|
const name = options?.id ?? `vue-flow-${id++}`
|
||||||
|
|
||||||
if (scope) {
|
if (scope) {
|
||||||
provide(VueFlow, vueFlow)
|
vueFlow = storage.create(name, options)
|
||||||
scope.vueFlow = vueFlow
|
provide(VueFlow, storage.get(name))
|
||||||
|
scope.vueFlowId = name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onScopeDispose(() => {
|
||||||
|
console.log(scope)
|
||||||
|
storage.remove(name)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
if (!vueFlow) throw new Error('VueFlow instance not found.')
|
if (!vueFlow) throw new Error('VueFlow instance not found.')
|
||||||
|
|
||||||
return <UseVueFlow<N, E>>vueFlow
|
return vueFlow
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-8
@@ -1,7 +1,7 @@
|
|||||||
import useState from './state'
|
import useState from './state'
|
||||||
import useActions from './actions'
|
import useActions from './actions'
|
||||||
import useGetters from './getters'
|
import useGetters from './getters'
|
||||||
import { FlowHooksOn, FlowOptions, Store, State } from '~/types'
|
import { FlowHooksOn, FlowOptions, State, Store } from '~/types'
|
||||||
|
|
||||||
export default (preloadedState?: FlowOptions): Store => {
|
export default (preloadedState?: FlowOptions): Store => {
|
||||||
const state: State = useState(preloadedState)
|
const state: State = useState(preloadedState)
|
||||||
@@ -20,7 +20,7 @@ export default (preloadedState?: FlowOptions): Store => {
|
|||||||
if (preloadedState.edges) actions.setEdges(preloadedState.edges)
|
if (preloadedState.edges) actions.setEdges(preloadedState.edges)
|
||||||
}
|
}
|
||||||
|
|
||||||
const store = {
|
return {
|
||||||
state: reactiveState,
|
state: reactiveState,
|
||||||
actions,
|
actions,
|
||||||
getters,
|
getters,
|
||||||
@@ -29,10 +29,4 @@ export default (preloadedState?: FlowOptions): Store => {
|
|||||||
...getters,
|
...getters,
|
||||||
...actions,
|
...actions,
|
||||||
} as unknown as Store
|
} as unknown as Store
|
||||||
|
|
||||||
onScopeDispose(() => {
|
|
||||||
store.$reset()
|
|
||||||
})
|
|
||||||
|
|
||||||
return store
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user