This commit is contained in:
Daniel Ledda
2024-10-31 23:46:23 +01:00
parent 314ccaa677
commit bcb820f35e
36 changed files with 4427 additions and 61 deletions

50
app/useAsyncState.ts Normal file
View File

@@ -0,0 +1,50 @@
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 };
}