@terraforge/core 0.0.3 → 0.0.5

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.
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/node.ts
2
- var nodeMetaSymbol = Symbol("metadata");
2
+ var nodeMetaSymbol = /* @__PURE__ */ Symbol("metadata");
3
3
  var isNode = (obj) => {
4
4
  const meta = obj[nodeMetaSymbol];
5
5
  return meta && typeof meta === "object" && meta !== null && "tag" in meta && typeof meta.tag === "string";
@@ -15,17 +15,14 @@ var isDataSource = (obj) => {
15
15
  };
16
16
 
17
17
  // src/group.ts
18
- class Group {
19
- parent;
20
- type;
21
- name;
22
- children = [];
18
+ var Group = class _Group {
23
19
  constructor(parent, type, name) {
24
20
  this.parent = parent;
25
21
  this.type = type;
26
22
  this.name = name;
27
23
  parent?.children.push(this);
28
24
  }
25
+ children = [];
29
26
  get urn() {
30
27
  const urn = this.parent ? this.parent.urn : "urn";
31
28
  return `${urn}:${this.type}:{${this.name}}`;
@@ -38,8 +35,8 @@ class Group {
38
35
  throw new Error(`Duplicate node found: ${meta.type}:${meta.logicalId}`);
39
36
  }
40
37
  }
41
- if (child instanceof Group) {
42
- const duplicate = this.children.filter((c) => c instanceof Group).find((c) => c.type === child.type && c.name === child.name);
38
+ if (child instanceof _Group) {
39
+ const duplicate = this.children.filter((c) => c instanceof _Group).find((c) => c.type === child.type && c.name === child.name);
43
40
  if (duplicate) {
44
41
  throw new Error(`Duplicate group found: ${child.type}:${child.name}`);
45
42
  }
@@ -53,7 +50,7 @@ class Group {
53
50
  }
54
51
  get nodes() {
55
52
  return this.children.map((child) => {
56
- if (child instanceof Group) {
53
+ if (child instanceof _Group) {
57
54
  return child.nodes;
58
55
  }
59
56
  if (isNode(child)) {
@@ -68,16 +65,15 @@ class Group {
68
65
  get dataSources() {
69
66
  return this.nodes.filter((node) => isDataSource(node));
70
67
  }
71
- }
68
+ };
72
69
 
73
70
  // src/stack.ts
74
- class Stack extends Group {
75
- app;
76
- dependencies = new Set;
71
+ var Stack = class extends Group {
77
72
  constructor(app, name) {
78
73
  super(app, "stack", name);
79
74
  this.app = app;
80
75
  }
76
+ dependencies = /* @__PURE__ */ new Set();
81
77
  dependsOn(...stacks) {
82
78
  for (const stack of stacks) {
83
79
  if (stack.app !== this.app) {
@@ -87,7 +83,7 @@ class Stack extends Group {
87
83
  }
88
84
  return this;
89
85
  }
90
- }
86
+ };
91
87
  var findParentStack = (group) => {
92
88
  if (group instanceof Stack) {
93
89
  return group;
@@ -99,31 +95,29 @@ var findParentStack = (group) => {
99
95
  };
100
96
 
101
97
  // src/app.ts
102
- class App extends Group {
103
- name;
98
+ var App = class extends Group {
104
99
  constructor(name) {
105
- super(undefined, "app", name);
100
+ super(void 0, "app", name);
106
101
  this.name = name;
107
102
  }
108
103
  get stacks() {
109
104
  return this.children.filter((child) => child instanceof Stack);
110
105
  }
111
- }
106
+ };
107
+
112
108
  // src/future.ts
113
109
  var IDLE = 0;
114
110
  var PENDING = 1;
115
111
  var RESOLVED = 2;
116
112
  var REJECTED = 3;
117
-
118
- class Future {
119
- callback;
120
- listeners = new Set;
121
- status = IDLE;
122
- data;
123
- error;
113
+ var Future = class _Future {
124
114
  constructor(callback) {
125
115
  this.callback = callback;
126
116
  }
117
+ listeners = /* @__PURE__ */ new Set();
118
+ status = IDLE;
119
+ data;
120
+ error;
127
121
  get [Symbol.toStringTag]() {
128
122
  switch (this.status) {
129
123
  case IDLE:
@@ -137,42 +131,45 @@ class Future {
137
131
  }
138
132
  }
139
133
  pipe(cb) {
140
- return new Future((resolve, reject) => {
134
+ return new _Future((resolve2, reject) => {
141
135
  this.then((value) => {
142
136
  Promise.resolve(cb(value)).then((value2) => {
143
- resolve(value2);
137
+ resolve2(value2);
144
138
  }).catch(reject);
145
139
  }, reject);
146
140
  });
147
141
  }
148
- then(resolve, reject) {
142
+ then(resolve2, reject) {
149
143
  if (this.status === RESOLVED) {
150
- resolve(this.data);
144
+ resolve2(this.data);
151
145
  } else if (this.status === REJECTED) {
152
146
  reject?.(this.error);
153
147
  } else {
154
- this.listeners.add({ resolve, reject });
148
+ this.listeners.add({ resolve: resolve2, reject });
155
149
  if (this.status === IDLE) {
156
150
  this.status = PENDING;
157
- this.callback((data) => {
158
- if (this.status === PENDING) {
159
- this.status = RESOLVED;
160
- this.data = data;
161
- this.listeners.forEach(({ resolve: resolve2 }) => resolve2(data));
162
- this.listeners.clear();
163
- }
164
- }, (error) => {
165
- if (this.status === PENDING) {
166
- this.status = REJECTED;
167
- this.error = error;
168
- this.listeners.forEach(({ reject: reject2 }) => reject2?.(error));
169
- this.listeners.clear();
151
+ this.callback(
152
+ (data) => {
153
+ if (this.status === PENDING) {
154
+ this.status = RESOLVED;
155
+ this.data = data;
156
+ this.listeners.forEach(({ resolve: resolve3 }) => resolve3(data));
157
+ this.listeners.clear();
158
+ }
159
+ },
160
+ (error) => {
161
+ if (this.status === PENDING) {
162
+ this.status = REJECTED;
163
+ this.error = error;
164
+ this.listeners.forEach(({ reject: reject2 }) => reject2?.(error));
165
+ this.listeners.clear();
166
+ }
170
167
  }
171
- });
168
+ );
172
169
  }
173
170
  }
174
171
  }
175
- }
172
+ };
176
173
 
177
174
  // src/input.ts
178
175
  var findInputDeps = (props) => {
@@ -201,26 +198,32 @@ var resolveInputs = async (inputs) => {
201
198
  }
202
199
  };
203
200
  find(inputs, {}, "root");
204
- const responses = await Promise.all(unresolved.map(async ([obj, key]) => {
205
- const promise = obj[key];
206
- let timeout;
207
- const response = await Promise.race([
208
- promise,
209
- new Promise((_, reject) => {
210
- timeout = setTimeout(() => {
211
- if (promise instanceof Output) {
212
- reject(new Error(`Resolving Output<${[...promise.dependencies].map((d) => d.urn).join(", ")}> took too long.`));
213
- } else if (promise instanceof Future) {
214
- reject(new Error("Resolving Future took too long."));
215
- } else {
216
- reject(new Error("Resolving Promise took too long."));
217
- }
218
- }, 3000);
219
- })
220
- ]);
221
- clearTimeout(timeout);
222
- return response;
223
- }));
201
+ const responses = await Promise.all(
202
+ unresolved.map(async ([obj, key]) => {
203
+ const promise = obj[key];
204
+ let timeout;
205
+ const response = await Promise.race([
206
+ promise,
207
+ new Promise((_, reject) => {
208
+ timeout = setTimeout(() => {
209
+ if (promise instanceof Output) {
210
+ reject(
211
+ new Error(
212
+ `Resolving Output<${[...promise.dependencies].map((d) => d.urn).join(", ")}> took too long.`
213
+ )
214
+ );
215
+ } else if (promise instanceof Future) {
216
+ reject(new Error("Resolving Future took too long."));
217
+ } else {
218
+ reject(new Error("Resolving Promise took too long."));
219
+ }
220
+ }, 3e3);
221
+ })
222
+ ]);
223
+ clearTimeout(timeout);
224
+ return response;
225
+ })
226
+ );
224
227
  unresolved.forEach(([props, key], i) => {
225
228
  props[key] = responses[i];
226
229
  });
@@ -228,33 +231,32 @@ var resolveInputs = async (inputs) => {
228
231
  };
229
232
 
230
233
  // src/output.ts
231
- class Output extends Future {
232
- dependencies;
234
+ var Output = class _Output extends Future {
233
235
  constructor(dependencies, callback) {
234
236
  super(callback);
235
237
  this.dependencies = dependencies;
236
238
  }
237
239
  pipe(cb) {
238
- return new Output(this.dependencies, (resolve, reject) => {
240
+ return new _Output(this.dependencies, (resolve2, reject) => {
239
241
  this.then((value) => {
240
242
  Promise.resolve(cb(value)).then((value2) => {
241
- resolve(value2);
243
+ resolve2(value2);
242
244
  }).catch(reject);
243
245
  }, reject);
244
246
  });
245
247
  }
246
- }
248
+ };
247
249
  var deferredOutput = (cb) => {
248
- return new Output(new Set, cb);
250
+ return new Output(/* @__PURE__ */ new Set(), cb);
249
251
  };
250
252
  var output = (value) => {
251
- return deferredOutput((resolve) => resolve(value));
253
+ return deferredOutput((resolve2) => resolve2(value));
252
254
  };
253
255
  var combine = (...inputs) => {
254
256
  const deps = new Set(findInputDeps(inputs));
255
- return new Output(deps, (resolve, reject) => {
257
+ return new Output(deps, (resolve2, reject) => {
256
258
  Promise.all(inputs).then((result) => {
257
- resolve(result);
259
+ resolve2(result);
258
260
  }, reject);
259
261
  });
260
262
  };
@@ -266,13 +268,14 @@ var resolve = (inputs, transformer) => {
266
268
  var interpolate = (literals, ...placeholders) => {
267
269
  return combine(...placeholders).pipe((unwrapped) => {
268
270
  const result = [];
269
- for (let i = 0;i < unwrapped.length; i++) {
271
+ for (let i = 0; i < unwrapped.length; i++) {
270
272
  result.push(literals[i], unwrapped[i]);
271
273
  }
272
274
  result.push(literals.at(-1));
273
275
  return result.join("");
274
276
  });
275
277
  };
278
+
276
279
  // src/urn.ts
277
280
  var createUrn = (tag, type, name, parentUrn) => {
278
281
  return `${parentUrn ? parentUrn : "urn"}:${tag}:${type}:{${name}}`;
@@ -293,7 +296,7 @@ var createMeta = (tag, provider, parent, type, logicalId, input, config) => {
293
296
  input,
294
297
  config,
295
298
  get dependencies() {
296
- const dependencies = new Set;
299
+ const dependencies = /* @__PURE__ */ new Set();
297
300
  const linkMetaDep = (dep) => {
298
301
  if (dep.urn === urn) {
299
302
  throw new Error("You can't depend on yourself");
@@ -308,11 +311,20 @@ var createMeta = (tag, provider, parent, type, logicalId, input, config) => {
308
311
  }
309
312
  return dependencies;
310
313
  },
314
+ // attach(value) {
315
+ // resource = value
316
+ // },
317
+ // dependOn(...resources: Resource[]) {},
318
+ // attachDependencies(props) {
319
+ // for (const dep of findInputDeps(props)) {
320
+ // linkMetaDep(dep)
321
+ // }
322
+ // },
311
323
  resolve(data) {
312
324
  output2 = data;
313
325
  },
314
326
  output(cb) {
315
- return new Output(new Set([this]), (resolve2) => {
327
+ return new Output(/* @__PURE__ */ new Set([this]), (resolve2) => {
316
328
  if (!output2) {
317
329
  throw new Error(`Unresolved output for ${tag}: ${urn}`);
318
330
  }
@@ -321,6 +333,7 @@ var createMeta = (tag, provider, parent, type, logicalId, input, config) => {
321
333
  }
322
334
  };
323
335
  };
336
+
324
337
  // src/debug.ts
325
338
  var enabled = false;
326
339
  var enableDebug = () => {
@@ -336,9 +349,10 @@ var createDebugger = (group) => {
336
349
  console.log();
337
350
  };
338
351
  };
352
+
339
353
  // src/workspace/exit.ts
340
354
  import asyncOnExit from "async-on-exit";
341
- var listeners = new Set;
355
+ var listeners = /* @__PURE__ */ new Set();
342
356
  var listening = false;
343
357
  var onExit = (cb) => {
344
358
  listeners.add(cb);
@@ -382,7 +396,7 @@ var lockApp = async (lockBackend, app, fn) => {
382
396
 
383
397
  // src/workspace/concurrency.ts
384
398
  import promiseLimit from "p-limit";
385
- var concurrencyQueue = (concurrency) => {
399
+ var createConcurrencyQueue = (concurrency) => {
386
400
  const queue = promiseLimit(concurrency);
387
401
  return (cb) => {
388
402
  return queue(cb);
@@ -399,9 +413,9 @@ var entries = (object) => {
399
413
  };
400
414
 
401
415
  // src/workspace/dependency.ts
402
- class DependencyGraph {
403
- graph = new DirectedGraph;
404
- callbacks = new Map;
416
+ var DependencyGraph = class {
417
+ graph = new DirectedGraph();
418
+ callbacks = /* @__PURE__ */ new Map();
405
419
  add(urn, deps, callback) {
406
420
  this.callbacks.set(urn, callback);
407
421
  this.graph.mergeNode(urn);
@@ -428,13 +442,15 @@ class DependencyGraph {
428
442
  const graph = topologicalGenerations(this.graph);
429
443
  const errors = [];
430
444
  for (const list of graph) {
431
- const result = await Promise.allSettled(list.map((urn) => {
432
- const callback = this.callbacks.get(urn);
433
- if (!callback) {
434
- return;
435
- }
436
- return callback();
437
- }));
445
+ const result = await Promise.allSettled(
446
+ list.map((urn) => {
447
+ const callback = this.callbacks.get(urn);
448
+ if (!callback) {
449
+ return;
450
+ }
451
+ return callback();
452
+ })
453
+ );
438
454
  for (const entry of result) {
439
455
  if (entry.status === "rejected") {
440
456
  if (entry.reason instanceof Error) {
@@ -450,7 +466,7 @@ class DependencyGraph {
450
466
  }
451
467
  return errors;
452
468
  }
453
- }
469
+ };
454
470
  var dependentsOn = (resources, dependency) => {
455
471
  const dependents = [];
456
472
  for (const [urn, resource] of entries(resources)) {
@@ -462,39 +478,31 @@ var dependentsOn = (resources, dependency) => {
462
478
  };
463
479
 
464
480
  // src/workspace/error.ts
465
- class ResourceError extends Error {
466
- urn;
467
- type;
468
- operation;
469
- static wrap(urn, type, operation, error) {
470
- if (error instanceof Error) {
471
- return new ResourceError(urn, type, operation, error.message);
472
- }
473
- return new ResourceError(urn, type, operation, "Unknown Error");
474
- }
481
+ var ResourceError = class _ResourceError extends Error {
475
482
  constructor(urn, type, operation, message) {
476
483
  super(message);
477
484
  this.urn = urn;
478
485
  this.type = type;
479
486
  this.operation = operation;
480
487
  }
481
- }
482
-
483
- class AppError extends Error {
484
- app;
485
- issues;
488
+ static wrap(urn, type, operation, error) {
489
+ if (error instanceof Error) {
490
+ return new _ResourceError(urn, type, operation, error.message);
491
+ }
492
+ return new _ResourceError(urn, type, operation, "Unknown Error");
493
+ }
494
+ };
495
+ var AppError = class extends Error {
486
496
  constructor(app, issues, message) {
487
497
  super(message);
488
498
  this.app = app;
489
499
  this.issues = issues;
490
500
  }
491
- }
492
-
493
- class ResourceNotFound extends Error {
494
- }
495
-
496
- class ResourceAlreadyExists extends Error {
497
- }
501
+ };
502
+ var ResourceNotFound = class extends Error {
503
+ };
504
+ var ResourceAlreadyExists = class extends Error {
505
+ };
498
506
 
499
507
  // src/workspace/state.ts
500
508
  var compareState = (left, right) => {
@@ -631,8 +639,8 @@ var deleteApp = async (app, opt) => {
631
639
  if (opt.filters && opt.filters.length > 0) {
632
640
  stackStates = stackStates.filter((stackState) => opt.filters.includes(stackState.name));
633
641
  }
634
- const queue = concurrencyQueue(opt.concurrency ?? 10);
635
- const graph = new DependencyGraph;
642
+ const queue = createConcurrencyQueue(opt.concurrency ?? 10);
643
+ const graph = new DependencyGraph();
636
644
  const allNodes = {};
637
645
  for (const stackState of Object.values(appState.stacks)) {
638
646
  for (const [urn, nodeState] of entries(stackState.nodes)) {
@@ -668,7 +676,7 @@ var requiresReplacement = (priorState, proposedState, replaceOnChanges) => {
668
676
  const priorValue = get(priorState, path);
669
677
  const proposedValue = get(proposedState, path);
670
678
  if (path.includes("*") && Array.isArray(priorValue)) {
671
- for (let i = 0;i < priorValue.length; i++) {
679
+ for (let i = 0; i < priorValue.length; i++) {
672
680
  if (!compareState(priorValue[i], proposedValue[i])) {
673
681
  return true;
674
682
  }
@@ -837,10 +845,12 @@ var debug7 = createDebugger("Deploy App");
837
845
  var deployApp = async (app, opt) => {
838
846
  debug7(app.name, "start");
839
847
  const latestState = await opt.backend.state.get(app.urn);
840
- const appState = migrateAppState(latestState ?? {
841
- name: app.name,
842
- stacks: {}
843
- });
848
+ const appState = migrateAppState(
849
+ latestState ?? {
850
+ name: app.name,
851
+ stacks: {}
852
+ }
853
+ );
844
854
  const releaseOnExit = onExit(async () => {
845
855
  await opt.backend.state.update(app.urn, appState);
846
856
  });
@@ -854,8 +864,8 @@ var deployApp = async (app, opt) => {
854
864
  stacks = app.stacks.filter((stack) => opt.filters.includes(stack.name));
855
865
  filteredOutStacks = app.stacks.filter((stack) => !opt.filters.includes(stack.name));
856
866
  }
857
- const queue = concurrencyQueue(opt.concurrency ?? 10);
858
- const graph = new DependencyGraph;
867
+ const queue = createConcurrencyQueue(opt.concurrency ?? 10);
868
+ const graph = new DependencyGraph();
859
869
  const allNodes = {};
860
870
  for (const stackState of Object.values(appState.stacks)) {
861
871
  for (const [urn, nodeState] of entries(stackState.nodes)) {
@@ -886,7 +896,15 @@ var deployApp = async (app, opt) => {
886
896
  for (const [urn2, nodeState] of entries(stackState.nodes)) {
887
897
  graph.add(urn2, dependentsOn(allNodes, urn2), async () => {
888
898
  if (nodeState.tag === "resource") {
889
- await queue(() => deleteResource(appState.idempotentToken, urn2, nodeState, opt));
899
+ await queue(
900
+ () => deleteResource(
901
+ //
902
+ appState.idempotentToken,
903
+ urn2,
904
+ nodeState,
905
+ opt
906
+ )
907
+ );
890
908
  }
891
909
  delete stackState.nodes[urn2];
892
910
  });
@@ -903,7 +921,15 @@ var deployApp = async (app, opt) => {
903
921
  if (!resource) {
904
922
  graph.add(urn, dependentsOn(allNodes, urn), async () => {
905
923
  if (nodeState.tag === "resource") {
906
- await queue(() => deleteResource(appState.idempotentToken, urn, nodeState, opt));
924
+ await queue(
925
+ () => deleteResource(
926
+ //
927
+ appState.idempotentToken,
928
+ urn,
929
+ nodeState,
930
+ opt
931
+ )
932
+ );
907
933
  }
908
934
  delete stackState.nodes[urn];
909
935
  });
@@ -915,8 +941,9 @@ var deployApp = async (app, opt) => {
915
941
  const partialNewResourceState = {
916
942
  dependencies,
917
943
  lifecycle: isResource(node) ? {
944
+ // deleteAfterCreate: meta.config?.deleteAfterCreate,
918
945
  retainOnDelete: getMeta(node).config?.retainOnDelete
919
- } : undefined
946
+ } : void 0
920
947
  };
921
948
  graph.add(meta.urn, dependencies, () => {
922
949
  return queue(async () => {
@@ -925,7 +952,13 @@ var deployApp = async (app, opt) => {
925
952
  try {
926
953
  input = await resolveInputs(meta.input);
927
954
  } catch (error) {
928
- throw ResourceError.wrap(meta.urn, meta.type, "resolve", error);
955
+ throw ResourceError.wrap(
956
+ //
957
+ meta.urn,
958
+ meta.type,
959
+ "resolve",
960
+ error
961
+ );
929
962
  }
930
963
  if (isDataSource(node)) {
931
964
  const meta2 = getMeta(node);
@@ -950,25 +983,52 @@ var deployApp = async (app, opt) => {
950
983
  if (!nodeState) {
951
984
  if (meta2.config?.import) {
952
985
  const importedState = await importResource(node, input, opt);
953
- const newResourceState = await updateResource(node, appState.idempotentToken, importedState.output, input, opt);
986
+ const newResourceState = await updateResource(
987
+ node,
988
+ appState.idempotentToken,
989
+ importedState.output,
990
+ input,
991
+ opt
992
+ );
954
993
  nodeState = stackState.nodes[meta2.urn] = {
955
994
  ...importedState,
956
995
  ...newResourceState,
957
996
  ...partialNewResourceState
958
997
  };
959
998
  } else {
960
- const newResourceState = await createResource(node, appState.idempotentToken, input, opt);
999
+ const newResourceState = await createResource(
1000
+ node,
1001
+ appState.idempotentToken,
1002
+ input,
1003
+ opt
1004
+ );
961
1005
  nodeState = stackState.nodes[meta2.urn] = {
962
1006
  ...newResourceState,
963
1007
  ...partialNewResourceState
964
1008
  };
965
1009
  }
966
- } else if (!compareState(nodeState.input, input)) {
1010
+ } else if (
1011
+ // --------------------------------------------------
1012
+ // Check if any state has changed
1013
+ !compareState(nodeState.input, input)
1014
+ ) {
967
1015
  let newResourceState;
968
1016
  if (requiresReplacement(nodeState.input, input, meta2.config?.replaceOnChanges ?? [])) {
969
- newResourceState = await replaceResource(node, appState.idempotentToken, nodeState.output, input, opt);
1017
+ newResourceState = await replaceResource(
1018
+ node,
1019
+ appState.idempotentToken,
1020
+ nodeState.output,
1021
+ input,
1022
+ opt
1023
+ );
970
1024
  } else {
971
- newResourceState = await updateResource(node, appState.idempotentToken, nodeState.output, input, opt);
1025
+ newResourceState = await updateResource(
1026
+ node,
1027
+ appState.idempotentToken,
1028
+ nodeState.output,
1029
+ input,
1030
+ opt
1031
+ );
972
1032
  }
973
1033
  Object.assign(nodeState, {
974
1034
  input,
@@ -1020,12 +1080,53 @@ var hydrate = async (app, opt) => {
1020
1080
  }
1021
1081
  };
1022
1082
 
1083
+ // src/workspace/procedure/refresh.ts
1084
+ var refresh = async (app, opt) => {
1085
+ const appState = await opt.backend.state.get(app.urn);
1086
+ const queue = createConcurrencyQueue(opt.concurrency ?? 10);
1087
+ if (appState) {
1088
+ await Promise.all(
1089
+ Object.values(appState.stacks).map((stackState) => {
1090
+ return Promise.all(
1091
+ Object.values(stackState.nodes).map((nodeState) => {
1092
+ return queue(async () => {
1093
+ const provider = findProvider(opt.providers, nodeState.provider);
1094
+ if (nodeState.tag === "data") {
1095
+ const result = await provider.getData?.({
1096
+ type: nodeState.type,
1097
+ state: nodeState.output
1098
+ });
1099
+ if (result && !compareState(result.state, nodeState.output)) {
1100
+ nodeState.output = result.state;
1101
+ nodeState.input = result.state;
1102
+ }
1103
+ } else if (nodeState.tag === "resource") {
1104
+ const result = await provider.getResource({
1105
+ type: nodeState.type,
1106
+ state: nodeState.output
1107
+ });
1108
+ if (result && !compareState(result.state, nodeState.output)) {
1109
+ nodeState.output = result.state;
1110
+ nodeState.input = result.state;
1111
+ }
1112
+ }
1113
+ });
1114
+ })
1115
+ );
1116
+ })
1117
+ );
1118
+ await opt.backend.state.update(app.urn, appState);
1119
+ }
1120
+ };
1121
+
1023
1122
  // src/workspace/workspace.ts
1024
- class WorkSpace {
1025
- props;
1123
+ var WorkSpace = class {
1026
1124
  constructor(props) {
1027
1125
  this.props = props;
1028
1126
  }
1127
+ /**
1128
+ * Deploy the entire app or use the filter option to deploy specific stacks inside your app.
1129
+ */
1029
1130
  deploy(app, options = {}) {
1030
1131
  return lockApp(this.props.backend.lock, app, async () => {
1031
1132
  try {
@@ -1035,6 +1136,9 @@ class WorkSpace {
1035
1136
  }
1036
1137
  });
1037
1138
  }
1139
+ /**
1140
+ * Delete the entire app or use the filter option to delete specific stacks inside your app.
1141
+ */
1038
1142
  delete(app, options = {}) {
1039
1143
  return lockApp(this.props.backend.lock, app, async () => {
1040
1144
  try {
@@ -1044,18 +1148,36 @@ class WorkSpace {
1044
1148
  }
1045
1149
  });
1046
1150
  }
1151
+ /**
1152
+ * Hydrate the outputs of the resources & data-sources inside your app.
1153
+ */
1047
1154
  hydrate(app) {
1048
1155
  return hydrate(app, this.props);
1049
1156
  }
1157
+ /**
1158
+ * Refresh the state of the resources & data-sources inside your app.
1159
+ */
1160
+ refresh(app) {
1161
+ return lockApp(this.props.backend.lock, app, async () => {
1162
+ try {
1163
+ await refresh(app, this.props);
1164
+ } finally {
1165
+ await this.destroyProviders();
1166
+ }
1167
+ });
1168
+ }
1050
1169
  async destroyProviders() {
1051
- await Promise.all(this.props.providers.map((p) => {
1052
- return p.destroy?.();
1053
- }));
1170
+ await Promise.all(
1171
+ this.props.providers.map((p) => {
1172
+ return p.destroy?.();
1173
+ })
1174
+ );
1054
1175
  }
1055
- }
1176
+ };
1177
+
1056
1178
  // src/backend/memory/state.ts
1057
- class MemoryStateBackend {
1058
- states = new Map;
1179
+ var MemoryStateBackend = class {
1180
+ states = /* @__PURE__ */ new Map();
1059
1181
  async get(urn) {
1060
1182
  return this.states.get(urn);
1061
1183
  }
@@ -1068,10 +1190,11 @@ class MemoryStateBackend {
1068
1190
  clear() {
1069
1191
  this.states.clear();
1070
1192
  }
1071
- }
1193
+ };
1194
+
1072
1195
  // src/backend/memory/lock.ts
1073
- class MemoryLockBackend {
1074
- locks = new Map;
1196
+ var MemoryLockBackend = class {
1197
+ locks = /* @__PURE__ */ new Map();
1075
1198
  async insecureReleaseLock(urn) {
1076
1199
  this.locks.delete(urn);
1077
1200
  }
@@ -1093,14 +1216,13 @@ class MemoryLockBackend {
1093
1216
  clear() {
1094
1217
  this.locks.clear();
1095
1218
  }
1096
- }
1219
+ };
1220
+
1097
1221
  // src/backend/file/state.ts
1098
- import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
1099
- import { join } from "node:path";
1222
+ import { mkdir, readFile, rm, writeFile } from "fs/promises";
1223
+ import { join } from "path";
1100
1224
  var debug8 = createDebugger("State");
1101
-
1102
- class FileStateBackend {
1103
- props;
1225
+ var FileStateBackend = class {
1104
1226
  constructor(props) {
1105
1227
  this.props = props;
1106
1228
  }
@@ -1125,21 +1247,20 @@ class FileStateBackend {
1125
1247
  async update(urn, state) {
1126
1248
  debug8("update");
1127
1249
  await this.mkdir();
1128
- await writeFile(this.stateFile(urn), JSON.stringify(state, undefined, 2));
1250
+ await writeFile(this.stateFile(urn), JSON.stringify(state, void 0, 2));
1129
1251
  }
1130
1252
  async delete(urn) {
1131
1253
  debug8("delete");
1132
1254
  await this.mkdir();
1133
1255
  await rm(this.stateFile(urn));
1134
1256
  }
1135
- }
1257
+ };
1258
+
1136
1259
  // src/backend/file/lock.ts
1137
- import { mkdir as mkdir2, rm as rm2, stat } from "node:fs/promises";
1138
- import { join as join2 } from "node:path";
1260
+ import { mkdir as mkdir2, rm as rm2, stat } from "fs/promises";
1261
+ import { join as join2 } from "path";
1139
1262
  import { lock } from "proper-lockfile";
1140
-
1141
- class FileLockBackend {
1142
- props;
1263
+ var FileLockBackend = class {
1143
1264
  constructor(props) {
1144
1265
  this.props = props;
1145
1266
  }
@@ -1166,7 +1287,8 @@ class FileLockBackend {
1166
1287
  realpath: false
1167
1288
  });
1168
1289
  }
1169
- }
1290
+ };
1291
+
1170
1292
  // src/backend/aws/s3-state.ts
1171
1293
  import {
1172
1294
  DeleteObjectCommand,
@@ -1175,21 +1297,21 @@ import {
1175
1297
  S3Client,
1176
1298
  S3ServiceException
1177
1299
  } from "@aws-sdk/client-s3";
1178
-
1179
- class S3StateBackend {
1180
- props;
1181
- client;
1300
+ var S3StateBackend = class {
1182
1301
  constructor(props) {
1183
1302
  this.props = props;
1184
1303
  this.client = new S3Client(props);
1185
1304
  }
1305
+ client;
1186
1306
  async get(urn) {
1187
1307
  let result;
1188
1308
  try {
1189
- result = await this.client.send(new GetObjectCommand({
1190
- Bucket: this.props.bucket,
1191
- Key: `${urn}.state`
1192
- }));
1309
+ result = await this.client.send(
1310
+ new GetObjectCommand({
1311
+ Bucket: this.props.bucket,
1312
+ Key: `${urn}.state`
1313
+ })
1314
+ );
1193
1315
  } catch (error) {
1194
1316
  if (error instanceof S3ServiceException && error.name === "NoSuchKey") {
1195
1317
  return;
@@ -1204,30 +1326,33 @@ class S3StateBackend {
1204
1326
  return state;
1205
1327
  }
1206
1328
  async update(urn, state) {
1207
- await this.client.send(new PutObjectCommand({
1208
- Bucket: this.props.bucket,
1209
- Key: `${urn}.state`,
1210
- Body: JSON.stringify(state)
1211
- }));
1329
+ await this.client.send(
1330
+ new PutObjectCommand({
1331
+ Bucket: this.props.bucket,
1332
+ Key: `${urn}.state`,
1333
+ Body: JSON.stringify(state)
1334
+ })
1335
+ );
1212
1336
  }
1213
1337
  async delete(urn) {
1214
- await this.client.send(new DeleteObjectCommand({
1215
- Bucket: this.props.bucket,
1216
- Key: `${urn}.state`
1217
- }));
1338
+ await this.client.send(
1339
+ new DeleteObjectCommand({
1340
+ Bucket: this.props.bucket,
1341
+ Key: `${urn}.state`
1342
+ })
1343
+ );
1218
1344
  }
1219
- }
1345
+ };
1346
+
1220
1347
  // src/backend/aws/dynamodb-lock.ts
1221
1348
  import { DynamoDB } from "@aws-sdk/client-dynamodb";
1222
1349
  import { marshall, unmarshall } from "@aws-sdk/util-dynamodb";
1223
-
1224
- class DynamoLockBackend {
1225
- props;
1226
- client;
1350
+ var DynamoLockBackend = class {
1227
1351
  constructor(props) {
1228
1352
  this.props = props;
1229
1353
  this.client = new DynamoDB(props);
1230
1354
  }
1355
+ client;
1231
1356
  async insecureReleaseLock(urn) {
1232
1357
  await this.client.updateItem({
1233
1358
  TableName: this.props.tableName,
@@ -1268,10 +1393,11 @@ class DynamoLockBackend {
1268
1393
  });
1269
1394
  };
1270
1395
  }
1271
- }
1396
+ };
1397
+
1272
1398
  // src/helpers.ts
1273
- import { createHash } from "node:crypto";
1274
- import { readFile as readFile2 } from "node:fs/promises";
1399
+ import { createHash } from "crypto";
1400
+ import { readFile as readFile2 } from "fs/promises";
1275
1401
  var file = (path, encoding = "utf8") => {
1276
1402
  return new Future(async (resolve2, reject) => {
1277
1403
  try {
@@ -1301,22 +1427,37 @@ var createCustomResourceClass = (providerId, resourceType) => {
1301
1427
  }, {
1302
1428
  construct(_, [parent, id, input, config]) {
1303
1429
  const meta = createMeta("resource", `custom:${providerId}`, parent, resourceType, id, input, config);
1304
- const node = new Proxy({}, {
1305
- get(_2, key) {
1306
- if (key === nodeMetaSymbol) {
1307
- return meta;
1308
- }
1309
- if (typeof key === "symbol") {
1310
- return;
1430
+ const node = new Proxy(
1431
+ {},
1432
+ {
1433
+ get(_2, key) {
1434
+ if (key === nodeMetaSymbol) {
1435
+ return meta;
1436
+ }
1437
+ if (key === "urn") {
1438
+ return meta.urn;
1439
+ }
1440
+ if (typeof key === "symbol") {
1441
+ return;
1442
+ }
1443
+ return meta.output((data) => data[key]);
1311
1444
  }
1312
- return meta.output((data) => data[key]);
1313
1445
  }
1314
- });
1446
+ );
1315
1447
  parent.add(node);
1316
1448
  return node;
1317
1449
  }
1450
+ // get(_, key: string) {
1451
+ // if (key === 'get') {
1452
+ // return (...args: any[]) => {
1453
+ // return get(...args)
1454
+ // }
1455
+ // }
1456
+ // return
1457
+ // },
1318
1458
  });
1319
1459
  };
1460
+
1320
1461
  // src/custom/provider.ts
1321
1462
  var createCustomProvider = (providerId, resourceProviders) => {
1322
1463
  const version = 1;
@@ -1382,34 +1523,34 @@ var createCustomProvider = (providerId, resourceProviders) => {
1382
1523
  };
1383
1524
  };
1384
1525
  export {
1385
- resolveInputs,
1386
- output,
1387
- nodeMetaSymbol,
1388
- isResource,
1389
- isNode,
1390
- isDataSource,
1391
- getMeta,
1392
- findInputDeps,
1393
- enableDebug,
1394
- deferredOutput,
1395
- createMeta,
1396
- createDebugger,
1397
- createCustomResourceClass,
1398
- createCustomProvider,
1399
- WorkSpace,
1400
- Stack,
1401
- S3StateBackend,
1402
- ResourceNotFound,
1403
- ResourceError,
1404
- ResourceAlreadyExists,
1405
- Output,
1406
- MemoryStateBackend,
1407
- MemoryLockBackend,
1408
- Group,
1409
- Future,
1410
- FileStateBackend,
1411
- FileLockBackend,
1412
- DynamoLockBackend,
1526
+ App,
1413
1527
  AppError,
1414
- App
1528
+ DynamoLockBackend,
1529
+ FileLockBackend,
1530
+ FileStateBackend,
1531
+ Future,
1532
+ Group,
1533
+ MemoryLockBackend,
1534
+ MemoryStateBackend,
1535
+ Output,
1536
+ ResourceAlreadyExists,
1537
+ ResourceError,
1538
+ ResourceNotFound,
1539
+ S3StateBackend,
1540
+ Stack,
1541
+ WorkSpace,
1542
+ createCustomProvider,
1543
+ createCustomResourceClass,
1544
+ createDebugger,
1545
+ createMeta,
1546
+ deferredOutput,
1547
+ enableDebug,
1548
+ findInputDeps,
1549
+ getMeta,
1550
+ isDataSource,
1551
+ isNode,
1552
+ isResource,
1553
+ nodeMetaSymbol,
1554
+ output,
1555
+ resolveInputs
1415
1556
  };