90 lines · 3.0 KB · TypeScript
RawDownload
import {  combineTerminalSessionState,  EMPTY_TERMINAL_BUFFER_STATE,  EMPTY_TERMINAL_SESSION_STATE,  selectRunningSubprocessTerminalIds,  type KnownTerminalSession,  type TerminalSessionState,} from "@t3tools/client-runtime/state/terminal";import { ThreadId, type EnvironmentId, type TerminalAttachInput } from "@t3tools/contracts";import { useMemo } from "react"; import { useEnvironmentQuery } from "./query";import { terminalEnvironment } from "./terminal"; export function useAttachedTerminalSession(input: {  readonly environmentId: EnvironmentId | null;  readonly terminal: TerminalAttachInput | null;}): TerminalSessionState {  const attach = useEnvironmentQuery(    input.environmentId !== null && input.terminal !== null      ? terminalEnvironment.attach({          environmentId: input.environmentId,          input: input.terminal,        })      : null,  );  const metadata = useEnvironmentQuery(    input.environmentId === null      ? null      : terminalEnvironment.metadata({          environmentId: input.environmentId,          input: null,        }),  );   return useMemo(() => {    if (input.environmentId === null || input.terminal === null) {      return EMPTY_TERMINAL_SESSION_STATE;    }    const summary =      metadata.data?.find(        (terminal) =>          terminal.threadId === input.terminal?.threadId &&          terminal.terminalId === input.terminal?.terminalId,      ) ?? null;    const state = combineTerminalSessionState(summary, attach.data ?? EMPTY_TERMINAL_BUFFER_STATE);    return attach.error === null ? state : { ...state, error: attach.error, status: "error" };  }, [attach.data, attach.error, input.environmentId, input.terminal, metadata.data]);} export function useKnownTerminalSessions(input: {  readonly environmentId: EnvironmentId | null;  readonly threadId: ThreadId | null;}): ReadonlyArray<KnownTerminalSession> {  const metadata = useEnvironmentQuery(    input.environmentId === null      ? null      : terminalEnvironment.metadata({          environmentId: input.environmentId,          input: null,        }),  );  return useMemo(() => {    if (input.environmentId === null) {      return [];    }    return (metadata.data ?? [])      .filter((summary) => input.threadId === null || summary.threadId === input.threadId)      .map((summary) => ({        target: {          environmentId: input.environmentId!,          threadId: ThreadId.make(summary.threadId),          terminalId: summary.terminalId,        },        state: combineTerminalSessionState(summary, EMPTY_TERMINAL_BUFFER_STATE),      }))      .sort((left, right) =>        left.target.terminalId.localeCompare(right.target.terminalId, undefined, {          numeric: true,        }),      );  }, [input.environmentId, input.threadId, metadata.data]);} export function useThreadRunningTerminalIds(input: {  readonly environmentId: EnvironmentId | null;  readonly threadId: ThreadId | null;}): ReadonlyArray<string> {  return selectRunningSubprocessTerminalIds(useKnownTerminalSessions(input));}