Skip to content

Instantly share code, notes, and snippets.

@Chriscbr
Created October 11, 2023 20:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Chriscbr/58384bdd7b8ce5e8fedf24ddba55e103 to your computer and use it in GitHub Desktop.
Save Chriscbr/58384bdd7b8ce5e8fedf24ddba55e103 to your computer and use it in GitHub Desktop.
const { Construct } = require("constructs");
const { writeFileSync } = require("node:fs");
class Lazy {
constructor(producer) {
this.producer = producer;
}
produce() {
return this.producer();
}
}
function resolveLazies(value) {
switch (typeof value) {
case "object":
if (value instanceof Lazy) {
return value.produce();
} else if (Array.isArray(value)) {
return value.map(resolveLazies);
} else {
const result = {};
for (const [key, val] of Object.entries(value)) {
result[key] = resolveLazies(val);
}
return result;
}
default:
return value;
}
}
class Flower extends Construct {
constructor(scope, id, props) {
super(scope, id, props);
this.kind = props.kind;
this.color = props.color;
this._nativeRegions = props.nativeRegions ?? [];
}
get nativeRegions() {
return new Lazy(() => [...this._nativeRegions]);
}
addNativeRegion(region) {
this._nativeRegions.push(region);
}
toJson() {
return {
id: this.node.path,
kind: this.kind,
color: this.color,
nativeRegions: this.nativeRegions,
};
}
}
class Garden extends Construct {
constructor(scope, id, props) {
super(scope, id, props);
}
synth() {
const hasToJson = (node) => typeof node.toJson === "function";
const objects = this.node.findAll().filter(hasToJson).map((c) => resolveLazies(c.toJson()));
writeFileSync("garden.json", JSON.stringify(objects, null, 2));
}
}
class Signpost extends Construct {
constructor(scope, id, props) {
super(scope, id);
this._message = new Lazy(() => {
const allRegions = new Set(props.flowers.flatMap((f) => f.nativeRegions.produce()));
let message = "Welcome to Tuple Trove, home to flowers from: ";
message += [...allRegions].join(", ");
message += ".";
return message;
});
}
toJson() {
return {
id: this.node.path,
message: this._message,
};
}
}
const garden = new Garden(undefined, "root");
const rose = new Flower(garden, "rose", { kind: "rose", color: "red" });
rose.addNativeRegion("Denmark");
new Signpost(garden, "signpost", { flowers: [rose] });
rose.addNativeRegion("Turkey");
rose.addNativeRegion("Greece");
garden.synth();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment