alchemy-effect 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (158) hide show
  1. package/bin/alchemy-effect.js +539 -223
  2. package/bin/alchemy-effect.js.map +1 -1
  3. package/lib/apply.d.ts +4 -4
  4. package/lib/apply.d.ts.map +1 -1
  5. package/lib/apply.js +411 -131
  6. package/lib/apply.js.map +1 -1
  7. package/lib/aws/dynamodb/table.provider.d.ts.map +1 -1
  8. package/lib/aws/dynamodb/table.provider.js +1 -0
  9. package/lib/aws/dynamodb/table.provider.js.map +1 -1
  10. package/lib/aws/ec2/index.d.ts +8 -0
  11. package/lib/aws/ec2/index.d.ts.map +1 -1
  12. package/lib/aws/ec2/index.js +8 -0
  13. package/lib/aws/ec2/index.js.map +1 -1
  14. package/lib/aws/ec2/internet-gateway.d.ts +65 -0
  15. package/lib/aws/ec2/internet-gateway.d.ts.map +1 -0
  16. package/lib/aws/ec2/internet-gateway.js +4 -0
  17. package/lib/aws/ec2/internet-gateway.js.map +1 -0
  18. package/lib/aws/ec2/internet-gateway.provider.d.ts +6 -0
  19. package/lib/aws/ec2/internet-gateway.provider.d.ts.map +1 -0
  20. package/lib/aws/ec2/internet-gateway.provider.js +193 -0
  21. package/lib/aws/ec2/internet-gateway.provider.js.map +1 -0
  22. package/lib/aws/ec2/route-table-association.d.ts +63 -0
  23. package/lib/aws/ec2/route-table-association.d.ts.map +1 -0
  24. package/lib/aws/ec2/route-table-association.js +4 -0
  25. package/lib/aws/ec2/route-table-association.js.map +1 -0
  26. package/lib/aws/ec2/route-table-association.provider.d.ts +4 -0
  27. package/lib/aws/ec2/route-table-association.provider.d.ts.map +1 -0
  28. package/lib/aws/ec2/route-table-association.provider.js +121 -0
  29. package/lib/aws/ec2/route-table-association.provider.js.map +1 -0
  30. package/lib/aws/ec2/route-table.d.ts +159 -0
  31. package/lib/aws/ec2/route-table.d.ts.map +1 -0
  32. package/lib/aws/ec2/route-table.js +4 -0
  33. package/lib/aws/ec2/route-table.js.map +1 -0
  34. package/lib/aws/ec2/route-table.provider.d.ts +6 -0
  35. package/lib/aws/ec2/route-table.provider.d.ts.map +1 -0
  36. package/lib/aws/ec2/route-table.provider.js +213 -0
  37. package/lib/aws/ec2/route-table.provider.js.map +1 -0
  38. package/lib/aws/ec2/route.d.ts +155 -0
  39. package/lib/aws/ec2/route.d.ts.map +1 -0
  40. package/lib/aws/ec2/route.js +3 -0
  41. package/lib/aws/ec2/route.js.map +1 -0
  42. package/lib/aws/ec2/route.provider.d.ts +4 -0
  43. package/lib/aws/ec2/route.provider.d.ts.map +1 -0
  44. package/lib/aws/ec2/route.provider.js +166 -0
  45. package/lib/aws/ec2/route.provider.js.map +1 -0
  46. package/lib/aws/ec2/subnet.provider.d.ts.map +1 -1
  47. package/lib/aws/ec2/subnet.provider.js +1 -1
  48. package/lib/aws/ec2/subnet.provider.js.map +1 -1
  49. package/lib/aws/ec2/vpc.d.ts +1 -0
  50. package/lib/aws/ec2/vpc.d.ts.map +1 -1
  51. package/lib/aws/ec2/vpc.provider.d.ts +2 -2
  52. package/lib/aws/ec2/vpc.provider.d.ts.map +1 -1
  53. package/lib/aws/ec2/vpc.provider.js +38 -15
  54. package/lib/aws/ec2/vpc.provider.js.map +1 -1
  55. package/lib/aws/index.d.ts +2 -3
  56. package/lib/aws/index.d.ts.map +1 -1
  57. package/lib/aws/index.js +2 -1
  58. package/lib/aws/index.js.map +1 -1
  59. package/lib/aws/lambda/function.provider.d.ts +2 -2
  60. package/lib/aws/lambda/function.provider.d.ts.map +1 -1
  61. package/lib/aws/lambda/function.provider.js +21 -20
  62. package/lib/aws/lambda/function.provider.js.map +1 -1
  63. package/lib/aws/sqs/queue.provider.d.ts +2 -2
  64. package/lib/aws/sqs/queue.provider.d.ts.map +1 -1
  65. package/lib/aws/sqs/queue.provider.js +3 -2
  66. package/lib/aws/sqs/queue.provider.js.map +1 -1
  67. package/lib/cli/index.d.ts +178 -99
  68. package/lib/cli/index.d.ts.map +1 -1
  69. package/lib/cloudflare/kv/namespace.client.d.ts +1 -1
  70. package/lib/cloudflare/kv/namespace.provider.d.ts.map +1 -1
  71. package/lib/cloudflare/kv/namespace.provider.js +1 -0
  72. package/lib/cloudflare/kv/namespace.provider.js.map +1 -1
  73. package/lib/cloudflare/r2/bucket.provider.d.ts.map +1 -1
  74. package/lib/cloudflare/r2/bucket.provider.js +6 -1
  75. package/lib/cloudflare/r2/bucket.provider.js.map +1 -1
  76. package/lib/cloudflare/worker/worker.provider.d.ts +1 -1
  77. package/lib/cloudflare/worker/worker.provider.d.ts.map +1 -1
  78. package/lib/cloudflare/worker/worker.provider.js +6 -2
  79. package/lib/cloudflare/worker/worker.provider.js.map +1 -1
  80. package/lib/diff.d.ts +8 -6
  81. package/lib/diff.d.ts.map +1 -1
  82. package/lib/diff.js +13 -0
  83. package/lib/diff.js.map +1 -1
  84. package/lib/event.d.ts +1 -1
  85. package/lib/event.d.ts.map +1 -1
  86. package/lib/instance-id.d.ts +8 -0
  87. package/lib/instance-id.d.ts.map +1 -0
  88. package/lib/instance-id.js +12 -0
  89. package/lib/instance-id.js.map +1 -0
  90. package/lib/output.d.ts +4 -2
  91. package/lib/output.d.ts.map +1 -1
  92. package/lib/output.js +18 -4
  93. package/lib/output.js.map +1 -1
  94. package/lib/physical-name.d.ts +14 -1
  95. package/lib/physical-name.d.ts.map +1 -1
  96. package/lib/physical-name.js +41 -2
  97. package/lib/physical-name.js.map +1 -1
  98. package/lib/plan.d.ts +49 -42
  99. package/lib/plan.d.ts.map +1 -1
  100. package/lib/plan.js +359 -127
  101. package/lib/plan.js.map +1 -1
  102. package/lib/provider.d.ts +26 -9
  103. package/lib/provider.d.ts.map +1 -1
  104. package/lib/provider.js +9 -0
  105. package/lib/provider.js.map +1 -1
  106. package/lib/resource.d.ts +2 -2
  107. package/lib/resource.d.ts.map +1 -1
  108. package/lib/resource.js.map +1 -1
  109. package/lib/state.d.ts +86 -9
  110. package/lib/state.d.ts.map +1 -1
  111. package/lib/state.js +21 -18
  112. package/lib/state.js.map +1 -1
  113. package/lib/tags.d.ts +15 -0
  114. package/lib/tags.d.ts.map +1 -1
  115. package/lib/tags.js +27 -0
  116. package/lib/tags.js.map +1 -1
  117. package/lib/test.d.ts +2 -2
  118. package/lib/test.d.ts.map +1 -1
  119. package/lib/test.js +4 -4
  120. package/lib/test.js.map +1 -1
  121. package/lib/todo.d.ts +3 -0
  122. package/lib/todo.d.ts.map +1 -0
  123. package/lib/todo.js +3 -0
  124. package/lib/todo.js.map +1 -0
  125. package/lib/tsconfig.test.tsbuildinfo +1 -1
  126. package/package.json +2 -2
  127. package/src/apply.ts +758 -374
  128. package/src/aws/dynamodb/table.provider.ts +1 -0
  129. package/src/aws/ec2/index.ts +8 -0
  130. package/src/aws/ec2/internet-gateway.provider.ts +316 -0
  131. package/src/aws/ec2/internet-gateway.ts +79 -0
  132. package/src/aws/ec2/route-table-association.provider.ts +214 -0
  133. package/src/aws/ec2/route-table-association.ts +82 -0
  134. package/src/aws/ec2/route-table.provider.ts +306 -0
  135. package/src/aws/ec2/route-table.ts +175 -0
  136. package/src/aws/ec2/route.provider.ts +213 -0
  137. package/src/aws/ec2/route.ts +192 -0
  138. package/src/aws/ec2/subnet.provider.ts +2 -2
  139. package/src/aws/ec2/vpc.provider.ts +43 -19
  140. package/src/aws/ec2/vpc.ts +2 -0
  141. package/src/aws/index.ts +4 -1
  142. package/src/aws/lambda/function.provider.ts +25 -23
  143. package/src/aws/sqs/queue.provider.ts +3 -2
  144. package/src/cloudflare/kv/namespace.provider.ts +1 -0
  145. package/src/cloudflare/r2/bucket.provider.ts +7 -1
  146. package/src/cloudflare/worker/worker.provider.ts +6 -2
  147. package/src/diff.ts +35 -17
  148. package/src/event.ts +6 -0
  149. package/src/instance-id.ts +16 -0
  150. package/src/output.ts +29 -5
  151. package/src/physical-name.ts +57 -2
  152. package/src/plan.ts +488 -197
  153. package/src/provider.ts +46 -9
  154. package/src/resource.ts +50 -4
  155. package/src/state.ts +150 -35
  156. package/src/tags.ts +31 -0
  157. package/src/test.ts +5 -5
  158. package/src/todo.ts +4 -0
