2022-04-13 17:41:41 +00:00
|
|
|
import { isRef, toRef } from 'vue'
|
2021-10-11 17:48:03 +00:00
|
|
|
import type { Ref } from 'vue'
|
|
|
|
import { useNuxtApp } from '#app'
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create a global reactive ref that will be hydrated but not shared across ssr requests
|
|
|
|
*
|
2021-10-12 14:59:19 +00:00
|
|
|
* @param key a unique key ensuring that data fetching can be properly de-duplicated across requests
|
|
|
|
* @param init a function that provides initial value for the state when it's not initiated
|
2021-10-11 17:48:03 +00:00
|
|
|
*/
|
2022-04-13 17:41:41 +00:00
|
|
|
export const useState = <T> (key: string, init?: (() => T | Ref<T>)): Ref<T> => {
|
2021-10-11 17:48:03 +00:00
|
|
|
const nuxt = useNuxtApp()
|
2021-10-12 14:28:49 +00:00
|
|
|
const state = toRef(nuxt.payload.state, key)
|
|
|
|
if (state.value === undefined && init) {
|
2022-04-13 17:41:41 +00:00
|
|
|
const initialValue = init()
|
|
|
|
if (isRef(initialValue)) {
|
|
|
|
// vue will unwrap the ref for us
|
|
|
|
nuxt.payload.state[key] = initialValue
|
|
|
|
return initialValue as Ref<T>
|
|
|
|
}
|
|
|
|
state.value = initialValue
|
2021-10-12 14:28:49 +00:00
|
|
|
}
|
|
|
|
return state
|
2021-10-11 17:48:03 +00:00
|
|
|
}
|