feat: use a storage class to map flow instances

* improves cleanup of instances
This commit is contained in:
Braks
2022-03-23 06:47:57 +01:00
parent 11da181d0f
commit 65d079db20
3 changed files with 59 additions and 26 deletions
+1 -4
View File
@@ -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,
+56 -14
View File
@@ -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
View File
@@ -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
} }