76 lines · 2.5 KB · TypeScript
RawDownload
"use client"; import { scopedThreadKey } from "@t3tools/client-runtime/environment";import type { ScopedThreadRef } from "@t3tools/contracts";import { useEffect } from "react"; import { readPreviewStateRevision, usePreviewStateStore } from "~/previewStateStore";import { previewEnvironment } from "~/state/preview";import { useEnvironmentQuery } from "~/state/query";import { useAtomCommand } from "~/state/use-atom-command"; import { refreshPreviewSessionState, usePreviewSessionState } from "./previewSessionState"; export function usePreviewSession(threadRef: ScopedThreadRef): void {  const query = usePreviewSessionState(threadRef);  const events = useEnvironmentQuery(    previewEnvironment.events({      environmentId: threadRef.environmentId,      input: {},    }),  );  const open = useAtomCommand(previewEnvironment.open);  const applyServerSnapshot = usePreviewStateStore((state) => state.applyServerSnapshot);  const applyServerEvent = usePreviewStateStore((state) => state.applyServerEvent);   useEffect(() => {    if (      query.isPending ||      !query.data ||      query.data.revision !== readPreviewStateRevision(threadRef)    ) {      return;    }    let cancelled = false;    if (query.data.result.sessions.length > 0) {      for (const snapshot of query.data.result.sessions) {        applyServerSnapshot(threadRef, snapshot);      }      return;    }     const localSnapshot =      usePreviewStateStore.getState().byThreadKey[scopedThreadKey(threadRef)]?.snapshot;    const recoverableUrl =      localSnapshot && localSnapshot.navStatus._tag !== "Idle" ? localSnapshot.navStatus.url : null;    if (!recoverableUrl) {      applyServerSnapshot(threadRef, null);      return;    }     void open({      environmentId: threadRef.environmentId,      input: { threadId: threadRef.threadId, url: recoverableUrl },    }).then((result) => {      if (cancelled) return;      if (result._tag === "Failure") {        return;      }      applyServerSnapshot(threadRef, result.value);      refreshPreviewSessionState(threadRef);    });     return () => {      cancelled = true;    };  }, [applyServerSnapshot, open, query.data, query.isPending, threadRef]);   useEffect(() => {    const event = events.data;    if (!event || event.threadId !== threadRef.threadId) return;    applyServerEvent(threadRef, event);    if (event.type === "opened" || event.type === "closed") {      refreshPreviewSessionState(threadRef);    }  }, [applyServerEvent, events.data, threadRef]);}