|
1 | 1 | import * as Data from "effect/Data"; |
2 | 2 | import * as Effect from "effect/Effect"; |
3 | 3 | import util from "node:util"; |
4 | | -import { isBound, type Bound } from "./bind.ts"; |
5 | 4 | import type { Capability, SerializedCapability } from "./capability.ts"; |
6 | | -import type { Phase } from "./phase.ts"; |
| 5 | +import type { Instance } from "./policy.ts"; |
7 | 6 | import { Provider, type ProviderService } from "./provider.ts"; |
8 | 7 | import type { Resource } from "./resource.ts"; |
9 | | -import type { Runtime } from "./runtime.ts"; |
| 8 | +import type { Service } from "./service.ts"; |
10 | 9 | import { State, type ResourceState } from "./state.ts"; |
11 | 10 |
|
12 | 11 | export type PlanError = never; |
@@ -139,65 +138,42 @@ export type Replace<R extends Resource> = { |
139 | 138 | deleteFirst?: boolean; |
140 | 139 | }; |
141 | 140 |
|
142 | | -type PlanNode = Bound<any> | Resource; |
143 | | -type PlanGraph = { |
144 | | - [id in string]: PlanNode; |
145 | | -}; |
146 | | -type PlanGraphEffect = Effect.Effect<PlanGraph, never, unknown>; |
147 | | - |
148 | | -type ApplyAll< |
149 | | - Subgraphs extends PlanGraphEffect[], |
150 | | - Accum extends Record<string, CRUD> = {}, |
151 | | -> = Subgraphs extends [ |
152 | | - infer Head extends PlanGraphEffect, |
153 | | - ...infer Tail extends PlanGraphEffect[], |
154 | | -] |
155 | | - ? ApplyAll< |
156 | | - Tail, |
157 | | - Accum & { |
158 | | - [id in keyof Effect.Effect.Success<Head>]: _Apply< |
159 | | - Extract<Effect.Effect.Success<Head>[id], PlanNode> |
160 | | - >; |
161 | | - } |
162 | | - > |
163 | | - : Accum; |
164 | | - |
165 | | -type _Apply<Item extends PlanNode> = |
166 | | - Item extends Bound<infer Run extends Runtime<string, any, any>> |
167 | | - ? Apply<Run> |
168 | | - : Item extends Resource |
169 | | - ? Apply<Item> |
170 | | - : never; |
171 | | - |
172 | | -type DerivePlan< |
173 | | - P extends Phase = Phase, |
174 | | - Resources extends PlanGraphEffect[] = PlanGraphEffect[], |
175 | | -> = P extends "update" |
176 | | - ? |
177 | | - | { |
178 | | - [k in keyof ApplyAll<Resources>]: ApplyAll<Resources>[k]; |
179 | | - } |
180 | | - | { |
181 | | - [k in Exclude<string, keyof ApplyAll<Resources>>]: Delete<Resource>; |
182 | | - } |
183 | | - : { |
184 | | - [k in Exclude<string, keyof ApplyAll<Resources>>]: Delete<Resource>; |
185 | | - }; |
186 | | - |
187 | 141 | export type Plan = { |
188 | 142 | [id in string]: CRUD; |
189 | 143 | }; |
190 | 144 |
|
191 | 145 | export const plan = < |
192 | 146 | const Phase extends "update" | "destroy", |
193 | | - const Resources extends PlanGraphEffect[], |
| 147 | + const Services extends Service[], |
194 | 148 | >({ |
195 | 149 | phase, |
196 | | - resources, |
| 150 | + services, |
197 | 151 | }: { |
198 | 152 | phase: Phase; |
199 | | - resources: Resources; |
| 153 | + services: Services; |
200 | 154 | }) => { |
| 155 | + type ServiceIDs = Services[number]["id"]; |
| 156 | + type ServiceHosts = { |
| 157 | + [ID in ServiceIDs]: Extract<Services[number], Service<Extract<ID, string>>>; |
| 158 | + }; |
| 159 | + |
| 160 | + type UpstreamTags = { |
| 161 | + [ID in ServiceIDs]: ServiceHosts[ID]["props"]["bindings"]["tags"][number]; |
| 162 | + }[ServiceIDs]; |
| 163 | + type UpstreamResources = { |
| 164 | + [ID in ServiceIDs]: Extract< |
| 165 | + ServiceHosts[ID]["props"]["bindings"]["capabilities"][number]["resource"], |
| 166 | + Resource |
| 167 | + >; |
| 168 | + }[ServiceIDs]; |
| 169 | + type Graph = { |
| 170 | + [ID in ServiceIDs]: Apply<Extract<Instance<ServiceHosts[ID]>, Resource>>; |
| 171 | + } & { |
| 172 | + [ID in UpstreamResources["id"]]: Apply< |
| 173 | + Extract<UpstreamResources, { id: ID }> |
| 174 | + >; |
| 175 | + }; |
| 176 | + |
201 | 177 | return Effect.gen(function* () { |
202 | 178 | const state = yield* State; |
203 | 179 |
|
@@ -228,7 +204,7 @@ export const plan = < |
228 | 204 | const updates = ( |
229 | 205 | phase === "update" |
230 | 206 | ? yield* Effect.all( |
231 | | - resources.map((resource) => |
| 207 | + services.map((resource) => |
232 | 208 | Effect.flatMap( |
233 | 209 | resource, |
234 | 210 | Effect.fn(function* (subgraph: { |
@@ -405,9 +381,11 @@ export const plan = < |
405 | 381 | {} as any, |
406 | 382 | ); |
407 | 383 | }) as Effect.Effect< |
408 | | - DerivePlan<Phase, Resources>, |
| 384 | + { |
| 385 | + [ID in keyof Graph]: Graph[ID]; |
| 386 | + }, |
409 | 387 | never, |
410 | | - Effect.Effect.Context<Resources[number]> | State |
| 388 | + UpstreamTags | State |
411 | 389 | >; |
412 | 390 | }; |
413 | 391 |
|
|
0 commit comments