Skip to content
Source
Sign inSign up
Open History to see the last commit

persistence.ts

157 lines5.4 KB

1import {
2 type EnvironmentId,
3 type OrchestrationV2ShellSnapshot,
4 type OrchestrationV2ThreadDetailSnapshot,
5 type ServerConfig,
6 type ThreadId,
7 type VcsListRefsResult,
8} from "@t3tools/contracts";
9import * as Context from "effect/Context";
10import * as Effect from "effect/Effect";
11import * as Option from "effect/Option";
12import * as Schema from "effect/Schema";
13​
14import type { ConnectionRegistration } from "../connection/catalog.ts";
15import type { DeferredShellSnapshot } from "../state/shellPullRequests.ts";
16import type { ConnectionTarget, PersistedConnectionTarget } from "../connection/model.ts";
17import type { ShellCacheOrigin } from "./orchestrationCache.ts";
18​
19export type { ShellCacheOrigin };
20​
21export interface CachedShellSnapshot extends DeferredShellSnapshot {
22 readonly origin?: ShellCacheOrigin;
24​
25export class ConnectionPersistenceError extends Schema.TaggedError<ConnectionPersistenceError>()(
26 "ConnectionPersistenceError",
27 {
28 operation: Schema.Literals([
29 "list-targets",
30 "list-disabled-targets",
31 "register-connection",
32 "set-connection-routes",
33 "remove-connection",
34 "set-connection-enabled",
35 "load-shell",
36 "save-shell",
37 "load-thread",
38 "save-thread",
39 "remove-thread",
40 "load-server-config",
41 "save-server-config",
42 "load-vcs-refs",
43 "save-vcs-refs",
44 "remove-vcs-refs",
45 "clear-vcs-refs",
46 "clear-environment",
47 ]),
48 message: Schema.String,
49 },
50) {}
51​
52export class ConnectionTargetStore extends Context.Service<
53 ConnectionTargetStore,
54 {
55 readonly list: Effect.Effect<ReadonlyArray<ConnectionTarget>, ConnectionPersistenceError>;
56 readonly listDisabled: Effect.Effect<ReadonlyArray<EnvironmentId>, ConnectionPersistenceError>;
57 }
58>()("@t3tools/client-runtime/platform/persistence/ConnectionTargetStore") {}
59​
60export class ConnectionRegistrationStore extends Context.Service<
61 ConnectionRegistrationStore,
62 {
63 /**
64 * Records of routes missing from `routes` are dropped.
65 */
66 readonly register: (
67 registration: ConnectionRegistration,
68 routes: ReadonlyArray<PersistedConnectionTarget>,
69 ) => Effect.Effect<void, ConnectionPersistenceError>;
70 /**
71 * `routes` must not be empty.
72 */
73 readonly setRoutes: (
74 environmentId: EnvironmentId,
75 routes: ReadonlyArray<PersistedConnectionTarget>,
76 ) => Effect.Effect<void, ConnectionPersistenceError>;
77 readonly remove: (
78 environmentId: EnvironmentId,
79 ) => Effect.Effect<void, ConnectionPersistenceError>;
80 readonly setEnabled: (
81 environmentId: EnvironmentId,
82 enabled: boolean,
83 ) => Effect.Effect<void, ConnectionPersistenceError>;
84 }
85>()("@t3tools/client-runtime/platform/persistence/ConnectionRegistrationStore") {}
86​
87export class EnvironmentCacheStore extends Context.Service<
88 EnvironmentCacheStore,
89 {
90 readonly loadShell: (
91 environmentId: EnvironmentId,
92 ) => Effect.Effect<Option.Option<CachedShellSnapshot>, ConnectionPersistenceError>;
93 /** `origin` only when the rows descend from a server snapshot. */
94 readonly saveShell: (
95 environmentId: EnvironmentId,
96 snapshot: OrchestrationV2ShellSnapshot,
97 origin?: ShellCacheOrigin,
98 ) => Effect.Effect<void, ConnectionPersistenceError>;
99 readonly loadThread: (
100 environmentId: EnvironmentId,
101 threadId: ThreadId,
102 ) => Effect.Effect<
103 Option.Option<OrchestrationV2ThreadDetailSnapshot>,
104 ConnectionPersistenceError
105 >;
106 readonly saveThread: (
107 environmentId: EnvironmentId,
108 snapshot: OrchestrationV2ThreadDetailSnapshot,
109 ) => Effect.Effect<void, ConnectionPersistenceError>;
110 readonly removeThread: (
111 environmentId: EnvironmentId,
112 threadId: ThreadId,
113 ) => Effect.Effect<void, ConnectionPersistenceError>;
114 readonly loadServerConfig: (
115 environmentId: EnvironmentId,
116 ) => Effect.Effect<Option.Option<ServerConfig>, ConnectionPersistenceError>;
117 readonly saveServerConfig: (
118 environmentId: EnvironmentId,
119 config: ServerConfig,
120 ) => Effect.Effect<void, ConnectionPersistenceError>;
121 /**
122 * Query-specific lists are not cached because they are incomplete and unsafe
123 * to present as a full picker.
124 */
125 readonly loadVcsRefs: (
126 environmentId: EnvironmentId,
127 cwd: string,
128 ) => Effect.Effect<Option.Option<VcsListRefsResult>, ConnectionPersistenceError>;
129 readonly saveVcsRefs: (
130 environmentId: EnvironmentId,
131 cwd: string,
132 refs: VcsListRefsResult,
133 ) => Effect.Effect<void, ConnectionPersistenceError>;
134 readonly removeVcsRefs: (
135 environmentId: EnvironmentId,
136 cwd: string,
137 ) => Effect.Effect<void, ConnectionPersistenceError>;
138 /**
139 * Git ref mutations are repository-wide, and linked worktrees may have
140 * cached the same refs under different working-directory keys.
141 */
142 readonly clearVcsRefs: (
143 environmentId: EnvironmentId,
144 ) => Effect.Effect<void, ConnectionPersistenceError>;
145 readonly clear: (
146 environmentId: EnvironmentId,
147 ) => Effect.Effect<void, ConnectionPersistenceError>;
148 }
149>()("@t3tools/client-runtime/platform/persistence/EnvironmentCacheStore") {}
150​
151export class EnvironmentOwnedDataCleanup extends Context.Reference<{
152 readonly clear: (environmentId: EnvironmentId) => Effect.Effect<void>;
153}>("@t3tools/client-runtime/platform/persistence/EnvironmentOwnedDataCleanup", {
154 defaultValue: () => ({
155 clear: () => Effect.void,
156 }),
157}) {}