Files
speckle-server/packages/frontend-2/lib/common/composables/singleton.ts
T
Kristaps Fabians Geikins 9686099863 fix(fe2): invalid totalCount cache updates for project.versions, project.models and model.versions (#1756)
* 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
2023-08-11 11:01:02 +03:00

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 }
}