@opentap/runner-client 2.25.0-alpha.1.1.11217168217 → 2.25.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.
@@ -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) {
@@ -61,6 +61,13 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
61
61
  if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
62
62
  }
63
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
+ };
64
71
  Object.defineProperty(exports, "__esModule", { value: true });
65
72
  exports.SessionClient = void 0;
66
73
  var DTOs_1 = require("./DTOs");
@@ -340,18 +347,90 @@ var SessionClient = /** @class */ (function (_super) {
340
347
  * @param {SubscriptionOptions} options?
341
348
  * @returns Subscription
342
349
  */
343
- SessionClient.prototype.connectMetric = function (metricInfo, handler) {
350
+ SessionClient.prototype.connectMetric = function (metricInfo, inactiveThresholdMilliseconds, maxBatchSize, handler) {
351
+ var _this = this;
344
352
  return this.createJetStreamConsumer('Metrics', "M.".concat(metricInfo.subjectPostfix), {
345
353
  domain: this.runnerId,
346
- }).then(function (consumer) {
347
- consumer.consume({
348
- callback: function (encodedMessage) {
349
- var _this = this;
350
- (function () { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) {
351
- return [2 /*return*/, handler(encodedMessage, metricInfo.type)];
352
- }); }); })();
353
- },
354
- });
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*/];
431
+ }
432
+ });
433
+ }); })();
355
434
  return consumer;
356
435
  });
357
436
  };
@@ -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,5 +1,5 @@
1
- import { BreakPoints, CommonContext, CommonSettings, DataGridControl, IMetricsConfiguration, ISessionMetricInfo, Image, Interaction, ListItemType, LogList, MetricsConfiguration, OnTestPlanRun, OnTestStepRun, Parameter, RepositoryPackageDefinition, RepositoryPackageReference, Resource, Result, RunStatus, SessionEvent, SessionMetricType, Setting, TestPlan, TestRun, TestStepType, TestStepValidationError, WatchDog } from './DTOs';
2
- import { ConnectionOptions, Consumer, JsMsg, NatsError, Subscription, SubscriptionOptions } from 'nats.ws';
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
+ import { ConnectionOptions, Consumer, NatsError, Subscription, SubscriptionOptions } from 'nats.ws';
3
3
  import { BaseClient } from './BaseClient';
4
4
  export declare class SessionClient extends BaseClient {
5
5
  private subscriptions;
@@ -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: JsMsg | undefined, type: SessionMetricType) => void): 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
  */
@@ -7,8 +7,15 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
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
+ };
10
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';
11
- import { JSONCodec } from 'nats.ws';
18
+ import { JSONCodec, nanos } from 'nats.ws';
12
19
  import { BaseClient } from './BaseClient';
13
20
  import { getSubjectParts } from './utils';
14
21
  export class SessionClient extends BaseClient {
@@ -282,15 +289,52 @@ export class SessionClient extends BaseClient {
282
289
  * @param {SubscriptionOptions} options?
283
290
  * @returns Subscription
284
291
  */
285
- connectMetric(metricInfo, handler) {
292
+ connectMetric(metricInfo, inactiveThresholdMilliseconds, maxBatchSize, handler) {
286
293
  return this.createJetStreamConsumer('Metrics', `M.${metricInfo.subjectPostfix}`, {
287
294
  domain: this.runnerId,
288
- }).then(consumer => {
289
- consumer.consume({
290
- callback(encodedMessage) {
291
- (() => __awaiter(this, void 0, void 0, function* () { return handler(encodedMessage, metricInfo.type); }))();
292
- },
293
- });
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;
314
+ try {
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); }))();
323
+ break;
324
+ }
325
+ // Increment the index
326
+ index++;
327
+ }
328
+ }
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; }
335
+ }
336
+ }
337
+ }))();
294
338
  return consumer;
295
339
  });
296
340
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opentap/runner-client",
3
- "version": "2.25.0-alpha.1.1.11217168217",
3
+ "version": "2.25.0",
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",