@opentap/runner-client 2.24.0 → 2.25.0-alpha.1.2.11236278236

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.
@@ -48,8 +48,8 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
48
48
  };
49
49
  Object.defineProperty(exports, "__esModule", { value: true });
50
50
  exports.BaseClient = void 0;
51
- var DTOs_1 = require("./DTOs");
52
51
  var nats_ws_1 = require("nats.ws");
52
+ var DTOs_1 = require("./DTOs");
53
53
  var events_1 = require("events");
54
54
  var uuid_1 = require("uuid");
55
55
  var DEFAULT_TIMEOUT = 40000; // default timeout of 40 seconds
@@ -278,21 +278,22 @@ var BaseClient = /** @class */ (function () {
278
278
  /**
279
279
  * Subscribes to given subject.
280
280
  * @param subject The subject to subscribe
281
- * @param options Subscription options
281
+ * @param jetStreamOptions Subscription options
282
282
  * @returns Subscription object
283
283
  */
284
- BaseClient.prototype.createJetStreamConsumer = function (stream, subject, options) {
284
+ BaseClient.prototype.createJetStreamConsumer = function (stream, subject, jetStreamOptions, consumerOptions) {
285
285
  var _this = this;
286
+ if (jetStreamOptions === void 0) { jetStreamOptions = {}; }
287
+ if (consumerOptions === void 0) { consumerOptions = {}; }
286
288
  if (!this.connection) {
287
289
  throw Error('Connection is not established');
288
290
  }
289
- return this.connection.jetstreamManager(__assign({}, options)).then(function (jetStreamManager) {
291
+ return this.connection.jetstreamManager(__assign({}, jetStreamOptions)).then(function (jetStreamManager) {
290
292
  return jetStreamManager.consumers
291
- .add(stream, {
292
- filter_subject: subject,
293
- ack_policy: nats_ws_1.AckPolicy.None,
294
- })
295
- .then(function (consumerInfo) { return _this.connection.jetstream(options).consumers.get(consumerInfo.stream_name, consumerInfo.name); });
293
+ .add(stream, __assign(__assign({}, consumerOptions), { filter_subject: subject, ack_policy: nats_ws_1.AckPolicy.None }))
294
+ .then(function (consumerInfo) {
295
+ return _this.connection.jetstream(jetStreamOptions).consumers.get(consumerInfo.stream_name, consumerInfo.name);
296
+ });
296
297
  });
297
298
  };
298
299
  BaseClient.prototype.encode = function (payload) {
@@ -25,11 +25,53 @@ var __assign = (this && this.__assign) || function () {
25
25
  };
26
26
  return __assign.apply(this, arguments);
27
27
  };
28
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
29
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
30
+ return new (P || (P = Promise))(function (resolve, reject) {
31
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
32
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
33
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
34
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
35
+ });
36
+ };
37
+ var __generator = (this && this.__generator) || function (thisArg, body) {
38
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
39
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
40
+ function verb(n) { return function (v) { return step([n, v]); }; }
41
+ function step(op) {
42
+ if (f) throw new TypeError("Generator is already executing.");
43
+ while (_) try {
44
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
45
+ if (y = 0, t) op = [op[0] & 2, t.value];
46
+ switch (op[0]) {
47
+ case 0: case 1: t = op; break;
48
+ case 4: _.label++; return { value: op[1], done: false };
49
+ case 5: _.label++; y = op[1]; op = [0]; continue;
50
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
51
+ default:
52
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
53
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
54
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
55
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
56
+ if (t[2]) _.ops.pop();
57
+ _.trys.pop(); continue;
58
+ }
59
+ op = body.call(thisArg, _);
60
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
61
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
62
+ }
63
+ };
64
+ var __asyncValues = (this && this.__asyncValues) || function (o) {
65
+ if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
66
+ var m = o[Symbol.asyncIterator], i;
67
+ return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
68
+ function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
69
+ function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
70
+ };
28
71
  Object.defineProperty(exports, "__esModule", { value: true });
29
72
  exports.SessionClient = void 0;
30
73
  var DTOs_1 = require("./DTOs");
31
74
  var nats_ws_1 = require("nats.ws");
32
- var encoders_1 = require("./encoders");
33
75
  var BaseClient_1 = require("./BaseClient");
34
76
  var utils_1 = require("./utils");
35
77
  var SessionClient = /** @class */ (function (_super) {
@@ -52,8 +94,8 @@ var SessionClient = /** @class */ (function (_super) {
52
94
  return;
53
95
  }
54
96
  try {
55
- var jsonCodec_1 = (0, nats_ws_1.JSONCodec)();
56
- var logListJson = jsonCodec_1.decode(encodedMessage === null || encodedMessage === void 0 ? void 0 : encodedMessage.data);
97
+ var jsonCodec = (0, nats_ws_1.JSONCodec)();
98
+ var logListJson = jsonCodec.decode(encodedMessage === null || encodedMessage === void 0 ? void 0 : encodedMessage.data);
57
99
  var logList = DTOs_1.LogList.fromJS(logListJson);
58
100
  sessionLogsHandler(logList, error);
59
101
  }
@@ -74,8 +116,8 @@ var SessionClient = /** @class */ (function (_super) {
74
116
  return;
75
117
  }
76
118
  try {
77
- var jsonCodec_2 = (0, nats_ws_1.JSONCodec)();
78
- var sessionEventJs = jsonCodec_2.decode(encodedMessage === null || encodedMessage === void 0 ? void 0 : encodedMessage.data);
119
+ var jsonCodec = (0, nats_ws_1.JSONCodec)();
120
+ var sessionEventJs = jsonCodec.decode(encodedMessage === null || encodedMessage === void 0 ? void 0 : encodedMessage.data);
79
121
  var sessionEvent = DTOs_1.SessionEvent.fromJS(sessionEventJs);
80
122
  eventHandler(sessionEvent, error);
81
123
  }
@@ -100,8 +142,8 @@ var SessionClient = /** @class */ (function (_super) {
100
142
  return;
101
143
  }
102
144
  try {
103
- var jsonCodec_3 = (0, nats_ws_1.JSONCodec)();
104
- var resultJs = jsonCodec_3.decode(encodedMessage === null || encodedMessage === void 0 ? void 0 : encodedMessage.data);
145
+ var jsonCodec = (0, nats_ws_1.JSONCodec)();
146
+ var resultJs = jsonCodec.decode(encodedMessage === null || encodedMessage === void 0 ? void 0 : encodedMessage.data);
105
147
  var result = DTOs_1.Result.fromJS(resultJs);
106
148
  resultHandler(result, error);
107
149
  }
@@ -115,8 +157,8 @@ var SessionClient = /** @class */ (function (_super) {
115
157
  return;
116
158
  }
117
159
  try {
118
- var jsonCodec_4 = (0, nats_ws_1.JSONCodec)();
119
- var testRunJs = jsonCodec_4.decode(encodedMessage === null || encodedMessage === void 0 ? void 0 : encodedMessage.data);
160
+ var jsonCodec = (0, nats_ws_1.JSONCodec)();
161
+ var testRunJs = jsonCodec.decode(encodedMessage === null || encodedMessage === void 0 ? void 0 : encodedMessage.data);
120
162
  var testRun = DTOs_1.TestRun.fromJS(testRunJs);
121
163
  testRunHandler(testRun, error);
122
164
  }
@@ -138,8 +180,8 @@ var SessionClient = /** @class */ (function (_super) {
138
180
  return;
139
181
  }
140
182
  try {
141
- var jsonCodec_5 = (0, nats_ws_1.JSONCodec)();
142
- var testRunJs = jsonCodec_5.decode(encodedMessage === null || encodedMessage === void 0 ? void 0 : encodedMessage.data);
183
+ var jsonCodec = (0, nats_ws_1.JSONCodec)();
184
+ var testRunJs = jsonCodec.decode(encodedMessage === null || encodedMessage === void 0 ? void 0 : encodedMessage.data);
143
185
  var testRun = DTOs_1.TestRun.fromJS(testRunJs);
144
186
  testRunHandler(testRun, error);
145
187
  }
@@ -162,8 +204,8 @@ var SessionClient = /** @class */ (function (_super) {
162
204
  return;
163
205
  }
164
206
  try {
165
- var jsonCodec_6 = (0, nats_ws_1.JSONCodec)();
166
- var onTestPlanRunJs = jsonCodec_6.decode(encodedMessage === null || encodedMessage === void 0 ? void 0 : encodedMessage.data);
207
+ var jsonCodec = (0, nats_ws_1.JSONCodec)();
208
+ var onTestPlanRunJs = jsonCodec.decode(encodedMessage === null || encodedMessage === void 0 ? void 0 : encodedMessage.data);
167
209
  var onTestPlanRun = DTOs_1.OnTestPlanRun.fromJS(onTestPlanRunJs);
168
210
  handler(onTestPlanRun, error);
169
211
  }
@@ -186,8 +228,8 @@ var SessionClient = /** @class */ (function (_super) {
186
228
  return;
187
229
  }
188
230
  try {
189
- var jsonCodec_7 = (0, nats_ws_1.JSONCodec)();
190
- var logListJson = jsonCodec_7.decode(encodedMessage === null || encodedMessage === void 0 ? void 0 : encodedMessage.data);
231
+ var jsonCodec = (0, nats_ws_1.JSONCodec)();
232
+ var logListJson = jsonCodec.decode(encodedMessage === null || encodedMessage === void 0 ? void 0 : encodedMessage.data);
191
233
  var logList = DTOs_1.LogList.fromJS(logListJson);
192
234
  handler(logList, error);
193
235
  }
@@ -210,8 +252,8 @@ var SessionClient = /** @class */ (function (_super) {
210
252
  return;
211
253
  }
212
254
  try {
213
- var jsonCodec_8 = (0, nats_ws_1.JSONCodec)();
214
- var parameterListJs = jsonCodec_8.decode(encodedMessage === null || encodedMessage === void 0 ? void 0 : encodedMessage.data);
255
+ var jsonCodec = (0, nats_ws_1.JSONCodec)();
256
+ var parameterListJs = jsonCodec.decode(encodedMessage === null || encodedMessage === void 0 ? void 0 : encodedMessage.data);
215
257
  var parameterList = parameterListJs.map(function (parameterJs) { return DTOs_1.Parameter.fromJS(parameterJs); });
216
258
  handler(parameterList, error);
217
259
  }
@@ -236,8 +278,8 @@ var SessionClient = /** @class */ (function (_super) {
236
278
  return;
237
279
  }
238
280
  try {
239
- var jsonCodec_9 = (0, nats_ws_1.JSONCodec)();
240
- var onTestStepRunJs = jsonCodec_9.decode(encodedMessage === null || encodedMessage === void 0 ? void 0 : encodedMessage.data);
281
+ var jsonCodec = (0, nats_ws_1.JSONCodec)();
282
+ var onTestStepRunJs = jsonCodec.decode(encodedMessage === null || encodedMessage === void 0 ? void 0 : encodedMessage.data);
241
283
  var onTestStepRun = DTOs_1.OnTestStepRun.fromJS(onTestStepRunJs);
242
284
  var stepRunId = (_a = encodedMessage.subject.match(/\.StepRun\.(.+)$/)) === null || _a === void 0 ? void 0 : _a[1];
243
285
  handler(stepRunId, onTestStepRun, error);
@@ -262,8 +304,8 @@ var SessionClient = /** @class */ (function (_super) {
262
304
  return;
263
305
  }
264
306
  try {
265
- var jsonCodec_10 = (0, nats_ws_1.JSONCodec)();
266
- var parameterListJs = jsonCodec_10.decode(encodedMessage === null || encodedMessage === void 0 ? void 0 : encodedMessage.data);
307
+ var jsonCodec = (0, nats_ws_1.JSONCodec)();
308
+ var parameterListJs = jsonCodec.decode(encodedMessage === null || encodedMessage === void 0 ? void 0 : encodedMessage.data);
267
309
  var parameterList = parameterListJs.map(function (parameterJs) { return DTOs_1.Parameter.fromJS(parameterJs); });
268
310
  handler(parameterList, error);
269
311
  }
@@ -288,8 +330,8 @@ var SessionClient = /** @class */ (function (_super) {
288
330
  return;
289
331
  }
290
332
  try {
291
- var jsonCodec_11 = (0, nats_ws_1.JSONCodec)();
292
- var resultJs = jsonCodec_11.decode(encodedMessage === null || encodedMessage === void 0 ? void 0 : encodedMessage.data);
333
+ var jsonCodec = (0, nats_ws_1.JSONCodec)();
334
+ var resultJs = jsonCodec.decode(encodedMessage === null || encodedMessage === void 0 ? void 0 : encodedMessage.data);
293
335
  var result = DTOs_1.Result.fromJS(resultJs);
294
336
  handler(result, error);
295
337
  }
@@ -305,44 +347,90 @@ var SessionClient = /** @class */ (function (_super) {
305
347
  * @param {SubscriptionOptions} options?
306
348
  * @returns Subscription
307
349
  */
308
- SessionClient.prototype.connectMetric = function (metricInfo, handler, sessionId) {
309
- var baseSubject = sessionId
310
- ? this.baseSubject
311
- .split('.')
312
- .map(function (part, index) { return (index === 4 ? sessionId : part); })
313
- .join('.')
314
- : this.baseSubject;
315
- return this.createJetStreamConsumer('Metrics', "".concat(baseSubject, ".Events.Metrics.").concat(metricInfo.subjectPostfix), {
350
+ SessionClient.prototype.connectMetric = function (metricInfo, inactiveThresholdMilliseconds, maxBatchSize, handler) {
351
+ var _this = this;
352
+ return this.createJetStreamConsumer('Metrics', "M.".concat(metricInfo.subjectPostfix), {
316
353
  domain: this.runnerId,
317
- }).then(function (consumer) {
318
- consumer === null || consumer === void 0 ? void 0 : consumer.consume({
319
- callback: function (encodedMessage) {
320
- var _a, _b;
321
- try {
322
- var time = Number.parseInt((_b = (_a = encodedMessage.headers) === null || _a === void 0 ? void 0 : _a.get('timestamp')) !== null && _b !== void 0 ? _b : '');
323
- var value = void 0;
324
- // Decode the value based on the metric value type given in the metric info
325
- switch (metricInfo.type) {
326
- case DTOs_1.SessionMetricType.Boolean:
327
- value = encoders_1.booleanCodec.decode(encodedMessage.data);
328
- break;
329
- case DTOs_1.SessionMetricType.Double:
330
- value = encoders_1.numberCodec.decode(encodedMessage.data);
331
- break;
332
- case DTOs_1.SessionMetricType.String:
333
- value = encoders_1.stringCodec.decode(encodedMessage.data);
334
- break;
335
- default:
336
- value = encoders_1.jsonCodec.decode(encodedMessage.data);
337
- break;
338
- }
339
- handler(new DTOs_1.MetricValue({ value: value, time: time }), null);
340
- }
341
- catch (error) {
342
- handler(undefined, error);
354
+ }, { inactive_threshold: (0, nats_ws_1.nanos)(inactiveThresholdMilliseconds) }).then(function (consumer) {
355
+ // Async function here so the loop starts without blocking returning a consumer
356
+ (function () { return __awaiter(_this, void 0, void 0, function () {
357
+ var _loop_1;
358
+ var _this = this;
359
+ var e_1, _a;
360
+ return __generator(this, function (_b) {
361
+ switch (_b.label) {
362
+ case 0:
363
+ _loop_1 = function () {
364
+ var consumerInfo, arraySize, metricData, messages, index, messages_1, messages_1_1, message, e_1_1;
365
+ return __generator(this, function (_c) {
366
+ switch (_c.label) {
367
+ case 0: return [4 /*yield*/, consumer.info()];
368
+ case 1:
369
+ consumerInfo = _c.sent();
370
+ arraySize = Math.min(maxBatchSize, consumerInfo.num_pending);
371
+ metricData = {
372
+ encodedMetrics: new Array(arraySize),
373
+ timestamps: new Array(arraySize),
374
+ };
375
+ return [4 /*yield*/, consumer.fetch({ max_messages: arraySize })];
376
+ case 2:
377
+ messages = _c.sent();
378
+ index = 0;
379
+ _c.label = 3;
380
+ case 3:
381
+ _c.trys.push([3, 8, 9, 14]);
382
+ messages_1 = (e_1 = void 0, __asyncValues(messages));
383
+ _c.label = 4;
384
+ case 4: return [4 /*yield*/, messages_1.next()];
385
+ case 5:
386
+ if (!(messages_1_1 = _c.sent(), !messages_1_1.done)) return [3 /*break*/, 7];
387
+ message = messages_1_1.value;
388
+ // Store the message data and timestamp
389
+ metricData.encodedMetrics[index] = message.data;
390
+ metricData.timestamps[index] = message.info.timestampNanos;
391
+ // If we are at the last message or there are no more pending messages, call the handler
392
+ if (index === arraySize - 1 || message.info.pending === 0) {
393
+ (function () { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) {
394
+ return [2 /*return*/, handler(metricData)];
395
+ }); }); })();
396
+ return [3 /*break*/, 7];
397
+ }
398
+ // Increment the index
399
+ index++;
400
+ _c.label = 6;
401
+ case 6: return [3 /*break*/, 4];
402
+ case 7: return [3 /*break*/, 14];
403
+ case 8:
404
+ e_1_1 = _c.sent();
405
+ e_1 = { error: e_1_1 };
406
+ return [3 /*break*/, 14];
407
+ case 9:
408
+ _c.trys.push([9, , 12, 13]);
409
+ if (!(messages_1_1 && !messages_1_1.done && (_a = messages_1.return))) return [3 /*break*/, 11];
410
+ return [4 /*yield*/, _a.call(messages_1)];
411
+ case 10:
412
+ _c.sent();
413
+ _c.label = 11;
414
+ case 11: return [3 /*break*/, 13];
415
+ case 12:
416
+ if (e_1) throw e_1.error;
417
+ return [7 /*endfinally*/];
418
+ case 13: return [7 /*endfinally*/];
419
+ case 14: return [2 /*return*/];
420
+ }
421
+ });
422
+ };
423
+ _b.label = 1;
424
+ case 1:
425
+ if (!true) return [3 /*break*/, 3];
426
+ return [5 /*yield**/, _loop_1()];
427
+ case 2:
428
+ _b.sent();
429
+ return [3 /*break*/, 1];
430
+ case 3: return [2 /*return*/];
343
431
  }
344
- },
345
- });
432
+ });
433
+ }); })();
346
434
  return consumer;
347
435
  });
348
436
  };
package/dist/cjs/index.js CHANGED
@@ -14,7 +14,12 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.SystemClient = exports.SessionClient = exports.RunnerClient = void 0;
17
+ exports.SystemClient = exports.SessionClient = exports.RunnerClient = exports.stringCodec = exports.numberCodec = exports.jsonCodec = exports.booleanCodec = void 0;
18
+ var encoders_1 = require("./encoders");
19
+ Object.defineProperty(exports, "booleanCodec", { enumerable: true, get: function () { return encoders_1.booleanCodec; } });
20
+ Object.defineProperty(exports, "jsonCodec", { enumerable: true, get: function () { return encoders_1.jsonCodec; } });
21
+ Object.defineProperty(exports, "numberCodec", { enumerable: true, get: function () { return encoders_1.numberCodec; } });
22
+ Object.defineProperty(exports, "stringCodec", { enumerable: true, get: function () { return encoders_1.stringCodec; } });
18
23
  var RunnerClient_1 = require("./RunnerClient");
19
24
  Object.defineProperty(exports, "RunnerClient", { enumerable: true, get: function () { return RunnerClient_1.RunnerClient; } });
20
25
  var SessionClient_1 = require("./SessionClient");
@@ -1,6 +1,6 @@
1
+ import { ConnectionOptions, Consumer, ConsumerConfig, JetStreamOptions, NatsError, PublishOptions, Subscription, SubscriptionOptions } from 'nats.ws';
1
2
  import { DownloadTapSettingsRequest } from './requestDTOs';
2
3
  import { ComponentSettingsBase, ComponentSettingsIdentifier, ComponentSettingsListItem, DataGridControl, ErrorResponse, FileParameter, ListItemType, ProfileGroup, RepositoryPackageReference, RepositorySettingsPackageDefinition } from './DTOs';
3
- import { ConnectionOptions, NatsError, Subscription, SubscriptionOptions, PublishOptions, JetStreamOptions, Consumer } from 'nats.ws';
4
4
  interface BaseClientRequestOptions {
5
5
  publishOptions?: PublishOptions;
6
6
  rawResponse?: boolean;
@@ -64,10 +64,10 @@ export declare class BaseClient {
64
64
  /**
65
65
  * Subscribes to given subject.
66
66
  * @param subject The subject to subscribe
67
- * @param options Subscription options
67
+ * @param jetStreamOptions Subscription options
68
68
  * @returns Subscription object
69
69
  */
70
- protected createJetStreamConsumer(stream: string, subject: string, options: JetStreamOptions): Promise<Consumer>;
70
+ protected createJetStreamConsumer(stream: string, subject: string, jetStreamOptions?: Partial<JetStreamOptions>, consumerOptions?: Partial<ConsumerConfig>): Promise<Consumer>;
71
71
  protected encode(payload: any): Uint8Array;
72
72
  /**
73
73
  * Create a connection to the nats server.
@@ -7,8 +7,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
+ import { AckPolicy, Empty, ErrorCode, JSONCodec, StringCodec, connect, headers, } from 'nats.ws';
10
11
  import { ComponentSettingsBase, ComponentSettingsIdentifier, ComponentSettingsListItem, DataGridControl, ErrorResponse, FileDescriptor, ListItemType, ProfileGroup, } from './DTOs';
11
- import { Empty, ErrorCode, JSONCodec, StringCodec, connect, headers, AckPolicy, } from 'nats.ws';
12
12
  import { EventEmitter } from 'events';
13
13
  import { v4 as uuidv4 } from 'uuid';
14
14
  const DEFAULT_TIMEOUT = 40000; // default timeout of 40 seconds
@@ -232,19 +232,16 @@ export class BaseClient {
232
232
  /**
233
233
  * Subscribes to given subject.
234
234
  * @param subject The subject to subscribe
235
- * @param options Subscription options
235
+ * @param jetStreamOptions Subscription options
236
236
  * @returns Subscription object
237
237
  */
238
- createJetStreamConsumer(stream, subject, options) {
238
+ createJetStreamConsumer(stream, subject, jetStreamOptions = {}, consumerOptions = {}) {
239
239
  if (!this.connection) {
240
240
  throw Error('Connection is not established');
241
241
  }
242
- return this.connection.jetstreamManager(Object.assign({}, options)).then(jetStreamManager => jetStreamManager.consumers
243
- .add(stream, {
244
- filter_subject: subject,
245
- ack_policy: AckPolicy.None,
246
- })
247
- .then(consumerInfo => this.connection.jetstream(options).consumers.get(consumerInfo.stream_name, consumerInfo.name)));
242
+ return this.connection.jetstreamManager(Object.assign({}, jetStreamOptions)).then(jetStreamManager => jetStreamManager.consumers
243
+ .add(stream, Object.assign(Object.assign({}, consumerOptions), { filter_subject: subject, ack_policy: AckPolicy.None }))
244
+ .then(consumerInfo => this.connection.jetstream(jetStreamOptions).consumers.get(consumerInfo.stream_name, consumerInfo.name)));
248
245
  }
249
246
  encode(payload) {
250
247
  if (!payload) {
@@ -1,4 +1,4 @@
1
- import { BreakPoints, CommonContext, CommonSettings, DataGridControl, IMetricValue, IMetricsConfiguration, ISessionMetricInfo, Image, Interaction, ListItemType, LogList, MetricsConfiguration, OnTestPlanRun, OnTestStepRun, Parameter, RepositoryPackageDefinition, RepositoryPackageReference, Resource, Result, RunStatus, SessionEvent, Setting, TestPlan, TestRun, TestStepType, TestStepValidationError, WatchDog } from './DTOs';
1
+ import { BreakPoints, CommonContext, CommonSettings, DataGridControl, IMetricsConfiguration, ISessionMetricInfo, Image, Interaction, ListItemType, LogList, MetricsConfiguration, OnTestPlanRun, OnTestStepRun, Parameter, RepositoryPackageDefinition, RepositoryPackageReference, Resource, Result, RunStatus, SessionEvent, Setting, TestPlan, TestRun, TestStepType, TestStepValidationError, WatchDog } from './DTOs';
2
2
  import { ConnectionOptions, Consumer, NatsError, Subscription, SubscriptionOptions } from 'nats.ws';
3
3
  import { BaseClient } from './BaseClient';
4
4
  export declare class SessionClient extends BaseClient {
@@ -89,7 +89,10 @@ export declare class SessionClient extends BaseClient {
89
89
  * @param {SubscriptionOptions} options?
90
90
  * @returns Subscription
91
91
  */
92
- connectMetric(metricInfo: ISessionMetricInfo, handler: (result: IMetricValue | undefined, err: NatsError | Error | null) => void, sessionId?: string): Promise<Consumer>;
92
+ connectMetric(metricInfo: ISessionMetricInfo, inactiveThresholdMilliseconds: number, maxBatchSize: number, handler: (metricData: {
93
+ encodedMetrics: Uint8Array[];
94
+ timestamps: number[];
95
+ }) => void): Promise<Consumer>;
93
96
  /**
94
97
  * Unsubscibe from session events
95
98
  */
@@ -1,6 +1,21 @@
1
- import { BreakPoints, CommonContext, CommonSettings, DataGridControl, Image, Interaction, ListItemType, LogList, MetricValue, MetricsConfiguration, OnTestPlanRun, OnTestStepRun, Parameter, Result, RunStatus, SessionEvent, SessionMetricType, Setting, TestPlan, TestRun, TestStepType, TestStepValidationError, WatchDog, } from './DTOs';
2
- import { JSONCodec } from 'nats.ws';
3
- import { booleanCodec, jsonCodec, numberCodec, stringCodec } from './encoders';
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ var __asyncValues = (this && this.__asyncValues) || function (o) {
11
+ if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
12
+ var m = o[Symbol.asyncIterator], i;
13
+ return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
14
+ function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
15
+ function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
16
+ };
17
+ import { BreakPoints, CommonContext, CommonSettings, DataGridControl, Image, Interaction, ListItemType, LogList, MetricsConfiguration, OnTestPlanRun, OnTestStepRun, Parameter, Result, RunStatus, SessionEvent, Setting, TestPlan, TestRun, TestStepType, TestStepValidationError, WatchDog, } from './DTOs';
18
+ import { JSONCodec, nanos } from 'nats.ws';
4
19
  import { BaseClient } from './BaseClient';
5
20
  import { getSubjectParts } from './utils';
6
21
  export class SessionClient extends BaseClient {
@@ -274,44 +289,52 @@ export class SessionClient extends BaseClient {
274
289
  * @param {SubscriptionOptions} options?
275
290
  * @returns Subscription
276
291
  */
277
- connectMetric(metricInfo, handler, sessionId) {
278
- const baseSubject = sessionId
279
- ? this.baseSubject
280
- .split('.')
281
- .map((part, index) => (index === 4 ? sessionId : part))
282
- .join('.')
283
- : this.baseSubject;
284
- return this.createJetStreamConsumer('Metrics', `${baseSubject}.Events.Metrics.${metricInfo.subjectPostfix}`, {
292
+ connectMetric(metricInfo, inactiveThresholdMilliseconds, maxBatchSize, handler) {
293
+ return this.createJetStreamConsumer('Metrics', `M.${metricInfo.subjectPostfix}`, {
285
294
  domain: this.runnerId,
286
- }).then(consumer => {
287
- consumer === null || consumer === void 0 ? void 0 : consumer.consume({
288
- callback(encodedMessage) {
289
- var _a, _b;
295
+ }, { inactive_threshold: nanos(inactiveThresholdMilliseconds) }).then(consumer => {
296
+ // Async function here so the loop starts without blocking returning a consumer
297
+ (() => __awaiter(this, void 0, void 0, function* () {
298
+ var e_1, _a;
299
+ // eslint-disable-next-line no-constant-condition
300
+ while (true) {
301
+ // Get the consumer info to determine the number of pending messages
302
+ const consumerInfo = yield consumer.info();
303
+ // We want to define the batch size based on how many message we will consume in the next fetch
304
+ const arraySize = Math.min(maxBatchSize, consumerInfo.num_pending);
305
+ // Create the object with preallocated arrays for better performance
306
+ const metricData = {
307
+ encodedMetrics: new Array(arraySize),
308
+ timestamps: new Array(arraySize),
309
+ };
310
+ // Fetch the messages
311
+ const messages = yield consumer.fetch({ max_messages: arraySize });
312
+ // for await of doesn't return the index, so we need to keep track of it
313
+ let index = 0;
290
314
  try {
291
- const time = Number.parseInt((_b = (_a = encodedMessage.headers) === null || _a === void 0 ? void 0 : _a.get('timestamp')) !== null && _b !== void 0 ? _b : '');
292
- let value;
293
- // Decode the value based on the metric value type given in the metric info
294
- switch (metricInfo.type) {
295
- case SessionMetricType.Boolean:
296
- value = booleanCodec.decode(encodedMessage.data);
297
- break;
298
- case SessionMetricType.Double:
299
- value = numberCodec.decode(encodedMessage.data);
300
- break;
301
- case SessionMetricType.String:
302
- value = stringCodec.decode(encodedMessage.data);
303
- break;
304
- default:
305
- value = jsonCodec.decode(encodedMessage.data);
315
+ for (var messages_1 = (e_1 = void 0, __asyncValues(messages)), messages_1_1; messages_1_1 = yield messages_1.next(), !messages_1_1.done;) {
316
+ const message = messages_1_1.value;
317
+ // Store the message data and timestamp
318
+ metricData.encodedMetrics[index] = message.data;
319
+ metricData.timestamps[index] = message.info.timestampNanos;
320
+ // If we are at the last message or there are no more pending messages, call the handler
321
+ if (index === arraySize - 1 || message.info.pending === 0) {
322
+ (() => __awaiter(this, void 0, void 0, function* () { return handler(metricData); }))();
306
323
  break;
324
+ }
325
+ // Increment the index
326
+ index++;
307
327
  }
308
- handler(new MetricValue({ value, time }), null);
309
328
  }
310
- catch (error) {
311
- handler(undefined, error);
329
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
330
+ finally {
331
+ try {
332
+ if (messages_1_1 && !messages_1_1.done && (_a = messages_1.return)) yield _a.call(messages_1);
333
+ }
334
+ finally { if (e_1) throw e_1.error; }
312
335
  }
313
- },
314
- });
336
+ }
337
+ }))();
315
338
  return consumer;
316
339
  });
317
340
  }
@@ -1,3 +1,4 @@
1
+ export { booleanCodec, jsonCodec, numberCodec, stringCodec } from './encoders';
1
2
  export { RunnerClient } from './RunnerClient';
2
3
  export { SessionClient } from './SessionClient';
3
4
  export { SystemClient, RunnerLifetimeEvent } from './SystemClient';
package/dist/mjs/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ export { booleanCodec, jsonCodec, numberCodec, stringCodec } from './encoders';
1
2
  export { RunnerClient } from './RunnerClient';
2
3
  export { SessionClient } from './SessionClient';
3
4
  export { SystemClient } from './SystemClient';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opentap/runner-client",
3
- "version": "2.24.0",
3
+ "version": "2.25.0-alpha.1.2.11236278236",
4
4
  "description": "This is the web client for the OpenTAP Runner.",
5
5
  "main": "./dist/cjs/index.js",
6
6
  "module": "./dist/mjs/index.js",