Skip to content
Source
Sign inSign up

sourceControl.ts

105 lines4.3 KB

1import { WS_METHODS } from "@t3tools/contracts";
2import { Atom } from "effect/reactivity";
3​
4import {
5 createAtomCommandScheduler,
6 createEnvironmentRpcCommand,
7 createEnvironmentRpcQueryAtomFamily,
8 createEnvironmentRpcSubscriptionAtomFamily,
9} from "./runtime.ts";
10import type { EnvironmentRegistry } from "../connection/registry.ts";
11import * as Persistence from "../platform/persistence.ts";
12import { vcsCommandConcurrency, vcsCommandScheduler } from "./vcsCommandScheduler.ts";
13import { invalidateCachedVcsRefs } from "./vcsRefInvalidation.ts";
14​
15export function createSourceControlEnvironmentAtoms<R, E>(
16 runtime: Atom.AtomRuntime<EnvironmentRegistry | Persistence.EnvironmentCacheStore | R, E>,
17) {
18 const commandScheduler = createAtomCommandScheduler();
19 return {
20 discovery: createEnvironmentRpcQueryAtomFamily(runtime, {
21 label: "environment-data:server:source-control-discovery",
22 tag: WS_METHODS.serverDiscoverSourceControl,
23 }),
24 appAccess: createEnvironmentRpcQueryAtomFamily(runtime, {
25 label: "environment-data:source-control:app-access",
26 tag: WS_METHODS.sourceControlAppAccess,
27 }),
28 // One check, as after cloning, where no view keeps the query mounted.
29 checkAppAccess: createEnvironmentRpcCommand(runtime, {
30 label: "environment-data:source-control:check-app-access",
31 tag: WS_METHODS.sourceControlAppAccess,
32 }),
33 checkStarred: createEnvironmentRpcCommand(runtime, {
34 label: "environment-data:source-control:check-starred",
35 tag: WS_METHODS.sourceControlStarred,
36 }),
37 star: createEnvironmentRpcCommand(runtime, {
38 label: "environment-data:source-control:star",
39 tag: WS_METHODS.sourceControlStar,
40 }),
41 repository: createEnvironmentRpcQueryAtomFamily(runtime, {
42 label: "environment-data:source-control:repository",
43 tag: WS_METHODS.sourceControlLookupRepository,
44 }),
45 // Clone-backed project creation. The RPC returns once the project exists
46 // and the clone runs in the background; `projectClones` carries progress.
47 startProjectClone: createEnvironmentRpcCommand(runtime, {
48 label: "environment-data:source-control:project-clone-start",
49 tag: WS_METHODS.projectCloneStart,
50 scheduler: commandScheduler,
51 concurrency: {
52 mode: "serial",
53 key: ({ environmentId }) => environmentId,
54 },
55 }),
56 // Cancel and retry share the start queue so a double click cannot race
57 // two actions against the same clone.
58 cancelProjectClone: createEnvironmentRpcCommand(runtime, {
59 label: "environment-data:source-control:project-clone-cancel",
60 tag: WS_METHODS.projectCloneCancel,
61 scheduler: commandScheduler,
62 concurrency: {
63 mode: "serial",
64 key: ({ environmentId }) => environmentId,
65 },
66 }),
67 retryProjectClone: createEnvironmentRpcCommand(runtime, {
68 label: "environment-data:source-control:project-clone-retry",
69 tag: WS_METHODS.projectCloneRetry,
70 scheduler: commandScheduler,
71 concurrency: {
72 mode: "serial",
73 key: ({ environmentId }) => environmentId,
74 },
75 }),
76 // Unscheduled: a pending sign-in waits on the user for minutes and must not hold up clones.
77 startSignIn: createEnvironmentRpcCommand(runtime, {
78 label: "environment-data:source-control:sign-in-start",
79 tag: WS_METHODS.sourceControlSignInStart,
80 }),
81 waitForSignIn: createEnvironmentRpcCommand(runtime, {
82 label: "environment-data:source-control:sign-in-wait",
83 tag: WS_METHODS.sourceControlSignInWait,
84 }),
85 cancelSignIn: createEnvironmentRpcCommand(runtime, {
86 label: "environment-data:source-control:sign-in-cancel",
87 tag: WS_METHODS.sourceControlSignInCancel,
88 }),
89 projectClones: createEnvironmentRpcSubscriptionAtomFamily(runtime, {
90 label: "environment-data:source-control:project-clones",
91 tag: WS_METHODS.subscribeProjectClones,
92 }),
93 publishRepository: createEnvironmentRpcCommand(runtime, {
94 label: "environment-data:source-control:publish-repository",
95 tag: WS_METHODS.sourceControlPublishRepository,
96 scheduler: vcsCommandScheduler,
97 concurrency: vcsCommandConcurrency,
98 onSettled: (target, registry) =>
99 invalidateCachedVcsRefs(registry, {
100 environmentId: target.environmentId,
101 cwd: target.input.cwd,
102 }),
103 }),
104 };