"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]);}
"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]);
}