callman-core 1.25.1 → 1.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/host/db/mysqlAdapter.d.ts.map +1 -1
- package/dist/host/db/mysqlAdapter.js +39 -9
- package/dist/host/db/mysqlAdapter.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/request/executeRequest.d.ts +1 -1
- package/dist/request/executeRequest.d.ts.map +1 -1
- package/dist/request/executeRequest.js +8 -1
- package/dist/request/executeRequest.js.map +1 -1
- package/dist/scenario-runner/adapters/request-executor.js +12 -3
- package/dist/scenario-runner/adapters/request-executor.js.map +1 -1
- package/dist/scenario-runner/adapters/script-executor.js +1 -1
- package/dist/scenario-runner/adapters/script-executor.js.map +1 -1
- package/dist/scenario-runner/adapters/types.d.ts +1 -0
- package/dist/scenario-runner/adapters/types.d.ts.map +1 -1
- package/dist/scenario-runner/boundSnapshot.d.ts +15 -0
- package/dist/scenario-runner/boundSnapshot.d.ts.map +1 -0
- package/dist/scenario-runner/boundSnapshot.js +67 -0
- package/dist/scenario-runner/boundSnapshot.js.map +1 -0
- package/dist/scenario-runner/runScenario.d.ts +1 -1
- package/dist/scenario-runner/runScenario.d.ts.map +1 -1
- package/dist/scenario-runner/runScenario.js +34 -25
- package/dist/scenario-runner/runScenario.js.map +1 -1
- package/dist/scenario-runner/runScenarioWithDataset.d.ts.map +1 -1
- package/dist/scenario-runner/runScenarioWithDataset.js +21 -6
- package/dist/scenario-runner/runScenarioWithDataset.js.map +1 -1
- package/dist/scenario-runner/types.d.ts +2 -0
- package/dist/scenario-runner/types.d.ts.map +1 -1
- package/dist/script/isolated-runner.d.ts +7 -1
- package/dist/script/isolated-runner.d.ts.map +1 -1
- package/dist/script/isolated-runner.js +11 -5
- package/dist/script/isolated-runner.js.map +1 -1
- package/dist/script/worker-entry.js +62 -28
- package/dist/script/worker-entry.js.map +1 -1
- package/dist/script/worker-pool.d.ts +60 -0
- package/dist/script/worker-pool.d.ts.map +1 -0
- package/dist/script/worker-pool.js +274 -0
- package/dist/script/worker-pool.js.map +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist-cjs/host/db/mysqlAdapter.js +39 -9
- package/dist-cjs/host/db/mysqlAdapter.js.map +1 -1
- package/dist-cjs/index.js +4 -1
- package/dist-cjs/index.js.map +1 -1
- package/dist-cjs/request/executeRequest.js +8 -1
- package/dist-cjs/request/executeRequest.js.map +1 -1
- package/dist-cjs/scenario-runner/adapters/request-executor.js +12 -3
- package/dist-cjs/scenario-runner/adapters/request-executor.js.map +1 -1
- package/dist-cjs/scenario-runner/adapters/script-executor.js +1 -1
- package/dist-cjs/scenario-runner/adapters/script-executor.js.map +1 -1
- package/dist-cjs/scenario-runner/boundSnapshot.js +71 -0
- package/dist-cjs/scenario-runner/boundSnapshot.js.map +1 -0
- package/dist-cjs/scenario-runner/runScenario.js +34 -25
- package/dist-cjs/scenario-runner/runScenario.js.map +1 -1
- package/dist-cjs/scenario-runner/runScenarioWithDataset.js +21 -6
- package/dist-cjs/scenario-runner/runScenarioWithDataset.js.map +1 -1
- package/dist-cjs/script/isolated-runner.js +12 -5
- package/dist-cjs/script/isolated-runner.js.map +1 -1
- package/dist-cjs/script/worker-entry.js +62 -28
- package/dist-cjs/script/worker-entry.js.map +1 -1
- package/dist-cjs/script/worker-pool.js +312 -0
- package/dist-cjs/script/worker-pool.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Size-capped deep copy of a runtime value for event context snapshots
|
|
3
|
+
// (`RunScenarioOptions.eventContextMode: "bounded"`).
|
|
4
|
+
//
|
|
5
|
+
// The caps are deliberately LOOSER than the backend report mapper's persist-
|
|
6
|
+
// time truncation (16 KB strings / 50 array items / 50 keys / depth 6), so
|
|
7
|
+
// everything the mapper keeps is still present verbatim after bounding —
|
|
8
|
+
// the persisted report is byte-identical whether bounding ran or not. What
|
|
9
|
+
// changes is what stays in the HEAP while the run is in flight: a bounded
|
|
10
|
+
// snapshot never holds a reference to a multi-megabyte response body.
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.boundSnapshot = exports.DEFAULT_BOUND_SNAPSHOT_LIMITS = void 0;
|
|
13
|
+
exports.DEFAULT_BOUND_SNAPSHOT_LIMITS = {
|
|
14
|
+
maxStringLength: 32 * 1024,
|
|
15
|
+
maxArrayItems: 100,
|
|
16
|
+
maxObjectKeys: 100,
|
|
17
|
+
maxDepth: 8,
|
|
18
|
+
};
|
|
19
|
+
const TRUNCATED = "…[truncated]";
|
|
20
|
+
const boundValueAt = (value, depth, limits) => {
|
|
21
|
+
if (value === null || value === undefined)
|
|
22
|
+
return value;
|
|
23
|
+
switch (typeof value) {
|
|
24
|
+
case "string":
|
|
25
|
+
return value.length > limits.maxStringLength
|
|
26
|
+
? `${value.slice(0, limits.maxStringLength)}${TRUNCATED}`
|
|
27
|
+
: value;
|
|
28
|
+
case "number":
|
|
29
|
+
case "boolean":
|
|
30
|
+
return value;
|
|
31
|
+
case "bigint":
|
|
32
|
+
return value.toString();
|
|
33
|
+
case "function":
|
|
34
|
+
case "symbol":
|
|
35
|
+
return undefined;
|
|
36
|
+
default:
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
if (value instanceof Date)
|
|
40
|
+
return new Date(value.getTime());
|
|
41
|
+
if (depth >= limits.maxDepth)
|
|
42
|
+
return TRUNCATED;
|
|
43
|
+
if (Array.isArray(value)) {
|
|
44
|
+
const kept = value.slice(0, limits.maxArrayItems).map((item) => boundValueAt(item, depth + 1, limits));
|
|
45
|
+
return kept;
|
|
46
|
+
}
|
|
47
|
+
if (typeof value.toJSON === "function") {
|
|
48
|
+
return boundValueAt(value.toJSON(), depth, limits);
|
|
49
|
+
}
|
|
50
|
+
const out = {};
|
|
51
|
+
let count = 0;
|
|
52
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
53
|
+
if (count >= limits.maxObjectKeys)
|
|
54
|
+
break;
|
|
55
|
+
const bounded = boundValueAt(entry, depth + 1, limits);
|
|
56
|
+
if (bounded !== undefined) {
|
|
57
|
+
out[key] = bounded;
|
|
58
|
+
count += 1;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return out;
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Returns a bounded deep copy of `value`. `undefined` and `null` pass
|
|
65
|
+
* through unchanged; typed callers cast the result back to their shape —
|
|
66
|
+
* bounding never changes the top-level structure, only trims what is nested
|
|
67
|
+
* inside it.
|
|
68
|
+
*/
|
|
69
|
+
const boundSnapshot = (value, limits = exports.DEFAULT_BOUND_SNAPSHOT_LIMITS) => (value === null || value === undefined ? value : boundValueAt(value, 0, limits));
|
|
70
|
+
exports.boundSnapshot = boundSnapshot;
|
|
71
|
+
//# sourceMappingURL=boundSnapshot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"boundSnapshot.js","sourceRoot":"","sources":["../../src/scenario-runner/boundSnapshot.ts"],"names":[],"mappings":";AAAA,uEAAuE;AACvE,sDAAsD;AACtD,EAAE;AACF,6EAA6E;AAC7E,2EAA2E;AAC3E,yEAAyE;AACzE,2EAA2E;AAC3E,0EAA0E;AAC1E,sEAAsE;;;AASzD,QAAA,6BAA6B,GAAwB;IAChE,eAAe,EAAE,EAAE,GAAG,IAAI;IAC1B,aAAa,EAAE,GAAG;IAClB,aAAa,EAAE,GAAG;IAClB,QAAQ,EAAE,CAAC;CACZ,CAAC;AAEF,MAAM,SAAS,GAAG,cAAc,CAAC;AAEjC,MAAM,YAAY,GAAG,CAAC,KAAc,EAAE,KAAa,EAAE,MAA2B,EAAW,EAAE;IAC3F,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACxD,QAAQ,OAAO,KAAK,EAAE,CAAC;QACrB,KAAK,QAAQ;YACX,OAAO,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,eAAe;gBAC1C,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,eAAe,CAAC,GAAG,SAAS,EAAE;gBACzD,CAAC,CAAC,KAAK,CAAC;QACZ,KAAK,QAAQ,CAAC;QACd,KAAK,SAAS;YACZ,OAAO,KAAK,CAAC;QACf,KAAK,QAAQ;YACX,OAAO,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC1B,KAAK,UAAU,CAAC;QAChB,KAAK,QAAQ;YACX,OAAO,SAAS,CAAC;QACnB;YACE,MAAM;IACV,CAAC;IACD,IAAI,KAAK,YAAY,IAAI;QAAE,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IAC5D,IAAI,KAAK,IAAI,MAAM,CAAC,QAAQ;QAAE,OAAO,SAAS,CAAC;IAC/C,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;QACvG,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,OAAQ,KAA8B,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;QACjE,OAAO,YAAY,CAAE,KAAmC,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACpF,CAAC;IACD,MAAM,GAAG,GAA4B,EAAE,CAAC;IACxC,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAgC,CAAC,EAAE,CAAC;QAC5E,IAAI,KAAK,IAAI,MAAM,CAAC,aAAa;YAAE,MAAM;QACzC,MAAM,OAAO,GAAG,YAAY,CAAC,KAAK,EAAE,KAAK,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;QACvD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,GAAG,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC;YACnB,KAAK,IAAI,CAAC,CAAC;QACb,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;AAEF;;;;;GAKG;AACI,MAAM,aAAa,GAAG,CAC3B,KAAQ,EACR,SAA8B,qCAA6B,EACxD,EAAE,CAAC,CAAC,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAE,YAAY,CAAC,KAAK,EAAE,CAAC,EAAE,MAAM,CAAO,CAAC,CAAC;AAHnF,QAAA,aAAa,iBAGsE"}
|
|
@@ -7,6 +7,7 @@ const assertion_js_1 = require("./assertion.js");
|
|
|
7
7
|
const graphTraversal_js_1 = require("./graphTraversal.js");
|
|
8
8
|
const websocket_js_1 = require("./websocket.js");
|
|
9
9
|
const executionPolicyRunner_js_1 = require("./executionPolicyRunner.js");
|
|
10
|
+
const boundSnapshot_js_1 = require("./boundSnapshot.js");
|
|
10
11
|
const nodePolicy_js_1 = require("./nodePolicy.js");
|
|
11
12
|
const templateResolver_js_1 = require("./templateResolver.js");
|
|
12
13
|
const waitNodeExecutor_js_1 = require("./waitNodeExecutor.js");
|
|
@@ -113,19 +114,24 @@ const createInputSnapshot = (context) => ({
|
|
|
113
114
|
result: context.redisResult ?? null,
|
|
114
115
|
},
|
|
115
116
|
});
|
|
116
|
-
const createContextSnapshot = (context) =>
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
117
|
+
const createContextSnapshot = (context, mode = "full") => {
|
|
118
|
+
// "bounded": the payload-bearing slots are size-capped copies instead of
|
|
119
|
+
// references, so the event log never pins a node's full response body.
|
|
120
|
+
const bound = mode === "bounded" ? boundSnapshot_js_1.boundSnapshot : (value) => value;
|
|
121
|
+
return {
|
|
122
|
+
environment: { ...context.environment },
|
|
123
|
+
globals: { ...context.globals },
|
|
124
|
+
workflowContext: bound({ ...context.workflowContext }),
|
|
125
|
+
nodeMetaByLabel: cloneNodeMetaByLabel(context.nodeMetaByLabel),
|
|
126
|
+
workflowMeta: cloneWorkflowExecutionMeta(context.workflowMeta),
|
|
127
|
+
responseRoot: context.responseRoot ? bound({ ...context.responseRoot }) : null,
|
|
128
|
+
lastResponse: bound(context.lastResponse),
|
|
129
|
+
dbResult: bound(context.dbResult),
|
|
130
|
+
kafkaEvent: bound(context.kafkaEvent),
|
|
131
|
+
kafkaCapture: bound(context.kafkaCapture),
|
|
132
|
+
redisResult: bound(context.redisResult),
|
|
133
|
+
};
|
|
134
|
+
};
|
|
129
135
|
const buildKafkaEventValue = (message) => {
|
|
130
136
|
const fallbackValue = {
|
|
131
137
|
value: message.valueJson ?? message.valueText,
|
|
@@ -560,7 +566,7 @@ const callHandler = async (handlers, event) => {
|
|
|
560
566
|
return;
|
|
561
567
|
}
|
|
562
568
|
};
|
|
563
|
-
const runScenario = async ({ scenario, environment = {}, globals = {}, runtimeAdapters, eventHandlers, signal, minNodeVisualStateMs = DEFAULT_MIN_NODE_VISUAL_STATE_MS, }) => {
|
|
569
|
+
const runScenario = async ({ scenario, environment = {}, globals = {}, runtimeAdapters, eventHandlers, signal, minNodeVisualStateMs = DEFAULT_MIN_NODE_VISUAL_STATE_MS, eventContextMode = "full", }) => {
|
|
564
570
|
const runId = createRunId();
|
|
565
571
|
const startedAtMs = Date.now();
|
|
566
572
|
const startedAt = new Date(startedAtMs).toISOString();
|
|
@@ -571,6 +577,9 @@ const runScenario = async ({ scenario, environment = {}, globals = {}, runtimeAd
|
|
|
571
577
|
const localStatuses = new Map(runtimeStepIds.map((stepId) => [stepId, "idle"]));
|
|
572
578
|
const records = new Map();
|
|
573
579
|
const events = [];
|
|
580
|
+
// Every emitted event carries a context snapshot; `runtimeContext` is
|
|
581
|
+
// assigned just below and is always initialised before the first emit.
|
|
582
|
+
const snapshotContext = () => createContextSnapshot(runtimeContext, eventContextMode);
|
|
574
583
|
const initialWorkflowMeta = createInitialWorkflowMeta({
|
|
575
584
|
startedAt,
|
|
576
585
|
totalNodes: runtimeStepIds.length,
|
|
@@ -980,7 +989,7 @@ const runScenario = async ({ scenario, environment = {}, globals = {}, runtimeAd
|
|
|
980
989
|
runId,
|
|
981
990
|
stepId,
|
|
982
991
|
node,
|
|
983
|
-
context:
|
|
992
|
+
context: snapshotContext(),
|
|
984
993
|
kafkaCapturePlans,
|
|
985
994
|
captureFromTimestampMs: startedAtMs,
|
|
986
995
|
signal,
|
|
@@ -1041,7 +1050,7 @@ const runScenario = async ({ scenario, environment = {}, globals = {}, runtimeAd
|
|
|
1041
1050
|
},
|
|
1042
1051
|
}
|
|
1043
1052
|
: {}),
|
|
1044
|
-
context:
|
|
1053
|
+
context: snapshotContext(),
|
|
1045
1054
|
signal,
|
|
1046
1055
|
});
|
|
1047
1056
|
runtimeContext.dbResult = dbResult.dbResult;
|
|
@@ -1074,7 +1083,7 @@ const runScenario = async ({ scenario, environment = {}, globals = {}, runtimeAd
|
|
|
1074
1083
|
runId,
|
|
1075
1084
|
stepId,
|
|
1076
1085
|
node,
|
|
1077
|
-
context:
|
|
1086
|
+
context: snapshotContext(),
|
|
1078
1087
|
signal,
|
|
1079
1088
|
});
|
|
1080
1089
|
scriptSource = scriptResult.scriptSource;
|
|
@@ -1098,7 +1107,7 @@ const runScenario = async ({ scenario, environment = {}, globals = {}, runtimeAd
|
|
|
1098
1107
|
stepId,
|
|
1099
1108
|
node,
|
|
1100
1109
|
resolvedCommands,
|
|
1101
|
-
context:
|
|
1110
|
+
context: snapshotContext(),
|
|
1102
1111
|
signal,
|
|
1103
1112
|
});
|
|
1104
1113
|
runtimeContext.redisResult = redisResult.redisResult;
|
|
@@ -1150,7 +1159,7 @@ const runScenario = async ({ scenario, environment = {}, globals = {}, runtimeAd
|
|
|
1150
1159
|
position: node.position,
|
|
1151
1160
|
data: { label: node.data.label, config: pollConfig.request },
|
|
1152
1161
|
},
|
|
1153
|
-
context:
|
|
1162
|
+
context: snapshotContext(),
|
|
1154
1163
|
kafkaCapturePlans: [],
|
|
1155
1164
|
captureFromTimestampMs: startedAtMs,
|
|
1156
1165
|
signal,
|
|
@@ -1190,7 +1199,7 @@ const runScenario = async ({ scenario, environment = {}, globals = {}, runtimeAd
|
|
|
1190
1199
|
},
|
|
1191
1200
|
resolvedQuery,
|
|
1192
1201
|
resolvedParams,
|
|
1193
|
-
context:
|
|
1202
|
+
context: snapshotContext(),
|
|
1194
1203
|
signal,
|
|
1195
1204
|
});
|
|
1196
1205
|
runtimeContext.dbResult = tickResult.dbResult;
|
|
@@ -1213,7 +1222,7 @@ const runScenario = async ({ scenario, environment = {}, globals = {}, runtimeAd
|
|
|
1213
1222
|
data: { label: node.data.label, config: pollConfig.redis },
|
|
1214
1223
|
},
|
|
1215
1224
|
resolvedCommands,
|
|
1216
|
-
context:
|
|
1225
|
+
context: snapshotContext(),
|
|
1217
1226
|
signal,
|
|
1218
1227
|
});
|
|
1219
1228
|
runtimeContext.redisResult = tickResult.redisResult;
|
|
@@ -1231,7 +1240,7 @@ const runScenario = async ({ scenario, environment = {}, globals = {}, runtimeAd
|
|
|
1231
1240
|
position: node.position,
|
|
1232
1241
|
data: { label: node.data.label, config: pollConfig.script },
|
|
1233
1242
|
},
|
|
1234
|
-
context:
|
|
1243
|
+
context: snapshotContext(),
|
|
1235
1244
|
signal,
|
|
1236
1245
|
});
|
|
1237
1246
|
scriptSource = tickResult.scriptSource;
|
|
@@ -1354,7 +1363,7 @@ const runScenario = async ({ scenario, environment = {}, globals = {}, runtimeAd
|
|
|
1354
1363
|
runId,
|
|
1355
1364
|
stepId,
|
|
1356
1365
|
node,
|
|
1357
|
-
context:
|
|
1366
|
+
context: snapshotContext(),
|
|
1358
1367
|
deliveryRequest,
|
|
1359
1368
|
signal,
|
|
1360
1369
|
});
|
|
@@ -1650,7 +1659,7 @@ const runScenario = async ({ scenario, environment = {}, globals = {}, runtimeAd
|
|
|
1650
1659
|
runId,
|
|
1651
1660
|
stepId,
|
|
1652
1661
|
node,
|
|
1653
|
-
context:
|
|
1662
|
+
context: snapshotContext(),
|
|
1654
1663
|
signal,
|
|
1655
1664
|
});
|
|
1656
1665
|
throwIfStopped(signal);
|
|
@@ -2642,7 +2651,7 @@ const runScenario = async ({ scenario, environment = {}, globals = {}, runtimeAd
|
|
|
2642
2651
|
durationMs: Date.now() - startedAtMs,
|
|
2643
2652
|
totalSteps: runtimeStepIds.length,
|
|
2644
2653
|
completedSteps: Array.from(localStatuses.values()).filter(isTerminalStatus).length,
|
|
2645
|
-
context:
|
|
2654
|
+
context: snapshotContext(),
|
|
2646
2655
|
workflowMeta: cloneWorkflowExecutionMeta(finalWorkflowMeta),
|
|
2647
2656
|
nodeExecutions: runtimeStepIds.map((stepId) => {
|
|
2648
2657
|
const descriptor = runtimeStepDescriptors.find((entry) => entry.stepId === stepId);
|