diff --git a/static/app.js b/static/app.js index 0fef3fd..55ca598 100644 --- a/static/app.js +++ b/static/app.js @@ -1,6 +1,5 @@ -import { generateNodeId, createSVGElement } from './utils.js'; import { ComponentNode } from './node.js' -import { Connection } from './connection.js' +import { generateNodeId, createSVGElement } from './utils.js'; export class CanvasApp { constructor() { @@ -24,6 +23,9 @@ export class CanvasApp { this.dbGroup = document.getElementById('db-group'); this.cacheGroup = document.getElementById('cache-group'); this.selectedNode = null; + this.computeTypes = ['webserver', 'microservice']; + this.computeGroup = document.getElementById('compute-group'); + this.placeholderText = createSVGElement('text', { x: '50%', @@ -110,6 +112,9 @@ export class CanvasApp { if (nodeObj.type === 'CacheStandard' || nodeObj.type === 'CacheLarge') { nodeObj.props.cacheTTL = parseInt(panel.querySelector("input[name='cacheTTL']").value, 10); } + if (this.computeTypes.includes(nodeObj.type)) { + nodeObj.props.instanceSize = panel.querySelector("select[name='instanceSize']").value; + } this.hidePropsPanel(); }); @@ -171,6 +176,15 @@ export class CanvasApp { this.propsSaveBtn.disabled = false; panel.style.display = 'block'; + + const isCompute = this.computeTypes.includes(nodeObj.type); + console.log(isCompute) + console.log(nodeObj) + this.computeGroup.style.display = isCompute ? 'block' : 'none'; + + if (isCompute) { + panel.querySelector("select[name='instanceSize']").value = nodeObj.props.instanceSize || 'medium'; + } } hidePropsPanel() { @@ -201,15 +215,35 @@ export class CanvasApp { } exportDesign() { - const nodes = this.placedComponents.map(n => ({ - id: n.id, - type: n.type, - props: n.props, - position: { - x: n.x, - y: n.y + const nodes = this.placedComponents.map(n => { + const baseProps = { label: n.props.label }; + + // Add only if it's a database + if (n.type === 'Database') { + baseProps.replication = n.props.replication; } - })); + + // Add only if it's a cache + if (n.type === 'CacheStandard' || n.type === 'CacheLarge') { + baseProps.cacheTTL = n.props.cacheTTL; + } + + // Add only if it's a compute node + const computeTypes = ['WebServer', 'Microservice']; + if (computeTypes.includes(n.type)) { + baseProps.instanceSize = n.props.instanceSize; + } + + return { + id: n.id, + type: n.type, + props: baseProps, + position: { + x: n.x, + y: n.y + } + }; + }); const connections = this.connections.map(c => ({ source: c.start.id, diff --git a/static/game.html b/static/game.html index e4af213..4961f85 100644 --- a/static/game.html +++ b/static/game.html @@ -523,6 +523,22 @@ color: #fff; border-radius: 4px; } + + #node-props-panel .form-group { + margin-bottom: 10px; +} + +#node-props-panel label { + display: block; + font-weight: bold; + margin-bottom: 4px; +} + +#node-props-panel select { + width: 100%; + padding: 4px; + font-size: 14px; +} @@ -596,29 +612,17 @@ cost: $5/mo
distributes traffic evenly
latency: 5 ms
-
- web server (small) - cost: $10/mo
capacity: 100 rps
base latency: 50 ms
-
- -
- web server (medium) - cost: $20/mo
capacity: 200 rps
base latency: 40 ms
+
+ webserver + cost: varies
capacity and latency depends on instance size
-
database cost: $20/mo
read capacity: 150 rps
base latency: 80 ms
supports replication
-
- cache (standard) - cost: $10/mo
capacity: 100 rps
latency: 5 ms
80% hit rate with 1hr ttl
-
- -
- cache (large) - cost: $20/mo
capacity: 200 rps
latency: 5 ms
higher hit rate for large datasets
+
+ cache
@@ -733,6 +737,15 @@
+
+ + +
+
diff --git a/static/node.js b/static/node.js index 58a22cb..cfe9b07 100644 --- a/static/node.js +++ b/static/node.js @@ -9,7 +9,8 @@ export class ComponentNode { this.props = { label: type, replication: 1, - cacheTTL: 0 + cacheTTL: 0, + instanceSize: 'medium' }; this.group = createSVGElement('g', { class: 'dropped', 'data-type': type }); const rect = createSVGElement('rect', {