|
- import { onMounted, onServerPrefetch, useSSRContext, shallowRef, type ShallowRef } from 'vue';
-
- declare global {
- // deno-lint-ignore no-var
- var appstate: Partial<Record<string, unknown>>;
- }
-
- export default function useAsyncState<T>(key: string, getter: (context: { hostUrl: string }) => Promise<T | null>, options?: { suspensible: boolean }): { result: ShallowRef<T | null>, stateIsReady: Promise<unknown> } {
- const ssrContext = useSSRContext<{ registry: Record<string, unknown> }>();
- const isClient = typeof ssrContext === 'undefined';
-
- const registry = ssrContext?.registry ?? globalThis?.appstate;
-
- const hostUrl = isClient ? globalThis.location.origin : 'http://localhost:8080';
-
- const state = shallowRef<T | null>(null);
-
- let resolve = () => {};
- const promise = new Promise<void>((res) => {
- resolve = res;
- });
-
- if (key in registry) {
- state.value = registry[key] as T;
- delete registry[key];
- resolve();
- } else {
- if (!isClient) {
- resolve();
- }
- onServerPrefetch(async () => {
- const result = await getter({ hostUrl });
- registry[key] = result;
- state.value = result;
- });
- if (options?.suspensible ?? true) {
- getter({ hostUrl }).then((result) => {
- state.value = result;
- resolve();
- }).catch(resolve);
- } else {
- onMounted(async () => {
- state.value = await getter({ hostUrl });
- resolve();
- });
- }
- }
-
- return { result: state, stateIsReady: promise };
- }
|