@sdeverywhere/check-core 0.1.1 → 0.1.2

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,10 +1,54 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defProps = Object.defineProperties;
3
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
+ var __spreadValues = (a, b) => {
9
+ for (var prop in b || (b = {}))
10
+ if (__hasOwnProp.call(b, prop))
11
+ __defNormalProp(a, prop, b[prop]);
12
+ if (__getOwnPropSymbols)
13
+ for (var prop of __getOwnPropSymbols(b)) {
14
+ if (__propIsEnum.call(b, prop))
15
+ __defNormalProp(a, prop, b[prop]);
16
+ }
17
+ return a;
18
+ };
19
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
+ var __async = (__this, __arguments, generator) => {
21
+ return new Promise((resolve, reject) => {
22
+ var fulfilled = (value) => {
23
+ try {
24
+ step(generator.next(value));
25
+ } catch (e) {
26
+ reject(e);
27
+ }
28
+ };
29
+ var rejected = (value) => {
30
+ try {
31
+ step(generator.throw(value));
32
+ } catch (e) {
33
+ reject(e);
34
+ }
35
+ };
36
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
37
+ step((generator = generator.apply(__this, __arguments)).next());
38
+ });
39
+ };
40
+
1
41
  // src/_shared/task-queue.ts
2
42
  var TaskQueue = class {
3
43
  constructor(processor) {
4
44
  this.processor = processor;
45
+ /** The queue of task keys, most recent at front. */
5
46
  this.taskKeyQueue = [];
47
+ /** The map of tasks. */
6
48
  this.taskMap = /* @__PURE__ */ new Map();
49
+ /** Whether tasks are being processed. */
7
50
  this.processing = false;
51
+ /** Whether `shutdown` has been called. */
8
52
  this.stopped = false;
9
53
  }
10
54
  addTask(key, input, onComplete) {
@@ -42,39 +86,41 @@ var TaskQueue = class {
42
86
  });
43
87
  }
44
88
  }
