Files
speckle-server/packages/frontend-2/lib/common/composables/singleton.ts
T
Kristaps Fabians Geikins f80a7189a0 chore(fe2): upgrade to nuxt 3.8.2 (#1887)
* chore(fe2): upgrade to nuxt 3.8.2

* fix tailwind-theme build

* readme update

* removing storybook from fe2 :(

* fix(fe2): codegen schema url resolution
2023-11-29 10:22:17 +02:00

58 lines
1.7 KiB
TypeScript

import { nanoid } from 'nanoid'
import { useScopedState } from '~~/lib/common/composables/scopedState'
import type { MaybeRef } from '@vueuse/core'
const useComponentLockState = () =>
useScopedState('componentLockState', () =>
shallowRef(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 = [...lockState.value, { key: unref(key), instanceId }]
}
},
{ immediate: true }
)
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 }
}