djledda.de main
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 

51 linhas
1.6 KiB

  1. import { onMounted, onServerPrefetch, useSSRContext, shallowRef, type ShallowRef } from 'vue';
  2. declare global {
  3. // deno-lint-ignore no-var
  4. var appstate: Partial<Record<string, unknown>>;
  5. }
  6. export default function useAsyncState<T>(key: string, getter: (context: { hostUrl: string }) => Promise<T | null>, options?: { suspensible: boolean }): { result: ShallowRef<T | null>, stateIsReady: Promise<unknown> } {
  7. const ssrContext = useSSRContext<{ registry: Record<string, unknown> }>();
  8. const isClient = typeof ssrContext === 'undefined';
  9. const registry = ssrContext?.registry ?? globalThis?.appstate;
  10. const hostUrl = isClient ? globalThis.location.origin : 'http://localhost:8080';
  11. const state = shallowRef<T | null>(null);
  12. let resolve = () => {};
  13. const promise = new Promise<void>((res) => {
  14. resolve = res;
  15. });
  16. if (key in registry) {
  17. state.value = registry[key] as T;
  18. delete registry[key];
  19. resolve();
  20. } else {
  21. if (!isClient) {
  22. resolve();
  23. }
  24. onServerPrefetch(async () => {
  25. const result = await getter({ hostUrl });
  26. registry[key] = result;
  27. state.value = result;
  28. });
  29. if (options?.suspensible ?? true) {
  30. getter({ hostUrl }).then((result) => {
  31. state.value = result;
  32. resolve();
  33. }).catch(resolve);
  34. } else {
  35. onMounted(async () => {
  36. state.value = await getter({ hostUrl });
  37. resolve();
  38. });
  39. }
  40. }
  41. return { result: state, stateIsReady: promise };
  42. }