45
- async processNextTask() {
46
- var _a, _b;
47
- const taskKey = this.taskKeyQueue.shift();
48
- if (!taskKey) {
49
- return;
50
- }
51
- const task = this.taskMap.get(taskKey);
52
- if (task) {
53
- this.taskMap.delete(taskKey);
54
- } else {
55
- return;
56
- }
57
- let output;
58
- try {
59
- output = await this.processor.process(task.input);
60
- } catch (e) {
61
- if (!this.stopped) {
62
- this.shutdown();
63
- (_a = this.onIdle) == null ? void 0 : _a.call(this, e);
89
+ processNextTask() {
90
+ return __async(this, null, function* () {
91
+ var _a, _b;
92
+ const taskKey = this.taskKeyQueue.shift();
93
+ if (!taskKey) {
94
+ return;
64
95
  }
65
- return;
66
- }
67
- task.onComplete(output);
68
- if (this.taskKeyQueue.length > 0) {
69
- setTimeout(() => {
70
- this.processNextTask();
71
- });
72
- } else {
73
- this.processing = false;
74
- if (!this.stopped) {
75
- (_b = this.onIdle) == null ? void 0 : _b.call(this);
96
+ const task = this.taskMap.get(taskKey);
97
+ if (task) {
98
+ this.taskMap.delete(taskKey);
99
+ } else {
100
+ return;
76
101
  }
77
- }
102
+ let output;
103
+ try {
104
+ output = yield this.processor.process(task.input);
105
+ } catch (e) {
106
+ if (!this.stopped) {
107
+ this.shutdown();
108
+ (_a = this.onIdle) == null ? void 0 : _a.call(this, e);
109
+ }
110
+ return;
111
+ }
112
+ task.onComplete(output);
113
+ if (this.taskKeyQueue.length > 0) {
114
+ setTimeout(() => {
115
+ this.processNextTask();
116
+ });
117
+ } else {
118
+ this.processing = false;
119
+ if (!this.stopped) {
120
+ (_b = this.onIdle) == null ? void 0 : _b.call(this);
121
+ }
122
+ }
123
+ });
78
124
  }
79
125
  };
80
126
 
@@ -83,13 +129,13 @@ var CheckDataCoordinator = class {
83
129
  constructor(bundleModel) {
84
130
  this.bundleModel = bundleModel;
85
131
  this.taskQueue = new TaskQueue({
86
- process: async (request) => {
87
- const result = await this.bundleModel.getDatasetsForScenario(request.scenarioSpec, [request.datasetKey]);
132
+ process: (request) => __async(this, null, function* () {
133
+ const result = yield this.bundleModel.getDatasetsForScenario(request.scenarioSpec, [request.datasetKey]);
88
134
  const dataset = result.datasetMap.get(request.datasetKey);
89
135
  return {
90
136
  dataset
91
137
  };
92
- }
138
+ })
93
139
  });
94
140
  }
95
141
  requestDataset(requestKey, scenarioSpec, datasetKey, onResponse) {
@@ -1642,6 +1688,24 @@ var CheckPlanner = class {
1642
1688
  dataRefs: this.dataRefs
1643
1689
  };
1644
1690
  }
1691
+ /**
1692
+ * Record any references to additional datasets contained in the given predicate.
1693
+ * For example, if the predicate is:
1694
+ * ```
1695
+ * gt:
1696
+ * dataset:
1697
+ * name: 'XYZ'
1698
+ * scenario:
1699
+ * inputs: all
1700
+ * at: default
1701
+ * ```
1702
+ * this will add a reference to the scenario/dataset pair so that the data can
1703
+ * be fetched in a later stage.
1704
+ *
1705
+ * @param predicateSpec The predicate spec.
1706
+ * @param checkScenario The scenario in which the dataset is being checked.
1707
+ * @param checkDataset The dataset that is being checked.
1708
+ */
1645
1709
  addDataRefs(predicateSpec, checkScenario, checkDataset) {
1646
1710
  let dataRefs;
1647
1711
  const addDataRef = (op) => {
@@ -1770,7 +1834,7 @@ var ComparisonDataCoordinator = class {
1770
1834
  this.bundleModelL = bundleModelL;
1771
1835
  this.bundleModelR = bundleModelR;
1772
1836
  this.taskQueue = new TaskQueue({
1773
- process: async (request) => {
1837
+ process: (request) => __async(this, null, function* () {
1774
1838
  switch (request.kind) {
1775
1839
  case "dataset":
1776
1840
  return this.processDatasetRequest(request);
@@ -1779,44 +1843,52 @@ var ComparisonDataCoordinator = class {
1779
1843
  default:
1780
1844
  assertNever7(request);
1781
1845
  }
1782
- }
1846
+ })
1783
1847
  });
1784
1848
  }
1785
- async processDatasetRequest(request) {
1786
- async function fetchDatasets(bundleModel, scenarioSpec) {
1787
- if (scenarioSpec) {
1788
- return bundleModel.getDatasetsForScenario(scenarioSpec, request.datasetKeys);
1789
- } else {
1790
- return void 0;
1849
+ processDatasetRequest(request) {
1850
+ return __async(this, null, function* () {
1851
+ function fetchDatasets(bundleModel, scenarioSpec) {
1852
+ return __async(this, null, function* () {
1853
+ if (scenarioSpec) {
1854
+ return bundleModel.getDatasetsForScenario(scenarioSpec, request.datasetKeys);
1855
+ } else {
1856
+ return void 0;
1857
+ }
1858
+ });
1791
1859
  }
1792
- }
1793
- const [resultL, resultR] = await Promise.all([
1794
- fetchDatasets(this.bundleModelL, request.scenarioSpecL),
1795
- fetchDatasets(this.bundleModelR, request.scenarioSpecR)
1796
- ]);
1797
- return {
1798
- kind: "dataset",
1799
- datasetMapL: resultL == null ? void 0 : resultL.datasetMap,
1800
- datasetMapR: resultR == null ? void 0 : resultR.datasetMap
1801
- };
1860
+ const [resultL, resultR] = yield Promise.all([
1861
+ fetchDatasets(this.bundleModelL, request.scenarioSpecL),
1862
+ fetchDatasets(this.bundleModelR, request.scenarioSpecR)
1863
+ ]);
1864
+ return {
1865
+ kind: "dataset",
1866
+ datasetMapL: resultL == null ? void 0 : resultL.datasetMap,
1867
+ datasetMapR: resultR == null ? void 0 : resultR.datasetMap
1868
+ };
1869
+ });
1802
1870
  }
1803
- async processGraphDataRequest(request) {
1804
- async function fetchGraphData(bundleModel, scenarioSpec) {
1805
- if (scenarioSpec) {
1806
- return bundleModel.getGraphDataForScenario(scenarioSpec, request.graphId);
1807
- } else {
1808
- return void 0;
1871
+ processGraphDataRequest(request) {
1872
+ return __async(this, null, function* () {
1873
+ function fetchGraphData(bundleModel, scenarioSpec) {
1874
+ return __async(this, null, function* () {
1875
+ if (scenarioSpec) {
1876
+ return bundleModel.getGraphDataForScenario(scenarioSpec, request.graphId);
1877
+ } else {
1878
+ return void 0;
1879
+ }
1880
+ });
1809
1881
  }
1810
- }
1811
- const [graphDataL, graphDataR] = await Promise.all([
1812
- fetchGraphData(this.bundleModelL, request.scenarioSpecL),
1813
- fetchGraphData(this.bundleModelR, request.scenarioSpecR)
1814
- ]);
1815
- return {
1816
- kind: "graph-data",
1817
- graphDataL,
1818
- graphDataR
1819
- };
1882
+ const [graphDataL, graphDataR] = yield Promise.all([
1883
+ fetchGraphData(this.bundleModelL, request.scenarioSpecL),
1884
+ fetchGraphData(this.bundleModelR, request.scenarioSpecR)
1885
+ ]);
1886
+ return {
1887
+ kind: "graph-data",
1888
+ graphDataL,
1889
+ graphDataR
1890
+ };
1891
+ });
1820
1892
  }
1821
1893
  requestDatasetMaps(requestKey, scenarioSpecL, scenarioSpecR, datasetKeys, onResponse) {
1822
1894
  const request = {
@@ -2252,7 +2324,9 @@ function compareScores(a, b) {
2252
2324
  // src/bundle/model-inputs.ts
2253
2325
  var ModelInputs = class {
2254
2326
  constructor(modelSpec) {
2327
+ /** All inputs keyed by lookup name (lowercase variable name or alias). */
2255
2328
  this.inputsByLookupName = /* @__PURE__ */ new Map();
2329
+ /** All input ID aliases. */
2256
2330
  this.inputIdAliases = /* @__PURE__ */ new Set();
2257
2331
  for (const inputVar of modelSpec.inputVars.values()) {
2258
2332
  const varNameKey = inputVar.varName.toLowerCase();
@@ -2282,9 +2356,17 @@ var ModelInputs = class {
2282
2356
  }
2283
2357
  }
2284
2358
  }
2359
+ /**
2360
+ * Return the set of `id XYZ` aliases for all input variables.
2361
+ */
2285
2362
  getAllInputIdAliases() {
2286
2363
  return [...this.inputIdAliases];
2287
2364
  }
2365
+ /**
2366
+ * Return the `InputVar` that matches the requested name (either by variable name or alias).
2367
+ *
2368
+ * @param name The variable name or alias to match.
2369
+ */
2288
2370
  getInputVarForName(name) {
2289
2371
  return this.inputsByLookupName.get(name.toLowerCase());
2290
2372
  }
@@ -2306,6 +2388,9 @@ var comparison_schema_default = {
2306
2388
  $ref: "#/$defs/top_level_array_item"
2307
2389
  },
2308
2390
  $defs: {
2391
+ //
2392
+ // TOP-LEVEL
2393
+ //
2309
2394
  top_level_array_item: {
2310
2395
  oneOf: [
2311
2396
  { $ref: "#/$defs/scenario_array_item" },
@@ -2313,6 +2398,9 @@ var comparison_schema_default = {
2313
2398
  { $ref: "#/$defs/view_group_array_item" }
2314
2399
  ]
2315
2400
  },
2401
+ //
2402
+ // SCENARIOS
2403
+ //
2316
2404
  scenario_array_item: {
2317
2405
  type: "object",
2318
2406
  additionalProperties: false,
@@ -2329,7 +2417,9 @@ var comparison_schema_default = {
2329
2417
  { $ref: "#/$defs/scenario_with_input_at_value" },
2330
2418
  { $ref: "#/$defs/scenario_with_multiple_input_settings" },
2331
2419
  { $ref: "#/$defs/scenario_with_inputs_in_preset_at_position" },
2420
+ // { $ref: '#/$defs/scenario_with_inputs_in_group_at_position' }
2332
2421
  { $ref: "#/$defs/scenario_preset" }
2422
+ // { $ref: '#/$defs/scenario_expand_for_each_input_in_group' }
2333
2423
  ]
2334
2424
  },
2335
2425
  scenario_position: {
@@ -2469,6 +2559,9 @@ var comparison_schema_default = {
2469
2559
  },
2470
2560
  required: ["preset"]
2471
2561
  },
2562
+ //
2563
+ // SCENARIO GROUPS
2564
+ //
2472
2565
  scenario_group_array_item: {
2473
2566
  type: "object",
2474
2567
  additionalProperties: false,
@@ -2544,6 +2637,9 @@ var comparison_schema_default = {
2544
2637
  },
2545
2638
  required: ["scenario_group_ref"]
2546
2639
  },
2640
+ //
2641
+ // VIEWS
2642
+ //
2547
2643
  view: {
2548
2644
  type: "object",
2549
2645
  additionalProperties: false,
@@ -2577,6 +2673,9 @@ var comparison_schema_default = {
2577
2673
  },
2578
2674
  minItems: 1
2579
2675
  },
2676
+ //
2677
+ // VIEW GROUPS
2678
+ //
2580
2679
  view_group_array_item: {
2581
2680
  type: "object",
2582
2681
  additionalProperties: false,
@@ -2860,15 +2959,18 @@ function scenarioSpecFromInputs(inputs, side) {
2860
2959
  if (state.inputVar === void 0) {
2861
2960
  return void 0;
2862
2961
  }
2863
- const varId = state.inputVar.varId;
2864
- if (state.position) {
2865
- settings.push(positionSetting(varId, state.position));
2866
- } else {
2867
- settings.push(valueSetting(varId, state.value));
2868
- }
2962
+ settings.push(inputSettingFromResolvedInputState(state));
2869
2963
  }
2870
2964
  return inputSettingsSpec(settings);
2871
2965
  }
2966
+ function inputSettingFromResolvedInputState(state) {
2967
+ const varId = state.inputVar.varId;
2968
+ if (state.position) {
2969
+ return positionSetting(varId, state.position);
2970
+ } else {
2971
+ return valueSetting(varId, state.value);
2972
+ }
2973
+ }
2872
2974
 
2873
2975
  // src/comparison/config/resolve/comparison-resolver.ts
2874
2976
  function resolveComparisonSpecs(modelInputsL, modelInputsR, specs) {
@@ -2904,7 +3006,7 @@ function resolveComparisonSpecs(modelInputsL, modelInputsR, specs) {
2904
3006
  if (scenarioItem.kind === "scenario-ref") {
2905
3007
  const referencedScenario = resolvedScenarios.getScenarioForId(scenarioItem.scenarioId);
2906
3008
  if (referencedScenario) {
2907
- const resolvedScenario = { ...referencedScenario };
3009
+ const resolvedScenario = __spreadValues({}, referencedScenario);
2908
3010
  if (scenarioItem.title) {
2909
3011
  resolvedScenario.title = scenarioItem.title;
2910
3012
  }
@@ -2942,7 +3044,9 @@ function resolveComparisonSpecs(modelInputsL, modelInputsR, specs) {
2942
3044
  }
2943
3045
  var ResolvedScenarios = class {
2944
3046
  constructor() {
3047
+ /** The array of all resolved scenarios. */
2945
3048
  this.resolvedScenarios = [];
3049
+ /** The set of resolved scenarios that include an ID, keyed by ID. */
2946
3050
  this.resolvedScenariosById = /* @__PURE__ */ new Map();
2947
3051
  }
2948
3052
  add(scenarios) {
@@ -2992,6 +3096,20 @@ function resolveScenariosFromSpec(modelInputsL, modelInputsR, scenarioSpec, genK
2992
3096
  )
2993
3097
  ];
2994
3098
  }
3099
+ case "scenario-with-distinct-inputs": {
3100
+ return [
3101
+ resolveScenarioForDistinctInputSpecs(
3102
+ modelInputsL,
3103
+ modelInputsR,
3104
+ genKey(),
3105
+ scenarioSpec.id,
3106
+ scenarioSpec.title,
3107
+ scenarioSpec.subtitle,
3108
+ scenarioSpec.inputsL,
3109
+ scenarioSpec.inputsR
3110
+ )
3111
+ ];
3112
+ }
2995
3113
  default:
2996
3114
  assertNever11(scenarioSpec);
2997
3115
  }
@@ -3068,6 +3186,59 @@ function resolveScenarioForInputSpecs(modelInputsL, modelInputsR, key, id, title
3068
3186
  specR
3069
3187
  };
3070
3188
  }
3189
+ function resolveScenarioForDistinctInputSpecs(modelInputsL, modelInputsR, key, id, title, subtitle, inputSpecsL, inputSpecsR) {
3190
+ const inputsWithErrors = [];
3191
+ const settingsL = [];
3192
+ const settingsR = [];
3193
+ function resolveInputSpec(side, modelInputs, inputSpec) {
3194
+ let inputState;
3195
+ switch (inputSpec.kind) {
3196
+ case "input-at-position":
3197
+ inputState = resolveInputForNameInModel(modelInputs, inputSpec.inputName, inputSpec.position);
3198
+ break;
3199
+ case "input-at-value":
3200
+ inputState = resolveInputForNameInModel(modelInputs, inputSpec.inputName, inputSpec.value);
3201
+ break;
3202
+ default:
3203
+ assertNever11(inputSpec);
3204
+ }
3205
+ if (inputState.error !== void 0) {
3206
+ inputsWithErrors.push({
3207
+ requestedName: inputSpec.inputName,
3208
+ stateL: side === "left" ? inputState : {},
3209
+ stateR: side === "right" ? inputState : {}
3210
+ });
3211
+ } else {
3212
+ const inputSetting = inputSettingFromResolvedInputState(inputState);
3213
+ if (side === "left") {
3214
+ settingsL.push(inputSetting);
3215
+ } else {
3216
+ settingsR.push(inputSetting);
3217
+ }
3218
+ }
3219
+ }
3220
+ inputSpecsL.forEach((inputSpec) => resolveInputSpec("left", modelInputsL, inputSpec));
3221
+ inputSpecsR.forEach((inputSpec) => resolveInputSpec("right", modelInputsR, inputSpec));
3222
+ let specL;
3223
+ let specR;
3224
+ if (inputsWithErrors.length === 0) {
3225
+ specL = inputSettingsSpec(settingsL);
3226
+ specR = inputSettingsSpec(settingsR);
3227
+ }
3228
+ return {
3229
+ kind: "scenario",
3230
+ key,
3231
+ id,
3232
+ title,
3233
+ subtitle,
3234
+ settings: {
3235
+ kind: "input-settings",
3236
+ inputs: inputsWithErrors
3237
+ },
3238
+ specL,
3239
+ specR
3240
+ };
3241
+ }
3071
3242
  function resolveInputForName(modelInputsL, modelInputsR, inputName, at) {
3072
3243
  return {
3073
3244
  requestedName: inputName,
@@ -3143,7 +3314,9 @@ function inputValueAtPosition2(inputVar, position) {
3143
3314
  }
3144
3315
  var ResolvedScenarioGroups = class {
3145
3316
  constructor() {
3317
+ /** The array of all resolved scenario groups. */
3146
3318
  this.resolvedGroups = [];
3319
+ /** The set of resolved scenario groups that include an ID, keyed by ID. */
3147
3320
  this.resolvedGroupsById = /* @__PURE__ */ new Map();
3148
3321
  }
3149
3322
  add(group) {
@@ -3315,6 +3488,11 @@ function getComparisonDatasets(modelSpecL, modelSpecR, datasetOptions) {
3315
3488
  return new ComparisonDatasetsImpl(modelSpecL, modelSpecR, datasetOptions);
3316
3489
  }
3317
3490
  var ComparisonDatasetsImpl = class {
3491
+ /**
3492
+ * @param modelSpecL The model spec for the "left" bundle being compared.
3493
+ * @param modelSpecR The model spec for the "right" bundle being compared.
3494
+ * @param datasetOptions The custom configuration for the datasets to be compared.
3495
+ */
3318
3496
  constructor(modelSpecL, modelSpecR, datasetOptions) {
3319
3497
  this.datasetOptions = datasetOptions;
3320
3498
  const renamedDatasetKeys = datasetOptions == null ? void 0 : datasetOptions.renamedDatasetKeys;
@@ -3353,12 +3531,15 @@ var ComparisonDatasetsImpl = class {
3353
3531
  });
3354
3532
  }
3355
3533
  }
3534
+ // from ComparisonDatasets interface
3356
3535
  getAllDatasets() {
3357
3536
  return this.allDatasets.values();
3358
3537
  }
3538
+ // from ComparisonDatasets interface
3359
3539
  getDataset(datasetKey) {
3360
3540
  return this.allDatasets.get(datasetKey);
3361
3541
  }
3542
+ // from ComparisonDatasets interface
3362
3543
  getDatasetKeysForScenario(scenario) {
3363
3544
  var _a;
3364
3545
  if (((_a = this.datasetOptions) == null ? void 0 : _a.datasetKeysForScenario) !== void 0) {
@@ -3384,9 +3565,17 @@ var ComparisonScenariosImpl = class {
3384
3565
  this.scenarioDefs.set(scenario.key, scenario);
3385
3566
  }
3386
3567
  }
3568
+ /**
3569
+ * Return all `ComparisonScenario` instances that are available for comparisons.
3570
+ */
3387
3571
  getAllScenarios() {
3388
3572
  return this.scenarioDefs.values();
3389
3573
  }
3574
+ /**
3575
+ * Return the scenario definition for the given key.
3576
+ *
3577
+ * @param key The key for the scenario.
3578
+ */
3390
3579
  getScenario(key) {
3391
3580
  return this.scenarioDefs.get(key);
3392
3581
  }
@@ -3413,11 +3602,11 @@ var PromiseQueue = class {
3413
3602
  }
3414
3603
  add(f) {
3415
3604
  return new Promise((resolve, reject) => {
3416
- const run = async () => {
3605
+ const run = () => __async(this, null, function* () {
3417
3606
  this.runningCount++;
3418
3607
  const promise = f();
3419
3608
  try {
3420
- const result = await promise;
3609
+ const result = yield promise;
3421
3610
  resolve(result);
3422
3611
  } catch (e) {
3423
3612
  reject(e);
@@ -3425,7 +3614,7 @@ var PromiseQueue = class {
3425
3614
  this.runningCount--;
3426
3615
  this.runNext();
3427
3616
  }
3428
- };
3617
+ });
3429
3618
  if (this.runningCount < 1) {
3430
3619
  run();
3431
3620
  } else {
@@ -3444,81 +3633,84 @@ var PromiseQueue = class {
3444
3633
  };
3445
3634
 
3446
3635
  // src/config/config.ts
3447
- async function createConfig(options) {
3448
- var _a;
3449
- const origCurrentBundle = await loadSynchronized(options.current);
3450
- let currentBundle;
3451
- let comparisonConfig;
3452
- if (options.comparison === void 0) {
3453
- currentBundle = origCurrentBundle;
3454
- } else {
3455
- const baselineBundle = await loadSynchronized(options.comparison.baseline);
3456
- const renamedDatasetKeys = (_a = options.comparison.datasets) == null ? void 0 : _a.renamedDatasetKeys;
3457
- const invertedRenamedKeys = /* @__PURE__ */ new Map();
3458
- renamedDatasetKeys == null ? void 0 : renamedDatasetKeys.forEach((newKey, oldKey) => {
3459
- invertedRenamedKeys.set(newKey, oldKey);
3460
- });
3461
- const rightKeyForLeftKey = (leftKey) => {
3462
- return (renamedDatasetKeys == null ? void 0 : renamedDatasetKeys.get(leftKey)) || leftKey;
3463
- };
3464
- const leftKeyForRightKey = (rightKey) => {
3465
- return invertedRenamedKeys.get(rightKey) || rightKey;
3466
- };
3467
- const origBundleModelR = origCurrentBundle.model;
3468
- const adjBundleModelR = {
3469
- modelSpec: origBundleModelR.modelSpec,
3470
- getDatasetsForScenario: async (scenarioSpec, datasetKeys) => {
3471
- const rightKeys = datasetKeys.map(rightKeyForLeftKey);
3472
- const result = await origBundleModelR.getDatasetsForScenario(scenarioSpec, rightKeys);
3473
- const mapWithRightKeys = result.datasetMap;
3474
- const mapWithLeftKeys = /* @__PURE__ */ new Map();
3475
- for (const [rightKey, dataset] of mapWithRightKeys.entries()) {
3476
- const leftKey = leftKeyForRightKey(rightKey);
3477
- mapWithLeftKeys.set(leftKey, dataset);
3478
- }
3479
- return {
3480
- datasetMap: mapWithLeftKeys,
3481
- modelRunTime: result.modelRunTime
3482
- };
3483
- },
3484
- getGraphDataForScenario: origBundleModelR.getGraphDataForScenario.bind(origBundleModelR),
3485
- getGraphLinksForScenario: origBundleModelR.getGraphLinksForScenario.bind(origBundleModelR)
3486
- };
3487
- currentBundle = {
3488
- ...origCurrentBundle,
3489
- model: adjBundleModelR
3636
+ function createConfig(options) {
3637
+ return __async(this, null, function* () {
3638
+ var _a;
3639
+ const origCurrentBundle = yield loadSynchronized(options.current);
3640
+ let currentBundle;
3641
+ let comparisonConfig;
3642
+ if (options.comparison === void 0) {
3643
+ currentBundle = origCurrentBundle;
3644
+ } else {
3645
+ const baselineBundle = yield loadSynchronized(options.comparison.baseline);
3646
+ const renamedDatasetKeys = (_a = options.comparison.datasets) == null ? void 0 : _a.renamedDatasetKeys;
3647
+ const invertedRenamedKeys = /* @__PURE__ */ new Map();
3648
+ renamedDatasetKeys == null ? void 0 : renamedDatasetKeys.forEach((newKey, oldKey) => {
3649
+ invertedRenamedKeys.set(newKey, oldKey);
3650
+ });
3651
+ const rightKeyForLeftKey = (leftKey) => {
3652
+ return (renamedDatasetKeys == null ? void 0 : renamedDatasetKeys.get(leftKey)) || leftKey;
3653
+ };
3654
+ const leftKeyForRightKey = (rightKey) => {
3655
+ return invertedRenamedKeys.get(rightKey) || rightKey;
3656
+ };
3657
+ const origBundleModelR = origCurrentBundle.model;
3658
+ const adjBundleModelR = {
3659
+ modelSpec: origBundleModelR.modelSpec,
3660
+ getDatasetsForScenario: (scenarioSpec, datasetKeys) => __async(this, null, function* () {
3661
+ const rightKeys = datasetKeys.map(rightKeyForLeftKey);
3662
+ const result = yield origBundleModelR.getDatasetsForScenario(scenarioSpec, rightKeys);
3663
+ const mapWithRightKeys = result.datasetMap;
3664
+ const mapWithLeftKeys = /* @__PURE__ */ new Map();
3665
+ for (const [rightKey, dataset] of mapWithRightKeys.entries()) {
3666
+ const leftKey = leftKeyForRightKey(rightKey);
3667
+ mapWithLeftKeys.set(leftKey, dataset);
3668
+ }
3669
+ return {
3670
+ datasetMap: mapWithLeftKeys,
3671
+ modelRunTime: result.modelRunTime
3672
+ };
3673
+ }),
3674
+ getGraphDataForScenario: origBundleModelR.getGraphDataForScenario.bind(origBundleModelR),
3675
+ getGraphLinksForScenario: origBundleModelR.getGraphLinksForScenario.bind(origBundleModelR)
3676
+ };
3677
+ currentBundle = __spreadProps(__spreadValues({}, origCurrentBundle), {
3678
+ model: adjBundleModelR
3679
+ });
3680
+ const modelSpecL = baselineBundle.model.modelSpec;
3681
+ const modelSpecR = currentBundle.model.modelSpec;
3682
+ const modelInputsL = new ModelInputs(modelSpecL);
3683
+ const modelInputsR = new ModelInputs(modelSpecR);
3684
+ const comparisonDefs = resolveComparisonSpecsFromSources(modelInputsL, modelInputsR, options.comparison.specs);
3685
+ comparisonConfig = {
3686
+ bundleL: baselineBundle,
3687
+ bundleR: currentBundle,
3688
+ thresholds: options.comparison.thresholds,
3689
+ scenarios: getComparisonScenarios(comparisonDefs.scenarios),
3690
+ datasets: getComparisonDatasets(modelSpecL, modelSpecR, options.comparison.datasets),
3691
+ viewGroups: comparisonDefs.viewGroups
3692
+ };
3693
+ }
3694
+ const checkConfig = {
3695
+ bundle: currentBundle,
3696
+ tests: options.check.tests
3490
3697
  };
3491
- const modelSpecL = baselineBundle.model.modelSpec;
3492
- const modelSpecR = currentBundle.model.modelSpec;
3493
- const modelInputsL = new ModelInputs(modelSpecL);
3494
- const modelInputsR = new ModelInputs(modelSpecR);
3495
- const comparisonDefs = resolveComparisonSpecsFromSources(modelInputsL, modelInputsR, options.comparison.specs);
3496
- comparisonConfig = {
3497
- bundleL: baselineBundle,
3498
- bundleR: currentBundle,
3499
- thresholds: options.comparison.thresholds,
3500
- scenarios: getComparisonScenarios(comparisonDefs.scenarios),
3501
- datasets: getComparisonDatasets(modelSpecL, modelSpecR, options.comparison.datasets),
3502
- viewGroups: comparisonDefs.viewGroups
3698
+ return {
3699
+ check: checkConfig,
3700
+ comparison: comparisonConfig
3503
3701
  };
3504
- }
3505
- const checkConfig = {
3506
- bundle: currentBundle,
3507
- tests: options.check.tests
3508
- };
3509
- return {
3510
- check: checkConfig,
3511
- comparison: comparisonConfig
3512
- };
3702
+ });
3513
3703
  }
3514
- async function loadSynchronized(sourceBundle) {
3515
- const sourceModel = await sourceBundle.bundle.initModel();
3516
- const synchronizedModel = synchronizedBundleModel(sourceModel);
3517
- return {
3518
- name: sourceBundle.name,
3519
- version: sourceBundle.bundle.version,
3520
- model: synchronizedModel
3521
- };
3704
+ function loadSynchronized(sourceBundle) {
3705
+ return __async(this, null, function* () {
3706
+ const sourceModel = yield sourceBundle.bundle.initModel();
3707
+ const synchronizedModel = synchronizedBundleModel(sourceModel);
3708
+ return {
3709
+ name: sourceBundle.name,
3710
+ version: sourceBundle.bundle.version,
3711
+ model: synchronizedModel
3712
+ };
3713
+ });
3522
3714
  }
3523
3715
 
3524
3716
  // src/perf/perf-runner.ts
@@ -3568,22 +3760,22 @@ var PerfRunner = class {
3568
3760
  this.mode = mode;
3569
3761
  const scenarioSpec = allInputsAtPositionSpec("at-default");
3570
3762
  this.taskQueue = new TaskQueue({
3571
- process: async (request) => {
3763
+ process: (request) => __async(this, null, function* () {
3572
3764
  switch (request.kind) {
3573
3765
  case "left": {
3574
- const result = await bundleModelL.getDatasetsForScenario(scenarioSpec, []);
3766
+ const result = yield bundleModelL.getDatasetsForScenario(scenarioSpec, []);
3575
3767
  return {
3576
3768
  runTimeL: result.modelRunTime
3577
3769
  };
3578
3770
  }
3579
3771
  case "right": {
3580
- const result = await bundleModelR.getDatasetsForScenario(scenarioSpec, []);
3772
+ const result = yield bundleModelR.getDatasetsForScenario(scenarioSpec, []);
3581
3773
  return {
3582
3774
  runTimeR: result.modelRunTime
3583
3775
  };
3584
3776
  }
3585
3777
  case "both": {
3586
- const [resultL, resultR] = await Promise.all([
3778
+ const [resultL, resultR] = yield Promise.all([
3587
3779
  bundleModelL.getDatasetsForScenario(scenarioSpec, []),
3588
3780
  bundleModelR.getDatasetsForScenario(scenarioSpec, [])
3589
3781
  ]);
@@ -3595,7 +3787,7 @@ var PerfRunner = class {
3595
3787
  default:
3596
3788
  assertNever12(request.kind);
3597
3789
  }
3598
- }
3790
+ })
3599
3791
  });
3600
3792
  }
3601
3793
  start() {
@@ -3643,13 +3835,31 @@ var PerfRunner = class {
3643
3835
 
3644
3836
  // src/data/data-planner.ts
3645
3837
  var DataPlanner = class {
3838
+ /**
3839
+ * @param batchSize The maximum number of impl vars that can be fetched
3840
+ * with a single request; this is usually the same as the number of
3841
+ * normal model outputs.
3842
+ */
3646
3843
  constructor(batchSize) {
3647
3844
  this.batchSize = batchSize;
3845
+ /** Tasks that need to access both "left" and "right" models in parallel. */
3648
3846
  this.taskSetsLR = /* @__PURE__ */ new Map();
3847
+ /** Tasks that only need to access the "left" model. */
3649
3848
  this.taskSetsL = /* @__PURE__ */ new Map();
3849
+ /** Tasks that only need to access the "right" model. */
3650
3850
  this.taskSetsR = /* @__PURE__ */ new Map();
3651
3851
  this.complete = false;
3652
3852
  }
3853
+ /**
3854
+ * Add a request to the plan for the given scenario(s) and data task.
3855
+ *
3856
+ * @param scenarioSpecL The input scenario used to configure the "left" model, or undefined if no data
3857
+ * is needed from the left model.
3858
+ * @param scenarioSpecR The input scenario used to configure the "right" model, or undefined if no data
3859
+ * is needed from the right model.
3860
+ * @param datasetKey The key for the dataset to be fetched from each model for the given scenario.
3861
+ * @param dataAction The action to be performed with the fetched datasets.
3862
+ */
3653
3863
  addRequest(scenarioSpecL, scenarioSpecR, datasetKey, dataAction) {
3654
3864
  if (scenarioSpecL === void 0 && scenarioSpecR === void 0) {
3655
3865
  console.warn("WARNING: Both scenario specs are undefined for DataPlanner request, skipping");
@@ -3677,6 +3887,9 @@ var DataPlanner = class {
3677
3887
  dataAction
3678
3888
  });
3679
3889
  }
3890
+ /**
3891
+ * Build a plan that minimizes the number of data fetches needed.
3892
+ */
3680
3893
  buildPlan() {
3681
3894
  if (this.complete) {
3682
3895
  throw new Error("DataPlanner.buildPlan() can only be called once");
@@ -3727,6 +3940,12 @@ var DataTaskSet = class {
3727
3940
  this.modelTasks = /* @__PURE__ */ new Map();
3728
3941
  this.modelImplTasks = /* @__PURE__ */ new Map();
3729
3942
  }
3943
+ /**
3944
+ * Add a task that will be performed when the data is fetched for the scenario(s)
3945
+ * associated with this task set.
3946
+ *
3947
+ * @param dataTask A task that performs an action using the fetched dataset(s).
3948
+ */
3730
3949
  addTask(dataTask) {
3731
3950
  let taskMap;
3732
3951
  if (dataTask.datasetKey.startsWith("ModelImpl")) {
@@ -3741,6 +3960,11 @@ var DataTaskSet = class {
3741
3960
  }
3742
3961
  tasks.push(dataTask);
3743
3962
  }
3963
+ /**
3964
+ * Add all tasks from the given set into this set.
3965
+ *
3966
+ * @param otherTaskSet The other task set that will be merged into this one.
3967
+ */
3744
3968
  merge(otherTaskSet) {
3745
3969
  for (const tasks of otherTaskSet.modelTasks.values()) {
3746
3970
  for (const task of tasks) {
@@ -3753,6 +3977,12 @@ var DataTaskSet = class {
3753
3977
  }
3754
3978
  }
3755
3979
  }
3980
+ /**
3981
+ * Create one or more data requests that can be used to fetch data for the configured scenario(s).
3982
+ *
3983
+ * @param batchSize The maximum number of impl vars that can be fetched with a single request.
3984
+ * This is usually the same as the number of normal model outputs.
3985
+ */
3756
3986
  buildRequests(batchSize) {
3757
3987
  const dataRequests = [];
3758
3988
  if (this.modelTasks.size > 0) {
@@ -3988,42 +4218,46 @@ var SuiteRunner = class {
3988
4218
  });
3989
4219
  }
3990
4220
  }
3991
- async processRequest(request) {
3992
- var _a, _b;
3993
- const datasetKeySet = /* @__PURE__ */ new Set();
3994
- for (const dataTask of request.dataTasks) {
3995
- datasetKeySet.add(dataTask.datasetKey);
3996
- }
3997
- const datasetKeys = [...datasetKeySet];
3998
- async function getDatasets(bundleModel, scenarioSpec) {
3999
- if (bundleModel && scenarioSpec) {
4000
- return bundleModel.getDatasetsForScenario(scenarioSpec, datasetKeys);
4001
- } else {
4002
- return void 0;
4003
- }
4004
- }
4005
- const bundleModelL = (_a = this.config.comparison) == null ? void 0 : _a.bundleL.model;
4006
- const bundleModelR = ((_b = this.config.comparison) == null ? void 0 : _b.bundleR.model) || this.config.check.bundle.model;
4007
- const [datasetsResultL, datasetsResultR] = await Promise.all([
4008
- getDatasets(bundleModelL, request.scenarioSpecL),
4009
- getDatasets(bundleModelR, request.scenarioSpecR)
4010
- ]);
4011
- if (datasetsResultL == null ? void 0 : datasetsResultL.modelRunTime) {
4012
- this.perfStatsL.addRun(datasetsResultL == null ? void 0 : datasetsResultL.modelRunTime);
4013
- }
4014
- if (datasetsResultR == null ? void 0 : datasetsResultR.modelRunTime) {
4015
- this.perfStatsR.addRun(datasetsResultR == null ? void 0 : datasetsResultR.modelRunTime);
4016
- }
4017
- const datasetMapL = datasetsResultL == null ? void 0 : datasetsResultL.datasetMap;
4018
- const datasetMapR = datasetsResultR == null ? void 0 : datasetsResultR.datasetMap;
4019
- for (const dataTask of request.dataTasks) {
4020
- const datasetL = datasetMapL == null ? void 0 : datasetMapL.get(dataTask.datasetKey);
4021
- const datasetR = datasetMapR == null ? void 0 : datasetMapR.get(dataTask.datasetKey);
4022
- dataTask.dataAction({
4023
- datasetL,
4024
- datasetR
4025
- });
4026
- }
4221
+ processRequest(request) {
4222
+ return __async(this, null, function* () {
4223
+ var _a, _b;
4224
+ const datasetKeySet = /* @__PURE__ */ new Set();
4225
+ for (const dataTask of request.dataTasks) {
4226
+ datasetKeySet.add(dataTask.datasetKey);
4227
+ }
4228
+ const datasetKeys = [...datasetKeySet];
4229
+ function getDatasets(bundleModel, scenarioSpec) {
4230
+ return __async(this, null, function* () {
4231
+ if (bundleModel && scenarioSpec) {
4232
+ return bundleModel.getDatasetsForScenario(scenarioSpec, datasetKeys);
4233
+ } else {
4234
+ return void 0;
4235
+ }
4236
+ });
4237
+ }
4238
+ const bundleModelL = (_a = this.config.comparison) == null ? void 0 : _a.bundleL.model;
4239
+ const bundleModelR = ((_b = this.config.comparison) == null ? void 0 : _b.bundleR.model) || this.config.check.bundle.model;
4240
+ const [datasetsResultL, datasetsResultR] = yield Promise.all([
4241
+ getDatasets(bundleModelL, request.scenarioSpecL),
4242
+ getDatasets(bundleModelR, request.scenarioSpecR)
4243
+ ]);
4244
+ if (datasetsResultL == null ? void 0 : datasetsResultL.modelRunTime) {
4245
+ this.perfStatsL.addRun(datasetsResultL == null ? void 0 : datasetsResultL.modelRunTime);
4246
+ }
4247
+ if (datasetsResultR == null ? void 0 : datasetsResultR.modelRunTime) {
4248
+ this.perfStatsR.addRun(datasetsResultR == null ? void 0 : datasetsResultR.modelRunTime);
4249
+ }
4250
+ const datasetMapL = datasetsResultL == null ? void 0 : datasetsResultL.datasetMap;
4251
+ const datasetMapR = datasetsResultR == null ? void 0 : datasetsResultR.datasetMap;
4252
+ for (const dataTask of request.dataTasks) {
4253
+ const datasetL = datasetMapL == null ? void 0 : datasetMapL.get(dataTask.datasetKey);
4254
+ const datasetR = datasetMapR == null ? void 0 : datasetMapR.get(dataTask.datasetKey);
4255
+ dataTask.dataAction({
4256
+ datasetL,
4257
+ datasetR
4258
+ });
4259
+ }
4260
+ });
4027
4261
  }
4028
4262
  };
4029
4263
  function runSuite(config, callbacks, options) {