|
- import { onMounted, onServerPrefetch, type ShallowRef, shallowRef } from "vue";
- import useDJSSRContext from "@/useDJSSRContext.ts";
-
- 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 = useDJSSRContext();
- 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 };
- }
|