116 lines · 4.4 KB · TypeScript
RawDownload
import { WS_METHODS } from "@t3tools/contracts";import { Atom } from "effect/unstable/reactivity"; import type { EnvironmentRegistry } from "../connection/registry.ts";import {  createAtomCommandScheduler,  createEnvironmentRpcCommand,  createEnvironmentRpcQueryAtomFamily,  createEnvironmentRpcSubscriptionAtomFamily,} from "./runtime.ts"; export const previewAutomationHostFocusConcurrencyKey = (value: {  readonly environmentId: string;  readonly input: {    readonly clientId: string;    readonly connectionId: string;  };}): string => JSON.stringify([value.environmentId, value.input.clientId, value.input.connectionId]); export function createPreviewEnvironmentAtoms<R, E>(  runtime: Atom.AtomRuntime<EnvironmentRegistry | R, E>,) {  const lifecycleScheduler = createAtomCommandScheduler();  const statusScheduler = createAtomCommandScheduler();  const automationScheduler = createAtomCommandScheduler();  const lifecycleConcurrency = {    mode: "serial" as const,    key: ({ environmentId, input }: { environmentId: string; input: { threadId: string } }) =>      JSON.stringify([environmentId, input.threadId]),  };  return {    list: createEnvironmentRpcQueryAtomFamily(runtime, {      label: "environment-data:preview:list",      tag: WS_METHODS.previewList,      staleTimeMs: 5_000,    }),    events: createEnvironmentRpcSubscriptionAtomFamily(runtime, {      label: "environment-data:preview:events",      tag: WS_METHODS.subscribePreviewEvents,    }),    discoveredServers: createEnvironmentRpcSubscriptionAtomFamily(runtime, {      label: "environment-data:preview:discovered-servers",      tag: WS_METHODS.subscribeDiscoveredLocalServers,      // Configured URLs are part of this atom's key. Dispose immediately so      // unmounted projects stop contributing probe candidates on the server.      idleTtlMs: 0,    }),    automationRequests: createEnvironmentRpcSubscriptionAtomFamily(runtime, {      label: "environment-data:preview:automation-requests",      tag: WS_METHODS.previewAutomationConnect,      // Automation requests are commands, not cached query data. Dispose the      // stream immediately with its owner so stale requests cannot replay when      // a thread remounts and the server can clear disconnected hosts promptly.      idleTtlMs: 0,    }),    open: createEnvironmentRpcCommand(runtime, {      label: "environment-data:preview:open",      tag: WS_METHODS.previewOpen,      scheduler: lifecycleScheduler,      concurrency: lifecycleConcurrency,    }),    navigate: createEnvironmentRpcCommand(runtime, {      label: "environment-data:preview:navigate",      tag: WS_METHODS.previewNavigate,      scheduler: lifecycleScheduler,      concurrency: lifecycleConcurrency,    }),    resize: createEnvironmentRpcCommand(runtime, {      label: "environment-data:preview:resize",      tag: WS_METHODS.previewResize,      scheduler: lifecycleScheduler,      concurrency: lifecycleConcurrency,    }),    refresh: createEnvironmentRpcCommand(runtime, {      label: "environment-data:preview:refresh",      tag: WS_METHODS.previewRefresh,      scheduler: lifecycleScheduler,      concurrency: lifecycleConcurrency,    }),    close: createEnvironmentRpcCommand(runtime, {      label: "environment-data:preview:close",      tag: WS_METHODS.previewClose,      scheduler: lifecycleScheduler,      concurrency: lifecycleConcurrency,    }),    reportStatus: createEnvironmentRpcCommand(runtime, {      label: "environment-data:preview:report-status",      tag: WS_METHODS.previewReportStatus,      scheduler: statusScheduler,      concurrency: {        mode: "latest",        key: ({ environmentId, input }) =>          JSON.stringify([environmentId, input.threadId, input.tabId]),      },    }),    respondToAutomation: createEnvironmentRpcCommand(runtime, {      label: "environment-data:preview:automation-respond",      tag: WS_METHODS.previewAutomationRespond,      scheduler: automationScheduler,      concurrency: {        mode: "singleFlight",        key: ({ environmentId, input }) =>          JSON.stringify([environmentId, input.connectionId, input.requestId]),      },    }),    focusAutomationHost: createEnvironmentRpcCommand(runtime, {      label: "environment-data:preview:automation-focus-host",      tag: WS_METHODS.previewAutomationFocusHost,      scheduler: automationScheduler,      concurrency: {        mode: "latest",        key: previewAutomationHostFocusConcurrencyKey,      },    }),  };}