package/lib/plan.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../src/plan.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../src/plan.ts"],"names":[],"mappings":"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"}
package/lib/plan.js CHANGED
@@ -1,12 +1,13 @@
1
1
  import * as Context from "effect/Context";
2
- import { App } from "./app.js";
3
2
  import * as Data from "effect/Data";
4
3
  import * as Effect from "effect/Effect";
5
4
  import { omit } from "effect/Struct";
5
+ import { App } from "./app.js";
6
6
  import * as Output from "./output.js";
7
- import {} from "./provider.js";
7
+ import { getProviderByType } from "./provider.js";
8
8
  import { isService } from "./service.js";
9
- import { State, StateStoreError } from "./state.js";
9
+ import { State, StateStoreError, } from "./state.js";
10
+ import { asEffect } from "./util.js";
10
11
  export const isBindNode = (node) => {
11
12
  return (node &&
12
13
  typeof node === "object" &&
@@ -22,34 +23,30 @@ export const isCRUD = (node) => {
22
23
  node.action === "replace" ||
23
24
  node.action === "noop"));
24
25
  };
25
- const Node = (node) => ({
26
- ...node,
27
- toString() {
28
- return `${this.action.charAt(0).toUpperCase()}${this.action.slice(1)}(${this.resource})`;
29
- },
30
- [Symbol.toStringTag]() {
31
- return this.toString();
32
- },
33
- });
34
- export const plan = (...resources) => Effect.gen(function* () {
26
+ export const plan = (..._resources) => Effect.gen(function* () {
35
27
  const state = yield* State;
28
+ const findResources = (resource, visited) => {
29
+ if (visited.has(resource.id)) {
30
+ return [];
31
+ }
32
+ visited.add(resource.id);
33
+ const upstream = Object.values(Output.upstreamAny(resource.props));
34
+ return [
35
+ resource,
36
+ ...upstream,
37
+ ...upstream.flatMap((r) => findResources(r, visited)),
38
+ ];
39
+ };
40
+ const resources = _resources
41
+ .flatMap((r) => findResources(r, new Set()))
42
+ .filter((r, i, arr) => arr.findIndex((r2) => r2.id === r.id) === i);
36
43
  // TODO(sam): rename terminology to Stack
37
44
  const app = yield* App;
38
45
  const resourceIds = yield* state.list({
39
46
  stack: app.name,
40
47
  stage: app.stage,
41
48
  });
42
- const resourcesState = yield* Effect.all(resourceIds.map((id) => state.get({ stack: app.name, stage: app.stage, resourceId: id })));
43
- // map of resource ID -> its downstream dependencies (resources that depend on it)
44
- const downstream = resourcesState
45
- .filter((resource) => !!resource?.bindings)
46
- .flatMap((resource) => resource.bindings.flatMap(({ binding }) => [
47
- [binding.capability.resource.id, binding.capability.resource],
48
- ]))
49
- .reduce((acc, [id, resourceId]) => ({
50
- ...acc,
51
- [id]: [...(acc[id] ?? []), resourceId],
52
- }), {});
49
+ const oldResources = yield* Effect.all(resourceIds.map((id) => state.get({ stack: app.name, stage: app.stage, resourceId: id })));
53
50
  const resolvedResources = {};
54
51
  const resolveResource = (resourceExpr) => Effect.gen(function* () {
55
52
  return yield* (resolvedResources[resourceExpr.src.id] ??=
@@ -62,37 +59,60 @@ export const plan = (...resources) => Effect.gen(function* () {
62
59
  stage: app.stage,
63
60
  resourceId: resource.id,
64
61
  });
65
- if (!oldState) {
62
+ if (!oldState || oldState.status === "creating") {
66
63
  return resourceExpr;
67
64
  }
65
+ const oldProps = oldState.status === "created" ||
66
+ oldState.status === "updated" ||
67
+ oldState.status === "replaced"
68
+ ? // if we're in a stable state, then just use the props
69
+ oldState.props
70
+ : // if we failed to update or replace, compare with the last known stable props
71
+ oldState.status === "updating" ||
72
+ oldState.status === "replacing"
73
+ ? oldState.old.props
74
+ : // TODO(sam): it kinda doesn't make sense to diff with a "deleting" state
75
+ oldState.props;
68
76
  const diff = yield* provider.diff
69
77
  ? provider.diff({
70
78
  id: resource.id,
71
- olds: oldState.props,
79
+ olds: oldProps,
80
+ instanceId: oldState.instanceId,
72
81
  news: props,
73
- output: oldState.output,
82
+ output: oldState.attr,
74
83
  })
75
84
  : Effect.succeed(undefined);
85
+ const stables = [
86
+ ...(provider.stables ?? []),
87
+ ...(diff?.stables ?? []),
88
+ ];
89
+ const withStables = (output) => stables.length > 0
90
+ ? new Output.ResourceExpr(resourceExpr.src, Object.fromEntries(stables.map((stable) => [stable, output?.[stable]])))
91
+ : // if there are no stable properties, treat every property as changed
92
+ resourceExpr;
76
93
  if (diff == null) {
77
- if (arePropsChanged(oldState, props)) {
94
+ if (arePropsChanged(oldProps, props)) {
78
95
  // the props have changed but the provider did not provide any hints as to what is stable
79
96
  // so we must assume everything has changed
80
- return resourceExpr;
97
+ return withStables(oldState?.attr);
81
98
  }
82
99
  }
83
100
  else if (diff.action === "update") {
84
- const output = oldState?.output;
85
- if (diff.stables) {
86
- return new Output.ResourceExpr(resourceExpr.src, Object.fromEntries(diff.stables.map((stable) => [stable, output?.[stable]])));
87
- }
88
- else {
89
- // if there are no stable properties, treat every property as changed
90
- return resourceExpr;
91
- }
101
+ return withStables(oldState?.attr);
92
102
  }
93
103
  else if (diff.action === "replace") {
104
+ return resourceExpr;
105
+ }
106
+ if (oldState.status === "created" ||
107
+ oldState.status === "updated" ||
108
+ oldState.status === "replaced") {
109
+ // we can safely return the attributes if we know they have stabilized
110
+ return oldState?.attr;
111
+ }
112
+ else {
113
+ // we must assume the resource doesn't exist if it hasn't stabilized
114
+ return resourceExpr;
94
115
  }
95
- return oldState?.output;
96
116
  })));
97
117
  });
98
118
  const resolveInput = (input) => Effect.gen(function* () {
@@ -120,36 +140,42 @@ export const plan = (...resources) => Effect.gen(function* () {
120
140
  }
121
141
  else if (Output.isApplyExpr(expr)) {
122
142
  const upstream = yield* resolveOutput(expr.expr);
123
- return Output.isOutput(upstream) ? expr : expr.f(upstream);
143
+ return Output.hasOutputs(upstream) ? expr : expr.f(upstream);
124
144
  }
125
145
  else if (Output.isEffectExpr(expr)) {
126
146
  const upstream = yield* resolveOutput(expr.expr);
127
- return Output.isOutput(upstream) ? expr : yield* expr.f(upstream);
147
+ return Output.hasOutputs(upstream) ? expr : yield* expr.f(upstream);
128
148
  }
129
149
  else if (Output.isAllExpr(expr)) {
130
150
  return yield* Effect.all(expr.outs.map(resolveOutput));
131
151
  }
132
152
  return yield* Effect.die(new Error("Not implemented yet"));
133
153
  });
134
- const resolveUpstream = (value) => {
135
- if (Output.isExpr(value)) {
136
- return Output.upstream(value);
137
- }
138
- else if (Array.isArray(value)) {
139
- return Object.assign({}, ...value.map(resolveUpstream));
140
- }
141
- else if (value &&
142
- (typeof value === "object" || typeof value === "function")) {
143
- return Object.assign({}, ...Object.values(value).map((value) => resolveUpstream(value)));
144
- }
145
- return {};
146
- };
154
+ // map of resource ID -> its downstream dependencies (resources that depend on it)
155
+ const oldDownstreamDependencies = Object.fromEntries(oldResources
156
+ .filter((resource) => !!resource)
157
+ .map((resource) => [resource.logicalId, resource.downstream]));
158
+ const newUpstreamDependencies = Object.fromEntries(resources.map((resource) => [
159
+ resource.id,
160
+ [
161
+ ...Object.values(Output.upstreamAny(resource.props)).map((r) => r.id),
162
+ ...(isService(resource)
163
+ ? resource.props.bindings.capabilities.map((cap) => cap.resource.id)
164
+ : []),
165
+ ],
166
+ ]));
167
+ const newDownstreamDependencies = Object.fromEntries(resources.map((resource) => [
168
+ resource.id,
169
+ Object.entries(newUpstreamDependencies)
170
+ .filter(([_, downstream]) => downstream.includes(resource.id))
171
+ .map(([id]) => id),
172
+ ]));
147
173
  const resourceGraph = Object.fromEntries((yield* Effect.all(resources
148
174
  .flatMap((resource) => [
149
175
  ...(isService(resource)
150
176
  ? resource.props.bindings.capabilities.map((cap) => cap.resource)
151
177
  : []),
152
- ...Object.values(resolveUpstream(resource.props)),
178
+ ...Object.values(Output.upstreamAny(resource.props)),
153
179
  resource,
154
180
  ])
155
181
  .filter((node, i, arr) => arr.findIndex((n) => n.id === node.id) === i)
@@ -163,6 +189,7 @@ export const plan = (...resources) => Effect.gen(function* () {
163
189
  resourceId: id,
164
190
  });
165
191
  const provider = yield* resource.provider.tag;
192
+ const downstream = newDownstreamDependencies[id] ?? [];
166
193
  const bindings = isService(node)
167
194
  ? yield* diffBindings({
168
195
  oldState,
@@ -170,79 +197,197 @@ export const plan = (...resources) => Effect.gen(function* () {
170
197
  target: {
171
198
  id: node.id,
172
199
  props: node.props,
173
- oldAttr: oldState?.output,
200
+ // TODO(sam): pick the right ones based on old status
201
+ oldAttr: oldState?.attr,
174
202
  oldProps: oldState?.props,
175
203
  },
176
204
  })
177
205
  : []; // TODO(sam): return undefined instead of empty array
178
- if (oldState === undefined || oldState.status === "creating") {
206
+ const Node = (node) => ({
207
+ ...node,
208
+ provider,
209
+ resource,
210
+ bindings,
211
+ downstream,
212
+ });
213
+ // handle empty and intermediate (non-final) states:
214
+ if (oldState === undefined) {
179
215
  return Node({
180
216
  action: "create",
181
- news,
182
- provider,
183
- resource,
184
- bindings,
185
- // phantom
186
- attributes: undefined,
217
+ props: news,
218
+ state: oldState,
187
219
  });
188
220
  }
189
- const diff = provider.diff
190
- ? yield* (() => {
191
- const diff = provider.diff({
192
- id,
193
- olds: oldState.props,
194
- news,
195
- output: oldState.output,
221
+ // TODO(sam): is this correct for all possible states a resource can be in?
222
+ const oldProps = oldState.props;
223
+ const diff = yield* asEffect(provider.diff
224
+ ? provider.diff({
225
+ id,
226
+ olds: oldProps,
227
+ instanceId: oldState.instanceId,
228
+ output: oldState.attr,
229
+ news,
230
+ })
231
+ : undefined).pipe(Effect.map((diff) => diff ??
232
+ {
233
+ action: arePropsChanged(oldProps, news)
234
+ ? "update"
235
+ : "noop",
236
+ }));
237
+ if (oldState.status === "creating") {
238
+ if (diff.action === "noop") {
239
+ // we're in the creating state and props are un-changed
240
+ // let's just continue where we left off
241
+ return Node({
242
+ action: "create",
243
+ props: news,
244
+ state: oldState,
245
+ });
246
+ }
247
+ else if (diff.action === "update") {
248
+ // props have changed in a way that is updatable
249
+ // again, just continue with the create
250
+ // TODO(sam): should we maybe try an update instead?
251
+ return Node({
252
+ action: "create",
253
+ props: news,
254
+ state: oldState,
255
+ });
256
+ }
257
+ else {
258
+ // props have changed in an incompatible way
259
+ // because it's possible that an un-updatable resource has already been created
260
+ // we must use a replace step to create a new one and delete the potential old one
261
+ return Node({
262
+ action: "replace",
263
+ props: news,
264
+ deleteFirst: diff.deleteFirst ?? false,
265
+ state: oldState,
266
+ });
267
+ }
268
+ }
269
+ else if (oldState.status === "updating") {
270
+ // we started to update a resource but did not complete
271
+ if (diff.action === "update" || diff.action === "noop") {
272
+ return Node({
273
+ action: "update",
274
+ props: news,
275
+ state: oldState,
276
+ });
277
+ }
278
+ else {
279
+ // we started to update a resource but now believe we should replace it
280
+ return Node({
281
+ action: "replace",
282
+ deleteFirst: diff.deleteFirst ?? false,
283
+ props: news,
284
+ // TODO(sam): can Apply handle replacements when the oldState is UpdatingResourceState?
285
+ // -> or is there we do a provider.read to try and reconcile back to UpdatedResourceState?
286
+ state: oldState,
287
+ });
288
+ }
289
+ }
290
+ else if (oldState.status === "replacing") {
291
+ // resource replacement started, but the replacement may or may not have been created
292
+ if (diff.action === "noop") {
293
+ // this is the stable case - noop means just continue with the replacement
294
+ return Node({
295
+ action: "replace",
296
+ deleteFirst: oldState.deleteFirst,
297
+ props: news,
298
+ state: oldState,
299
+ });
300
+ }
301
+ else if (diff.action === "update") {
302
+ // potential problem here - the props have changed since we tried to replace,
303
+ // but not enough to trigger another replacement. the resource provider should
304
+ // be designed as idempotent to converge to the right state when creating the new resource
305
+ // the newly generated instanceId is intended to assist with this
306
+ return Node({
307
+ action: "replace",
308
+ deleteFirst: oldState.deleteFirst,
309
+ props: news,
310
+ state: oldState,
311
+ });
312
+ }
313
+ else {
314
+ // ah shit, so we tried to replace the resource and then crashed
315
+ // now the props have changed again in such a way that the (maybe, maybe not)
316
+ // created resource should also be replaced
317
+ // TODO(sam): what should we do?
318
+ // 1. trigger a deletion of the potentially created resource
319
+ // 2. expect the resource provider to handle it idempotently?
320
+ // -> i don't think this case is fair to put on the resource provider
321
+ // because if the resource was created, it's in a state that can't be updated
322
+ return yield* Effect.fail(new CannotReplacePartiallyReplacedResource(id));
323
+ }
324
+ }
325
+ else if (oldState.status === "replaced") {
326
+ // replacement has been created but we're not done cleaning up the old state
327
+ if (diff.action === "noop") {
328
+ // this is the stable case - noop means just continue cleaning up the replacement
329
+ return Node({
330
+ action: "replace",
331
+ deleteFirst: oldState.deleteFirst,
332
+ props: news,
333
+ state: oldState,
334
+ });
335
+ }
336
+ else if (diff.action === "update") {
337
+ // the replacement has been created but now also needs to be updated
338
+ // the resource provider should:
339
+ // 1. Update the newly created replacement resource
340
+ // 2. Then proceed as normal to delete the replaced resources (after all downstream references are updated)
341
+ return Node({
342
+ action: "update",
343
+ props: news,
344
+ state: oldState,
345
+ });
346
+ }
347
+ else {
348
+ // the replacement has been created but now it needs to be replaced
349
+ // this is the worst-case scenario because downstream resources
350
+ // could have been been updated to point to the replaced resources
351
+ return yield* Effect.fail(new CannotReplacePartiallyReplacedResource(id));
352
+ }
353
+ }
354
+ else if (oldState.status === "deleting") {
355
+ if (diff.action === "noop" || diff.action === "update") {
356
+ // we're in a partially deleted state, it is unclear whether it was or was not deleted
357
+ // it should be safe to re-create it with the same instanceId?
358
+ return Node({
359
+ action: "create",
360
+ props: news,
361
+ state: {
362
+ ...oldState,
363
+ status: "creating",
364
+ props: news,
365
+ },
196
366
  });
197
- return Effect.isEffect(diff) ? diff : Effect.succeed(diff);
198
- })()
199
- : undefined;
200
- if (!diff && arePropsChanged(oldState, news)) {
367
+ }
368
+ else {
369
+ return yield* Effect.fail(new CannotReplacePartiallyReplacedResource(id));
370
+ }
371
+ }
372
+ else if (diff.action === "update") {
201
373
  return Node({
202
374
  action: "update",
203
- olds: oldState.props,
204
- news,
205
- output: oldState.output,
206
- provider,
207
- resource,
208
- bindings,
209
- // phantom
210
- attributes: undefined,
375
+ props: news,
376
+ state: oldState,
211
377
  });
212
378
  }
213
- else if (diff?.action === "replace") {
379
+ else if (diff.action === "replace") {
214
380
  return Node({
215
381
  action: "replace",
216
- olds: oldState.props,
217
- news,
218
- output: oldState.output,
219
- provider,
220
- resource,
221
- bindings,
222
- // phantom
223
- attributes: undefined,
224
- });
225
- }
226
- else if (diff?.action === "update") {
227
- return Node({
228
- action: "update",
229
- olds: oldState.props,
230
- news,
231
- output: oldState.output,
232
- provider,
233
- resource,
234
- bindings,
235
- // phantom
236
- attributes: undefined,
382
+ props: news,
383
+ state: oldState,
384
+ deleteFirst: diff?.deleteFirst ?? false,
237
385
  });
238
386
  }
239
387
  else {
240
388
  return Node({
241
389
  action: "noop",
242
- resource,
243
- bindings,
244
- // phantom
245
- attributes: undefined,
390
+ state: oldState,
246
391
  });
247
392
  }
248
393
  })))).map((update) => [update.resource.id, update]));
@@ -255,35 +400,30 @@ export const plan = (...resources) => Effect.gen(function* () {
255
400
  stage: app.stage,
256
401
  resourceId: id,
257
402
  });
258
- const context = yield* Effect.context();
259
403
  if (oldState) {
260
- const provider = context.unsafeMap.get(oldState?.type);
261
- if (!provider) {
262
- yield* Effect.die(new Error(`Provider not found for ${oldState?.type}`));
263
- }
404
+ const provider = yield* getProviderByType(oldState.resourceType);
264
405
  return [
265
406
  id,
266
407
  {
267
408
  action: "delete",
268
- olds: oldState.props,
269
- output: oldState.output,
270
- provider,
271
- attributes: oldState?.output,
272
- // TODO(sam): Support Detach Bindings
409
+ state: oldState,
410
+ // // TODO(sam): Support Detach Bindings
273
411
  bindings: [],
412
+ provider,
274
413
  resource: {
275
414
  id: id,
276
- type: oldState.type,
277
- attr: oldState.output,
415
+ type: oldState.resourceType,
416
+ attr: oldState.attr,
278
417
  props: oldState.props,
279
418
  },
280
- downstream: downstream[id] ?? [],
419
+ // TODO(sam): is it enough to just pass through oldState?
420
+ downstream: oldDownstreamDependencies[id] ?? [],
281
421
  },
282
422
  ];
283
423
  }
284
424
  })))).filter((v) => !!v));
285
425
  for (const [resourceId, deletion] of Object.entries(deletions)) {
286
- const dependencies = deletion.downstream.filter((d) => d in resourceGraph);
426
+ const dependencies = deletion.state.downstream.filter((d) => d in resourceGraph);
287
427
  if (dependencies.length > 0) {
288
428
  return yield* Effect.fail(new DeleteResourceHasDownstreamDependencies({
289
429
  message: `Resource ${resourceId} has downstream dependencies`,
@@ -297,16 +437,29 @@ export const plan = (...resources) => Effect.gen(function* () {
297
437
  deletions,
298
438
  };
299
439
  });
300
- class DeleteResourceHasDownstreamDependencies extends Data.TaggedError("DeleteResourceHasDownstreamDependencies") {
440
+ export class CannotReplacePartiallyReplacedResource extends Data.TaggedError("CannotReplacePartiallyReplacedResource") {
441
+ constructor(logicalId) {
442
+ super({
443
+ message: `Resource '${logicalId}' did not finish being replaced in a previous deployment ` +
444
+ `and is expected to be replaced again in this deployment. ` +
445
+ `You should revert its properties and try again after a successful deployment.`,
446
+ logicalId,
447
+ });
448
+ }
449
+ }
450
+ export class DeleteResourceHasDownstreamDependencies extends Data.TaggedError("DeleteResourceHasDownstreamDependencies") {
301
451
  }
302
- const arePropsChanged = (oldState, newProps) => {
303
- return (JSON.stringify(omit(oldState?.props ?? {}, "bindings")) !==
304
- JSON.stringify(omit((newProps ?? {}), "bindings")));
452
+ const arePropsChanged = (oldProps, newProps) => {
453
+ return (Output.hasOutputs(newProps) ||
454
+ JSON.stringify(omit((oldProps ?? {}), "bindings")) !==
455
+ JSON.stringify(omit((newProps ?? {}), "bindings")));
305
456
  };
306
457
  const diffBindings = Effect.fn(function* ({ oldState, bindings, target, }) {
307
458
  // const actions: BindNode[] = [];
308
459
  const oldBindings = oldState?.bindings;
309
- const oldSids = new Set(oldBindings?.map(({ binding }) => binding.capability.sid));
460
+ // const oldSids = new Set(
461
+ // oldBindings?.map(({ binding }) => binding.capability.sid),
462
+ // );
310
463
  const diffBinding = Effect.fn(function* (binding) {
311
464
  const cap = binding.capability;
312
465
  const sid = cap.sid ?? `${cap.action}:${cap.resource.ID}`;
@@ -383,7 +536,7 @@ const isBindingDiff = Effect.fn(function* ({ target, oldBinding: { binding: oldB
383
536
  id: oldCap.resource.id,
384
537
  props: newCap.resource.props,
385
538
  oldProps: oldState?.props,
386
- oldAttr: oldState?.output,
539
+ oldAttr: oldState?.attr,
387
540
  },
388
541
  props: newBinding.props,
389
542
  attr: oldBinding.attr,
@@ -403,4 +556,83 @@ const isBindingDiff = Effect.fn(function* ({ target, oldBinding: { binding: oldB
403
556
  });
404
557
  // TODO(sam): compare props
405
558
  // oldBinding.props !== newBinding.props;
559
+ /**
560
+ * Print a plan in a human-readable format that shows the graph topology.
561
+ */
562
+ export const printPlan = (plan) => {
563
+ const lines = [];
564
+ const allNodes = { ...plan.resources, ...plan.deletions };
565
+ // Build reverse mapping: upstream -> downstream
566
+ const upstreamMap = {};
567
+ for (const [id] of Object.entries(allNodes)) {
568
+ upstreamMap[id] = [];
569
+ }
570
+ for (const [id, node] of Object.entries(allNodes)) {
571
+ if (!node)
572
+ continue;
573
+ for (const downstreamId of node.state?.downstream ?? []) {
574
+ if (upstreamMap[downstreamId]) {
575
+ upstreamMap[downstreamId].push(id);
576
+ }
577
+ }
578
+ }
579
+ // Action symbols
580
+ const actionSymbol = (action) => {
581
+ switch (action) {
582
+ case "create":
583
+ return "+";
584
+ case "update":
585
+ return "~";
586
+ case "delete":
587
+ return "-";
588
+ case "replace":
589
+ return "±";
590
+ case "noop":
591
+ return "=";
592
+ default:
593
+ return "?";
594
+ }
595
+ };
596
+ // Print header
597
+ lines.push("╔════════════════════════════════════════════════════════════════╗");
598
+ lines.push("║ PLAN ║");
599
+ lines.push("╠════════════════════════════════════════════════════════════════╣");
600
+ lines.push("║ Legend: + create, ~ update, - delete, ± replace, = noop ║");
601
+ lines.push("╚════════════════════════════════════════════════════════════════╝");
602
+ lines.push("");
603
+ // Print resources section
604
+ lines.push("┌─ Resources ────────────────────────────────────────────────────┐");
605
+ const resourceIds = Object.keys(plan.resources).sort();
606
+ for (const id of resourceIds) {
607
+ const node = plan.resources[id];
608
+ const symbol = actionSymbol(node.action);
609
+ const type = node.resource?.type ?? "unknown";
610
+ const downstream = node.state?.downstream?.length
611
+ ? ` → [${node.state?.downstream.join(", ")}]`
612
+ : "";
613
+ lines.push(`│ [${symbol}] ${id} (${type})${downstream}`);
614
+ }
615
+ if (resourceIds.length === 0) {
616
+ lines.push("│ (none)");
617
+ }
618
+ lines.push("└────────────────────────────────────────────────────────────────┘");
619
+ lines.push("");
620
+ // Print deletions section
621
+ lines.push("┌─ Deletions ────────────────────────────────────────────────────┐");
622
+ const deletionIds = Object.keys(plan.deletions).sort();
623
+ for (const id of deletionIds) {
624
+ const node = plan.deletions[id];
625
+ const type = node.resource?.type ?? "unknown";
626
+ const downstream = node.state.downstream?.length
627
+ ? ` → [${node.state.downstream.join(", ")}]`
628
+ : "";
629
+ lines.push(`│ [-] ${id} (${type})${downstream}`);
630
+ }
631
+ if (deletionIds.length === 0) {
632
+ lines.push("│ (none)");
633
+ }
634
+ lines.push("└────────────────────────────────────────────────────────────────┘");
635
+ lines.push("");
636
+ return lines.join("\n");
637
+ };
406
638
  //# sourceMappingURL=plan.js.map