@loadmap/cli 0.11.0 → 0.13.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.
package/dist/bin.js
CHANGED
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { t as USAGE, o as check, a as fmt, s as github, n as main, r as parseRecord, i as record } from "./src-
|
|
1
|
+
export { t as USAGE, o as check, a as fmt, s as github, n as main, r as parseRecord, i as record } from "./src-uR5aJH2I.js";
|
|
@@ -588,6 +588,21 @@ function defineModel(def) {
|
|
|
588
588
|
firstLimit: first
|
|
589
589
|
};
|
|
590
590
|
};
|
|
591
|
+
const resolveStages = (ctx, shed) => {
|
|
592
|
+
const stages = {};
|
|
593
|
+
for (const s of stageIds) {
|
|
594
|
+
const st = resolveStage(s, def.stages[s], ctx, flowIds, thresholds.full);
|
|
595
|
+
stages[s] = st.kind === "pass" || st.kind === "limit" || st.kind === "cache" ? {
|
|
596
|
+
...st,
|
|
597
|
+
shed: shed(s)
|
|
598
|
+
} : st;
|
|
599
|
+
}
|
|
600
|
+
for (const st of Object.values(stages)) if (st.kind === "fanout") for (const b of Object.values(st.to).flat()) {
|
|
601
|
+
const to = stages[b.stage];
|
|
602
|
+
if (!to || to.kind === "queue" || to.kind === "workers" || to.kind === "fanout") throw new Error(`loadmap: fan-out "${st.id}" branches to "${b.stage}", which is not a sink, store or pass stage`);
|
|
603
|
+
}
|
|
604
|
+
return stages;
|
|
605
|
+
};
|
|
591
606
|
const evaluate = (partial) => {
|
|
592
607
|
const values = {
|
|
593
608
|
...defaults(),
|
|
@@ -632,18 +647,7 @@ function defineModel(def) {
|
|
|
632
647
|
const full = edges("fullRange");
|
|
633
648
|
const flows = {};
|
|
634
649
|
for (const f of flowIds) flows[f] = ctx.flows[f];
|
|
635
|
-
const stages =
|
|
636
|
-
for (const s of stageIds) {
|
|
637
|
-
const st = resolveStage(s, def.stages[s], ctx, flowIds, thresholds.full);
|
|
638
|
-
stages[s] = st.kind === "pass" || st.kind === "limit" || st.kind === "cache" ? {
|
|
639
|
-
...st,
|
|
640
|
-
shed: shed(s)
|
|
641
|
-
} : st;
|
|
642
|
-
}
|
|
643
|
-
for (const st of Object.values(stages)) if (st.kind === "fanout") for (const b of Object.values(st.to).flat()) {
|
|
644
|
-
const to = stages[b.stage];
|
|
645
|
-
if (!to || to.kind === "queue" || to.kind === "workers" || to.kind === "fanout") throw new Error(`loadmap: fan-out "${st.id}" branches to "${b.stage}", which is not a sink, store or pass stage`);
|
|
646
|
-
}
|
|
650
|
+
const stages = resolveStages(ctx, shed);
|
|
647
651
|
const overload = {};
|
|
648
652
|
for (const f of flowIds) overload[f] = overloadOf(f);
|
|
649
653
|
const at = {};
|
|
@@ -710,6 +714,18 @@ function defineModel(def) {
|
|
|
710
714
|
return d ? isEnabled(d, values) : false;
|
|
711
715
|
},
|
|
712
716
|
evaluate,
|
|
717
|
+
stagesAt: (partial) => {
|
|
718
|
+
const values = {
|
|
719
|
+
...defaults(),
|
|
720
|
+
...partial
|
|
721
|
+
};
|
|
722
|
+
const { ctx, shed } = context(def, values);
|
|
723
|
+
return {
|
|
724
|
+
values,
|
|
725
|
+
ctx,
|
|
726
|
+
stages: resolveStages(ctx, shed)
|
|
727
|
+
};
|
|
728
|
+
},
|
|
713
729
|
utilization: (partial, bound) => {
|
|
714
730
|
const util = context(def, {
|
|
715
731
|
...defaults(),
|
|
@@ -1260,6 +1276,8 @@ function defineView(model, def) {
|
|
|
1260
1276
|
const nodes = def.nodes;
|
|
1261
1277
|
for (const e of def.edges) for (const end of [e.from, e.to]) if (!(end in nodes)) throw new Error(`loadmap: edge to unknown node "${end}"`);
|
|
1262
1278
|
for (const [f, fv] of Object.entries(def.flows)) if (!(fv.from in nodes)) throw new Error(`loadmap: flow "${f}" starts at unknown node "${fv.from}"`);
|
|
1279
|
+
const tiers = def.tiers ?? {};
|
|
1280
|
+
for (const [id, n] of Object.entries(nodes)) if (n.tier != null && !Object.hasOwn(tiers, n.tier)) throw new Error(`loadmap: node "${id}" stands in unknown tier "${n.tier}"`);
|
|
1263
1281
|
const shows = (n, s) => Array.isArray(n.stage) ? n.stage.includes(s) : n.stage === s;
|
|
1264
1282
|
for (const s of model.stageIds) if (!Object.values(nodes).some((n) => shows(n, s))) throw new Error(`loadmap: no node shows stage "${s}"`);
|
|
1265
1283
|
return {
|
|
@@ -1486,6 +1504,11 @@ const SUB = {
|
|
|
1486
1504
|
scope: "ctx",
|
|
1487
1505
|
doc: "The second line of the box."
|
|
1488
1506
|
};
|
|
1507
|
+
const TIER = {
|
|
1508
|
+
value: "tier",
|
|
1509
|
+
scope: "const",
|
|
1510
|
+
doc: "The tier the box stands in; without one, that of the boxes that feed it."
|
|
1511
|
+
};
|
|
1489
1512
|
const OVERLOAD_WHEN = {
|
|
1490
1513
|
value: "boolean",
|
|
1491
1514
|
scope: "ctx",
|
|
@@ -1579,6 +1602,7 @@ const SCHEMA = {
|
|
|
1579
1602
|
"node",
|
|
1580
1603
|
"cluster",
|
|
1581
1604
|
"pool",
|
|
1605
|
+
"tier",
|
|
1582
1606
|
"thresholds"
|
|
1583
1607
|
],
|
|
1584
1608
|
edges: "edges"
|
|
@@ -2021,6 +2045,20 @@ const SCHEMA = {
|
|
|
2021
2045
|
props: COMPONENT_PROPS,
|
|
2022
2046
|
children: []
|
|
2023
2047
|
},
|
|
2048
|
+
tier: {
|
|
2049
|
+
doc: "A band across the flow (edge, app, data) drawn behind its boxes. Tiers run in the order they are declared.",
|
|
2050
|
+
example: "tier data \"Data\"",
|
|
2051
|
+
args: [{
|
|
2052
|
+
name: "id",
|
|
2053
|
+
kind: "id"
|
|
2054
|
+
}, {
|
|
2055
|
+
name: "label",
|
|
2056
|
+
kind: "text",
|
|
2057
|
+
optional: true
|
|
2058
|
+
}],
|
|
2059
|
+
props: {},
|
|
2060
|
+
children: []
|
|
2061
|
+
},
|
|
2024
2062
|
node: {
|
|
2025
2063
|
doc: "A box. It may run a stage (pass, store, sink, fanout) and own a component (demand and capacity lines).",
|
|
2026
2064
|
example: "node gateway \"API gateway\" { pass; demand: flows.orders; capacity: estimated(20000, \"req/s\") }",
|
|
@@ -2033,6 +2071,7 @@ const SCHEMA = {
|
|
|
2033
2071
|
values: ["box", "cylinder"],
|
|
2034
2072
|
doc: "box (the default) or cylinder."
|
|
2035
2073
|
},
|
|
2074
|
+
tier: TIER,
|
|
2036
2075
|
...COMPONENT_PROPS
|
|
2037
2076
|
},
|
|
2038
2077
|
children: [
|
|
@@ -2063,6 +2102,7 @@ const SCHEMA = {
|
|
|
2063
2102
|
scope: "i",
|
|
2064
2103
|
doc: "Each member's label, from its index i: `broker ${i}`."
|
|
2065
2104
|
},
|
|
2105
|
+
tier: TIER,
|
|
2066
2106
|
...COMPONENT_PROPS
|
|
2067
2107
|
},
|
|
2068
2108
|
children: ["queue", "component"]
|
|
@@ -2078,6 +2118,7 @@ const SCHEMA = {
|
|
|
2078
2118
|
scope: "i",
|
|
2079
2119
|
doc: "Each pod's label, from its index i: `pod ${i}`."
|
|
2080
2120
|
},
|
|
2121
|
+
tier: TIER,
|
|
2081
2122
|
...COMPONENT_PROPS
|
|
2082
2123
|
},
|
|
2083
2124
|
children: ["workers", "component"]
|
|
@@ -3771,10 +3812,30 @@ var Compiler = class {
|
|
|
3771
3812
|
}
|
|
3772
3813
|
const searchMax = this.constProp(root, "searchMax");
|
|
3773
3814
|
if (searchMax != null) model.searchMax = searchMax;
|
|
3815
|
+
const tiers = {};
|
|
3816
|
+
const tierNames = /* @__PURE__ */ new Map();
|
|
3817
|
+
for (const b of byKind("tier")) {
|
|
3818
|
+
if (!b.args.id) continue;
|
|
3819
|
+
this.declare("tier", b.args.id.name, b.args.id, b, tierNames);
|
|
3820
|
+
tiers[b.args.id.name] = { label: this.text(b.args.label) ?? b.args.id.name };
|
|
3821
|
+
}
|
|
3774
3822
|
const nodes = {};
|
|
3775
|
-
for (const box of boxes)
|
|
3823
|
+
for (const box of boxes) {
|
|
3824
|
+
nodes[box.id] = this.node(box);
|
|
3825
|
+
const tier = this.named(box.block, "tier", [...tierNames.keys()], "tier");
|
|
3826
|
+
if (tier) nodes[box.id].tier = tier;
|
|
3827
|
+
}
|
|
3776
3828
|
const edges = [];
|
|
3777
3829
|
for (const e of root.edges) edges.push(...this.edges(e, boxById));
|
|
3830
|
+
const tierOf = (id) => {
|
|
3831
|
+
const t = nodes[id]?.tier;
|
|
3832
|
+
return t == null ? void 0 : Object.keys(tiers).indexOf(t);
|
|
3833
|
+
};
|
|
3834
|
+
for (const e of root.edges) e.chain.forEach((to, i) => {
|
|
3835
|
+
const from = e.chain[i - 1];
|
|
3836
|
+
const [a, b] = from ? [tierOf(from.name), tierOf(to.name)] : [];
|
|
3837
|
+
if (from && a != null && b != null && a > b) this.report.warning(to, `${from.name} -> ${to.name} runs back from the tier "${nodes[from.name].tier}" to "${nodes[to.name].tier}"`);
|
|
3838
|
+
});
|
|
3778
3839
|
if (!flows.length) this.report.error({
|
|
3779
3840
|
from: 0,
|
|
3780
3841
|
to: 0
|
|
@@ -3796,11 +3857,13 @@ var Compiler = class {
|
|
|
3796
3857
|
if (typeof v === "string") options.assumptions.push(v);
|
|
3797
3858
|
}
|
|
3798
3859
|
if (this.report.failed) return void 0;
|
|
3799
|
-
|
|
3860
|
+
const view = {
|
|
3800
3861
|
nodes,
|
|
3801
3862
|
edges,
|
|
3802
|
-
flows: flowViews
|
|
3803
|
-
|
|
3863
|
+
flows: flowViews,
|
|
3864
|
+
...Object.keys(tiers).length ? { tiers } : {}
|
|
3865
|
+
};
|
|
3866
|
+
return this.build(model, view, options, byKind("preset"), byKind("scenario"));
|
|
3804
3867
|
}
|
|
3805
3868
|
/** Hands the parts to core and layout, then runs the model once per preset and scenario so formula errors show now. */
|
|
3806
3869
|
build(modelDef, viewDef, options, presets, scenarios) {
|