106 lines · 3.7 KB · TypeScript
RawDownload
import { type EnvironmentId, type ProjectReadFileResult, WS_METHODS } from "@t3tools/contracts";import * as Crypto from "effect/Crypto";import { Atom } from "effect/unstable/reactivity"; import {  createAtomCommandScheduler,  createEnvironmentCommand,  createEnvironmentRpcCommand,  createEnvironmentRpcQueryAtomFamily,} from "./runtime.ts";import {  type CreateProjectInput,  type DeleteProjectInput,  type UpdateProjectInput,  createProject,  deleteProject,  updateProject,} from "../operations/commands.ts";import type { EnvironmentRegistry } from "../connection/registry.ts"; export type {  CreateProjectInput,  DeleteProjectInput,  UpdateProjectInput,} from "../operations/commands.ts"; export interface OptimisticProjectFile {  readonly data: ProjectReadFileResult;  readonly confirmedAgainst: object | null | undefined;} export interface OptimisticProjectFileTarget {  readonly environmentId: EnvironmentId;  readonly cwd: string;  readonly relativePath: string;} function optimisticProjectFileKey(target: OptimisticProjectFileTarget): string {  return JSON.stringify([target.environmentId, target.cwd, target.relativePath]);} export function createProjectEnvironmentAtoms<R, E>(  runtime: Atom.AtomRuntime<EnvironmentRegistry | Crypto.Crypto | R, E>,) {  const projectScheduler = createAtomCommandScheduler();  const fileScheduler = createAtomCommandScheduler();  const optimisticFileFamily = Atom.family((key: string) =>    Atom.make<OptimisticProjectFile | null>(null).pipe(      Atom.withLabel(`environment-data:projects:optimistic-file:${key}`),    ),  );  const projectConcurrency = {    mode: "serial" as const,    key: ({ environmentId, input }: { environmentId: string; input: { projectId: string } }) =>      JSON.stringify([environmentId, input.projectId]),  };  return {    searchEntries: createEnvironmentRpcQueryAtomFamily(runtime, {      label: "environment-data:projects:search-entries",      tag: WS_METHODS.projectsSearchEntries,      staleTimeMs: 15_000,    }),    listEntries: createEnvironmentRpcQueryAtomFamily(runtime, {      label: "environment-data:projects:list-entries",      tag: WS_METHODS.projectsListEntries,      staleTimeMs: 30_000,      idleTtlMs: 5 * 60_000,    }),    readFile: createEnvironmentRpcQueryAtomFamily(runtime, {      label: "environment-data:projects:read-file",      tag: WS_METHODS.projectsReadFile,      staleTimeMs: 30_000,      idleTtlMs: 5 * 60_000,    }),    optimisticFile: (target: OptimisticProjectFileTarget) =>      optimisticFileFamily(optimisticProjectFileKey(target)),    create: createEnvironmentCommand(runtime, {      label: "environment-data:commands:project:create",      execute: (input: CreateProjectInput) => createProject(input),      scheduler: projectScheduler,      concurrency: projectConcurrency,    }),    update: createEnvironmentCommand(runtime, {      label: "environment-data:commands:project:update",      execute: (input: UpdateProjectInput) => updateProject(input),      scheduler: projectScheduler,      concurrency: projectConcurrency,    }),    delete: createEnvironmentCommand(runtime, {      label: "environment-data:commands:project:delete",      execute: (input: DeleteProjectInput) => deleteProject(input),      scheduler: projectScheduler,      concurrency: projectConcurrency,    }),    writeFile: createEnvironmentRpcCommand(runtime, {      label: "environment-data:projects:write-file",      tag: WS_METHODS.projectsWriteFile,      scheduler: fileScheduler,      concurrency: {        mode: "serial",        key: ({ environmentId, input }) =>          JSON.stringify([environmentId, input.cwd, input.relativePath]),      },    }),  };}