@sdeverywhere/check-core 0.1.4 → 0.1.6
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.cjs +1227 -439
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +499 -105
- package/dist/index.d.ts +499 -105
- package/dist/index.js +1218 -437
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -38,33 +38,178 @@ var __async = (__this, __arguments, generator) => {
|
|
|
38
38
|
});
|
|
39
39
|
};
|
|
40
40
|
|
|
41
|
+
// src/bundle/impl-vars-codec.ts
|
|
42
|
+
function encodeImplVars(input) {
|
|
43
|
+
const subscripts = [];
|
|
44
|
+
const variables = [];
|
|
45
|
+
const varTypes = [];
|
|
46
|
+
const varInstances = {};
|
|
47
|
+
const subscriptMap = /* @__PURE__ */ new Map();
|
|
48
|
+
const variableMap = /* @__PURE__ */ new Map();
|
|
49
|
+
const varTypeMap = /* @__PURE__ */ new Map();
|
|
50
|
+
for (const [groupKey, implVars] of Object.entries(input)) {
|
|
51
|
+
const instances = [];
|
|
52
|
+
for (const implVar of implVars) {
|
|
53
|
+
const varIdInfo = parseSubscripts(implVar.varId);
|
|
54
|
+
const varNameInfo = parseSubscripts(implVar.varName);
|
|
55
|
+
let varTypeIndex = varTypeMap.get(implVar.varType);
|
|
56
|
+
if (varTypeIndex === void 0) {
|
|
57
|
+
varTypeIndex = varTypes.length;
|
|
58
|
+
varTypes.push(implVar.varType);
|
|
59
|
+
varTypeMap.set(implVar.varType, varTypeIndex);
|
|
60
|
+
}
|
|
61
|
+
let variableIndex = variableMap.get(implVar.varIndex);
|
|
62
|
+
if (variableIndex === void 0) {
|
|
63
|
+
variableIndex = variables.length;
|
|
64
|
+
variables.push({
|
|
65
|
+
n: varNameInfo.base,
|
|
66
|
+
i: varIdInfo.base,
|
|
67
|
+
x: implVar.varIndex
|
|
68
|
+
});
|
|
69
|
+
variableMap.set(implVar.varIndex, variableIndex);
|
|
70
|
+
}
|
|
71
|
+
let subscriptIndices;
|
|
72
|
+
let subscriptValues;
|
|
73
|
+
if (varIdInfo.subscripts.length > 0) {
|
|
74
|
+
subscriptIndices = [];
|
|
75
|
+
subscriptValues = implVar.subscriptIndices || [];
|
|
76
|
+
for (let i = 0; i < varIdInfo.subscripts.length; i++) {
|
|
77
|
+
const subscriptId = varIdInfo.subscripts[i];
|
|
78
|
+
const subscriptName = varNameInfo.subscripts[i];
|
|
79
|
+
let subscriptIndex = subscriptMap.get(subscriptId);
|
|
80
|
+
if (subscriptIndex === void 0) {
|
|
81
|
+
subscriptIndex = subscripts.length;
|
|
82
|
+
subscripts.push({
|
|
83
|
+
n: subscriptName,
|
|
84
|
+
i: subscriptId
|
|
85
|
+
});
|
|
86
|
+
subscriptMap.set(subscriptId, subscriptIndex);
|
|
87
|
+
}
|
|
88
|
+
subscriptIndices.push(subscriptIndex);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
const instance = [varTypeIndex, variableIndex];
|
|
92
|
+
if (subscriptIndices) {
|
|
93
|
+
instance.push(...subscriptIndices, ...subscriptValues);
|
|
94
|
+
}
|
|
95
|
+
instances.push(instance);
|
|
96
|
+
}
|
|
97
|
+
varInstances[groupKey] = instances;
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
subscripts,
|
|
101
|
+
variables,
|
|
102
|
+
varTypes,
|
|
103
|
+
varInstances
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
function decodeImplVars(encoded) {
|
|
107
|
+
const result = {};
|
|
108
|
+
for (const [groupKey, instances] of Object.entries(encoded.varInstances)) {
|
|
109
|
+
const implVars = [];
|
|
110
|
+
for (const instance of instances) {
|
|
111
|
+
const varType = encoded.varTypes[instance[0]];
|
|
112
|
+
const variable = encoded.variables[instance[1]];
|
|
113
|
+
let varId = variable.i;
|
|
114
|
+
let varName = variable.n;
|
|
115
|
+
if (instance.length > 2) {
|
|
116
|
+
const subscriptIds = [];
|
|
117
|
+
const subscriptNames = [];
|
|
118
|
+
const subscriptCount = (instance.length - 2) / 2;
|
|
119
|
+
const subscriptIndices = instance.slice(2, 2 + subscriptCount);
|
|
120
|
+
for (const subscriptIndex of subscriptIndices) {
|
|
121
|
+
const subscript = encoded.subscripts[subscriptIndex];
|
|
122
|
+
subscriptIds.push(subscript.i);
|
|
123
|
+
subscriptNames.push(subscript.n);
|
|
124
|
+
}
|
|
125
|
+
varId += `[${subscriptIds.join(",")}]`;
|
|
126
|
+
varName += `[${subscriptNames.join(",")}]`;
|
|
127
|
+
}
|
|
128
|
+
const implVar = {
|
|
129
|
+
varId,
|
|
130
|
+
varName,
|
|
131
|
+
varType,
|
|
132
|
+
varIndex: variable.x,
|
|
133
|
+
subscriptIndices: instance.length > 2 ? instance.slice(2 + (instance.length - 2) / 2) : void 0
|
|
134
|
+
};
|
|
135
|
+
implVars.push(implVar);
|
|
136
|
+
}
|
|
137
|
+
result[groupKey] = implVars;
|
|
138
|
+
}
|
|
139
|
+
return result;
|
|
140
|
+
}
|
|
141
|
+
function parseSubscripts(text) {
|
|
142
|
+
const bracketIndex = text.indexOf("[");
|
|
143
|
+
if (bracketIndex === -1) {
|
|
144
|
+
return { base: text, subscripts: [] };
|
|
145
|
+
}
|
|
146
|
+
const base = text.substring(0, bracketIndex);
|
|
147
|
+
const subscriptText = text.substring(bracketIndex + 1, text.lastIndexOf("]"));
|
|
148
|
+
const subscripts = subscriptText.split(",").map((s) => s.trim());
|
|
149
|
+
return { base, subscripts };
|
|
150
|
+
}
|
|
151
|
+
|
|
41
152
|
// src/_shared/task-queue.ts
|
|
42
|
-
var TaskQueue = class {
|
|
43
|
-
|
|
44
|
-
|
|
153
|
+
var TaskQueue = class _TaskQueue {
|
|
154
|
+
/**
|
|
155
|
+
* @param executors The map of available task executors.
|
|
156
|
+
*/
|
|
157
|
+
constructor(executors) {
|
|
158
|
+
this.executors = executors;
|
|
45
159
|
/** The queue of task keys, most recent at front. */
|
|
46
160
|
this.taskKeyQueue = [];
|
|
47
161
|
/** The map of tasks. */
|
|
48
162
|
this.taskMap = /* @__PURE__ */ new Map();
|
|
163
|
+
// /** The set of keys for the executors that are currently processing tasks. */
|
|
164
|
+
// private readonly activeExecutorKeys: Set<TaskExecutorKey> = new Set()
|
|
165
|
+
/** The idle event listeners. */
|
|
166
|
+
this.idleListeners = [];
|
|
49
167
|
/** Whether tasks are being processed. */
|
|
50
168
|
this.processing = false;
|
|
51
169
|
/** Whether `shutdown` has been called. */
|
|
52
170
|
this.stopped = false;
|
|
53
171
|
}
|
|
54
|
-
|
|
172
|
+
/**
|
|
173
|
+
* Initialize the shared `TaskQueue` instance.
|
|
174
|
+
*
|
|
175
|
+
* @param executors The map of available task executors.
|
|
176
|
+
*/
|
|
177
|
+
static initialize(executors) {
|
|
178
|
+
if (executors.size === 0) {
|
|
179
|
+
throw new Error("Must provide at least one executor");
|
|
180
|
+
}
|
|
181
|
+
this.instance = new _TaskQueue(executors);
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Get the shared `TaskQueue` instance.
|
|
185
|
+
*/
|
|
186
|
+
static getInstance() {
|
|
187
|
+
if (!this.instance) {
|
|
188
|
+
throw new Error("TaskQueue not initialized; must call `initialize` first");
|
|
189
|
+
}
|
|
190
|
+
return this.instance;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Add a task to the queue.
|
|
194
|
+
*
|
|
195
|
+
* @param task The task to add.
|
|
196
|
+
*/
|
|
197
|
+
addTask(task) {
|
|
55
198
|
if (this.stopped) {
|
|
56
199
|
return;
|
|
57
200
|
}
|
|
58
|
-
if (this.taskMap.has(key)) {
|
|
59
|
-
throw new Error(`Task already added for key ${key}`);
|
|
201
|
+
if (this.taskMap.has(task.key)) {
|
|
202
|
+
throw new Error(`Task already added for key ${task.key}`);
|
|
60
203
|
}
|
|
61
|
-
this.taskKeyQueue.push(key);
|
|
62
|
-
this.taskMap.set(key,
|
|
63
|
-
input,
|
|
64
|
-
onComplete
|
|
65
|
-
});
|
|
204
|
+
this.taskKeyQueue.push(task.key);
|
|
205
|
+
this.taskMap.set(task.key, task);
|
|
66
206
|
this.processTasksIfNeeded();
|
|
67
207
|
}
|
|
208
|
+
/**
|
|
209
|
+
* Cancel a task.
|
|
210
|
+
*
|
|
211
|
+
* @param taskKey The key of the task to cancel.
|
|
212
|
+
*/
|
|
68
213
|
cancelTask(taskKey) {
|
|
69
214
|
const index = this.taskKeyQueue.indexOf(taskKey);
|
|
70
215
|
if (index >= 0) {
|
|
@@ -72,9 +217,37 @@ var TaskQueue = class {
|
|
|
72
217
|
}
|
|
73
218
|
this.taskMap.delete(taskKey);
|
|
74
219
|
}
|
|
220
|
+
/**
|
|
221
|
+
* Add an idle listener.
|
|
222
|
+
*
|
|
223
|
+
* @param listener The listener to add.
|
|
224
|
+
*/
|
|
225
|
+
onIdle(listener) {
|
|
226
|
+
this.idleListeners.push(listener);
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Remove an idle listener.
|
|
230
|
+
*
|
|
231
|
+
* @param listener The listener to remove.
|
|
232
|
+
*/
|
|
233
|
+
removeIdleListener(listener) {
|
|
234
|
+
this.idleListeners.splice(this.idleListeners.indexOf(listener), 1);
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Notify the idle listeners.
|
|
238
|
+
*
|
|
239
|
+
* @param error The error to notify the listeners with.
|
|
240
|
+
*/
|
|
241
|
+
notifyIdle(error) {
|
|
242
|
+
for (const listener of this.idleListeners) {
|
|
243
|
+
listener(error);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Shutdown the task queue, cancelling all pending tasks.
|
|
248
|
+
*/
|
|
75
249
|
shutdown() {
|
|
76
250
|
this.stopped = true;
|
|
77
|
-
this.processing = false;
|
|
78
251
|
this.taskKeyQueue.length = 0;
|
|
79
252
|
this.taskMap.clear();
|
|
80
253
|
}
|
|
@@ -82,75 +255,98 @@ var TaskQueue = class {
|
|
|
82
255
|
if (!this.stopped && !this.processing) {
|
|
83
256
|
this.processing = true;
|
|
84
257
|
setTimeout(() => {
|
|
85
|
-
this.
|
|
258
|
+
this.processNextTasks();
|
|
86
259
|
});
|
|
87
260
|
}
|
|
88
261
|
}
|
|
89
|
-
|
|
262
|
+
processNextTasks() {
|
|
90
263
|
return __async(this, null, function* () {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
264
|
+
const taskKeys = this.taskKeyQueue.splice(0, this.executors.size);
|
|
265
|
+
if (taskKeys.length === 0) {
|
|
266
|
+
this.processing = false;
|
|
267
|
+
if (!this.stopped) {
|
|
268
|
+
this.notifyIdle();
|
|
269
|
+
}
|
|
94
270
|
return;
|
|
95
271
|
}
|
|
96
|
-
const
|
|
97
|
-
|
|
272
|
+
const executeCalls = [];
|
|
273
|
+
const availableExecutorKeys = Array.from(this.executors.keys());
|
|
274
|
+
for (const taskKey of taskKeys) {
|
|
275
|
+
const task = this.taskMap.get(taskKey);
|
|
276
|
+
if (!task) {
|
|
277
|
+
continue;
|
|
278
|
+
}
|
|
98
279
|
this.taskMap.delete(taskKey);
|
|
99
|
-
|
|
100
|
-
|
|
280
|
+
const executorKey = availableExecutorKeys.shift();
|
|
281
|
+
const executor = this.executors.get(executorKey);
|
|
282
|
+
if (!executor) {
|
|
283
|
+
throw new Error(`No executor found for key ${executorKey}`);
|
|
284
|
+
}
|
|
285
|
+
executeCalls.push(executor.execute(task));
|
|
101
286
|
}
|
|
102
|
-
let output;
|
|
103
287
|
try {
|
|
104
|
-
|
|
288
|
+
yield Promise.all(executeCalls);
|
|
105
289
|
} catch (e) {
|
|
106
290
|
if (!this.stopped) {
|
|
107
291
|
this.shutdown();
|
|
108
|
-
|
|
292
|
+
this.notifyIdle(e);
|
|
109
293
|
}
|
|
110
294
|
return;
|
|
111
295
|
}
|
|
112
|
-
task.onComplete(output);
|
|
113
296
|
if (this.taskKeyQueue.length > 0) {
|
|
114
297
|
setTimeout(() => {
|
|
115
|
-
this.
|
|
298
|
+
this.processNextTasks();
|
|
116
299
|
});
|
|
117
300
|
} else {
|
|
118
301
|
this.processing = false;
|
|
119
302
|
if (!this.stopped) {
|
|
120
|
-
|
|
303
|
+
this.notifyIdle();
|
|
121
304
|
}
|
|
122
305
|
}
|
|
123
306
|
});
|
|
124
307
|
}
|
|
125
308
|
};
|
|
309
|
+
function createExecutor(bundleModelL, bundleModelR) {
|
|
310
|
+
return {
|
|
311
|
+
execute: (task) => __async(this, null, function* () {
|
|
312
|
+
return task.process({
|
|
313
|
+
L: bundleModelL,
|
|
314
|
+
R: bundleModelR
|
|
315
|
+
});
|
|
316
|
+
})
|
|
317
|
+
};
|
|
318
|
+
}
|
|
126
319
|
|
|
127
320
|
// src/check/check-data-coordinator.ts
|
|
128
321
|
var CheckDataCoordinator = class {
|
|
129
|
-
constructor(
|
|
130
|
-
this.
|
|
131
|
-
this.taskQueue = new TaskQueue({
|
|
132
|
-
process: (request) => __async(this, null, function* () {
|
|
133
|
-
const result = yield this.bundleModel.getDatasetsForScenario(request.scenarioSpec, [request.datasetKey]);
|
|
134
|
-
const dataset = result.datasetMap.get(request.datasetKey);
|
|
135
|
-
return {
|
|
136
|
-
dataset
|
|
137
|
-
};
|
|
138
|
-
})
|
|
139
|
-
});
|
|
322
|
+
constructor(taskQueue) {
|
|
323
|
+
this.taskQueue = taskQueue;
|
|
140
324
|
}
|
|
141
325
|
requestDataset(requestKey, scenarioSpec, datasetKey, onResponse) {
|
|
142
|
-
const
|
|
143
|
-
|
|
144
|
-
|
|
326
|
+
const task = {
|
|
327
|
+
key: requestKey,
|
|
328
|
+
kind: "check-data-coordinator",
|
|
329
|
+
process: (bundleModels) => __async(this, null, function* () {
|
|
330
|
+
const bundleModelR = bundleModels.R;
|
|
331
|
+
const result = yield bundleModelR.getDatasetsForScenario(scenarioSpec, [datasetKey]);
|
|
332
|
+
const dataset = result.datasetMap.get(datasetKey);
|
|
333
|
+
onResponse(dataset);
|
|
334
|
+
})
|
|
145
335
|
};
|
|
146
|
-
this.taskQueue.addTask(
|
|
147
|
-
onResponse(response.dataset);
|
|
148
|
-
});
|
|
336
|
+
this.taskQueue.addTask(task);
|
|
149
337
|
}
|
|
150
338
|
cancelRequest(key) {
|
|
151
339
|
this.taskQueue.cancelTask(key);
|
|
152
340
|
}
|
|
153
341
|
};
|
|
342
|
+
function createCheckDataCoordinator() {
|
|
343
|
+
return new CheckDataCoordinator(TaskQueue.getInstance());
|
|
344
|
+
}
|
|
345
|
+
function createCheckDataCoordinatorForTests(bundleModel) {
|
|
346
|
+
const executor = createExecutor(void 0, bundleModel);
|
|
347
|
+
const taskQueue = new TaskQueue(/* @__PURE__ */ new Map([["test-executor-0", executor]]));
|
|
348
|
+
return new CheckDataCoordinator(taskQueue);
|
|
349
|
+
}
|
|
154
350
|
|
|
155
351
|
// src/check/check-report.ts
|
|
156
352
|
import assertNever2 from "assert-never";
|
|
@@ -212,6 +408,10 @@ function buildCheckReport(checkPlan, checkResults) {
|
|
|
212
408
|
testStatus = "failed";
|
|
213
409
|
scenarioStatus = "failed";
|
|
214
410
|
datasetStatus = "failed";
|
|
411
|
+
} else if (checkResult.status === "skipped" && testStatus === "passed") {
|
|
412
|
+
testStatus = "skipped";
|
|
413
|
+
scenarioStatus = "skipped";
|
|
414
|
+
datasetStatus = "skipped";
|
|
215
415
|
}
|
|
216
416
|
}
|
|
217
417
|
predicateReports.push(predicateReport(predicatePlan, checkKey, checkResult));
|
|
@@ -1147,16 +1347,6 @@ function actionForPredicate(predicateSpec) {
|
|
|
1147
1347
|
};
|
|
1148
1348
|
}
|
|
1149
1349
|
|
|
1150
|
-
// src/_shared/combo.ts
|
|
1151
|
-
function cartesianProductOf(arr) {
|
|
1152
|
-
return arr.reduce(
|
|
1153
|
-
(a, b) => {
|
|
1154
|
-
return a.map((x) => b.map((y) => x.concat([y]))).reduce((v, w) => v.concat(w), []);
|
|
1155
|
-
},
|
|
1156
|
-
[[]]
|
|
1157
|
-
);
|
|
1158
|
-
}
|
|
1159
|
-
|
|
1160
1350
|
// src/check/check-dataset.ts
|
|
1161
1351
|
function expandDatasets(modelSpec, datasetSpec) {
|
|
1162
1352
|
var _a;
|
|
@@ -1185,25 +1375,10 @@ function expandDatasets(modelSpec, datasetSpec) {
|
|
|
1185
1375
|
name: match.outputVar.varName
|
|
1186
1376
|
});
|
|
1187
1377
|
} else if (match.implVar) {
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
const subscriptCombos = cartesianProductOf(subscripts);
|
|
1193
|
-
for (const subscriptCombo of subscriptCombos) {
|
|
1194
|
-
const subIdParts = subscriptCombo.map((sub) => `[${sub.id}]`).join("");
|
|
1195
|
-
const subNameParts = subscriptCombo.map((sub) => sub.name).join(",");
|
|
1196
|
-
checkDatasets.push({
|
|
1197
|
-
datasetKey: `${baseDatasetKey}${subIdParts}`,
|
|
1198
|
-
name: `${implVar.varName}[${subNameParts}]`
|
|
1199
|
-
});
|
|
1200
|
-
}
|
|
1201
|
-
} else {
|
|
1202
|
-
checkDatasets.push({
|
|
1203
|
-
datasetKey: match.datasetKey,
|
|
1204
|
-
name: implVar.varName
|
|
1205
|
-
});
|
|
1206
|
-
}
|
|
1378
|
+
checkDatasets.push({
|
|
1379
|
+
datasetKey: match.datasetKey,
|
|
1380
|
+
name: match.implVar.varName
|
|
1381
|
+
});
|
|
1207
1382
|
}
|
|
1208
1383
|
}
|
|
1209
1384
|
return checkDatasets;
|
|
@@ -1611,12 +1786,18 @@ var CheckPlanner = class {
|
|
|
1611
1786
|
this.dataRefs = /* @__PURE__ */ new Map();
|
|
1612
1787
|
this.checkKey = 1;
|
|
1613
1788
|
}
|
|
1614
|
-
addAllChecks(checkSpec,
|
|
1789
|
+
addAllChecks(checkSpec, skipChecks) {
|
|
1790
|
+
function skipCheckKey(groupName, testName) {
|
|
1791
|
+
return `${groupName.toLowerCase()} :: ${testName.toLowerCase()}`;
|
|
1792
|
+
}
|
|
1793
|
+
const skipChecksSet = new Set(skipChecks.map((check) => skipCheckKey(check.groupName, check.testName)));
|
|
1615
1794
|
for (const groupSpec of checkSpec.groups) {
|
|
1616
1795
|
const groupName = groupSpec.describe;
|
|
1617
1796
|
const planTests = [];
|
|
1618
1797
|
for (const testSpec of groupSpec.tests) {
|
|
1619
1798
|
const testName = testSpec.it;
|
|
1799
|
+
const shouldSkip = skipChecksSet.has(skipCheckKey(groupName, testName));
|
|
1800
|
+
const simplifyScenarios = false;
|
|
1620
1801
|
const checkScenarios = expandScenarios(this.modelSpec, testSpec.scenarios || [], simplifyScenarios);
|
|
1621
1802
|
const checkDatasets = [];
|
|
1622
1803
|
for (const datasetSpec of testSpec.datasets) {
|
|
@@ -1657,7 +1838,8 @@ var CheckPlanner = class {
|
|
|
1657
1838
|
scenario: checkScenario,
|
|
1658
1839
|
dataset: checkDataset,
|
|
1659
1840
|
action: checkAction,
|
|
1660
|
-
dataRefs
|
|
1841
|
+
dataRefs,
|
|
1842
|
+
skip: shouldSkip
|
|
1661
1843
|
});
|
|
1662
1844
|
}
|
|
1663
1845
|
planDatasets.push({
|
|
@@ -1794,6 +1976,7 @@ function checkSummaryFromReport(checkReport) {
|
|
|
1794
1976
|
break;
|
|
1795
1977
|
case "failed":
|
|
1796
1978
|
case "error":
|
|
1979
|
+
case "skipped":
|
|
1797
1980
|
predicateSummaries.push({
|
|
1798
1981
|
checkKey: predicate.checkKey,
|
|
1799
1982
|
result: predicate.result
|
|
@@ -1811,14 +1994,14 @@ function checkSummaryFromReport(checkReport) {
|
|
|
1811
1994
|
predicateSummaries
|
|
1812
1995
|
};
|
|
1813
1996
|
}
|
|
1814
|
-
function checkReportFromSummary(checkConfig, checkSummary) {
|
|
1997
|
+
function checkReportFromSummary(checkConfig, checkSummary, skipChecks = []) {
|
|
1815
1998
|
const checkSpecResult = parseTestYaml(checkConfig.tests);
|
|
1816
1999
|
if (checkSpecResult.isErr()) {
|
|
1817
2000
|
return void 0;
|
|
1818
2001
|
}
|
|
1819
2002
|
const checkSpec = checkSpecResult.value;
|
|
1820
|
-
const checkPlanner = new CheckPlanner(checkConfig.bundle.
|
|
1821
|
-
checkPlanner.addAllChecks(checkSpec,
|
|
2003
|
+
const checkPlanner = new CheckPlanner(checkConfig.bundle.modelSpec);
|
|
2004
|
+
checkPlanner.addAllChecks(checkSpec, skipChecks);
|
|
1822
2005
|
const checkPlan = checkPlanner.buildPlan();
|
|
1823
2006
|
const checkResults = /* @__PURE__ */ new Map();
|
|
1824
2007
|
for (const predicateSummary of checkSummary.predicateSummaries) {
|
|
@@ -1828,98 +2011,115 @@ function checkReportFromSummary(checkConfig, checkSummary) {
|
|
|
1828
2011
|
}
|
|
1829
2012
|
|
|
1830
2013
|
// src/comparison/run/comparison-data-coordinator.ts
|
|
1831
|
-
import { assertNever as assertNever7 } from "assert-never";
|
|
1832
2014
|
var ComparisonDataCoordinator = class {
|
|
1833
|
-
constructor(
|
|
1834
|
-
this.
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
2015
|
+
constructor(taskQueue) {
|
|
2016
|
+
this.taskQueue = taskQueue;
|
|
2017
|
+
}
|
|
2018
|
+
/**
|
|
2019
|
+
* Request datasets from the two models.
|
|
2020
|
+
*
|
|
2021
|
+
* @param requestKey The unique key for the request.
|
|
2022
|
+
* @param sourceL The source of the first ("left") dataset. If "left", the datasets will
|
|
2023
|
+
* be fetched from the "left" bundle's model, otherwise they will be fetched from the
|
|
2024
|
+
* "right" bundle's model.
|
|
2025
|
+
* @param scenarioSpecL The scenario used for the first ("left") model of the comparison.
|
|
2026
|
+
* @param sourceR The source of the second ("right") dataset. If "left", the datasets
|
|
2027
|
+
* will be fetched from the "left" bundle's model, otherwise they will be fetched from
|
|
2028
|
+
* the "right" bundle's model.
|
|
2029
|
+
* @param scenarioSpecR The scenario used for the second ("right") model of the comparison.
|
|
2030
|
+
* @param graphId The keys of the datasets to be fetched.
|
|
2031
|
+
* @param onResponse The callback that will be called with the dataset maps.
|
|
2032
|
+
*/
|
|
2033
|
+
requestDatasetMaps(requestKey, sourceL, scenarioSpecL, sourceR, scenarioSpecR, datasetKeys, onResponse) {
|
|
2034
|
+
function fetchDatasets(bundleModel, scenarioSpec) {
|
|
2035
|
+
return __async(this, null, function* () {
|
|
2036
|
+
if (scenarioSpec) {
|
|
2037
|
+
return bundleModel.getDatasetsForScenario(scenarioSpec, datasetKeys);
|
|
2038
|
+
} else {
|
|
2039
|
+
return void 0;
|
|
1845
2040
|
}
|
|
2041
|
+
});
|
|
2042
|
+
}
|
|
2043
|
+
const task = {
|
|
2044
|
+
key: requestKey,
|
|
2045
|
+
kind: "comparison-data-coordinator",
|
|
2046
|
+
process: (bundleModels) => __async(this, null, function* () {
|
|
2047
|
+
const modelL = sourceL === "left" ? bundleModels.L : bundleModels.R;
|
|
2048
|
+
const modelR = sourceR === "left" ? bundleModels.L : bundleModels.R;
|
|
2049
|
+
let resultL;
|
|
2050
|
+
let resultR;
|
|
2051
|
+
if (modelL === modelR) {
|
|
2052
|
+
resultL = yield fetchDatasets(modelL, scenarioSpecL);
|
|
2053
|
+
resultR = yield fetchDatasets(modelR, scenarioSpecR);
|
|
2054
|
+
} else {
|
|
2055
|
+
const results = yield Promise.all([
|
|
2056
|
+
fetchDatasets(modelL, scenarioSpecL),
|
|
2057
|
+
fetchDatasets(modelR, scenarioSpecR)
|
|
2058
|
+
]);
|
|
2059
|
+
resultL = results[0];
|
|
2060
|
+
resultR = results[1];
|
|
2061
|
+
}
|
|
2062
|
+
onResponse(resultL == null ? void 0 : resultL.datasetMap, resultR == null ? void 0 : resultR.datasetMap);
|
|
1846
2063
|
})
|
|
1847
|
-
});
|
|
1848
|
-
}
|
|
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
|
-
});
|
|
1859
|
-
}
|
|
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
|
-
});
|
|
1870
|
-
}
|
|
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
|
-
});
|
|
1881
|
-
}
|
|
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
|
-
});
|
|
1892
|
-
}
|
|
1893
|
-
requestDatasetMaps(requestKey, scenarioSpecL, scenarioSpecR, datasetKeys, onResponse) {
|
|
1894
|
-
const request = {
|
|
1895
|
-
kind: "dataset",
|
|
1896
|
-
scenarioSpecL,
|
|
1897
|
-
scenarioSpecR,
|
|
1898
|
-
datasetKeys
|
|
1899
2064
|
};
|
|
1900
|
-
this.taskQueue.addTask(
|
|
1901
|
-
if (response.kind === "dataset") {
|
|
1902
|
-
onResponse(response.datasetMapL, response.datasetMapR);
|
|
1903
|
-
}
|
|
1904
|
-
});
|
|
2065
|
+
this.taskQueue.addTask(task);
|
|
1905
2066
|
}
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
2067
|
+
/**
|
|
2068
|
+
* Request graph data from the two models.
|
|
2069
|
+
*
|
|
2070
|
+
* @param requestKey The unique key for the request.
|
|
2071
|
+
* @param sourceL The source of the first ("left") dataset. If "left", the datasets will
|
|
2072
|
+
* be fetched from the "left" bundle's model, otherwise they will be fetched from the
|
|
2073
|
+
* "right" bundle's model.
|
|
2074
|
+
* @param scenarioSpecL The scenario used for the first ("left") model of the comparison.
|
|
2075
|
+
* @param sourceR The source of the second ("right") dataset. If "left", the datasets
|
|
2076
|
+
* will be fetched from the "left" bundle's model, otherwise they will be fetched from
|
|
2077
|
+
* the "right" bundle's model.
|
|
2078
|
+
* @param scenarioSpecR The scenario used for the second ("right") model of the comparison.
|
|
2079
|
+
* @param graphId The ID of the graph for which data will be fetched.
|
|
2080
|
+
* @param onResponse The callback that will be called with the graph data.
|
|
2081
|
+
*/
|
|
2082
|
+
requestGraphData(requestKey, sourceL, scenarioSpecL, sourceR, scenarioSpecR, graphId, onResponse) {
|
|
2083
|
+
function fetchGraphData(bundleModel, scenarioSpec) {
|
|
2084
|
+
return __async(this, null, function* () {
|
|
2085
|
+
if (scenarioSpec) {
|
|
2086
|
+
return bundleModel.getGraphDataForScenario(scenarioSpec, graphId);
|
|
2087
|
+
} else {
|
|
2088
|
+
return void 0;
|
|
2089
|
+
}
|
|
2090
|
+
});
|
|
2091
|
+
}
|
|
2092
|
+
const task = {
|
|
2093
|
+
key: requestKey,
|
|
2094
|
+
kind: "comparison-data-coordinator",
|
|
2095
|
+
process: (bundleModels) => __async(this, null, function* () {
|
|
2096
|
+
const modelL = sourceL === "left" ? bundleModels.L : bundleModels.R;
|
|
2097
|
+
const modelR = sourceR === "left" ? bundleModels.L : bundleModels.R;
|
|
2098
|
+
let graphDataL;
|
|
2099
|
+
let graphDataR;
|
|
2100
|
+
if (modelL === modelR) {
|
|
2101
|
+
graphDataL = yield fetchGraphData(modelL, scenarioSpecL);
|
|
2102
|
+
graphDataR = yield fetchGraphData(modelR, scenarioSpecR);
|
|
2103
|
+
} else {
|
|
2104
|
+
const results = yield Promise.all([
|
|
2105
|
+
fetchGraphData(modelL, scenarioSpecL),
|
|
2106
|
+
fetchGraphData(modelR, scenarioSpecR)
|
|
2107
|
+
]);
|
|
2108
|
+
graphDataL = results[0];
|
|
2109
|
+
graphDataR = results[1];
|
|
2110
|
+
}
|
|
2111
|
+
onResponse(graphDataL, graphDataR);
|
|
2112
|
+
})
|
|
1912
2113
|
};
|
|
1913
|
-
this.taskQueue.addTask(
|
|
1914
|
-
if (response.kind === "graph-data") {
|
|
1915
|
-
onResponse(response.graphDataL, response.graphDataR);
|
|
1916
|
-
}
|
|
1917
|
-
});
|
|
2114
|
+
this.taskQueue.addTask(task);
|
|
1918
2115
|
}
|
|
1919
2116
|
cancelRequest(key) {
|
|
1920
2117
|
this.taskQueue.cancelTask(key);
|
|
1921
2118
|
}
|
|
1922
2119
|
};
|
|
2120
|
+
function createComparisonDataCoordinator() {
|
|
2121
|
+
return new ComparisonDataCoordinator(TaskQueue.getInstance());
|
|
2122
|
+
}
|
|
1923
2123
|
|
|
1924
2124
|
// src/comparison/diff-datasets/diff-datasets.ts
|
|
1925
2125
|
function diffDatasets(datasetL, datasetR) {
|
|
@@ -2069,14 +2269,14 @@ function diffGraphs(graphL, graphR, scenarioKey, testSummaries) {
|
|
|
2069
2269
|
|
|
2070
2270
|
// src/comparison/report/comparison-reporting.ts
|
|
2071
2271
|
function comparisonSummaryFromReport(comparisonReport) {
|
|
2272
|
+
var _a, _b;
|
|
2072
2273
|
const terseSummaries = [];
|
|
2073
2274
|
for (const r of comparisonReport.testReports) {
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
});
|
|
2275
|
+
const baselineMaxDiff = (_a = r.baselineDiffReport) == null ? void 0 : _a.maxDiff;
|
|
2276
|
+
const baselineAvgDiff = (_b = r.baselineDiffReport) == null ? void 0 : _b.avgDiff;
|
|
2277
|
+
const summary = testSummaryFromReport(r, baselineMaxDiff, baselineAvgDiff);
|
|
2278
|
+
if (summary) {
|
|
2279
|
+
terseSummaries.push(summary);
|
|
2080
2280
|
}
|
|
2081
2281
|
}
|
|
2082
2282
|
return {
|
|
@@ -2085,6 +2285,43 @@ function comparisonSummaryFromReport(comparisonReport) {
|
|
|
2085
2285
|
perfReportR: comparisonReport.perfReportR
|
|
2086
2286
|
};
|
|
2087
2287
|
}
|
|
2288
|
+
function testSummaryFromReport(r, baselineMaxDiff, baselineAvgDiff) {
|
|
2289
|
+
var _a;
|
|
2290
|
+
function baselineRelativeDiff(diffValue, baselineDiffValue) {
|
|
2291
|
+
if (baselineDiffValue !== void 0) {
|
|
2292
|
+
const epsilon = 1e-6;
|
|
2293
|
+
if (baselineDiffValue === 0) {
|
|
2294
|
+
baselineDiffValue = epsilon;
|
|
2295
|
+
}
|
|
2296
|
+
return diffValue / baselineDiffValue;
|
|
2297
|
+
} else {
|
|
2298
|
+
if (diffValue === 0) {
|
|
2299
|
+
return 0;
|
|
2300
|
+
} else {
|
|
2301
|
+
return 1;
|
|
2302
|
+
}
|
|
2303
|
+
}
|
|
2304
|
+
}
|
|
2305
|
+
if (r.diffReport === void 0) {
|
|
2306
|
+
return {
|
|
2307
|
+
s: r.scenarioKey,
|
|
2308
|
+
d: r.datasetKey
|
|
2309
|
+
};
|
|
2310
|
+
} else if (((_a = r.diffReport) == null ? void 0 : _a.validity) === "both" && r.diffReport.maxDiff > 0) {
|
|
2311
|
+
const maxDiffRelativeToBaseline = baselineRelativeDiff(r.diffReport.maxDiff, baselineMaxDiff);
|
|
2312
|
+
const avgDiffRelativeToBaseline = baselineRelativeDiff(r.diffReport.avgDiff, baselineAvgDiff);
|
|
2313
|
+
return {
|
|
2314
|
+
s: r.scenarioKey,
|
|
2315
|
+
d: r.datasetKey,
|
|
2316
|
+
md: r.diffReport.maxDiff,
|
|
2317
|
+
ad: r.diffReport.avgDiff,
|
|
2318
|
+
mdb: maxDiffRelativeToBaseline,
|
|
2319
|
+
adb: avgDiffRelativeToBaseline
|
|
2320
|
+
};
|
|
2321
|
+
} else {
|
|
2322
|
+
return void 0;
|
|
2323
|
+
}
|
|
2324
|
+
}
|
|
2088
2325
|
function restoreFromTerseSummaries(comparisonConfig, terseSummaries) {
|
|
2089
2326
|
const existingSummaries = /* @__PURE__ */ new Map();
|
|
2090
2327
|
for (const summary of terseSummaries) {
|
|
@@ -2097,24 +2334,33 @@ function restoreFromTerseSummaries(comparisonConfig, terseSummaries) {
|
|
|
2097
2334
|
for (const datasetKey of datasetKeys) {
|
|
2098
2335
|
const key = `${scenario.key}::${datasetKey}`;
|
|
2099
2336
|
const existingSummary = existingSummaries.get(key);
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2337
|
+
if (existingSummary) {
|
|
2338
|
+
allTestSummaries.push(existingSummary);
|
|
2339
|
+
} else {
|
|
2340
|
+
allTestSummaries.push({
|
|
2341
|
+
s: scenario.key,
|
|
2342
|
+
d: datasetKey,
|
|
2343
|
+
md: 0,
|
|
2344
|
+
ad: 0,
|
|
2345
|
+
mdb: 0,
|
|
2346
|
+
adb: 0
|
|
2347
|
+
});
|
|
2348
|
+
}
|
|
2106
2349
|
}
|
|
2107
2350
|
}
|
|
2108
2351
|
return allTestSummaries;
|
|
2109
2352
|
}
|
|
2110
2353
|
|
|
2111
2354
|
// src/comparison/report/buckets.ts
|
|
2112
|
-
function getBucketIndex(
|
|
2113
|
-
if (
|
|
2355
|
+
function getBucketIndex(diff, thresholds) {
|
|
2356
|
+
if (diff === void 0) {
|
|
2357
|
+
return thresholds.length + 2;
|
|
2358
|
+
}
|
|
2359
|
+
if (diff === 0) {
|
|
2114
2360
|
return 0;
|
|
2115
2361
|
}
|
|
2116
2362
|
for (let i = 0; i < thresholds.length; i++) {
|
|
2117
|
-
if (
|
|
2363
|
+
if (diff < thresholds[i]) {
|
|
2118
2364
|
return i + 1;
|
|
2119
2365
|
}
|
|
2120
2366
|
}
|
|
@@ -2122,14 +2368,32 @@ function getBucketIndex(diffPct, thresholds) {
|
|
|
2122
2368
|
}
|
|
2123
2369
|
|
|
2124
2370
|
// src/comparison/report/comparison-group-scores.ts
|
|
2125
|
-
function getScoresForTestSummaries(testSummaries, thresholds) {
|
|
2126
|
-
const diffCountByBucket = Array(thresholds.length +
|
|
2127
|
-
const
|
|
2371
|
+
function getScoresForTestSummaries(testSummaries, thresholds, sortMode) {
|
|
2372
|
+
const diffCountByBucket = Array(thresholds.length + 3).fill(0);
|
|
2373
|
+
const totalDiffByBucket = Array(thresholds.length + 3).fill(0);
|
|
2128
2374
|
let totalDiffCount = 0;
|
|
2375
|
+
let valueKey;
|
|
2376
|
+
switch (sortMode) {
|
|
2377
|
+
case "max-diff":
|
|
2378
|
+
valueKey = "md";
|
|
2379
|
+
break;
|
|
2380
|
+
case "avg-diff":
|
|
2381
|
+
valueKey = "ad";
|
|
2382
|
+
break;
|
|
2383
|
+
case "max-diff-relative":
|
|
2384
|
+
valueKey = "mdb";
|
|
2385
|
+
break;
|
|
2386
|
+
case "avg-diff-relative":
|
|
2387
|
+
valueKey = "adb";
|
|
2388
|
+
break;
|
|
2389
|
+
}
|
|
2129
2390
|
for (const testSummary of testSummaries) {
|
|
2130
|
-
const
|
|
2391
|
+
const value = testSummary[valueKey];
|
|
2392
|
+
const bucketIndex = getBucketIndex(value, thresholds);
|
|
2131
2393
|
diffCountByBucket[bucketIndex]++;
|
|
2132
|
-
|
|
2394
|
+
if (value !== void 0) {
|
|
2395
|
+
totalDiffByBucket[bucketIndex] += value;
|
|
2396
|
+
}
|
|
2133
2397
|
totalDiffCount++;
|
|
2134
2398
|
}
|
|
2135
2399
|
let diffPercentByBucket;
|
|
@@ -2140,20 +2404,20 @@ function getScoresForTestSummaries(testSummaries, thresholds) {
|
|
|
2140
2404
|
}
|
|
2141
2405
|
return {
|
|
2142
2406
|
totalDiffCount,
|
|
2143
|
-
|
|
2407
|
+
totalDiffByBucket,
|
|
2144
2408
|
diffCountByBucket,
|
|
2145
2409
|
diffPercentByBucket
|
|
2146
2410
|
};
|
|
2147
2411
|
}
|
|
2148
2412
|
|
|
2149
2413
|
// src/comparison/report/comparison-grouping.ts
|
|
2150
|
-
import { assertNever as
|
|
2151
|
-
function categorizeComparisonTestSummaries(comparisonConfig, terseSummaries) {
|
|
2414
|
+
import { assertNever as assertNever7 } from "assert-never";
|
|
2415
|
+
function categorizeComparisonTestSummaries(comparisonConfig, terseSummaries, sortMode) {
|
|
2152
2416
|
const allTestSummaries = restoreFromTerseSummaries(comparisonConfig, terseSummaries);
|
|
2153
2417
|
const groupsByScenario = groupComparisonTestSummaries(allTestSummaries, "by-scenario");
|
|
2154
|
-
const byScenario = categorizeComparisonGroups(comparisonConfig, [...groupsByScenario.values()]);
|
|
2418
|
+
const byScenario = categorizeComparisonGroups(comparisonConfig, [...groupsByScenario.values()], sortMode);
|
|
2155
2419
|
const groupsByDataset = groupComparisonTestSummaries(allTestSummaries, "by-dataset");
|
|
2156
|
-
const byDataset = categorizeComparisonGroups(comparisonConfig, [...groupsByDataset.values()]);
|
|
2420
|
+
const byDataset = categorizeComparisonGroups(comparisonConfig, [...groupsByDataset.values()], sortMode);
|
|
2157
2421
|
return {
|
|
2158
2422
|
allTestSummaries,
|
|
2159
2423
|
byScenario,
|
|
@@ -2172,7 +2436,7 @@ function groupComparisonTestSummaries(testSummaries, groupKind) {
|
|
|
2172
2436
|
groupKey = testSummary.s;
|
|
2173
2437
|
break;
|
|
2174
2438
|
default:
|
|
2175
|
-
|
|
2439
|
+
assertNever7(groupKind);
|
|
2176
2440
|
}
|
|
2177
2441
|
const group = groups.get(groupKey);
|
|
2178
2442
|
if (group) {
|
|
@@ -2187,7 +2451,7 @@ function groupComparisonTestSummaries(testSummaries, groupKind) {
|
|
|
2187
2451
|
}
|
|
2188
2452
|
return groups;
|
|
2189
2453
|
}
|
|
2190
|
-
function categorizeComparisonGroups(comparisonConfig, allGroups) {
|
|
2454
|
+
function categorizeComparisonGroups(comparisonConfig, allGroups, sortMode) {
|
|
2191
2455
|
const allGroupSummaries = /* @__PURE__ */ new Map();
|
|
2192
2456
|
const withErrors = [];
|
|
2193
2457
|
const onlyInLeft = [];
|
|
@@ -2197,7 +2461,9 @@ function categorizeComparisonGroups(comparisonConfig, allGroups) {
|
|
|
2197
2461
|
function addSummaryForGroup(group, root, validInL, validInR) {
|
|
2198
2462
|
let scores;
|
|
2199
2463
|
if (validInL && validInR) {
|
|
2200
|
-
|
|
2464
|
+
const isRelativeMode = sortMode === "max-diff-relative" || sortMode === "avg-diff-relative";
|
|
2465
|
+
const thresholds = isRelativeMode ? comparisonConfig.ratioThresholds : comparisonConfig.thresholds;
|
|
2466
|
+
scores = getScoresForTestSummaries(group.testSummaries, thresholds, sortMode);
|
|
2201
2467
|
}
|
|
2202
2468
|
const groupSummary = {
|
|
2203
2469
|
root,
|
|
@@ -2206,7 +2472,9 @@ function categorizeComparisonGroups(comparisonConfig, allGroups) {
|
|
|
2206
2472
|
};
|
|
2207
2473
|
allGroupSummaries.set(group.key, groupSummary);
|
|
2208
2474
|
if (validInL && validInR) {
|
|
2209
|
-
|
|
2475
|
+
const noDiffCount = scores.diffCountByBucket[0];
|
|
2476
|
+
const skippedCount = scores.diffCountByBucket[5];
|
|
2477
|
+
if (scores.totalDiffCount !== noDiffCount + skippedCount) {
|
|
2210
2478
|
withDiffs.push(groupSummary);
|
|
2211
2479
|
} else {
|
|
2212
2480
|
withoutDiffs.push(groupSummary);
|
|
@@ -2236,7 +2504,7 @@ function categorizeComparisonGroups(comparisonConfig, allGroups) {
|
|
|
2236
2504
|
break;
|
|
2237
2505
|
}
|
|
2238
2506
|
default:
|
|
2239
|
-
|
|
2507
|
+
assertNever7(group.kind);
|
|
2240
2508
|
}
|
|
2241
2509
|
}
|
|
2242
2510
|
if (withDiffs.length > 1) {
|
|
@@ -2298,13 +2566,13 @@ function sortScenarioGroupSummaries(summaries) {
|
|
|
2298
2566
|
});
|
|
2299
2567
|
}
|
|
2300
2568
|
function compareScores(a, b) {
|
|
2301
|
-
if (a.
|
|
2569
|
+
if (a.totalDiffByBucket.length !== b.totalDiffByBucket.length) {
|
|
2302
2570
|
return 0;
|
|
2303
2571
|
}
|
|
2304
|
-
const len = a.
|
|
2572
|
+
const len = a.totalDiffByBucket.length;
|
|
2305
2573
|
for (let i = len - 1; i >= 0; i--) {
|
|
2306
|
-
const aTotal = a.
|
|
2307
|
-
const bTotal = b.
|
|
2574
|
+
const aTotal = a.totalDiffByBucket[i];
|
|
2575
|
+
const bTotal = b.totalDiffByBucket[i];
|
|
2308
2576
|
if (aTotal > bTotal) {
|
|
2309
2577
|
return 1;
|
|
2310
2578
|
} else if (aTotal < bTotal) {
|
|
@@ -2316,7 +2584,7 @@ function compareScores(a, b) {
|
|
|
2316
2584
|
|
|
2317
2585
|
// src/comparison/config/parse/comparison-parser.ts
|
|
2318
2586
|
import Ajv2 from "ajv";
|
|
2319
|
-
import
|
|
2587
|
+
import assertNever8 from "assert-never";
|
|
2320
2588
|
import { err as err2, ok as ok2 } from "neverthrow";
|
|
2321
2589
|
import yaml2 from "yaml";
|
|
2322
2590
|
|
|
@@ -2852,7 +3120,7 @@ function parseComparisonSpecs(specSource) {
|
|
|
2852
3120
|
parsed = yaml2.parse(specSource.content);
|
|
2853
3121
|
break;
|
|
2854
3122
|
default:
|
|
2855
|
-
|
|
3123
|
+
assertNever8(specSource.kind);
|
|
2856
3124
|
}
|
|
2857
3125
|
if (validate(parsed)) {
|
|
2858
3126
|
for (const specItem of parsed) {
|
|
@@ -3079,11 +3347,12 @@ function viewGroupSpecFromParsed(parsedViewGroup) {
|
|
|
3079
3347
|
}
|
|
3080
3348
|
|
|
3081
3349
|
// src/comparison/config/resolve/comparison-resolver.ts
|
|
3082
|
-
import { assertNever as
|
|
3350
|
+
import { assertNever as assertNever10 } from "assert-never";
|
|
3083
3351
|
|
|
3084
3352
|
// src/bundle/model-inputs.ts
|
|
3085
3353
|
var ModelInputs = class {
|
|
3086
3354
|
constructor(modelSpec) {
|
|
3355
|
+
this.modelSpec = modelSpec;
|
|
3087
3356
|
/** All inputs keyed by lookup name (lowercase variable name or alias). */
|
|
3088
3357
|
this.inputsByLookupName = /* @__PURE__ */ new Map();
|
|
3089
3358
|
/** All input ID aliases. */
|
|
@@ -3130,10 +3399,18 @@ var ModelInputs = class {
|
|
|
3130
3399
|
getInputVarForName(name) {
|
|
3131
3400
|
return this.inputsByLookupName.get(name.toLowerCase());
|
|
3132
3401
|
}
|
|
3402
|
+
/**
|
|
3403
|
+
* Return the `InputVar` that matches the requested variable ID.
|
|
3404
|
+
*
|
|
3405
|
+
* @param varId The variable identifier to match.
|
|
3406
|
+
*/
|
|
3407
|
+
getInputVarForVarId(varId) {
|
|
3408
|
+
return this.modelSpec.inputVars.get(varId);
|
|
3409
|
+
}
|
|
3133
3410
|
};
|
|
3134
3411
|
|
|
3135
3412
|
// src/comparison/config/resolve/comparison-scenario-specs.ts
|
|
3136
|
-
import { assertNever as
|
|
3413
|
+
import { assertNever as assertNever9 } from "assert-never";
|
|
3137
3414
|
function scenarioSpecsFromSettings(settings) {
|
|
3138
3415
|
switch (settings.kind) {
|
|
3139
3416
|
case "all-inputs-settings": {
|
|
@@ -3146,7 +3423,7 @@ function scenarioSpecsFromSettings(settings) {
|
|
|
3146
3423
|
return [specL, specR];
|
|
3147
3424
|
}
|
|
3148
3425
|
default:
|
|
3149
|
-
|
|
3426
|
+
assertNever9(settings);
|
|
3150
3427
|
}
|
|
3151
3428
|
}
|
|
3152
3429
|
function scenarioSpecFromInputs(inputs, side) {
|
|
@@ -3351,8 +3628,21 @@ function resolveScenariosFromSpec(modelInputsL, modelInputsR, scenarioSpec, genK
|
|
|
3351
3628
|
)
|
|
3352
3629
|
];
|
|
3353
3630
|
}
|
|
3631
|
+
case "scenario-with-setting-group": {
|
|
3632
|
+
return [
|
|
3633
|
+
resolveScenarioForSettingGroup(
|
|
3634
|
+
modelInputsL,
|
|
3635
|
+
modelInputsR,
|
|
3636
|
+
genKey(),
|
|
3637
|
+
scenarioSpec.id,
|
|
3638
|
+
scenarioSpec.title,
|
|
3639
|
+
scenarioSpec.subtitle,
|
|
3640
|
+
scenarioSpec.settingGroupId
|
|
3641
|
+
)
|
|
3642
|
+
];
|
|
3643
|
+
}
|
|
3354
3644
|
default:
|
|
3355
|
-
|
|
3645
|
+
assertNever10(scenarioSpec);
|
|
3356
3646
|
}
|
|
3357
3647
|
}
|
|
3358
3648
|
function resolveScenarioMatrix(modelInputsL, modelInputsR, genKey) {
|
|
@@ -3408,7 +3698,7 @@ function resolveScenarioForInputSpecs(modelInputsL, modelInputsR, key, id, title
|
|
|
3408
3698
|
case "input-at-value":
|
|
3409
3699
|
return resolveInputForName(modelInputsL, modelInputsR, inputSpec.inputName, inputSpec.value);
|
|
3410
3700
|
default:
|
|
3411
|
-
|
|
3701
|
+
assertNever10(inputSpec);
|
|
3412
3702
|
}
|
|
3413
3703
|
});
|
|
3414
3704
|
const settings = {
|
|
@@ -3441,7 +3731,7 @@ function resolveScenarioForDistinctInputSpecs(modelInputsL, modelInputsR, key, i
|
|
|
3441
3731
|
inputState = resolveInputForNameInModel(modelInputs, inputSpec.inputName, inputSpec.value);
|
|
3442
3732
|
break;
|
|
3443
3733
|
default:
|
|
3444
|
-
|
|
3734
|
+
assertNever10(inputSpec);
|
|
3445
3735
|
}
|
|
3446
3736
|
if (inputState.error !== void 0) {
|
|
3447
3737
|
inputsWithErrors.push({
|
|
@@ -3480,6 +3770,113 @@ function resolveScenarioForDistinctInputSpecs(modelInputsL, modelInputsR, key, i
|
|
|
3480
3770
|
specR
|
|
3481
3771
|
};
|
|
3482
3772
|
}
|
|
3773
|
+
function resolveScenarioForSettingGroup(modelInputsL, modelInputsR, key, id, title, subtitle, settingGroupId) {
|
|
3774
|
+
var _a, _b;
|
|
3775
|
+
function inputVarNameForVarId(modelInputs, varId) {
|
|
3776
|
+
const inputVar = modelInputs.getInputVarForVarId(varId);
|
|
3777
|
+
if (inputVar !== void 0) {
|
|
3778
|
+
return inputVar.varName;
|
|
3779
|
+
} else {
|
|
3780
|
+
return varId;
|
|
3781
|
+
}
|
|
3782
|
+
}
|
|
3783
|
+
function inputPositionForPosition(position) {
|
|
3784
|
+
switch (position) {
|
|
3785
|
+
case "at-minimum":
|
|
3786
|
+
return "min";
|
|
3787
|
+
case "at-maximum":
|
|
3788
|
+
return "max";
|
|
3789
|
+
case "at-default":
|
|
3790
|
+
return "default";
|
|
3791
|
+
default:
|
|
3792
|
+
throw new Error(`Unknown input position: ${position}`);
|
|
3793
|
+
}
|
|
3794
|
+
}
|
|
3795
|
+
function inputSpecForSetting(modelInputs, inputSetting) {
|
|
3796
|
+
switch (inputSetting.kind) {
|
|
3797
|
+
case "position":
|
|
3798
|
+
return {
|
|
3799
|
+
kind: "input-at-position",
|
|
3800
|
+
inputName: inputVarNameForVarId(modelInputs, inputSetting.inputVarId),
|
|
3801
|
+
position: inputPositionForPosition(inputSetting.position)
|
|
3802
|
+
};
|
|
3803
|
+
case "value":
|
|
3804
|
+
return {
|
|
3805
|
+
kind: "input-at-value",
|
|
3806
|
+
inputName: inputVarNameForVarId(modelInputs, inputSetting.inputVarId),
|
|
3807
|
+
value: inputSetting.value
|
|
3808
|
+
};
|
|
3809
|
+
default:
|
|
3810
|
+
throw new Error(`Unknown input setting kind: ${inputSetting}`);
|
|
3811
|
+
}
|
|
3812
|
+
}
|
|
3813
|
+
function inputSpecsForSettingGroup(modelInputs, inputSettings) {
|
|
3814
|
+
return inputSettings.map((inputSetting) => inputSpecForSetting(modelInputs, inputSetting));
|
|
3815
|
+
}
|
|
3816
|
+
const inputSettingsL = ((_a = modelInputsL.modelSpec.inputSettingGroups) == null ? void 0 : _a.get(settingGroupId)) || [];
|
|
3817
|
+
const inputSettingsR = ((_b = modelInputsR.modelSpec.inputSettingGroups) == null ? void 0 : _b.get(settingGroupId)) || [];
|
|
3818
|
+
const inputsL = inputSpecsForSettingGroup(modelInputsL, inputSettingsL);
|
|
3819
|
+
const inputsR = inputSpecsForSettingGroup(modelInputsR, inputSettingsR);
|
|
3820
|
+
const scenario = resolveScenarioForDistinctInputSpecs(
|
|
3821
|
+
modelInputsL,
|
|
3822
|
+
modelInputsR,
|
|
3823
|
+
key,
|
|
3824
|
+
id,
|
|
3825
|
+
title,
|
|
3826
|
+
subtitle,
|
|
3827
|
+
inputsL,
|
|
3828
|
+
inputsR
|
|
3829
|
+
);
|
|
3830
|
+
function scenarioString(scenario2) {
|
|
3831
|
+
if (scenario2.kind === "input-settings") {
|
|
3832
|
+
const settings = scenario2.settings.map((setting) => {
|
|
3833
|
+
switch (setting.kind) {
|
|
3834
|
+
case "position":
|
|
3835
|
+
return `${setting.inputVarId}=${setting.position}`;
|
|
3836
|
+
case "value":
|
|
3837
|
+
return `${setting.inputVarId}=${setting.value}`;
|
|
3838
|
+
default:
|
|
3839
|
+
throw new Error(`Unexpected input setting kind: ${setting}`);
|
|
3840
|
+
}
|
|
3841
|
+
});
|
|
3842
|
+
return settings.sort().join("__");
|
|
3843
|
+
} else {
|
|
3844
|
+
throw new Error(`Unexpected scenario spec kind: ${scenario2.kind}`);
|
|
3845
|
+
}
|
|
3846
|
+
}
|
|
3847
|
+
function scenariosAreEqual(scenarioL, scenarioR) {
|
|
3848
|
+
return scenarioString(scenarioL) === scenarioString(scenarioR);
|
|
3849
|
+
}
|
|
3850
|
+
function errorState(inputSettings) {
|
|
3851
|
+
if (inputSettings.length === 0) {
|
|
3852
|
+
return { error: { kind: "unknown-input-setting-group" } };
|
|
3853
|
+
} else {
|
|
3854
|
+
return {};
|
|
3855
|
+
}
|
|
3856
|
+
}
|
|
3857
|
+
if (inputSettingsL.length === 0 || inputSettingsR.length === 0) {
|
|
3858
|
+
if (scenario.settings.kind === "input-settings") {
|
|
3859
|
+
const errorSetting = {
|
|
3860
|
+
requestedName: settingGroupId,
|
|
3861
|
+
stateL: errorState(inputSettingsL),
|
|
3862
|
+
stateR: errorState(inputSettingsR)
|
|
3863
|
+
};
|
|
3864
|
+
scenario.settings.inputs.unshift(errorSetting);
|
|
3865
|
+
}
|
|
3866
|
+
if (inputSettingsL.length === 0) {
|
|
3867
|
+
scenario.specL = void 0;
|
|
3868
|
+
}
|
|
3869
|
+
if (inputSettingsR.length === 0) {
|
|
3870
|
+
scenario.specR = void 0;
|
|
3871
|
+
}
|
|
3872
|
+
}
|
|
3873
|
+
if (scenario.settings.kind === "input-settings") {
|
|
3874
|
+
if (scenario.specL && scenario.specR && !scenariosAreEqual(scenario.specL, scenario.specR)) {
|
|
3875
|
+
scenario.settings.settingsDiffer = true;
|
|
3876
|
+
}
|
|
3877
|
+
}
|
|
3878
|
+
return scenario;
|
|
3879
|
+
}
|
|
3483
3880
|
function resolveInputForName(modelInputsL, modelInputsR, inputName, at) {
|
|
3484
3881
|
return {
|
|
3485
3882
|
requestedName: inputName,
|
|
@@ -3550,7 +3947,7 @@ function inputValueAtPosition2(inputVar, position) {
|
|
|
3550
3947
|
case "at-maximum":
|
|
3551
3948
|
return inputVar.maxValue;
|
|
3552
3949
|
default:
|
|
3553
|
-
|
|
3950
|
+
assertNever10(position);
|
|
3554
3951
|
}
|
|
3555
3952
|
}
|
|
3556
3953
|
var ResolvedScenarioGroups = class {
|
|
@@ -3609,7 +4006,7 @@ function resolveGraphsFromSpec(modelSpecL, modelSpecR, resolvedGraphGroups, grap
|
|
|
3609
4006
|
return [...graphIds];
|
|
3610
4007
|
}
|
|
3611
4008
|
default:
|
|
3612
|
-
|
|
4009
|
+
assertNever10(graphsSpec.preset);
|
|
3613
4010
|
}
|
|
3614
4011
|
}
|
|
3615
4012
|
// eslint-disable-next-line no-fallthrough
|
|
@@ -3623,7 +4020,7 @@ function resolveGraphsFromSpec(modelSpecL, modelSpecR, resolvedGraphGroups, grap
|
|
|
3623
4020
|
return groupSpec.graphIds;
|
|
3624
4021
|
}
|
|
3625
4022
|
default:
|
|
3626
|
-
|
|
4023
|
+
assertNever10(graphsSpec);
|
|
3627
4024
|
}
|
|
3628
4025
|
}
|
|
3629
4026
|
function resolveViewForScenarioId(resolvedScenarios, viewTitle, viewSubtitle, scenarioId, graphIds, graphOrder) {
|
|
@@ -3797,7 +4194,7 @@ function resolveViewGroupFromSpec(modelSpecL, modelSpecR, modelOutputs, resolved
|
|
|
3797
4194
|
views.push(resolveViewForScenario(void 0, void 0, scenario, graphIds, graphOrder));
|
|
3798
4195
|
break;
|
|
3799
4196
|
default:
|
|
3800
|
-
|
|
4197
|
+
assertNever10(scenario);
|
|
3801
4198
|
}
|
|
3802
4199
|
}
|
|
3803
4200
|
} else {
|
|
@@ -3806,13 +4203,13 @@ function resolveViewGroupFromSpec(modelSpecL, modelSpecR, modelOutputs, resolved
|
|
|
3806
4203
|
break;
|
|
3807
4204
|
}
|
|
3808
4205
|
default:
|
|
3809
|
-
|
|
4206
|
+
assertNever10(refSpec);
|
|
3810
4207
|
}
|
|
3811
4208
|
}
|
|
3812
4209
|
break;
|
|
3813
4210
|
}
|
|
3814
4211
|
default:
|
|
3815
|
-
|
|
4212
|
+
assertNever10(viewGroupSpec);
|
|
3816
4213
|
}
|
|
3817
4214
|
return {
|
|
3818
4215
|
kind: "view-group",
|
|
@@ -3875,9 +4272,9 @@ var ComparisonDatasetsImpl = class {
|
|
|
3875
4272
|
}
|
|
3876
4273
|
const allOutputVarKeysSet = /* @__PURE__ */ new Set();
|
|
3877
4274
|
const modelOutputVarKeysSet = /* @__PURE__ */ new Set();
|
|
3878
|
-
function addOutputVars(outputVars,
|
|
4275
|
+
function addOutputVars(outputVars, handleRenames2) {
|
|
3879
4276
|
outputVars.forEach((outputVar, key) => {
|
|
3880
|
-
const remappedKey =
|
|
4277
|
+
const remappedKey = handleRenames2 ? leftKeyForRightKey(key) : key;
|
|
3881
4278
|
allOutputVarKeysSet.add(remappedKey);
|
|
3882
4279
|
if (outputVar.sourceName === void 0) {
|
|
3883
4280
|
modelOutputVarKeysSet.add(remappedKey);
|
|
@@ -3991,109 +4388,41 @@ var ComparisonScenariosImpl = class {
|
|
|
3991
4388
|
}
|
|
3992
4389
|
};
|
|
3993
4390
|
|
|
3994
|
-
// src/config/synchronized-model.ts
|
|
3995
|
-
function synchronizedBundleModel(sourceModel) {
|
|
3996
|
-
const promiseQueue = new PromiseQueue();
|
|
3997
|
-
return {
|
|
3998
|
-
modelSpec: sourceModel.modelSpec,
|
|
3999
|
-
getDatasetsForScenario: (scenarioSpec, datasetKeys) => {
|
|
4000
|
-
return promiseQueue.add(() => sourceModel.getDatasetsForScenario(scenarioSpec, datasetKeys));
|
|
4001
|
-
},
|
|
4002
|
-
getGraphDataForScenario: (scenarioSpec, graphId) => {
|
|
4003
|
-
return promiseQueue.add(() => sourceModel.getGraphDataForScenario(scenarioSpec, graphId));
|
|
4004
|
-
},
|
|
4005
|
-
getGraphLinksForScenario: sourceModel.getGraphLinksForScenario.bind(sourceModel)
|
|
4006
|
-
};
|
|
4007
|
-
}
|
|
4008
|
-
var PromiseQueue = class {
|
|
4009
|
-
constructor() {
|
|
4010
|
-
this.tasks = [];
|
|
4011
|
-
this.runningCount = 0;
|
|
4012
|
-
}
|
|
4013
|
-
add(f) {
|
|
4014
|
-
return new Promise((resolve, reject) => {
|
|
4015
|
-
const run = () => __async(this, null, function* () {
|
|
4016
|
-
this.runningCount++;
|
|
4017
|
-
const promise = f();
|
|
4018
|
-
try {
|
|
4019
|
-
const result = yield promise;
|
|
4020
|
-
resolve(result);
|
|
4021
|
-
} catch (e) {
|
|
4022
|
-
reject(e);
|
|
4023
|
-
} finally {
|
|
4024
|
-
this.runningCount--;
|
|
4025
|
-
this.runNext();
|
|
4026
|
-
}
|
|
4027
|
-
});
|
|
4028
|
-
if (this.runningCount < 1) {
|
|
4029
|
-
run();
|
|
4030
|
-
} else {
|
|
4031
|
-
this.tasks.push(run);
|
|
4032
|
-
}
|
|
4033
|
-
});
|
|
4034
|
-
}
|
|
4035
|
-
runNext() {
|
|
4036
|
-
if (this.tasks.length > 0) {
|
|
4037
|
-
const task = this.tasks.shift();
|
|
4038
|
-
if (task) {
|
|
4039
|
-
task();
|
|
4040
|
-
}
|
|
4041
|
-
}
|
|
4042
|
-
}
|
|
4043
|
-
};
|
|
4044
|
-
|
|
4045
4391
|
// src/config/config.ts
|
|
4046
4392
|
function createConfig(options) {
|
|
4047
4393
|
return __async(this, null, function* () {
|
|
4048
|
-
var _a;
|
|
4049
|
-
|
|
4394
|
+
var _a, _b, _c, _d, _e;
|
|
4395
|
+
let concurrentModels;
|
|
4396
|
+
if (options.concurrency === void 0) {
|
|
4397
|
+
concurrentModels = 1;
|
|
4398
|
+
} else if (options.concurrency === 0) {
|
|
4399
|
+
let coreCount;
|
|
4400
|
+
if (typeof navigator !== "undefined") {
|
|
4401
|
+
coreCount = navigator.hardwareConcurrency;
|
|
4402
|
+
}
|
|
4403
|
+
if (coreCount === void 0 || coreCount < 1) {
|
|
4404
|
+
coreCount = 1;
|
|
4405
|
+
}
|
|
4406
|
+
concurrentModels = Math.max(1, Math.floor(coreCount / 2));
|
|
4407
|
+
} else {
|
|
4408
|
+
concurrentModels = Math.max(1, options.concurrency);
|
|
4409
|
+
}
|
|
4410
|
+
const origCurrentBundle = yield loadBundle(options.current, concurrentModels);
|
|
4050
4411
|
let currentBundle;
|
|
4051
4412
|
let comparisonConfig;
|
|
4052
4413
|
if (options.comparison === void 0) {
|
|
4053
4414
|
currentBundle = origCurrentBundle;
|
|
4054
4415
|
} else {
|
|
4055
|
-
const baselineBundle = yield
|
|
4056
|
-
|
|
4057
|
-
const
|
|
4058
|
-
|
|
4059
|
-
invertedRenamedKeys.set(newKey, oldKey);
|
|
4060
|
-
});
|
|
4061
|
-
const rightKeyForLeftKey = (leftKey) => {
|
|
4062
|
-
return (renamedDatasetKeys == null ? void 0 : renamedDatasetKeys.get(leftKey)) || leftKey;
|
|
4063
|
-
};
|
|
4064
|
-
const leftKeyForRightKey = (rightKey) => {
|
|
4065
|
-
return invertedRenamedKeys.get(rightKey) || rightKey;
|
|
4066
|
-
};
|
|
4067
|
-
const origBundleModelR = origCurrentBundle.model;
|
|
4068
|
-
const adjBundleModelR = {
|
|
4069
|
-
modelSpec: origBundleModelR.modelSpec,
|
|
4070
|
-
getDatasetsForScenario: (scenarioSpec, datasetKeys) => __async(this, null, function* () {
|
|
4071
|
-
const rightKeys = datasetKeys.map(rightKeyForLeftKey);
|
|
4072
|
-
const result = yield origBundleModelR.getDatasetsForScenario(scenarioSpec, rightKeys);
|
|
4073
|
-
const mapWithRightKeys = result.datasetMap;
|
|
4074
|
-
const mapWithLeftKeys = /* @__PURE__ */ new Map();
|
|
4075
|
-
for (const [rightKey, dataset] of mapWithRightKeys.entries()) {
|
|
4076
|
-
const leftKey = leftKeyForRightKey(rightKey);
|
|
4077
|
-
mapWithLeftKeys.set(leftKey, dataset);
|
|
4078
|
-
}
|
|
4079
|
-
return {
|
|
4080
|
-
datasetMap: mapWithLeftKeys,
|
|
4081
|
-
modelRunTime: result.modelRunTime
|
|
4082
|
-
};
|
|
4083
|
-
}),
|
|
4084
|
-
getGraphDataForScenario: origBundleModelR.getGraphDataForScenario.bind(origBundleModelR),
|
|
4085
|
-
getGraphLinksForScenario: origBundleModelR.getGraphLinksForScenario.bind(origBundleModelR)
|
|
4086
|
-
};
|
|
4087
|
-
currentBundle = __spreadProps(__spreadValues({}, origCurrentBundle), {
|
|
4088
|
-
model: adjBundleModelR
|
|
4089
|
-
});
|
|
4090
|
-
const modelSpecL = baselineBundle.model.modelSpec;
|
|
4091
|
-
const modelSpecR = currentBundle.model.modelSpec;
|
|
4416
|
+
const baselineBundle = yield loadBundle(options.comparison.baseline, concurrentModels);
|
|
4417
|
+
currentBundle = handleRenames(origCurrentBundle, (_a = options.comparison.datasets) == null ? void 0 : _a.renamedDatasetKeys);
|
|
4418
|
+
const modelSpecL = baselineBundle.modelSpec;
|
|
4419
|
+
const modelSpecR = currentBundle.modelSpec;
|
|
4092
4420
|
const comparisonDefs = resolveComparisonSpecsFromSources(modelSpecL, modelSpecR, options.comparison.specs);
|
|
4093
4421
|
comparisonConfig = {
|
|
4094
4422
|
bundleL: baselineBundle,
|
|
4095
4423
|
bundleR: currentBundle,
|
|
4096
|
-
thresholds: options.comparison.thresholds,
|
|
4424
|
+
thresholds: (_b = options.comparison.thresholds) != null ? _b : [1, 5, 10],
|
|
4425
|
+
ratioThresholds: (_c = options.comparison.ratioThresholds) != null ? _c : [1, 2, 3],
|
|
4097
4426
|
scenarios: getComparisonScenarios(comparisonDefs.scenarios),
|
|
4098
4427
|
datasets: getComparisonDatasets(modelSpecL, modelSpecR, options.comparison.datasets),
|
|
4099
4428
|
viewGroups: comparisonDefs.viewGroups,
|
|
@@ -4104,26 +4433,75 @@ function createConfig(options) {
|
|
|
4104
4433
|
bundle: currentBundle,
|
|
4105
4434
|
tests: options.check.tests
|
|
4106
4435
|
};
|
|
4436
|
+
const executors = /* @__PURE__ */ new Map();
|
|
4437
|
+
for (let i = 0; i < checkConfig.bundle.models.length; i++) {
|
|
4438
|
+
const bundleModelL = (_d = comparisonConfig == null ? void 0 : comparisonConfig.bundleL.models) == null ? void 0 : _d[i];
|
|
4439
|
+
const bundleModelR = ((_e = comparisonConfig == null ? void 0 : comparisonConfig.bundleR.models) == null ? void 0 : _e[i]) || checkConfig.bundle.models[i];
|
|
4440
|
+
const executor = createExecutor(bundleModelL, bundleModelR);
|
|
4441
|
+
executors.set(`executor-${i}`, executor);
|
|
4442
|
+
}
|
|
4443
|
+
TaskQueue.initialize(executors);
|
|
4107
4444
|
return {
|
|
4108
4445
|
check: checkConfig,
|
|
4109
4446
|
comparison: comparisonConfig
|
|
4110
4447
|
};
|
|
4111
4448
|
});
|
|
4112
4449
|
}
|
|
4113
|
-
function
|
|
4450
|
+
function loadBundle(bundle, concurrentModels) {
|
|
4114
4451
|
return __async(this, null, function* () {
|
|
4115
|
-
const
|
|
4116
|
-
const
|
|
4452
|
+
const initCalls = Array.from({ length: concurrentModels }, () => bundle.bundle.initModel());
|
|
4453
|
+
const models = yield Promise.all(initCalls);
|
|
4117
4454
|
return {
|
|
4118
|
-
name:
|
|
4119
|
-
version:
|
|
4120
|
-
|
|
4455
|
+
name: bundle.name,
|
|
4456
|
+
version: bundle.bundle.version,
|
|
4457
|
+
modelSpec: bundle.bundle.modelSpec,
|
|
4458
|
+
models
|
|
4121
4459
|
};
|
|
4122
4460
|
});
|
|
4123
4461
|
}
|
|
4462
|
+
function handleRenames(origCurrentBundle, renamedDatasetKeys) {
|
|
4463
|
+
if (renamedDatasetKeys === void 0 || renamedDatasetKeys.size === 0) {
|
|
4464
|
+
return origCurrentBundle;
|
|
4465
|
+
}
|
|
4466
|
+
const invertedRenamedKeys = /* @__PURE__ */ new Map();
|
|
4467
|
+
renamedDatasetKeys.forEach((newKey, oldKey) => {
|
|
4468
|
+
invertedRenamedKeys.set(newKey, oldKey);
|
|
4469
|
+
});
|
|
4470
|
+
const rightKeyForLeftKey = (leftKey) => {
|
|
4471
|
+
return (renamedDatasetKeys == null ? void 0 : renamedDatasetKeys.get(leftKey)) || leftKey;
|
|
4472
|
+
};
|
|
4473
|
+
const leftKeyForRightKey = (rightKey) => {
|
|
4474
|
+
return invertedRenamedKeys.get(rightKey) || rightKey;
|
|
4475
|
+
};
|
|
4476
|
+
function wrapModel(origBundleModelR) {
|
|
4477
|
+
return {
|
|
4478
|
+
modelSpec: origBundleModelR.modelSpec,
|
|
4479
|
+
getDatasetsForScenario: (scenarioSpec, datasetKeys) => __async(this, null, function* () {
|
|
4480
|
+
const rightKeys = datasetKeys.map(rightKeyForLeftKey);
|
|
4481
|
+
const result = yield origBundleModelR.getDatasetsForScenario(scenarioSpec, rightKeys);
|
|
4482
|
+
const mapWithRightKeys = result.datasetMap;
|
|
4483
|
+
const mapWithLeftKeys = /* @__PURE__ */ new Map();
|
|
4484
|
+
for (const [rightKey, dataset] of mapWithRightKeys.entries()) {
|
|
4485
|
+
const leftKey = leftKeyForRightKey(rightKey);
|
|
4486
|
+
mapWithLeftKeys.set(leftKey, dataset);
|
|
4487
|
+
}
|
|
4488
|
+
return {
|
|
4489
|
+
datasetMap: mapWithLeftKeys,
|
|
4490
|
+
modelRunTime: result.modelRunTime
|
|
4491
|
+
};
|
|
4492
|
+
}),
|
|
4493
|
+
getGraphDataForScenario: origBundleModelR.getGraphDataForScenario.bind(origBundleModelR),
|
|
4494
|
+
getGraphLinksForScenario: origBundleModelR.getGraphLinksForScenario.bind(origBundleModelR)
|
|
4495
|
+
};
|
|
4496
|
+
}
|
|
4497
|
+
const wrappedModels = origCurrentBundle.models.map(wrapModel);
|
|
4498
|
+
return __spreadProps(__spreadValues({}, origCurrentBundle), {
|
|
4499
|
+
models: wrappedModels
|
|
4500
|
+
});
|
|
4501
|
+
}
|
|
4124
4502
|
|
|
4125
4503
|
// src/perf/perf-runner.ts
|
|
4126
|
-
import { assertNever as
|
|
4504
|
+
import { assertNever as assertNever11 } from "assert-never";
|
|
4127
4505
|
|
|
4128
4506
|
// src/perf/perf-stats.ts
|
|
4129
4507
|
var PerfStats = class {
|
|
@@ -4160,80 +4538,110 @@ var PerfStats = class {
|
|
|
4160
4538
|
};
|
|
4161
4539
|
|
|
4162
4540
|
// src/perf/perf-runner.ts
|
|
4163
|
-
|
|
4164
|
-
|
|
4541
|
+
function runPerfWithTaskQueue(taskQueue, callbacks, options) {
|
|
4542
|
+
const perfRunner = new PerfRunner(taskQueue, callbacks, options);
|
|
4543
|
+
perfRunner.start();
|
|
4544
|
+
return () => {
|
|
4545
|
+
perfRunner.cancel();
|
|
4546
|
+
};
|
|
4547
|
+
}
|
|
4548
|
+
function runPerf(callbacks, options) {
|
|
4549
|
+
const taskQueue = TaskQueue.getInstance();
|
|
4550
|
+
return runPerfWithTaskQueue(taskQueue, callbacks, options);
|
|
4551
|
+
}
|
|
4165
4552
|
var PerfRunner = class {
|
|
4166
|
-
constructor(
|
|
4167
|
-
this.
|
|
4168
|
-
this.
|
|
4169
|
-
this.
|
|
4170
|
-
|
|
4171
|
-
this.
|
|
4172
|
-
|
|
4173
|
-
|
|
4174
|
-
|
|
4175
|
-
|
|
4176
|
-
|
|
4177
|
-
|
|
4178
|
-
|
|
4179
|
-
|
|
4180
|
-
case "right": {
|
|
4181
|
-
const result = yield bundleModelR.getDatasetsForScenario(scenarioSpec, []);
|
|
4182
|
-
return {
|
|
4183
|
-
runTimeR: result.modelRunTime
|
|
4184
|
-
};
|
|
4185
|
-
}
|
|
4186
|
-
case "both": {
|
|
4187
|
-
const [resultL, resultR] = yield Promise.all([
|
|
4188
|
-
bundleModelL.getDatasetsForScenario(scenarioSpec, []),
|
|
4189
|
-
bundleModelR.getDatasetsForScenario(scenarioSpec, [])
|
|
4190
|
-
]);
|
|
4191
|
-
return {
|
|
4192
|
-
runTimeL: resultL.modelRunTime,
|
|
4193
|
-
runTimeR: resultR.modelRunTime
|
|
4194
|
-
};
|
|
4195
|
-
}
|
|
4196
|
-
default:
|
|
4197
|
-
assertNever12(request.kind);
|
|
4198
|
-
}
|
|
4199
|
-
})
|
|
4200
|
-
});
|
|
4553
|
+
constructor(taskQueue, callbacks, options) {
|
|
4554
|
+
this.taskQueue = taskQueue;
|
|
4555
|
+
this.callbacks = callbacks;
|
|
4556
|
+
this.options = options;
|
|
4557
|
+
this.pendingTaskKeys = /* @__PURE__ */ new Set();
|
|
4558
|
+
this.stopped = false;
|
|
4559
|
+
}
|
|
4560
|
+
cancel() {
|
|
4561
|
+
if (!this.stopped) {
|
|
4562
|
+
for (const taskKey of this.pendingTaskKeys) {
|
|
4563
|
+
this.taskQueue.cancelTask(taskKey);
|
|
4564
|
+
}
|
|
4565
|
+
this.stopped = true;
|
|
4566
|
+
}
|
|
4201
4567
|
}
|
|
4202
4568
|
start() {
|
|
4569
|
+
var _a, _b, _c, _d, _e, _f;
|
|
4203
4570
|
const statsL = new PerfStats();
|
|
4204
4571
|
const statsR = new PerfStats();
|
|
4205
|
-
|
|
4206
|
-
|
|
4207
|
-
|
|
4208
|
-
|
|
4209
|
-
|
|
4210
|
-
|
|
4211
|
-
|
|
4212
|
-
|
|
4213
|
-
const taskQueue = this.taskQueue;
|
|
4214
|
-
function addTask(index, warmup, kind) {
|
|
4215
|
-
const key = `${warmup ? "warmup-" : ""}${kind}-${index}`;
|
|
4216
|
-
const request = {
|
|
4217
|
-
kind
|
|
4218
|
-
};
|
|
4219
|
-
taskQueue.addTask(key, request, (response) => {
|
|
4220
|
-
if (!warmup && response.runTimeL !== void 0) {
|
|
4221
|
-
statsL.addRun(response.runTimeL);
|
|
4222
|
-
}
|
|
4223
|
-
if (!warmup && response.runTimeR !== void 0) {
|
|
4224
|
-
statsR.addRun(response.runTimeR);
|
|
4225
|
-
}
|
|
4226
|
-
});
|
|
4572
|
+
const scenarioSpec = allInputsAtPositionSpec("at-default");
|
|
4573
|
+
const warmupCount = (_b = (_a = this.options) == null ? void 0 : _a.warmupCount) != null ? _b : 5;
|
|
4574
|
+
const runCount = (_d = (_c = this.options) == null ? void 0 : _c.runCount) != null ? _d : 100;
|
|
4575
|
+
let totalTasks = 0;
|
|
4576
|
+
if (((_e = this.options) == null ? void 0 : _e.mode) === "parallel") {
|
|
4577
|
+
totalTasks = warmupCount + runCount;
|
|
4578
|
+
} else {
|
|
4579
|
+
totalTasks = (warmupCount + runCount) * 2;
|
|
4227
4580
|
}
|
|
4581
|
+
let tasksCompleted = 0;
|
|
4582
|
+
let perfTaskId = 1;
|
|
4583
|
+
const addTask = (warmup, kind) => {
|
|
4584
|
+
const task = {
|
|
4585
|
+
key: `perf-runner-${perfTaskId++}`,
|
|
4586
|
+
kind: "perf-runner",
|
|
4587
|
+
process: (bundleModels) => __async(this, null, function* () {
|
|
4588
|
+
var _a2, _b2, _c2, _d2;
|
|
4589
|
+
this.pendingTaskKeys.delete(task.key);
|
|
4590
|
+
try {
|
|
4591
|
+
let runTimeL;
|
|
4592
|
+
let runTimeR;
|
|
4593
|
+
switch (kind) {
|
|
4594
|
+
case "left": {
|
|
4595
|
+
const result = yield bundleModels.L.getDatasetsForScenario(scenarioSpec, []);
|
|
4596
|
+
runTimeL = result.modelRunTime;
|
|
4597
|
+
break;
|
|
4598
|
+
}
|
|
4599
|
+
case "right": {
|
|
4600
|
+
const result = yield bundleModels.R.getDatasetsForScenario(scenarioSpec, []);
|
|
4601
|
+
runTimeR = result.modelRunTime;
|
|
4602
|
+
break;
|
|
4603
|
+
}
|
|
4604
|
+
case "both": {
|
|
4605
|
+
const [resultL, resultR] = yield Promise.all([
|
|
4606
|
+
bundleModels.L.getDatasetsForScenario(scenarioSpec, []),
|
|
4607
|
+
bundleModels.R.getDatasetsForScenario(scenarioSpec, [])
|
|
4608
|
+
]);
|
|
4609
|
+
runTimeL = resultL.modelRunTime;
|
|
4610
|
+
runTimeR = resultR.modelRunTime;
|
|
4611
|
+
break;
|
|
4612
|
+
}
|
|
4613
|
+
default:
|
|
4614
|
+
assertNever11(kind);
|
|
4615
|
+
}
|
|
4616
|
+
if (!warmup) {
|
|
4617
|
+
if (runTimeL !== void 0) {
|
|
4618
|
+
statsL.addRun(runTimeL);
|
|
4619
|
+
}
|
|
4620
|
+
if (runTimeR !== void 0) {
|
|
4621
|
+
statsR.addRun(runTimeR);
|
|
4622
|
+
}
|
|
4623
|
+
}
|
|
4624
|
+
tasksCompleted++;
|
|
4625
|
+
if (tasksCompleted === totalTasks) {
|
|
4626
|
+
(_b2 = (_a2 = this.callbacks).onComplete) == null ? void 0 : _b2.call(_a2, statsL.toReport(), statsR.toReport());
|
|
4627
|
+
}
|
|
4628
|
+
} catch (error) {
|
|
4629
|
+
(_d2 = (_c2 = this.callbacks).onError) == null ? void 0 : _d2.call(_c2, error);
|
|
4630
|
+
}
|
|
4631
|
+
})
|
|
4632
|
+
};
|
|
4633
|
+
this.taskQueue.addTask(task);
|
|
4634
|
+
this.pendingTaskKeys.add(task.key);
|
|
4635
|
+
};
|
|
4228
4636
|
function addTasks(kind) {
|
|
4229
4637
|
for (let i = 0; i < warmupCount; i++) {
|
|
4230
|
-
addTask(
|
|
4638
|
+
addTask(true, kind);
|
|
4231
4639
|
}
|
|
4232
4640
|
for (let i = 0; i < runCount; i++) {
|
|
4233
|
-
addTask(
|
|
4641
|
+
addTask(false, kind);
|
|
4234
4642
|
}
|
|
4235
4643
|
}
|
|
4236
|
-
if (this.mode === "parallel") {
|
|
4644
|
+
if (((_f = this.options) == null ? void 0 : _f.mode) === "parallel") {
|
|
4237
4645
|
addTasks("both");
|
|
4238
4646
|
} else {
|
|
4239
4647
|
addTasks("left");
|
|
@@ -4242,6 +4650,303 @@ var PerfRunner = class {
|
|
|
4242
4650
|
}
|
|
4243
4651
|
};
|
|
4244
4652
|
|
|
4653
|
+
// src/trace/trace-runner.ts
|
|
4654
|
+
import { assertNever as assertNever12 } from "assert-never";
|
|
4655
|
+
function runTraceWithTaskQueue(modelSpec, taskQueue, callbacks, options) {
|
|
4656
|
+
const traceRunner = new TraceRunner(taskQueue, callbacks);
|
|
4657
|
+
traceRunner.start(modelSpec, options);
|
|
4658
|
+
return () => {
|
|
4659
|
+
traceRunner.cancel();
|
|
4660
|
+
};
|
|
4661
|
+
}
|
|
4662
|
+
function runTrace(modelSpec, callbacks, options) {
|
|
4663
|
+
const taskQueue = TaskQueue.getInstance();
|
|
4664
|
+
return runTraceWithTaskQueue(modelSpec, taskQueue, callbacks, options);
|
|
4665
|
+
}
|
|
4666
|
+
var TraceRunner = class {
|
|
4667
|
+
constructor(taskQueue, callbacks) {
|
|
4668
|
+
this.taskQueue = taskQueue;
|
|
4669
|
+
this.callbacks = callbacks;
|
|
4670
|
+
this.pendingTaskKeys = /* @__PURE__ */ new Set();
|
|
4671
|
+
this.stopped = false;
|
|
4672
|
+
}
|
|
4673
|
+
cancel() {
|
|
4674
|
+
if (!this.stopped) {
|
|
4675
|
+
for (const taskKey of this.pendingTaskKeys) {
|
|
4676
|
+
this.taskQueue.cancelTask(taskKey);
|
|
4677
|
+
}
|
|
4678
|
+
this.stopped = true;
|
|
4679
|
+
}
|
|
4680
|
+
}
|
|
4681
|
+
start(modelSpec, options) {
|
|
4682
|
+
const allDatasetKeys = [...modelSpec.implVars.keys()];
|
|
4683
|
+
const traceRequests = [];
|
|
4684
|
+
const batchSize = 2e3;
|
|
4685
|
+
for (let i = 0; i < allDatasetKeys.length; i += batchSize) {
|
|
4686
|
+
const datasetKeysForBatch = allDatasetKeys.slice(i, i + batchSize);
|
|
4687
|
+
switch (options.kind) {
|
|
4688
|
+
case "compare-to-bundle":
|
|
4689
|
+
traceRequests.push({
|
|
4690
|
+
kind: "compare-to-bundle",
|
|
4691
|
+
datasetKeys: datasetKeysForBatch,
|
|
4692
|
+
bundleSide0: options.bundleSide0,
|
|
4693
|
+
scenarioSpec0: options.scenarioSpec0,
|
|
4694
|
+
bundleSide1: options.bundleSide1,
|
|
4695
|
+
scenarioSpec1: options.scenarioSpec1
|
|
4696
|
+
});
|
|
4697
|
+
break;
|
|
4698
|
+
case "compare-to-ext-data":
|
|
4699
|
+
traceRequests.push({
|
|
4700
|
+
kind: "compare-to-ext-data",
|
|
4701
|
+
datasetKeys: datasetKeysForBatch,
|
|
4702
|
+
extData: options.extData,
|
|
4703
|
+
bundleSide: options.bundleSide,
|
|
4704
|
+
scenarioSpec: options.scenarioSpec
|
|
4705
|
+
});
|
|
4706
|
+
break;
|
|
4707
|
+
default:
|
|
4708
|
+
assertNever12(options);
|
|
4709
|
+
}
|
|
4710
|
+
}
|
|
4711
|
+
const allDatasetReports = /* @__PURE__ */ new Map();
|
|
4712
|
+
const taskCount = traceRequests.length;
|
|
4713
|
+
let tasksCompleted = 0;
|
|
4714
|
+
let traceTaskId = 1;
|
|
4715
|
+
for (const traceRequest of traceRequests) {
|
|
4716
|
+
const task = {
|
|
4717
|
+
key: `trace-runner-${traceTaskId++}`,
|
|
4718
|
+
kind: "trace-runner",
|
|
4719
|
+
process: (bundleModels) => __async(this, null, function* () {
|
|
4720
|
+
var _a, _b;
|
|
4721
|
+
this.pendingTaskKeys.delete(task.key);
|
|
4722
|
+
let datasetReports;
|
|
4723
|
+
switch (traceRequest.kind) {
|
|
4724
|
+
case "compare-to-bundle":
|
|
4725
|
+
datasetReports = yield processCompareToBundleRequest(traceRequest, bundleModels);
|
|
4726
|
+
break;
|
|
4727
|
+
case "compare-to-ext-data":
|
|
4728
|
+
datasetReports = yield processCompareToExtDataRequest(traceRequest, bundleModels);
|
|
4729
|
+
break;
|
|
4730
|
+
default:
|
|
4731
|
+
assertNever12(traceRequest);
|
|
4732
|
+
}
|
|
4733
|
+
for (const datasetReport of datasetReports) {
|
|
4734
|
+
allDatasetReports.set(datasetReport.datasetKey, datasetReport);
|
|
4735
|
+
}
|
|
4736
|
+
tasksCompleted++;
|
|
4737
|
+
if (tasksCompleted === taskCount) {
|
|
4738
|
+
const traceReport = {
|
|
4739
|
+
datasetReports: allDatasetReports
|
|
4740
|
+
};
|
|
4741
|
+
(_b = (_a = this.callbacks).onComplete) == null ? void 0 : _b.call(_a, traceReport);
|
|
4742
|
+
}
|
|
4743
|
+
})
|
|
4744
|
+
};
|
|
4745
|
+
this.taskQueue.addTask(task);
|
|
4746
|
+
this.pendingTaskKeys.add(task.key);
|
|
4747
|
+
}
|
|
4748
|
+
}
|
|
4749
|
+
};
|
|
4750
|
+
function processCompareToBundleRequest(request, bundleModels) {
|
|
4751
|
+
return __async(this, null, function* () {
|
|
4752
|
+
const bundleModel0 = request.bundleSide0 === "left" ? bundleModels.L : bundleModels.R;
|
|
4753
|
+
const bundleModel1 = request.bundleSide1 === "left" ? bundleModels.L : bundleModels.R;
|
|
4754
|
+
let result0;
|
|
4755
|
+
let result1;
|
|
4756
|
+
if (bundleModel1 === bundleModel0) {
|
|
4757
|
+
result0 = yield bundleModel0.getDatasetsForScenario(request.scenarioSpec0, request.datasetKeys);
|
|
4758
|
+
result1 = yield bundleModel1.getDatasetsForScenario(request.scenarioSpec1, request.datasetKeys);
|
|
4759
|
+
} else {
|
|
4760
|
+
;
|
|
4761
|
+
[result0, result1] = yield Promise.all([
|
|
4762
|
+
bundleModel0.getDatasetsForScenario(request.scenarioSpec0, request.datasetKeys),
|
|
4763
|
+
bundleModel1.getDatasetsForScenario(request.scenarioSpec1, request.datasetKeys)
|
|
4764
|
+
]);
|
|
4765
|
+
}
|
|
4766
|
+
const datasetReports = [];
|
|
4767
|
+
for (const datasetKey of request.datasetKeys) {
|
|
4768
|
+
const dataset0 = result0.datasetMap.get(datasetKey);
|
|
4769
|
+
const dataset1 = result1.datasetMap.get(datasetKey);
|
|
4770
|
+
const datasetReport = diffDatasets2(
|
|
4771
|
+
datasetKey,
|
|
4772
|
+
dataset0,
|
|
4773
|
+
dataset1,
|
|
4774
|
+
/*matchPrecisionOfLeft=*/
|
|
4775
|
+
false
|
|
4776
|
+
);
|
|
4777
|
+
datasetReports.push(datasetReport);
|
|
4778
|
+
}
|
|
4779
|
+
return datasetReports;
|
|
4780
|
+
});
|
|
4781
|
+
}
|
|
4782
|
+
function processCompareToExtDataRequest(request, bundleModels) {
|
|
4783
|
+
return __async(this, null, function* () {
|
|
4784
|
+
const bundleModel = request.bundleSide === "left" ? bundleModels.L : bundleModels.R;
|
|
4785
|
+
const resultR = yield bundleModel.getDatasetsForScenario(request.scenarioSpec, request.datasetKeys);
|
|
4786
|
+
const datasetReports = [];
|
|
4787
|
+
for (const datasetKey of request.datasetKeys) {
|
|
4788
|
+
let datasetL = request.extData.get(datasetKey);
|
|
4789
|
+
if (datasetL === void 0) {
|
|
4790
|
+
const datasetKeyParts = datasetKey.split("[");
|
|
4791
|
+
if (datasetKeyParts.length === 2) {
|
|
4792
|
+
const baseKey = datasetKeyParts[0];
|
|
4793
|
+
const keySubParts = datasetKeyParts[1].replace("]", "");
|
|
4794
|
+
const keySubIds = keySubParts.split(",");
|
|
4795
|
+
const subIdPermutations = permutationsOf(keySubIds);
|
|
4796
|
+
for (const subIds of subIdPermutations) {
|
|
4797
|
+
const datDatasetKey = `${baseKey}[${subIds.join(",")}]`;
|
|
4798
|
+
datasetL = request.extData.get(datDatasetKey);
|
|
4799
|
+
if (datasetL !== void 0) {
|
|
4800
|
+
break;
|
|
4801
|
+
}
|
|
4802
|
+
}
|
|
4803
|
+
}
|
|
4804
|
+
if (datasetL === void 0) {
|
|
4805
|
+
console.warn(`WARNING: Failed to find data in dat file for key=${datasetKey}`);
|
|
4806
|
+
}
|
|
4807
|
+
}
|
|
4808
|
+
const datasetR = resultR.datasetMap.get(datasetKey);
|
|
4809
|
+
const datasetReport = diffDatasets2(
|
|
4810
|
+
datasetKey,
|
|
4811
|
+
datasetL,
|
|
4812
|
+
datasetR,
|
|
4813
|
+
/*matchPrecisionOfLeft=*/
|
|
4814
|
+
true
|
|
4815
|
+
);
|
|
4816
|
+
datasetReports.push(datasetReport);
|
|
4817
|
+
}
|
|
4818
|
+
return datasetReports;
|
|
4819
|
+
});
|
|
4820
|
+
}
|
|
4821
|
+
function diffDatasets2(datasetKey, datasetL, datasetR, matchPrecisionOfLeft) {
|
|
4822
|
+
const points = /* @__PURE__ */ new Map();
|
|
4823
|
+
let minValueL = Number.MAX_VALUE;
|
|
4824
|
+
let maxValueL = Number.MIN_VALUE;
|
|
4825
|
+
let minValueR = Number.MAX_VALUE;
|
|
4826
|
+
let maxValueR = Number.MIN_VALUE;
|
|
4827
|
+
let minValue = Number.MAX_VALUE;
|
|
4828
|
+
let maxValue = Number.MIN_VALUE;
|
|
4829
|
+
let minRawDiff = Number.MAX_VALUE;
|
|
4830
|
+
let maxRawDiff = -1;
|
|
4831
|
+
let maxDiffPoint;
|
|
4832
|
+
let diffCount = 0;
|
|
4833
|
+
let totalRawDiff = 0;
|
|
4834
|
+
if (datasetL && datasetR) {
|
|
4835
|
+
const times = /* @__PURE__ */ new Set([...datasetL.keys(), ...datasetR.keys()]);
|
|
4836
|
+
for (const t of times) {
|
|
4837
|
+
const valueL = datasetL.get(t);
|
|
4838
|
+
if (valueL !== void 0) {
|
|
4839
|
+
if (valueL < minValueL) minValueL = valueL;
|
|
4840
|
+
if (valueL > maxValueL) maxValueL = valueL;
|
|
4841
|
+
if (valueL < minValue) minValue = valueL;
|
|
4842
|
+
if (valueL > maxValue) maxValue = valueL;
|
|
4843
|
+
}
|
|
4844
|
+
let valueR;
|
|
4845
|
+
const rawValueR = datasetR.get(t);
|
|
4846
|
+
if (rawValueR !== void 0) {
|
|
4847
|
+
if (matchPrecisionOfLeft && valueL !== void 0) {
|
|
4848
|
+
valueR = matchPrecision(rawValueR, valueL);
|
|
4849
|
+
} else {
|
|
4850
|
+
valueR = rawValueR;
|
|
4851
|
+
}
|
|
4852
|
+
if (valueR < minValueR) minValueR = valueR;
|
|
4853
|
+
if (valueR > maxValueR) maxValueR = valueR;
|
|
4854
|
+
if (valueR < minValue) minValue = valueR;
|
|
4855
|
+
if (valueR > maxValue) maxValue = valueR;
|
|
4856
|
+
}
|
|
4857
|
+
if (valueL === void 0 || valueR === void 0) {
|
|
4858
|
+
continue;
|
|
4859
|
+
}
|
|
4860
|
+
const point = {
|
|
4861
|
+
time: t,
|
|
4862
|
+
valueL,
|
|
4863
|
+
valueR
|
|
4864
|
+
};
|
|
4865
|
+
points.set(t, point);
|
|
4866
|
+
const rawDiff = Math.abs(valueR - valueL);
|
|
4867
|
+
if (rawDiff < minRawDiff) {
|
|
4868
|
+
minRawDiff = rawDiff;
|
|
4869
|
+
}
|
|
4870
|
+
if (rawDiff > maxRawDiff) {
|
|
4871
|
+
maxRawDiff = rawDiff;
|
|
4872
|
+
maxDiffPoint = point;
|
|
4873
|
+
}
|
|
4874
|
+
diffCount++;
|
|
4875
|
+
totalRawDiff += rawDiff;
|
|
4876
|
+
}
|
|
4877
|
+
}
|
|
4878
|
+
function pct(x) {
|
|
4879
|
+
return x * 100;
|
|
4880
|
+
}
|
|
4881
|
+
let minDiff;
|
|
4882
|
+
let maxDiff;
|
|
4883
|
+
let avgDiff;
|
|
4884
|
+
if (minValueL === maxValueL && minValueR === maxValueR) {
|
|
4885
|
+
const diff = pct(maxValueL !== 0 ? Math.abs((maxValueR - maxValueL) / maxValueL) : 1);
|
|
4886
|
+
minDiff = diff;
|
|
4887
|
+
maxDiff = diff;
|
|
4888
|
+
avgDiff = diff;
|
|
4889
|
+
} else {
|
|
4890
|
+
const spread = maxValue - minValue;
|
|
4891
|
+
minDiff = pct(spread > 0 ? minRawDiff / spread : 0);
|
|
4892
|
+
maxDiff = pct(spread > 0 ? maxRawDiff / spread : 0);
|
|
4893
|
+
const avgRawDiff = totalRawDiff / diffCount;
|
|
4894
|
+
avgDiff = pct(spread > 0 ? avgRawDiff / spread : 0);
|
|
4895
|
+
}
|
|
4896
|
+
let validity;
|
|
4897
|
+
if (datasetL && datasetR) {
|
|
4898
|
+
validity = "both";
|
|
4899
|
+
} else if (datasetL) {
|
|
4900
|
+
validity = "left-only";
|
|
4901
|
+
} else if (datasetR) {
|
|
4902
|
+
validity = "right-only";
|
|
4903
|
+
} else {
|
|
4904
|
+
validity = "neither";
|
|
4905
|
+
}
|
|
4906
|
+
return {
|
|
4907
|
+
datasetKey,
|
|
4908
|
+
validity,
|
|
4909
|
+
points,
|
|
4910
|
+
minValue,
|
|
4911
|
+
maxValue,
|
|
4912
|
+
avgDiff,
|
|
4913
|
+
minDiff,
|
|
4914
|
+
maxDiff,
|
|
4915
|
+
maxDiffPoint
|
|
4916
|
+
};
|
|
4917
|
+
}
|
|
4918
|
+
function matchPrecision(x, baseline) {
|
|
4919
|
+
const s = baseline.toString();
|
|
4920
|
+
if (s.includes("e")) {
|
|
4921
|
+
return x;
|
|
4922
|
+
}
|
|
4923
|
+
const parts = s.split(".");
|
|
4924
|
+
if (parts.length < 2) {
|
|
4925
|
+
return x;
|
|
4926
|
+
}
|
|
4927
|
+
const sigDigits = parts[1].replace(/0+$/, "").length;
|
|
4928
|
+
if (sigDigits > 21) {
|
|
4929
|
+
return x;
|
|
4930
|
+
}
|
|
4931
|
+
return parseFloat(x.toFixed(sigDigits));
|
|
4932
|
+
}
|
|
4933
|
+
function permutationsOf(inputArr) {
|
|
4934
|
+
const result = [];
|
|
4935
|
+
const permute = (arr, m = []) => {
|
|
4936
|
+
if (arr.length === 0) {
|
|
4937
|
+
result.push(m);
|
|
4938
|
+
} else {
|
|
4939
|
+
for (let i = 0; i < arr.length; i++) {
|
|
4940
|
+
const curr = arr.slice();
|
|
4941
|
+
const next = curr.splice(i, 1);
|
|
4942
|
+
permute(curr.slice(), m.concat(next));
|
|
4943
|
+
}
|
|
4944
|
+
}
|
|
4945
|
+
};
|
|
4946
|
+
permute(inputArr);
|
|
4947
|
+
return result;
|
|
4948
|
+
}
|
|
4949
|
+
|
|
4245
4950
|
// src/data/data-planner.ts
|
|
4246
4951
|
var DataPlanner = class {
|
|
4247
4952
|
/**
|
|
@@ -4428,10 +5133,10 @@ function scenarioPairUid(scenarioSpecL, scenarioSpecR) {
|
|
|
4428
5133
|
}
|
|
4429
5134
|
|
|
4430
5135
|
// src/check/check-runner.ts
|
|
4431
|
-
function runChecks(checkConfig, checkSpec, dataPlanner, refDataPlanner,
|
|
4432
|
-
const modelSpec = checkConfig.bundle.
|
|
5136
|
+
function runChecks(checkConfig, checkSpec, dataPlanner, refDataPlanner, skipChecks) {
|
|
5137
|
+
const modelSpec = checkConfig.bundle.modelSpec;
|
|
4433
5138
|
const checkPlanner = new CheckPlanner(modelSpec);
|
|
4434
|
-
checkPlanner.addAllChecks(checkSpec,
|
|
5139
|
+
checkPlanner.addAllChecks(checkSpec, skipChecks);
|
|
4435
5140
|
const checkPlan = checkPlanner.buildPlan();
|
|
4436
5141
|
const refDatasets = /* @__PURE__ */ new Map();
|
|
4437
5142
|
for (const [dataRefKey, dataRef] of checkPlan.dataRefs.entries()) {
|
|
@@ -4444,11 +5149,15 @@ function runChecks(checkConfig, checkSpec, dataPlanner, refDataPlanner, simplify
|
|
|
4444
5149
|
}
|
|
4445
5150
|
const checkResults = /* @__PURE__ */ new Map();
|
|
4446
5151
|
for (const [checkKey, checkTask] of checkPlan.tasks.entries()) {
|
|
4447
|
-
|
|
4448
|
-
|
|
4449
|
-
|
|
4450
|
-
|
|
4451
|
-
|
|
5152
|
+
if (checkTask.skip === true) {
|
|
5153
|
+
checkResults.set(checkKey, { status: "skipped" });
|
|
5154
|
+
} else {
|
|
5155
|
+
dataPlanner.addRequest(void 0, checkTask.scenario.spec, checkTask.dataset.datasetKey, (datasets) => {
|
|
5156
|
+
const dataset = datasets.datasetR;
|
|
5157
|
+
const checkResult = runCheck(checkTask, dataset, refDatasets);
|
|
5158
|
+
checkResults.set(checkKey, checkResult);
|
|
5159
|
+
});
|
|
5160
|
+
}
|
|
4452
5161
|
}
|
|
4453
5162
|
return () => {
|
|
4454
5163
|
return buildCheckReport(checkPlan, checkResults);
|
|
@@ -4513,21 +5222,73 @@ function runCheck(checkTask, dataset, refDatasets) {
|
|
|
4513
5222
|
}
|
|
4514
5223
|
|
|
4515
5224
|
// src/comparison/run/comparison-runner.ts
|
|
4516
|
-
function runComparisons(comparisonConfig, dataPlanner) {
|
|
5225
|
+
function runComparisons(comparisonConfig, dataPlanner, skipScenarios) {
|
|
5226
|
+
function skipScenarioKey(title, subtitle) {
|
|
5227
|
+
let key = title.toLowerCase();
|
|
5228
|
+
if (subtitle) {
|
|
5229
|
+
key += ` :: ${subtitle.toLowerCase()}`;
|
|
5230
|
+
}
|
|
5231
|
+
return key;
|
|
5232
|
+
}
|
|
5233
|
+
const skipScenariosSet = new Set(skipScenarios.map((scenario) => skipScenarioKey(scenario.title, scenario.subtitle)));
|
|
5234
|
+
const allScenarios = [...comparisonConfig.scenarios.getAllScenarios()];
|
|
5235
|
+
let baselineScenario;
|
|
5236
|
+
const baselineScenarioIndex = allScenarios.findIndex((scenario) => {
|
|
5237
|
+
const settings = scenario.settings;
|
|
5238
|
+
return settings.kind === "all-inputs-settings" && settings.position === "at-default";
|
|
5239
|
+
});
|
|
5240
|
+
if (baselineScenarioIndex !== -1) {
|
|
5241
|
+
baselineScenario = allScenarios.splice(baselineScenarioIndex, 1)[0];
|
|
5242
|
+
}
|
|
4517
5243
|
const testReports = [];
|
|
4518
|
-
|
|
5244
|
+
const baselineDiffReports = /* @__PURE__ */ new Map();
|
|
5245
|
+
function runComparisonsForScenario(scenario, isBaseline) {
|
|
4519
5246
|
const datasetKeys = comparisonConfig.datasets.getDatasetKeysForScenario(scenario);
|
|
4520
|
-
|
|
4521
|
-
|
|
4522
|
-
|
|
5247
|
+
const shouldSkip = skipScenariosSet.has(skipScenarioKey(scenario.title, scenario.subtitle));
|
|
5248
|
+
if (shouldSkip) {
|
|
5249
|
+
for (const datasetKey of datasetKeys) {
|
|
4523
5250
|
testReports.push({
|
|
4524
5251
|
scenarioKey: scenario.key,
|
|
4525
5252
|
datasetKey,
|
|
4526
|
-
diffReport
|
|
5253
|
+
diffReport: void 0
|
|
4527
5254
|
});
|
|
5255
|
+
}
|
|
5256
|
+
return;
|
|
5257
|
+
}
|
|
5258
|
+
for (const datasetKey of datasetKeys) {
|
|
5259
|
+
dataPlanner.addRequest(scenario.specL, scenario.specR, datasetKey, (datasets) => {
|
|
5260
|
+
const diffReport = diffDatasets(datasets.datasetL, datasets.datasetR);
|
|
5261
|
+
if (isBaseline) {
|
|
5262
|
+
baselineDiffReports.set(datasetKey, diffReport);
|
|
5263
|
+
testReports.push({
|
|
5264
|
+
scenarioKey: scenario.key,
|
|
5265
|
+
datasetKey,
|
|
5266
|
+
diffReport
|
|
5267
|
+
});
|
|
5268
|
+
} else {
|
|
5269
|
+
const baselineDiffReport = baselineDiffReports.get(datasetKey);
|
|
5270
|
+
testReports.push({
|
|
5271
|
+
scenarioKey: scenario.key,
|
|
5272
|
+
datasetKey,
|
|
5273
|
+
diffReport,
|
|
5274
|
+
baselineDiffReport
|
|
5275
|
+
});
|
|
5276
|
+
}
|
|
4528
5277
|
});
|
|
4529
5278
|
}
|
|
4530
5279
|
}
|
|
5280
|
+
runComparisonsForScenario(
|
|
5281
|
+
baselineScenario,
|
|
5282
|
+
/*isBaseline=*/
|
|
5283
|
+
true
|
|
5284
|
+
);
|
|
5285
|
+
for (const scenario of allScenarios) {
|
|
5286
|
+
runComparisonsForScenario(
|
|
5287
|
+
scenario,
|
|
5288
|
+
/*isBaseline=*/
|
|
5289
|
+
false
|
|
5290
|
+
);
|
|
5291
|
+
}
|
|
4531
5292
|
return () => {
|
|
4532
5293
|
return testReports;
|
|
4533
5294
|
};
|
|
@@ -4535,74 +5296,52 @@ function runComparisons(comparisonConfig, dataPlanner) {
|
|
|
4535
5296
|
|
|
4536
5297
|
// src/suite/suite-runner.ts
|
|
4537
5298
|
var SuiteRunner = class {
|
|
4538
|
-
constructor(config, callbacks) {
|
|
5299
|
+
constructor(config, taskQueue, callbacks) {
|
|
4539
5300
|
this.config = config;
|
|
5301
|
+
this.taskQueue = taskQueue;
|
|
4540
5302
|
this.callbacks = callbacks;
|
|
4541
5303
|
this.perfStatsL = new PerfStats();
|
|
4542
5304
|
this.perfStatsR = new PerfStats();
|
|
5305
|
+
this.pendingTaskKeys = /* @__PURE__ */ new Set();
|
|
4543
5306
|
this.stopped = false;
|
|
4544
|
-
this.taskQueue = new TaskQueue({
|
|
4545
|
-
process: (request) => {
|
|
4546
|
-
return this.processRequest(request);
|
|
4547
|
-
}
|
|
4548
|
-
});
|
|
4549
5307
|
}
|
|
4550
5308
|
cancel() {
|
|
4551
5309
|
if (!this.stopped) {
|
|
5310
|
+
for (const taskKey of this.pendingTaskKeys) {
|
|
5311
|
+
this.taskQueue.cancelTask(taskKey);
|
|
5312
|
+
}
|
|
4552
5313
|
this.stopped = true;
|
|
4553
|
-
this.taskQueue.shutdown();
|
|
4554
5314
|
}
|
|
4555
5315
|
}
|
|
4556
5316
|
start(options) {
|
|
4557
5317
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
4558
5318
|
(_b = (_a = this.callbacks).onProgress) == null ? void 0 : _b.call(_a, 0);
|
|
4559
|
-
const
|
|
4560
|
-
const dataPlanner = new DataPlanner(
|
|
4561
|
-
const refDataPlanner = new DataPlanner(
|
|
5319
|
+
const modelSpecR = this.config.check.bundle.modelSpec;
|
|
5320
|
+
const dataPlanner = new DataPlanner(modelSpecR.outputVars.size);
|
|
5321
|
+
const refDataPlanner = new DataPlanner(modelSpecR.outputVars.size);
|
|
4562
5322
|
const checkSpecResult = parseTestYaml(this.config.check.tests);
|
|
4563
5323
|
if (checkSpecResult.isErr()) {
|
|
4564
5324
|
(_d = (_c = this.callbacks).onError) == null ? void 0 : _d.call(_c, checkSpecResult.error);
|
|
4565
5325
|
return;
|
|
4566
5326
|
}
|
|
4567
5327
|
const checkSpec = checkSpecResult.value;
|
|
4568
|
-
const
|
|
4569
|
-
const buildCheckReport2 = runChecks(this.config.check, checkSpec, dataPlanner, refDataPlanner,
|
|
5328
|
+
const skipChecks = (options == null ? void 0 : options.skipChecks) || [];
|
|
5329
|
+
const buildCheckReport2 = runChecks(this.config.check, checkSpec, dataPlanner, refDataPlanner, skipChecks);
|
|
4570
5330
|
let buildComparisonTestReports;
|
|
4571
5331
|
if (this.config.comparison) {
|
|
4572
|
-
|
|
5332
|
+
const skipScenarios = (options == null ? void 0 : options.skipComparisonScenarios) || [];
|
|
5333
|
+
buildComparisonTestReports = runComparisons(this.config.comparison, dataPlanner, skipScenarios);
|
|
4573
5334
|
}
|
|
4574
|
-
this.taskQueue.onIdle = (error) => {
|
|
4575
|
-
var _a2, _b2, _c2, _d2;
|
|
4576
|
-
if (this.stopped) {
|
|
4577
|
-
return;
|
|
4578
|
-
}
|
|
4579
|
-
if (error) {
|
|
4580
|
-
(_b2 = (_a2 = this.callbacks).onError) == null ? void 0 : _b2.call(_a2, error);
|
|
4581
|
-
} else {
|
|
4582
|
-
const checkReport = buildCheckReport2();
|
|
4583
|
-
let comparisonReport;
|
|
4584
|
-
if (this.config.comparison) {
|
|
4585
|
-
comparisonReport = {
|
|
4586
|
-
testReports: buildComparisonTestReports(),
|
|
4587
|
-
perfReportL: this.perfStatsL.toReport(),
|
|
4588
|
-
perfReportR: this.perfStatsR.toReport()
|
|
4589
|
-
};
|
|
4590
|
-
}
|
|
4591
|
-
(_d2 = (_c2 = this.callbacks).onComplete) == null ? void 0 : _d2.call(_c2, {
|
|
4592
|
-
checkReport,
|
|
4593
|
-
comparisonReport
|
|
4594
|
-
});
|
|
4595
|
-
}
|
|
4596
|
-
};
|
|
4597
5335
|
const refDataPlan = refDataPlanner.buildPlan();
|
|
4598
5336
|
const dataPlan = dataPlanner.buildPlan();
|
|
4599
5337
|
const dataRequests = [...refDataPlan.requests, ...dataPlan.requests];
|
|
4600
5338
|
const taskCount = dataRequests.length;
|
|
4601
5339
|
if (taskCount === 0) {
|
|
5340
|
+
const checkReport = buildCheckReport2();
|
|
4602
5341
|
let comparisonReport;
|
|
4603
5342
|
if (this.config.comparison) {
|
|
4604
5343
|
comparisonReport = {
|
|
4605
|
-
testReports:
|
|
5344
|
+
testReports: buildComparisonTestReports(),
|
|
4606
5345
|
perfReportL: this.perfStatsL.toReport(),
|
|
4607
5346
|
perfReportR: this.perfStatsR.toReport()
|
|
4608
5347
|
};
|
|
@@ -4610,26 +5349,54 @@ var SuiteRunner = class {
|
|
|
4610
5349
|
this.cancel();
|
|
4611
5350
|
(_f = (_e = this.callbacks).onProgress) == null ? void 0 : _f.call(_e, 1);
|
|
4612
5351
|
(_h = (_g = this.callbacks).onComplete) == null ? void 0 : _h.call(_g, {
|
|
4613
|
-
checkReport
|
|
4614
|
-
groups: []
|
|
4615
|
-
},
|
|
5352
|
+
checkReport,
|
|
4616
5353
|
comparisonReport
|
|
4617
5354
|
});
|
|
4618
5355
|
return;
|
|
4619
5356
|
}
|
|
5357
|
+
const buildReport = (error) => {
|
|
5358
|
+
var _a2, _b2, _c2, _d2;
|
|
5359
|
+
if (error) {
|
|
5360
|
+
(_b2 = (_a2 = this.callbacks).onError) == null ? void 0 : _b2.call(_a2, error);
|
|
5361
|
+
} else {
|
|
5362
|
+
const checkReport = buildCheckReport2();
|
|
5363
|
+
let comparisonReport;
|
|
5364
|
+
if (this.config.comparison) {
|
|
5365
|
+
comparisonReport = {
|
|
5366
|
+
testReports: buildComparisonTestReports(),
|
|
5367
|
+
perfReportL: this.perfStatsL.toReport(),
|
|
5368
|
+
perfReportR: this.perfStatsR.toReport()
|
|
5369
|
+
};
|
|
5370
|
+
}
|
|
5371
|
+
(_d2 = (_c2 = this.callbacks).onComplete) == null ? void 0 : _d2.call(_c2, {
|
|
5372
|
+
checkReport,
|
|
5373
|
+
comparisonReport
|
|
5374
|
+
});
|
|
5375
|
+
}
|
|
5376
|
+
};
|
|
4620
5377
|
let tasksCompleted = 0;
|
|
4621
5378
|
let dataTaskId = 1;
|
|
4622
5379
|
for (const dataRequest of dataRequests) {
|
|
4623
|
-
|
|
4624
|
-
|
|
4625
|
-
|
|
4626
|
-
(
|
|
4627
|
-
|
|
5380
|
+
const task = {
|
|
5381
|
+
key: `suite-runner-${dataTaskId++}`,
|
|
5382
|
+
kind: "suite-runner",
|
|
5383
|
+
process: (bundleModels) => __async(this, null, function* () {
|
|
5384
|
+
var _a2, _b2;
|
|
5385
|
+
this.pendingTaskKeys.delete(task.key);
|
|
5386
|
+
yield this.processRequest(dataRequest, bundleModels);
|
|
5387
|
+
tasksCompleted++;
|
|
5388
|
+
(_b2 = (_a2 = this.callbacks).onProgress) == null ? void 0 : _b2.call(_a2, tasksCompleted / taskCount);
|
|
5389
|
+
if (tasksCompleted === taskCount) {
|
|
5390
|
+
buildReport();
|
|
5391
|
+
}
|
|
5392
|
+
})
|
|
5393
|
+
};
|
|
5394
|
+
this.taskQueue.addTask(task);
|
|
5395
|
+
this.pendingTaskKeys.add(task.key);
|
|
4628
5396
|
}
|
|
4629
5397
|
}
|
|
4630
|
-
processRequest(request) {
|
|
5398
|
+
processRequest(request, bundleModels) {
|
|
4631
5399
|
return __async(this, null, function* () {
|
|
4632
|
-
var _a, _b;
|
|
4633
5400
|
const datasetKeySet = /* @__PURE__ */ new Set();
|
|
4634
5401
|
for (const dataTask of request.dataTasks) {
|
|
4635
5402
|
datasetKeySet.add(dataTask.datasetKey);
|
|
@@ -4644,8 +5411,8 @@ var SuiteRunner = class {
|
|
|
4644
5411
|
}
|
|
4645
5412
|
});
|
|
4646
5413
|
}
|
|
4647
|
-
const bundleModelL =
|
|
4648
|
-
const bundleModelR =
|
|
5414
|
+
const bundleModelL = bundleModels.L;
|
|
5415
|
+
const bundleModelR = bundleModels.R;
|
|
4649
5416
|
const [datasetsResultL, datasetsResultR] = yield Promise.all([
|
|
4650
5417
|
getDatasets(bundleModelL, request.scenarioSpecL),
|
|
4651
5418
|
getDatasets(bundleModelR, request.scenarioSpecR)
|
|
@@ -4669,22 +5436,29 @@ var SuiteRunner = class {
|
|
|
4669
5436
|
});
|
|
4670
5437
|
}
|
|
4671
5438
|
};
|
|
4672
|
-
function
|
|
4673
|
-
const suiteRunner = new SuiteRunner(config, callbacks);
|
|
5439
|
+
function runSuiteWithTaskQueue(config, taskQueue, callbacks, options) {
|
|
5440
|
+
const suiteRunner = new SuiteRunner(config, taskQueue, callbacks);
|
|
4674
5441
|
suiteRunner.start(options);
|
|
4675
5442
|
return () => {
|
|
4676
5443
|
suiteRunner.cancel();
|
|
4677
5444
|
};
|
|
4678
5445
|
}
|
|
5446
|
+
function runSuite(config, callbacks, options) {
|
|
5447
|
+
const taskQueue = TaskQueue.getInstance();
|
|
5448
|
+
return runSuiteWithTaskQueue(config, taskQueue, callbacks, options);
|
|
5449
|
+
}
|
|
4679
5450
|
|
|
4680
5451
|
// src/suite/suite-reporting.ts
|
|
4681
|
-
function suiteSummaryFromReport(suiteReport) {
|
|
5452
|
+
function suiteSummaryFromReport(suiteReport, elapsedMillis) {
|
|
4682
5453
|
const checkSummary = checkSummaryFromReport(suiteReport.checkReport);
|
|
4683
5454
|
let comparisonSummary;
|
|
4684
5455
|
if (suiteReport.comparisonReport) {
|
|
4685
5456
|
comparisonSummary = comparisonSummaryFromReport(suiteReport.comparisonReport);
|
|
4686
5457
|
}
|
|
5458
|
+
const date = (/* @__PURE__ */ new Date()).toISOString();
|
|
4687
5459
|
return {
|
|
5460
|
+
date,
|
|
5461
|
+
elapsed: elapsedMillis,
|
|
4688
5462
|
checkSummary,
|
|
4689
5463
|
comparisonSummary
|
|
4690
5464
|
};
|
|
@@ -4692,20 +5466,27 @@ function suiteSummaryFromReport(suiteReport) {
|
|
|
4692
5466
|
export {
|
|
4693
5467
|
CheckDataCoordinator,
|
|
4694
5468
|
ComparisonDataCoordinator,
|
|
4695
|
-
PerfRunner,
|
|
4696
5469
|
PerfStats,
|
|
4697
5470
|
categorizeComparisonTestSummaries,
|
|
4698
5471
|
checkReportFromSummary,
|
|
4699
5472
|
checkSummaryFromReport,
|
|
4700
5473
|
comparisonSummaryFromReport,
|
|
5474
|
+
createCheckDataCoordinator,
|
|
5475
|
+
createCheckDataCoordinatorForTests,
|
|
5476
|
+
createComparisonDataCoordinator,
|
|
4701
5477
|
createConfig,
|
|
4702
5478
|
datasetMessage,
|
|
5479
|
+
decodeImplVars,
|
|
4703
5480
|
diffDatasets,
|
|
4704
5481
|
diffGraphs,
|
|
5482
|
+
encodeImplVars,
|
|
4705
5483
|
getScoresForTestSummaries,
|
|
4706
5484
|
predicateMessage,
|
|
5485
|
+
runPerf,
|
|
4707
5486
|
runSuite,
|
|
5487
|
+
runTrace,
|
|
4708
5488
|
scenarioMessage,
|
|
4709
|
-
suiteSummaryFromReport
|
|
5489
|
+
suiteSummaryFromReport,
|
|
5490
|
+
testSummaryFromReport
|
|
4710
5491
|
};
|
|
4711
5492
|
//# sourceMappingURL=index.js.map
|