9686099863
* converting various 'brittle' subscriptions to use locks * minor cache update fixes * added useful debugging utils to local cache updates * fixed incorrect project.versions, project.models, model.versions cache updates
58 lines
1.7 KiB
TypeScript
58 lines
1.7 KiB
TypeScript
import { nanoid } from 'nanoid'
|
|
import { useScopedState } from '~~/lib/common/composables/scopedState'
|
|
import { MaybeRef } from '@vueuse/core'
|
|
|
|
const useComponentLockState = () =>
|
|
useScopedState('componentLockState', () =>
|
|
ref(new Array<{ key: string; instanceId: string }>())
|
|
)
|
|
|
|
/**
|
|
* A lock that is scoped to a component. If multiple instances of the same lock composable are invoked,
|
|
* only the first one will have the lock.
|
|
*
|
|
* The lock is released when the component that owns the composable invocation is unmounted
|
|
*/
|
|
export const useLock = (key: MaybeRef<string>) => {
|
|
const instanceId = nanoid()
|
|
const lockState = useComponentLockState()
|
|
|
|
const isActiveInstance = computed(() => {
|
|
return (
|
|
lockState.value.find((lock) => lock.key === unref(key))?.instanceId === instanceId
|
|
)
|
|
})
|
|
|
|
// On unmount, remove this instance from the list of active instances
|
|
onBeforeUnmount(() => {
|
|
lockState.value = lockState.value.filter(
|
|
(lock) => lock.key !== unref(key) || lock.instanceId !== instanceId
|
|
)
|
|
})
|
|
|
|
watch(
|
|
lockState,
|
|
() => {
|
|
// If there is no active instance, mark this as the active one
|
|
if (!lockState.value.find((lock) => lock.key === unref(key))) {
|
|
lockState.value.push({ key: unref(key), instanceId })
|
|
}
|
|
},
|
|
{ immediate: true, deep: true, flush: 'sync' }
|
|
)
|
|
|
|
watch(
|
|
() => unref(key),
|
|
(newKey, oldKey) => {
|
|
if (newKey === oldKey) return
|
|
|
|
// If the key changes, remove the old key from the list of active instances
|
|
lockState.value = lockState.value.filter(
|
|
(lock) => lock.key !== oldKey || lock.instanceId !== instanceId
|
|
)
|
|
}
|
|
)
|
|
|
|
return { hasLock: isActiveInstance }
|
|
}
|