94 lines · 3.2 KB · TypeScript
RawDownload
import type { ScopedThreadRef } from "@t3tools/contracts";import { isAtomCommandInterrupted } from "@t3tools/client-runtime/state/runtime";import * as Schema from "effect/Schema"; import {  browserDefaultOpenProfileId,  browserDefaultOpenViewport,  resolveBrowserDefaults,} from "~/browser/browserDefaults";import { isWebUrl, resolveBrowserLinkTargetPreference } from "~/browser/browserLinkTarget";import type { OpenPreviewMutation } from "~/browser/openFileInPreview";import { recordVisitForThread } from "~/browserHistoryStore";import { applyPreviewServerSnapshot, isPreviewSupportedInRuntime } from "~/previewStateStore";import { useRightPanelStore } from "~/rightPanelStore"; const terminalLinkErrorContext = {  environmentId: Schema.String,  threadId: Schema.String,  targetOrigin: Schema.String,  cause: Schema.Defect(),}; export class TerminalLinkPreviewOpenError extends Schema.TaggedErrorClass<TerminalLinkPreviewOpenError>()(  "TerminalLinkPreviewOpenError",  terminalLinkErrorContext,) {  override get message(): string {    return `Failed to open terminal link ${this.targetOrigin} in preview for thread ${this.threadId}.`;  }} interface OpenTerminalLinkInPreviewInput<E> {  readonly url: string;  readonly threadRef: ScopedThreadRef;  readonly openPreview: OpenPreviewMutation<E>;  readonly fallbackToBrowser: () => void;} /** * Opens a terminal hyperlink where the "Open links in" setting says. Terminal * links are activated with the platform modifier already held, so unlike chat * links the modifier cannot double as the system-browser override; the setting * alone decides, and the system browser is the fallback whenever the in-app * one cannot take the URL. */export async function openTerminalLinkInPreview<E>(  input: OpenTerminalLinkInPreviewInput<E>,): Promise<void> {  const supportsPreview =    isWebUrl(input.url) &&    isPreviewSupportedInRuntime() &&    input.threadRef.threadId.length > 0 &&    (await resolveBrowserLinkTargetPreference()) === "app";   if (!supportsPreview) {    input.fallbackToBrowser();    return;  }   const errorContext = {    environmentId: input.threadRef.environmentId,    threadId: input.threadRef.threadId,    targetOrigin: new URL(input.url).origin,  };   const defaults = await resolveBrowserDefaults();  const result = await input.openPreview({    environmentId: input.threadRef.environmentId,    input: {      threadId: input.threadRef.threadId,      url: input.url,      // Same reason as `openUrlInPreview`: this path handles its own result      // mapping, so the configured defaults are applied explicitly.      viewport: browserDefaultOpenViewport(defaults),      profileId: browserDefaultOpenProfileId(defaults),    },  });  if (result._tag === "Failure") {    if (isAtomCommandInterrupted(result)) {      return;    }    console.error(      new TerminalLinkPreviewOpenError({        ...errorContext,        cause: result.cause,      }),    );    input.fallbackToBrowser();    return;  }  recordVisitForThread(input.threadRef, input.url);  applyPreviewServerSnapshot(input.threadRef, result.value);  useRightPanelStore.getState().openBrowser(input.threadRef, result.value.tabId);}