@opentap/runner-client 4.2.0 → 4.4.0-beta.1.34231471562
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/cjs/BaseClient.d.ts +6 -10
- package/dist/cjs/BaseClient.js +104 -51
- package/dist/cjs/DTOs.d.ts +20 -2
- package/dist/cjs/DTOs.js +58 -1
- package/dist/cjs/RunnerClient.d.ts +6 -0
- package/dist/cjs/RunnerClient.js +10 -0
- package/dist/cjs/SessionClient.js +2 -0
- package/dist/mjs/BaseClient.d.ts +6 -10
- package/dist/mjs/BaseClient.js +98 -51
- package/dist/mjs/DTOs.d.ts +20 -2
- package/dist/mjs/DTOs.js +49 -0
- package/dist/mjs/RunnerClient.d.ts +6 -0
- package/dist/mjs/RunnerClient.js +10 -0
- package/dist/mjs/SessionClient.js +3 -1
- package/package.json +1 -1
package/dist/cjs/BaseClient.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ConnectionOptions, Consumer, ConsumerConfig, JetStreamOptions, NatsError, PublishOptions, Subscription, SubscriptionOptions } from 'nats.ws';
|
|
1
|
+
import { ConnectionOptions, Consumer, ConsumerConfig, JetStreamOptions, NatsConnection, NatsError, PublishOptions, Subscription, SubscriptionOptions } from 'nats.ws';
|
|
2
2
|
import { DownloadTapSettingsRequest } from './requestDTOs';
|
|
3
3
|
import { ComponentSettingsBase, ComponentSettingsIdentifier, ComponentSettingsListItem, DataGridControl, ErrorResponse, FileParameter, ListItemType, ProfileGroup, RepositoryPackageReference, RepositorySettingsPackageDefinition } from './DTOs';
|
|
4
4
|
interface BaseClientRequestOptions {
|
|
@@ -12,28 +12,23 @@ interface BaseClientRequestOptions {
|
|
|
12
12
|
}
|
|
13
13
|
export declare class BaseClient {
|
|
14
14
|
readonly baseSubject: string;
|
|
15
|
-
private
|
|
15
|
+
private natsConnection;
|
|
16
16
|
private connectionOptions;
|
|
17
17
|
private domainAccess;
|
|
18
18
|
private eventEmitter;
|
|
19
19
|
private _accessToken;
|
|
20
20
|
private _headers;
|
|
21
21
|
private _timeout;
|
|
22
|
-
|
|
22
|
+
get connection(): NatsConnection | null;
|
|
23
23
|
get accessToken(): string;
|
|
24
|
-
/** Set request access token */
|
|
25
24
|
set accessToken(value: string);
|
|
26
|
-
/** Get request headers */
|
|
27
25
|
get headers(): {
|
|
28
26
|
[key: string]: string;
|
|
29
27
|
};
|
|
30
|
-
/** Set request headers */
|
|
31
28
|
set headers(value: {
|
|
32
29
|
[key: string]: string;
|
|
33
30
|
});
|
|
34
|
-
/** Get timeout */
|
|
35
31
|
get timeout(): number;
|
|
36
|
-
/** Set timeout in milliseconds. Default is 40000 milliseconds */
|
|
37
32
|
set timeout(value: number);
|
|
38
33
|
constructor(baseSubject: string, options: ConnectionOptions);
|
|
39
34
|
private withTimeout;
|
|
@@ -44,7 +39,7 @@ export declare class BaseClient {
|
|
|
44
39
|
* @param options (optional)
|
|
45
40
|
* @returns Promise of an object
|
|
46
41
|
*/
|
|
47
|
-
|
|
42
|
+
request<T>(subject: string, payload?: any, options?: BaseClientRequestOptions): Promise<T>;
|
|
48
43
|
/**
|
|
49
44
|
* Handle the error
|
|
50
45
|
* @param error
|
|
@@ -78,7 +73,7 @@ export declare class BaseClient {
|
|
|
78
73
|
* Create a connection to the nats server.
|
|
79
74
|
* @param {ConnectionOptions} options
|
|
80
75
|
*/
|
|
81
|
-
connect(): Promise<void>;
|
|
76
|
+
connect(connection?: NatsConnection): Promise<void>;
|
|
82
77
|
/**
|
|
83
78
|
* Close the connection.
|
|
84
79
|
*/
|
|
@@ -258,6 +253,7 @@ export declare class BaseClient {
|
|
|
258
253
|
* Dispatches a request with the given subject and returns a Promise of type T
|
|
259
254
|
* @param subject The subject to send the request to
|
|
260
255
|
* @returns Promise<T> The response from the request
|
|
256
|
+
* @deprecated Use {@link request} instead.
|
|
261
257
|
*/
|
|
262
258
|
dispatchRequest<T>(subject: string, payload?: any, options?: BaseClientRequestOptions): Promise<T>;
|
|
263
259
|
}
|
package/dist/cjs/BaseClient.js
CHANGED
|
@@ -52,6 +52,28 @@ var nats_ws_1 = require("nats.ws");
|
|
|
52
52
|
var DTOs_1 = require("./DTOs");
|
|
53
53
|
var events_1 = require("events");
|
|
54
54
|
var uuid_1 = require("uuid");
|
|
55
|
+
// A browser extension like CrowdStrike may have already replaced globalThis.WebSocket before this module loads,
|
|
56
|
+
// so reading the global is unreliable. A freshly created same-origin iframe exposes the browser's
|
|
57
|
+
// pristine, un-patched WebSocket; NATS traffic is pinned to it to bypass any extension shim.
|
|
58
|
+
// The iframe is kept attached because a detached iframe's realm becomes unusable in some browsers.
|
|
59
|
+
function getNativeWebSocket() {
|
|
60
|
+
var _a, _b, _c;
|
|
61
|
+
var globalWebSocket = typeof globalThis !== 'undefined' ? globalThis.WebSocket : undefined;
|
|
62
|
+
var doc = globalThis.document;
|
|
63
|
+
if (!doc || typeof doc.createElement !== 'function') {
|
|
64
|
+
return globalWebSocket;
|
|
65
|
+
}
|
|
66
|
+
try {
|
|
67
|
+
var iframe = doc.createElement('iframe');
|
|
68
|
+
iframe.style.display = 'none';
|
|
69
|
+
((_a = doc.body) !== null && _a !== void 0 ? _a : doc.documentElement).appendChild(iframe);
|
|
70
|
+
return (_c = (_b = iframe.contentWindow) === null || _b === void 0 ? void 0 : _b.WebSocket) !== null && _c !== void 0 ? _c : globalWebSocket;
|
|
71
|
+
}
|
|
72
|
+
catch (_d) {
|
|
73
|
+
return globalWebSocket;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
var OriginalWebSocket = getNativeWebSocket();
|
|
55
77
|
var DEFAULT_TIMEOUT = 40000; // default timeout of 40 seconds
|
|
56
78
|
var Events;
|
|
57
79
|
(function (Events) {
|
|
@@ -64,14 +86,28 @@ var BaseClient = /** @class */ (function () {
|
|
|
64
86
|
this.baseSubject = baseSubject;
|
|
65
87
|
this.connectionOptions = __assign({}, options);
|
|
66
88
|
this.connectionOptions.timeout = (options === null || options === void 0 ? void 0 : options.timeout) || DEFAULT_TIMEOUT;
|
|
89
|
+
// Force NATS to use the WebSocket captured at load time so an extension that later
|
|
90
|
+
// overrides globalThis.WebSocket cannot intercept NATS traffic. Respect a caller-provided factory.
|
|
91
|
+
// wsFactory is read by nats.ws's WsTransport at runtime but lives on WsConnectionOptions, which
|
|
92
|
+
// isn't re-exported, so it's absent from the public ConnectionOptions type and requires this cast.
|
|
93
|
+
if (OriginalWebSocket && !this.connectionOptions.wsFactory) {
|
|
94
|
+
this.connectionOptions.wsFactory = function (url) {
|
|
95
|
+
return Promise.resolve({ socket: new OriginalWebSocket(url), encrypted: url.indexOf('wss://') === 0 });
|
|
96
|
+
};
|
|
97
|
+
}
|
|
67
98
|
this.eventEmitter = new events_1.EventEmitter();
|
|
68
99
|
}
|
|
100
|
+
Object.defineProperty(BaseClient.prototype, "connection", {
|
|
101
|
+
get: function () {
|
|
102
|
+
return this.natsConnection;
|
|
103
|
+
},
|
|
104
|
+
enumerable: false,
|
|
105
|
+
configurable: true
|
|
106
|
+
});
|
|
69
107
|
Object.defineProperty(BaseClient.prototype, "accessToken", {
|
|
70
|
-
/** Get request access token */
|
|
71
108
|
get: function () {
|
|
72
109
|
return this._accessToken;
|
|
73
110
|
},
|
|
74
|
-
/** Set request access token */
|
|
75
111
|
set: function (value) {
|
|
76
112
|
this._accessToken = value;
|
|
77
113
|
},
|
|
@@ -79,11 +115,9 @@ var BaseClient = /** @class */ (function () {
|
|
|
79
115
|
configurable: true
|
|
80
116
|
});
|
|
81
117
|
Object.defineProperty(BaseClient.prototype, "headers", {
|
|
82
|
-
/** Get request headers */
|
|
83
118
|
get: function () {
|
|
84
119
|
return this._headers;
|
|
85
120
|
},
|
|
86
|
-
/** Set request headers */
|
|
87
121
|
set: function (value) {
|
|
88
122
|
this._headers = value;
|
|
89
123
|
},
|
|
@@ -91,11 +125,9 @@ var BaseClient = /** @class */ (function () {
|
|
|
91
125
|
configurable: true
|
|
92
126
|
});
|
|
93
127
|
Object.defineProperty(BaseClient.prototype, "timeout", {
|
|
94
|
-
/** Get timeout */
|
|
95
128
|
get: function () {
|
|
96
129
|
return this._timeout || DEFAULT_TIMEOUT;
|
|
97
130
|
},
|
|
98
|
-
/** Set timeout in milliseconds. Default is 40000 milliseconds */
|
|
99
131
|
set: function (value) {
|
|
100
132
|
this._timeout = value;
|
|
101
133
|
},
|
|
@@ -127,9 +159,9 @@ var BaseClient = /** @class */ (function () {
|
|
|
127
159
|
if (!(options === null || options === void 0 ? void 0 : options.fullSubject)) {
|
|
128
160
|
subject = "".concat(this.baseSubject, ".Request.").concat(subject);
|
|
129
161
|
}
|
|
130
|
-
if (!this.
|
|
162
|
+
if (!this.natsConnection)
|
|
131
163
|
return [2 /*return*/, Promise.reject("".concat(subject, ": Connection is down! Please try again!"))];
|
|
132
|
-
if (this.
|
|
164
|
+
if (this.natsConnection.isClosed())
|
|
133
165
|
return [2 /*return*/, Promise.reject("".concat(subject, ": Connection has been closed! Please reconnect!"))];
|
|
134
166
|
data = this.encode(payload);
|
|
135
167
|
headers = this.buildHeaders();
|
|
@@ -141,7 +173,7 @@ var BaseClient = /** @class */ (function () {
|
|
|
141
173
|
}
|
|
142
174
|
timeout = (options === null || options === void 0 ? void 0 : options.timeout) || this.timeout;
|
|
143
175
|
replySubject = (_b = (_a = options === null || options === void 0 ? void 0 : options.publishOptions) === null || _a === void 0 ? void 0 : _a.reply) !== null && _b !== void 0 ? _b : "".concat(subject, ".Reply.").concat((0, uuid_1.v4)());
|
|
144
|
-
serverMaxPayload = (_d = (_c = this.
|
|
176
|
+
serverMaxPayload = (_d = (_c = this.natsConnection) === null || _c === void 0 ? void 0 : _c.info) === null || _d === void 0 ? void 0 : _d.max_payload;
|
|
145
177
|
chunkSize = serverMaxPayload ? serverMaxPayload - 50000 : 512000;
|
|
146
178
|
// The Session and the Client need to agree on the chunk size. Put it in a header.
|
|
147
179
|
headers.append('ChunkSize', chunkSize.toString());
|
|
@@ -155,9 +187,16 @@ var BaseClient = /** @class */ (function () {
|
|
|
155
187
|
var offset = chunk * fileDescriptor.chunkSize;
|
|
156
188
|
return data.slice(offset, offset + fileDescriptor.chunkSize);
|
|
157
189
|
};
|
|
158
|
-
subscription = this.
|
|
190
|
+
subscription = this.natsConnection.subscribe(replySubject);
|
|
159
191
|
responsePromise = new Promise(function (resolve, reject) {
|
|
192
|
+
// Chunk payloads stored at their sequence index so order is preserved
|
|
193
|
+
// regardless of the order in which messages arrive.
|
|
160
194
|
var messages = [];
|
|
195
|
+
var receivedCount = 0;
|
|
196
|
+
// Total number of chunks and the size of the final chunk, both known
|
|
197
|
+
// once the final (smaller) chunk arrives.
|
|
198
|
+
var expectedCount;
|
|
199
|
+
var finalChunkLength = 0;
|
|
161
200
|
subscription.callback = function (error, message) {
|
|
162
201
|
var _a, _b, _c, _d;
|
|
163
202
|
if (error) {
|
|
@@ -173,59 +212,65 @@ var BaseClient = /** @class */ (function () {
|
|
|
173
212
|
subscription.unsubscribe();
|
|
174
213
|
return resolve({ byteArray: message.data, isErrorResponse: ((_c = message.headers) === null || _c === void 0 ? void 0 : _c.get('OpenTapNatsError')) === 'true' });
|
|
175
214
|
}
|
|
176
|
-
//
|
|
177
|
-
messages
|
|
178
|
-
|
|
179
|
-
|
|
215
|
+
// Place each chunk at its sequence position (ChunkNumber is 1-based).
|
|
216
|
+
messages[parseInt(chunkNumber) - 1] = message.data;
|
|
217
|
+
receivedCount += 1;
|
|
218
|
+
// The final chunk is the only one smaller than chunkSize; its sequence
|
|
219
|
+
// number tells us how many chunks to expect and its length fixes the total size.
|
|
220
|
+
if (message.data.length < chunkSize) {
|
|
221
|
+
expectedCount = parseInt(chunkNumber);
|
|
222
|
+
finalChunkLength = message.data.length;
|
|
223
|
+
}
|
|
224
|
+
// Keep waiting until every expected chunk has been received.
|
|
225
|
+
if (expectedCount === undefined || receivedCount < expectedCount) {
|
|
180
226
|
return;
|
|
181
227
|
}
|
|
182
|
-
//
|
|
183
|
-
// If the final message was received, we can safely unsubscribe
|
|
228
|
+
// All expected chunks received; we can safely unsubscribe.
|
|
184
229
|
subscription.unsubscribe();
|
|
185
|
-
//
|
|
186
|
-
//
|
|
187
|
-
|
|
188
|
-
if (parseInt(chunkNumber) !== messages.length) {
|
|
189
|
-
return reject(Error("Expected {finalMessageNumber} chunks, but received ".concat(messages.length, ". ") +
|
|
190
|
-
"The connection may have been interrupted."));
|
|
191
|
-
}
|
|
192
|
-
// Concatenate the payloads
|
|
193
|
-
// When there are many chunks, doing a single allocation
|
|
194
|
-
// is significantly faster than concatenating arrays in sequence
|
|
195
|
-
var flattenedSize = messages.reduce(function (sum, array) { return sum + array.data.length; }, 0);
|
|
230
|
+
// Every chunk before the last is exactly chunkSize, so the total size is
|
|
231
|
+
// deterministic and each chunk's offset is simply its index * chunkSize.
|
|
232
|
+
var flattenedSize = (expectedCount - 1) * chunkSize + finalChunkLength;
|
|
196
233
|
var flattenedArray = new Uint8Array(flattenedSize);
|
|
197
|
-
var
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
234
|
+
for (var i = 0; i < expectedCount; i++) {
|
|
235
|
+
var chunk_1 = messages[i];
|
|
236
|
+
// A missing chunk means we dropped one, likely due to a network error,
|
|
237
|
+
// so the entire message is invalid.
|
|
238
|
+
if (!chunk_1) {
|
|
239
|
+
return reject(Error("Expected ".concat(expectedCount, " chunks, but chunk ").concat(i + 1, " is missing. ") +
|
|
240
|
+
"The connection may have been interrupted."));
|
|
201
241
|
}
|
|
202
|
-
|
|
242
|
+
flattenedArray.set(chunk_1, i * chunkSize);
|
|
243
|
+
}
|
|
203
244
|
return resolve({ byteArray: flattenedArray, isErrorResponse: ((_d = message.headers) === null || _d === void 0 ? void 0 : _d.get('OpenTapNatsError')) === 'true' });
|
|
204
245
|
};
|
|
205
246
|
}).then(function (_a) {
|
|
206
247
|
var byteArray = _a.byteArray, isErrorResponse = _a.isErrorResponse;
|
|
248
|
+
var jsonCodec = (0, nats_ws_1.JSONCodec)();
|
|
249
|
+
if (isErrorResponse) {
|
|
250
|
+
return Promise.reject(DTOs_1.ErrorResponse.fromJS(jsonCodec.decode(byteArray)));
|
|
251
|
+
}
|
|
207
252
|
if (byteArray.length === 0) {
|
|
208
253
|
return Promise.resolve(undefined);
|
|
209
254
|
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
return
|
|
255
|
+
if (options === null || options === void 0 ? void 0 : options.rawResponse) {
|
|
256
|
+
return Promise.resolve(byteArray);
|
|
257
|
+
}
|
|
258
|
+
return Promise.resolve(jsonCodec.decode(byteArray));
|
|
214
259
|
});
|
|
215
260
|
chunk = getChunk(0);
|
|
216
|
-
this.
|
|
261
|
+
this.natsConnection.publish(subject, chunk, opts);
|
|
217
262
|
chunkNumber += 1;
|
|
218
263
|
for (i = 1; i < fileDescriptor.numberOfChunks; i++) {
|
|
219
264
|
headers.set('ChunkNumber', chunkNumber.toString());
|
|
220
265
|
chunk = getChunk(i);
|
|
221
|
-
this.
|
|
266
|
+
this.natsConnection.publish(subject, chunk, opts);
|
|
222
267
|
chunkNumber += 1;
|
|
223
268
|
}
|
|
224
269
|
// In the special case where the last published chunk was full, we need to publish
|
|
225
270
|
// an empty message
|
|
226
271
|
if (data.length > 0 && data.length % fileDescriptor.chunkSize === 0) {
|
|
227
272
|
headers.set('ChunkNumber', chunkNumber.toString());
|
|
228
|
-
this.
|
|
273
|
+
this.natsConnection.publish(subject, nats_ws_1.Empty, opts);
|
|
229
274
|
}
|
|
230
275
|
// Now that we have sent the terminating chunk, the result should arrive on our promise.
|
|
231
276
|
return [2 /*return*/, this.withTimeout(responsePromise, timeout, subject).catch(function (err) {
|
|
@@ -281,12 +326,12 @@ var BaseClient = /** @class */ (function () {
|
|
|
281
326
|
if (options === void 0) { options = {}; }
|
|
282
327
|
if (!subject)
|
|
283
328
|
throw Error('Subject is not defined!');
|
|
284
|
-
if (!this.
|
|
329
|
+
if (!this.natsConnection)
|
|
285
330
|
throw Error('Connection is not up yet! Please try again later!');
|
|
286
|
-
if (this.
|
|
331
|
+
if (this.natsConnection.isClosed())
|
|
287
332
|
throw Error('Connection has been closed! Please reconnect!');
|
|
288
333
|
var natsSubject = options.fullSubject ? subject : "".concat(this.baseSubject, ".").concat(subject);
|
|
289
|
-
return this.
|
|
334
|
+
return this.natsConnection.subscribe(natsSubject, options);
|
|
290
335
|
};
|
|
291
336
|
/**
|
|
292
337
|
* Subscribes to given subject.
|
|
@@ -298,14 +343,14 @@ var BaseClient = /** @class */ (function () {
|
|
|
298
343
|
var _this = this;
|
|
299
344
|
if (jetStreamOptions === void 0) { jetStreamOptions = {}; }
|
|
300
345
|
if (consumerOptions === void 0) { consumerOptions = {}; }
|
|
301
|
-
if (!this.
|
|
346
|
+
if (!this.natsConnection) {
|
|
302
347
|
throw Error('Connection is not established');
|
|
303
348
|
}
|
|
304
|
-
return this.
|
|
349
|
+
return this.natsConnection.jetstreamManager(__assign({}, jetStreamOptions)).then(function (jetStreamManager) {
|
|
305
350
|
return jetStreamManager.consumers
|
|
306
351
|
.add(stream, __assign(__assign({}, consumerOptions), { filter_subject: subject, ack_policy: nats_ws_1.AckPolicy.None }))
|
|
307
352
|
.then(function (consumerInfo) {
|
|
308
|
-
return _this.
|
|
353
|
+
return _this.natsConnection.jetstream(jetStreamOptions).consumers.get(consumerInfo.stream_name, consumerInfo.name);
|
|
309
354
|
});
|
|
310
355
|
});
|
|
311
356
|
};
|
|
@@ -322,7 +367,7 @@ var BaseClient = /** @class */ (function () {
|
|
|
322
367
|
* Create a connection to the nats server.
|
|
323
368
|
* @param {ConnectionOptions} options
|
|
324
369
|
*/
|
|
325
|
-
BaseClient.prototype.connect = function () {
|
|
370
|
+
BaseClient.prototype.connect = function (connection) {
|
|
326
371
|
return __awaiter(this, void 0, void 0, function () {
|
|
327
372
|
var error_1;
|
|
328
373
|
var _this = this;
|
|
@@ -331,14 +376,21 @@ var BaseClient = /** @class */ (function () {
|
|
|
331
376
|
case 0:
|
|
332
377
|
if (!this.baseSubject)
|
|
333
378
|
return [2 /*return*/, Promise.reject('Subject must be given')];
|
|
334
|
-
if (this.
|
|
379
|
+
if (this.natsConnection)
|
|
380
|
+
return [2 /*return*/, Promise.resolve()];
|
|
381
|
+
if (connection) {
|
|
382
|
+
if (connection.isClosed()) {
|
|
383
|
+
return [2 /*return*/, Promise.reject('Provided connection is closed')];
|
|
384
|
+
}
|
|
385
|
+
this.natsConnection = connection;
|
|
335
386
|
return [2 /*return*/, Promise.resolve()];
|
|
387
|
+
}
|
|
336
388
|
_a.label = 1;
|
|
337
389
|
case 1:
|
|
338
390
|
_a.trys.push([1, 3, , 4]);
|
|
339
391
|
return [4 /*yield*/, (0, nats_ws_1.connect)(this.connectionOptions)
|
|
340
392
|
.then(function (connection) {
|
|
341
|
-
_this.
|
|
393
|
+
_this.natsConnection = connection;
|
|
342
394
|
return Promise.resolve();
|
|
343
395
|
})
|
|
344
396
|
.catch(function (error) { return Promise.reject("Failed to connect to ".concat(_this.connectionOptions.servers, " with ").concat(error)); })];
|
|
@@ -361,9 +413,9 @@ var BaseClient = /** @class */ (function () {
|
|
|
361
413
|
return __generator(this, function (_b) {
|
|
362
414
|
switch (_b.label) {
|
|
363
415
|
case 0:
|
|
364
|
-
if (!this.
|
|
365
|
-
return [4 /*yield*/, ((_a = this.
|
|
366
|
-
_this.
|
|
416
|
+
if (!this.natsConnection) return [3 /*break*/, 2];
|
|
417
|
+
return [4 /*yield*/, ((_a = this.natsConnection) === null || _a === void 0 ? void 0 : _a.close().then(function () {
|
|
418
|
+
_this.natsConnection = null;
|
|
367
419
|
}).catch(function (error) {
|
|
368
420
|
throw new Error("failed to close connection: ".concat(error));
|
|
369
421
|
}))];
|
|
@@ -699,6 +751,7 @@ var BaseClient = /** @class */ (function () {
|
|
|
699
751
|
* Dispatches a request with the given subject and returns a Promise of type T
|
|
700
752
|
* @param subject The subject to send the request to
|
|
701
753
|
* @returns Promise<T> The response from the request
|
|
754
|
+
* @deprecated Use {@link request} instead.
|
|
702
755
|
*/
|
|
703
756
|
BaseClient.prototype.dispatchRequest = function (subject, payload, options) {
|
|
704
757
|
return __awaiter(this, void 0, void 0, function () {
|
package/dist/cjs/DTOs.d.ts
CHANGED
|
@@ -876,7 +876,8 @@ export declare enum SessionState {
|
|
|
876
876
|
Breaking = "Breaking",
|
|
877
877
|
Aborting = "Aborting",
|
|
878
878
|
WaitingForUserInput = "WaitingForUserInput",
|
|
879
|
-
Loading = "Loading"
|
|
879
|
+
Loading = "Loading",
|
|
880
|
+
Restarting = "Restarting"
|
|
880
881
|
}
|
|
881
882
|
export declare class TestPlan implements ITestPlan {
|
|
882
883
|
childTestSteps?: TestStep[] | undefined;
|
|
@@ -1207,7 +1208,9 @@ export declare enum SessionEventName {
|
|
|
1207
1208
|
TestStepChanged = "TestStepChanged",
|
|
1208
1209
|
Break = "Break",
|
|
1209
1210
|
UserInputRequested = "UserInputRequested",
|
|
1210
|
-
UserInputRequestCompleted = "UserInputRequestCompleted"
|
|
1211
|
+
UserInputRequestCompleted = "UserInputRequestCompleted",
|
|
1212
|
+
RestartInitiated = "RestartInitiated",
|
|
1213
|
+
RestartCompleted = "RestartCompleted"
|
|
1211
1214
|
}
|
|
1212
1215
|
export declare abstract class SessionEvent {
|
|
1213
1216
|
readonly eventName: SessionEventName;
|
|
@@ -1315,6 +1318,21 @@ export declare class UserInputRequestCompletedEvent extends SessionEvent {
|
|
|
1315
1318
|
static fromJS(data: any): UserInputRequestCompletedEvent;
|
|
1316
1319
|
toJSON(data?: any): any;
|
|
1317
1320
|
}
|
|
1321
|
+
export declare class RestartInitiatedEvent extends SessionEvent {
|
|
1322
|
+
oldProcessId?: number;
|
|
1323
|
+
constructor(data?: Partial<RestartInitiatedEvent>);
|
|
1324
|
+
init(_data?: any): void;
|
|
1325
|
+
static fromJS(data: any): RestartInitiatedEvent;
|
|
1326
|
+
toJSON(data?: any): any;
|
|
1327
|
+
}
|
|
1328
|
+
export declare class RestartCompletedEvent extends SessionEvent {
|
|
1329
|
+
success?: boolean;
|
|
1330
|
+
newProcessId?: number;
|
|
1331
|
+
constructor(data?: Partial<RestartCompletedEvent>);
|
|
1332
|
+
init(_data?: any): void;
|
|
1333
|
+
static fromJS(data: any): RestartCompletedEvent;
|
|
1334
|
+
toJSON(data?: any): any;
|
|
1335
|
+
}
|
|
1318
1336
|
export type ISessionEvent = SessionEvent;
|
|
1319
1337
|
export interface IOnTestPlanRun {
|
|
1320
1338
|
status?: string;
|
package/dist/cjs/DTOs.js
CHANGED
|
@@ -17,7 +17,7 @@ var __extends = (this && this.__extends) || (function () {
|
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
18
|
exports.SettingsTapPackage = exports.SaveTestPlanToRepositoryResponse = exports.GetTestPlanReferenceResponse = exports.RepositorySettingsPackageDefinition = exports.RepositoryPackageDefinition = exports.RepositoryPackageReference = exports.ProfileGroup = exports.ListItemType = exports.ComponentSettings = exports.FileDescriptor = exports.Resource = exports.PluginTypeSelectorControl = exports.PictureControl = exports.PasswordControl = exports.MultiSelectControl = exports.DropdownControl = exports.EnabledControl = exports.DirectoryPathControl = exports.FilePathControl = exports.ComboBoxControl = exports.TextBoxControl = exports.DataGridControl = exports.DataGridReferenceControl = exports.CheckBoxControl = exports.AvailableValue = exports.ButtonsControl = exports.ButtonControl = exports.ExternalParameter = exports.MetaData = exports.DisplayAttribute = exports.VisualStatus = exports.UnitAttribute = exports.Icon = exports.ColumnDisplayName = exports.LayoutMode = exports.Layout = exports.Setting = exports.ComponentSettingsListItem = exports.AnnotatedObject = exports.ComponentSettingsList = exports.DisplayMode = exports.ComponentSettingsIdentifier = exports.ComponentSettingsBase = exports.Links = exports.Session = exports.ImageResolveErrorResponse = exports.NoResponderError = exports.ErrorResponse = exports.PackageSpecifier = exports.Image = void 0;
|
|
19
19
|
exports.StartedEvent = exports.StartingEvent = exports.SessionTimeoutEvent = exports.TestPlanSettingsChangedEvent = exports.TypeCacheInvalidatedEvent = exports.SessionEvent = exports.SessionEventName = exports.MetricValue = exports.MetricsConfiguration = exports.SessionMetricInfo = exports.MetricsPollRate = exports.SessionMetricType = exports.SessionMetricKind = exports.ResultColumn = exports.Result = exports.LogEvent = exports.TestStepRun = exports.WatchDog = exports.Parameter = exports.BreakPoints = exports.InstalledFile = exports.Interaction = exports.CommonContext = exports.CommonSettings = exports.ValidationError = exports.TestStepValidationError = exports.TestStepCopy = exports.TestStepType = exports.TestStep = exports.TestPlan = exports.SessionState = exports.Verdict = exports.EditStatus = exports.RunStatus = exports.MissingLicenseResponse = exports.LogEntry = exports.LogList = exports.ApiException = exports.ImageCreationFailed = exports.ImageCreated = exports.ImageCreating = exports.ImageEventArgs = exports.SessionInactivityLimitHit = exports.SessionShutdownFailed = exports.SessionShutdown = exports.SessionShutdownInitiated = exports.SessionStartFailed = exports.SessionStarted = exports.SessionStartInitiated = exports.SessionEventArgs = void 0;
|
|
20
|
-
exports.RunnerStatus = exports.StreamInfoStatus = exports.RemoteConnection = exports.SaveDefaultSettings = exports.AssetUpdatedEvent = exports.MetadataUpdatedEvent = exports.RunnerDeletedEvent = exports.RunnerUpdatedEvent = exports.RunnerRegisteredEvent = exports.RunnerEvent = exports.TestPlanRunCompletedEvent = exports.TestPlanRunStartEvent = exports.TestPlanRunEvent = exports.OnTestStepRun = exports.OnTestPlanRun = exports.UserInputRequestCompletedEvent = exports.UserInputRequestedEvent = exports.BreakEvent = exports.TestStepChangedEvent = exports.SettingsChangedEvent = exports.HeartbeatEvent = exports.SessionStateChangedEvent = exports.TestPlanReferenceChangedEvent = exports.TestPlanChangedEvent = exports.StoppedEvent = exports.StoppingEvent = void 0;
|
|
20
|
+
exports.RunnerStatus = exports.StreamInfoStatus = exports.RemoteConnection = exports.SaveDefaultSettings = exports.AssetUpdatedEvent = exports.MetadataUpdatedEvent = exports.RunnerDeletedEvent = exports.RunnerUpdatedEvent = exports.RunnerRegisteredEvent = exports.RunnerEvent = exports.TestPlanRunCompletedEvent = exports.TestPlanRunStartEvent = exports.TestPlanRunEvent = exports.OnTestStepRun = exports.OnTestPlanRun = exports.RestartCompletedEvent = exports.RestartInitiatedEvent = exports.UserInputRequestCompletedEvent = exports.UserInputRequestedEvent = exports.BreakEvent = exports.TestStepChangedEvent = exports.SettingsChangedEvent = exports.HeartbeatEvent = exports.SessionStateChangedEvent = exports.TestPlanReferenceChangedEvent = exports.TestPlanChangedEvent = exports.StoppedEvent = exports.StoppingEvent = void 0;
|
|
21
21
|
var Image = /** @class */ (function () {
|
|
22
22
|
function Image(data) {
|
|
23
23
|
this.packages = [];
|
|
@@ -2444,6 +2444,7 @@ var SessionState;
|
|
|
2444
2444
|
SessionState["Aborting"] = "Aborting";
|
|
2445
2445
|
SessionState["WaitingForUserInput"] = "WaitingForUserInput";
|
|
2446
2446
|
SessionState["Loading"] = "Loading";
|
|
2447
|
+
SessionState["Restarting"] = "Restarting";
|
|
2447
2448
|
})(SessionState || (exports.SessionState = SessionState = {}));
|
|
2448
2449
|
var TestPlan = /** @class */ (function () {
|
|
2449
2450
|
function TestPlan(data) {
|
|
@@ -3326,6 +3327,8 @@ var SessionEventName;
|
|
|
3326
3327
|
SessionEventName["Break"] = "Break";
|
|
3327
3328
|
SessionEventName["UserInputRequested"] = "UserInputRequested";
|
|
3328
3329
|
SessionEventName["UserInputRequestCompleted"] = "UserInputRequestCompleted";
|
|
3330
|
+
SessionEventName["RestartInitiated"] = "RestartInitiated";
|
|
3331
|
+
SessionEventName["RestartCompleted"] = "RestartCompleted";
|
|
3329
3332
|
})(SessionEventName || (exports.SessionEventName = SessionEventName = {}));
|
|
3330
3333
|
var SessionEvent = /** @class */ (function () {
|
|
3331
3334
|
function SessionEvent(eventName) {
|
|
@@ -3659,6 +3662,60 @@ var UserInputRequestCompletedEvent = /** @class */ (function (_super) {
|
|
|
3659
3662
|
return UserInputRequestCompletedEvent;
|
|
3660
3663
|
}(SessionEvent));
|
|
3661
3664
|
exports.UserInputRequestCompletedEvent = UserInputRequestCompletedEvent;
|
|
3665
|
+
var RestartInitiatedEvent = /** @class */ (function (_super) {
|
|
3666
|
+
__extends(RestartInitiatedEvent, _super);
|
|
3667
|
+
function RestartInitiatedEvent(data) {
|
|
3668
|
+
var _this = _super.call(this, SessionEventName.RestartInitiated) || this;
|
|
3669
|
+
if (data) {
|
|
3670
|
+
Object.assign(_this, data);
|
|
3671
|
+
}
|
|
3672
|
+
return _this;
|
|
3673
|
+
}
|
|
3674
|
+
RestartInitiatedEvent.prototype.init = function (_data) {
|
|
3675
|
+
var data = ensureObject(_data);
|
|
3676
|
+
this.oldProcessId = data['OldProcessId'];
|
|
3677
|
+
};
|
|
3678
|
+
RestartInitiatedEvent.fromJS = function (data) {
|
|
3679
|
+
var result = new RestartInitiatedEvent();
|
|
3680
|
+
result.init(data);
|
|
3681
|
+
return result;
|
|
3682
|
+
};
|
|
3683
|
+
RestartInitiatedEvent.prototype.toJSON = function (data) {
|
|
3684
|
+
var json = ensureObject(data);
|
|
3685
|
+
json['OldProcessId'] = this.oldProcessId;
|
|
3686
|
+
return json;
|
|
3687
|
+
};
|
|
3688
|
+
return RestartInitiatedEvent;
|
|
3689
|
+
}(SessionEvent));
|
|
3690
|
+
exports.RestartInitiatedEvent = RestartInitiatedEvent;
|
|
3691
|
+
var RestartCompletedEvent = /** @class */ (function (_super) {
|
|
3692
|
+
__extends(RestartCompletedEvent, _super);
|
|
3693
|
+
function RestartCompletedEvent(data) {
|
|
3694
|
+
var _this = _super.call(this, SessionEventName.RestartCompleted) || this;
|
|
3695
|
+
if (data) {
|
|
3696
|
+
Object.assign(_this, data);
|
|
3697
|
+
}
|
|
3698
|
+
return _this;
|
|
3699
|
+
}
|
|
3700
|
+
RestartCompletedEvent.prototype.init = function (_data) {
|
|
3701
|
+
var data = ensureObject(_data);
|
|
3702
|
+
this.success = data['Success'];
|
|
3703
|
+
this.newProcessId = data['NewProcessId'];
|
|
3704
|
+
};
|
|
3705
|
+
RestartCompletedEvent.fromJS = function (data) {
|
|
3706
|
+
var result = new RestartCompletedEvent();
|
|
3707
|
+
result.init(data);
|
|
3708
|
+
return result;
|
|
3709
|
+
};
|
|
3710
|
+
RestartCompletedEvent.prototype.toJSON = function (data) {
|
|
3711
|
+
var json = ensureObject(data);
|
|
3712
|
+
json['Success'] = this.success;
|
|
3713
|
+
json['NewProcessId'] = this.newProcessId;
|
|
3714
|
+
return json;
|
|
3715
|
+
};
|
|
3716
|
+
return RestartCompletedEvent;
|
|
3717
|
+
}(SessionEvent));
|
|
3718
|
+
exports.RestartCompletedEvent = RestartCompletedEvent;
|
|
3662
3719
|
var OnTestPlanRun = /** @class */ (function () {
|
|
3663
3720
|
function OnTestPlanRun(data) {
|
|
3664
3721
|
if (data) {
|
|
@@ -58,6 +58,12 @@ export declare class RunnerClient extends BaseClient {
|
|
|
58
58
|
* @returns {{Promise<void>}}
|
|
59
59
|
*/
|
|
60
60
|
shutdownSession(sessionId: string, force?: boolean): Promise<void>;
|
|
61
|
+
/**
|
|
62
|
+
* Restart a session
|
|
63
|
+
* @param sessionId the ID of the session to restart
|
|
64
|
+
* @returns {{Promise<void>}}
|
|
65
|
+
*/
|
|
66
|
+
restartSession(sessionId: string): Promise<void>;
|
|
61
67
|
/**
|
|
62
68
|
* Start a session
|
|
63
69
|
* @returns {{Promise<Session>}}
|
package/dist/cjs/RunnerClient.js
CHANGED
|
@@ -232,6 +232,16 @@ var RunnerClient = /** @class */ (function (_super) {
|
|
|
232
232
|
.catch(this.error())
|
|
233
233
|
: Promise.reject('sessionId is not defined');
|
|
234
234
|
};
|
|
235
|
+
/**
|
|
236
|
+
* Restart a session
|
|
237
|
+
* @param sessionId the ID of the session to restart
|
|
238
|
+
* @returns {{Promise<void>}}
|
|
239
|
+
*/
|
|
240
|
+
RunnerClient.prototype.restartSession = function (sessionId) {
|
|
241
|
+
return (sessionId === null || sessionId === void 0 ? void 0 : sessionId.length) > 0
|
|
242
|
+
? this.request('RestartSession', { SessionId: sessionId }).then(this.success()).catch(this.error())
|
|
243
|
+
: Promise.reject('sessionId is not defined');
|
|
244
|
+
};
|
|
235
245
|
/**
|
|
236
246
|
* Start a session
|
|
237
247
|
* @returns {{Promise<Session>}}
|
|
@@ -847,6 +847,8 @@ var SessionClient = /** @class */ (function (_super) {
|
|
|
847
847
|
_a[DTOs_1.SessionEventName.Break] = function (payload) { return DTOs_1.BreakEvent.fromJS(payload); },
|
|
848
848
|
_a[DTOs_1.SessionEventName.UserInputRequested] = function (payload) { return DTOs_1.UserInputRequestedEvent.fromJS(payload); },
|
|
849
849
|
_a[DTOs_1.SessionEventName.UserInputRequestCompleted] = function (payload) { return DTOs_1.UserInputRequestCompletedEvent.fromJS(payload); },
|
|
850
|
+
_a[DTOs_1.SessionEventName.RestartInitiated] = function (payload) { return DTOs_1.RestartInitiatedEvent.fromJS(payload); },
|
|
851
|
+
_a[DTOs_1.SessionEventName.RestartCompleted] = function (payload) { return DTOs_1.RestartCompletedEvent.fromJS(payload); },
|
|
850
852
|
_a);
|
|
851
853
|
return SessionClient;
|
|
852
854
|
}(BaseClient_1.BaseClient));
|
package/dist/mjs/BaseClient.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ConnectionOptions, Consumer, ConsumerConfig, JetStreamOptions, NatsError, PublishOptions, Subscription, SubscriptionOptions } from 'nats.ws';
|
|
1
|
+
import { ConnectionOptions, Consumer, ConsumerConfig, JetStreamOptions, NatsConnection, NatsError, PublishOptions, Subscription, SubscriptionOptions } from 'nats.ws';
|
|
2
2
|
import { DownloadTapSettingsRequest } from './requestDTOs';
|
|
3
3
|
import { ComponentSettingsBase, ComponentSettingsIdentifier, ComponentSettingsListItem, DataGridControl, ErrorResponse, FileParameter, ListItemType, ProfileGroup, RepositoryPackageReference, RepositorySettingsPackageDefinition } from './DTOs';
|
|
4
4
|
interface BaseClientRequestOptions {
|
|
@@ -12,28 +12,23 @@ interface BaseClientRequestOptions {
|
|
|
12
12
|
}
|
|
13
13
|
export declare class BaseClient {
|
|
14
14
|
readonly baseSubject: string;
|
|
15
|
-
private
|
|
15
|
+
private natsConnection;
|
|
16
16
|
private connectionOptions;
|
|
17
17
|
private domainAccess;
|
|
18
18
|
private eventEmitter;
|
|
19
19
|
private _accessToken;
|
|
20
20
|
private _headers;
|
|
21
21
|
private _timeout;
|
|
22
|
-
|
|
22
|
+
get connection(): NatsConnection | null;
|
|
23
23
|
get accessToken(): string;
|
|
24
|
-
/** Set request access token */
|
|
25
24
|
set accessToken(value: string);
|
|
26
|
-
/** Get request headers */
|
|
27
25
|
get headers(): {
|
|
28
26
|
[key: string]: string;
|
|
29
27
|
};
|
|
30
|
-
/** Set request headers */
|
|
31
28
|
set headers(value: {
|
|
32
29
|
[key: string]: string;
|
|
33
30
|
});
|
|
34
|
-
/** Get timeout */
|
|
35
31
|
get timeout(): number;
|
|
36
|
-
/** Set timeout in milliseconds. Default is 40000 milliseconds */
|
|
37
32
|
set timeout(value: number);
|
|
38
33
|
constructor(baseSubject: string, options: ConnectionOptions);
|
|
39
34
|
private withTimeout;
|
|
@@ -44,7 +39,7 @@ export declare class BaseClient {
|
|
|
44
39
|
* @param options (optional)
|
|
45
40
|
* @returns Promise of an object
|
|
46
41
|
*/
|
|
47
|
-
|
|
42
|
+
request<T>(subject: string, payload?: any, options?: BaseClientRequestOptions): Promise<T>;
|
|
48
43
|
/**
|
|
49
44
|
* Handle the error
|
|
50
45
|
* @param error
|
|
@@ -78,7 +73,7 @@ export declare class BaseClient {
|
|
|
78
73
|
* Create a connection to the nats server.
|
|
79
74
|
* @param {ConnectionOptions} options
|
|
80
75
|
*/
|
|
81
|
-
connect(): Promise<void>;
|
|
76
|
+
connect(connection?: NatsConnection): Promise<void>;
|
|
82
77
|
/**
|
|
83
78
|
* Close the connection.
|
|
84
79
|
*/
|
|
@@ -258,6 +253,7 @@ export declare class BaseClient {
|
|
|
258
253
|
* Dispatches a request with the given subject and returns a Promise of type T
|
|
259
254
|
* @param subject The subject to send the request to
|
|
260
255
|
* @returns Promise<T> The response from the request
|
|
256
|
+
* @deprecated Use {@link request} instead.
|
|
261
257
|
*/
|
|
262
258
|
dispatchRequest<T>(subject: string, payload?: any, options?: BaseClientRequestOptions): Promise<T>;
|
|
263
259
|
}
|
package/dist/mjs/BaseClient.js
CHANGED
|
@@ -11,33 +11,52 @@ import { AckPolicy, Empty, ErrorCode, JSONCodec, StringCodec, connect, headers,
|
|
|
11
11
|
import { ComponentSettingsBase, ComponentSettingsIdentifier, ComponentSettingsListItem, DataGridControl, ErrorResponse, FileDescriptor, ListItemType, NoResponderError, ProfileGroup, } from './DTOs';
|
|
12
12
|
import { EventEmitter } from 'events';
|
|
13
13
|
import { v4 as uuidv4 } from 'uuid';
|
|
14
|
+
// A browser extension like CrowdStrike may have already replaced globalThis.WebSocket before this module loads,
|
|
15
|
+
// so reading the global is unreliable. A freshly created same-origin iframe exposes the browser's
|
|
16
|
+
// pristine, un-patched WebSocket; NATS traffic is pinned to it to bypass any extension shim.
|
|
17
|
+
// The iframe is kept attached because a detached iframe's realm becomes unusable in some browsers.
|
|
18
|
+
function getNativeWebSocket() {
|
|
19
|
+
var _a, _b, _c;
|
|
20
|
+
const globalWebSocket = typeof globalThis !== 'undefined' ? globalThis.WebSocket : undefined;
|
|
21
|
+
const doc = globalThis.document;
|
|
22
|
+
if (!doc || typeof doc.createElement !== 'function') {
|
|
23
|
+
return globalWebSocket;
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
const iframe = doc.createElement('iframe');
|
|
27
|
+
iframe.style.display = 'none';
|
|
28
|
+
((_a = doc.body) !== null && _a !== void 0 ? _a : doc.documentElement).appendChild(iframe);
|
|
29
|
+
return (_c = (_b = iframe.contentWindow) === null || _b === void 0 ? void 0 : _b.WebSocket) !== null && _c !== void 0 ? _c : globalWebSocket;
|
|
30
|
+
}
|
|
31
|
+
catch (_d) {
|
|
32
|
+
return globalWebSocket;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
const OriginalWebSocket = getNativeWebSocket();
|
|
14
36
|
const DEFAULT_TIMEOUT = 40000; // default timeout of 40 seconds
|
|
15
37
|
var Events;
|
|
16
38
|
(function (Events) {
|
|
17
39
|
Events["ERROR"] = "error_event";
|
|
18
40
|
})(Events || (Events = {}));
|
|
19
41
|
export class BaseClient {
|
|
20
|
-
|
|
42
|
+
get connection() {
|
|
43
|
+
return this.natsConnection;
|
|
44
|
+
}
|
|
21
45
|
get accessToken() {
|
|
22
46
|
return this._accessToken;
|
|
23
47
|
}
|
|
24
|
-
/** Set request access token */
|
|
25
48
|
set accessToken(value) {
|
|
26
49
|
this._accessToken = value;
|
|
27
50
|
}
|
|
28
|
-
/** Get request headers */
|
|
29
51
|
get headers() {
|
|
30
52
|
return this._headers;
|
|
31
53
|
}
|
|
32
|
-
/** Set request headers */
|
|
33
54
|
set headers(value) {
|
|
34
55
|
this._headers = value;
|
|
35
56
|
}
|
|
36
|
-
/** Get timeout */
|
|
37
57
|
get timeout() {
|
|
38
58
|
return this._timeout || DEFAULT_TIMEOUT;
|
|
39
59
|
}
|
|
40
|
-
/** Set timeout in milliseconds. Default is 40000 milliseconds */
|
|
41
60
|
set timeout(value) {
|
|
42
61
|
this._timeout = value;
|
|
43
62
|
}
|
|
@@ -47,6 +66,13 @@ export class BaseClient {
|
|
|
47
66
|
this.baseSubject = baseSubject;
|
|
48
67
|
this.connectionOptions = Object.assign({}, options);
|
|
49
68
|
this.connectionOptions.timeout = (options === null || options === void 0 ? void 0 : options.timeout) || DEFAULT_TIMEOUT;
|
|
69
|
+
// Force NATS to use the WebSocket captured at load time so an extension that later
|
|
70
|
+
// overrides globalThis.WebSocket cannot intercept NATS traffic. Respect a caller-provided factory.
|
|
71
|
+
// wsFactory is read by nats.ws's WsTransport at runtime but lives on WsConnectionOptions, which
|
|
72
|
+
// isn't re-exported, so it's absent from the public ConnectionOptions type and requires this cast.
|
|
73
|
+
if (OriginalWebSocket && !this.connectionOptions.wsFactory) {
|
|
74
|
+
this.connectionOptions.wsFactory = (url) => Promise.resolve({ socket: new OriginalWebSocket(url), encrypted: url.indexOf('wss://') === 0 });
|
|
75
|
+
}
|
|
50
76
|
this.eventEmitter = new EventEmitter();
|
|
51
77
|
}
|
|
52
78
|
withTimeout(promise, timeout, subject) {
|
|
@@ -69,9 +95,9 @@ export class BaseClient {
|
|
|
69
95
|
if (!(options === null || options === void 0 ? void 0 : options.fullSubject)) {
|
|
70
96
|
subject = `${this.baseSubject}.Request.${subject}`;
|
|
71
97
|
}
|
|
72
|
-
if (!this.
|
|
98
|
+
if (!this.natsConnection)
|
|
73
99
|
return Promise.reject(`${subject}: Connection is down! Please try again!`);
|
|
74
|
-
if (this.
|
|
100
|
+
if (this.natsConnection.isClosed())
|
|
75
101
|
return Promise.reject(`${subject}: Connection has been closed! Please reconnect!`);
|
|
76
102
|
const data = this.encode(payload);
|
|
77
103
|
const headers = this.buildHeaders();
|
|
@@ -88,7 +114,7 @@ export class BaseClient {
|
|
|
88
114
|
// If serverMaxPayload is not available for some reason, we just use a default chunk size of 512000.
|
|
89
115
|
// We subtract 50000 from max_payload in order to leave room for headers, which
|
|
90
116
|
// can be quite large since they can contain jwt tokens, which may contain all sorts of information.
|
|
91
|
-
const serverMaxPayload = (_d = (_c = this.
|
|
117
|
+
const serverMaxPayload = (_d = (_c = this.natsConnection) === null || _c === void 0 ? void 0 : _c.info) === null || _d === void 0 ? void 0 : _d.max_payload;
|
|
92
118
|
const chunkSize = serverMaxPayload ? serverMaxPayload - 50000 : 512000;
|
|
93
119
|
// The Session and the Client need to agree on the chunk size. Put it in a header.
|
|
94
120
|
headers.append('ChunkSize', chunkSize.toString());
|
|
@@ -105,11 +131,18 @@ export class BaseClient {
|
|
|
105
131
|
return data.slice(offset, offset + fileDescriptor.chunkSize);
|
|
106
132
|
};
|
|
107
133
|
// Set up the subscription before we start publishing chunks
|
|
108
|
-
const subscription = this.
|
|
134
|
+
const subscription = this.natsConnection.subscribe(replySubject);
|
|
109
135
|
// The response from the session will arrive in this promise after we have finished
|
|
110
136
|
// publishing chunks
|
|
111
137
|
const responsePromise = new Promise((resolve, reject) => {
|
|
138
|
+
// Chunk payloads stored at their sequence index so order is preserved
|
|
139
|
+
// regardless of the order in which messages arrive.
|
|
112
140
|
const messages = [];
|
|
141
|
+
let receivedCount = 0;
|
|
142
|
+
// Total number of chunks and the size of the final chunk, both known
|
|
143
|
+
// once the final (smaller) chunk arrives.
|
|
144
|
+
let expectedCount;
|
|
145
|
+
let finalChunkLength = 0;
|
|
113
146
|
subscription.callback = (error, message) => {
|
|
114
147
|
var _a, _b, _c, _d;
|
|
115
148
|
if (error) {
|
|
@@ -125,60 +158,66 @@ export class BaseClient {
|
|
|
125
158
|
subscription.unsubscribe();
|
|
126
159
|
return resolve({ byteArray: message.data, isErrorResponse: ((_c = message.headers) === null || _c === void 0 ? void 0 : _c.get('OpenTapNatsError')) === 'true' });
|
|
127
160
|
}
|
|
128
|
-
//
|
|
129
|
-
messages
|
|
130
|
-
|
|
131
|
-
|
|
161
|
+
// Place each chunk at its sequence position (ChunkNumber is 1-based).
|
|
162
|
+
messages[parseInt(chunkNumber) - 1] = message.data;
|
|
163
|
+
receivedCount += 1;
|
|
164
|
+
// The final chunk is the only one smaller than chunkSize; its sequence
|
|
165
|
+
// number tells us how many chunks to expect and its length fixes the total size.
|
|
166
|
+
if (message.data.length < chunkSize) {
|
|
167
|
+
expectedCount = parseInt(chunkNumber);
|
|
168
|
+
finalChunkLength = message.data.length;
|
|
169
|
+
}
|
|
170
|
+
// Keep waiting until every expected chunk has been received.
|
|
171
|
+
if (expectedCount === undefined || receivedCount < expectedCount) {
|
|
132
172
|
return;
|
|
133
173
|
}
|
|
134
|
-
//
|
|
135
|
-
// If the final message was received, we can safely unsubscribe
|
|
174
|
+
// All expected chunks received; we can safely unsubscribe.
|
|
136
175
|
subscription.unsubscribe();
|
|
137
|
-
//
|
|
138
|
-
//
|
|
139
|
-
|
|
140
|
-
if (parseInt(chunkNumber) !== messages.length) {
|
|
141
|
-
return reject(Error(`Expected {finalMessageNumber} chunks, but received ${messages.length}. ` +
|
|
142
|
-
`The connection may have been interrupted.`));
|
|
143
|
-
}
|
|
144
|
-
// Concatenate the payloads
|
|
145
|
-
// When there are many chunks, doing a single allocation
|
|
146
|
-
// is significantly faster than concatenating arrays in sequence
|
|
147
|
-
const flattenedSize = messages.reduce((sum, array) => sum + array.data.length, 0);
|
|
176
|
+
// Every chunk before the last is exactly chunkSize, so the total size is
|
|
177
|
+
// deterministic and each chunk's offset is simply its index * chunkSize.
|
|
178
|
+
const flattenedSize = (expectedCount - 1) * chunkSize + finalChunkLength;
|
|
148
179
|
const flattenedArray = new Uint8Array(flattenedSize);
|
|
149
|
-
let
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
180
|
+
for (let i = 0; i < expectedCount; i++) {
|
|
181
|
+
const chunk = messages[i];
|
|
182
|
+
// A missing chunk means we dropped one, likely due to a network error,
|
|
183
|
+
// so the entire message is invalid.
|
|
184
|
+
if (!chunk) {
|
|
185
|
+
return reject(Error(`Expected ${expectedCount} chunks, but chunk ${i + 1} is missing. ` +
|
|
186
|
+
`The connection may have been interrupted.`));
|
|
153
187
|
}
|
|
154
|
-
|
|
188
|
+
flattenedArray.set(chunk, i * chunkSize);
|
|
189
|
+
}
|
|
155
190
|
return resolve({ byteArray: flattenedArray, isErrorResponse: ((_d = message.headers) === null || _d === void 0 ? void 0 : _d.get('OpenTapNatsError')) === 'true' });
|
|
156
191
|
};
|
|
157
192
|
}).then(({ byteArray, isErrorResponse }) => {
|
|
193
|
+
const jsonCodec = JSONCodec();
|
|
194
|
+
if (isErrorResponse) {
|
|
195
|
+
return Promise.reject(ErrorResponse.fromJS(jsonCodec.decode(byteArray)));
|
|
196
|
+
}
|
|
158
197
|
if (byteArray.length === 0) {
|
|
159
198
|
return Promise.resolve(undefined);
|
|
160
199
|
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
return
|
|
200
|
+
if (options === null || options === void 0 ? void 0 : options.rawResponse) {
|
|
201
|
+
return Promise.resolve(byteArray);
|
|
202
|
+
}
|
|
203
|
+
return Promise.resolve(jsonCodec.decode(byteArray));
|
|
165
204
|
});
|
|
166
205
|
// 'Manually' publish the first chunk. This is to ensure that **at least** one chunk is published.
|
|
167
206
|
// This is a special case for empty payloads (which are common)
|
|
168
207
|
let chunk = getChunk(0);
|
|
169
|
-
this.
|
|
208
|
+
this.natsConnection.publish(subject, chunk, opts);
|
|
170
209
|
chunkNumber += 1;
|
|
171
210
|
for (let i = 1; i < fileDescriptor.numberOfChunks; i++) {
|
|
172
211
|
headers.set('ChunkNumber', chunkNumber.toString());
|
|
173
212
|
chunk = getChunk(i);
|
|
174
|
-
this.
|
|
213
|
+
this.natsConnection.publish(subject, chunk, opts);
|
|
175
214
|
chunkNumber += 1;
|
|
176
215
|
}
|
|
177
216
|
// In the special case where the last published chunk was full, we need to publish
|
|
178
217
|
// an empty message
|
|
179
218
|
if (data.length > 0 && data.length % fileDescriptor.chunkSize === 0) {
|
|
180
219
|
headers.set('ChunkNumber', chunkNumber.toString());
|
|
181
|
-
this.
|
|
220
|
+
this.natsConnection.publish(subject, Empty, opts);
|
|
182
221
|
}
|
|
183
222
|
// Now that we have sent the terminating chunk, the result should arrive on our promise.
|
|
184
223
|
return this.withTimeout(responsePromise, timeout, subject).catch(err => {
|
|
@@ -229,12 +268,12 @@ export class BaseClient {
|
|
|
229
268
|
subscribe(subject, options = {}) {
|
|
230
269
|
if (!subject)
|
|
231
270
|
throw Error('Subject is not defined!');
|
|
232
|
-
if (!this.
|
|
271
|
+
if (!this.natsConnection)
|
|
233
272
|
throw Error('Connection is not up yet! Please try again later!');
|
|
234
|
-
if (this.
|
|
273
|
+
if (this.natsConnection.isClosed())
|
|
235
274
|
throw Error('Connection has been closed! Please reconnect!');
|
|
236
275
|
const natsSubject = options.fullSubject ? subject : `${this.baseSubject}.${subject}`;
|
|
237
|
-
return this.
|
|
276
|
+
return this.natsConnection.subscribe(natsSubject, options);
|
|
238
277
|
}
|
|
239
278
|
/**
|
|
240
279
|
* Subscribes to given subject.
|
|
@@ -243,12 +282,12 @@ export class BaseClient {
|
|
|
243
282
|
* @returns Subscription object
|
|
244
283
|
*/
|
|
245
284
|
createJetStreamConsumer(stream, subject, jetStreamOptions = {}, consumerOptions = {}) {
|
|
246
|
-
if (!this.
|
|
285
|
+
if (!this.natsConnection) {
|
|
247
286
|
throw Error('Connection is not established');
|
|
248
287
|
}
|
|
249
|
-
return this.
|
|
288
|
+
return this.natsConnection.jetstreamManager(Object.assign({}, jetStreamOptions)).then(jetStreamManager => jetStreamManager.consumers
|
|
250
289
|
.add(stream, Object.assign(Object.assign({}, consumerOptions), { filter_subject: subject, ack_policy: AckPolicy.None }))
|
|
251
|
-
.then(consumerInfo => this.
|
|
290
|
+
.then(consumerInfo => this.natsConnection.jetstream(jetStreamOptions).consumers.get(consumerInfo.stream_name, consumerInfo.name)));
|
|
252
291
|
}
|
|
253
292
|
encode(payload) {
|
|
254
293
|
if (!payload) {
|
|
@@ -263,16 +302,23 @@ export class BaseClient {
|
|
|
263
302
|
* Create a connection to the nats server.
|
|
264
303
|
* @param {ConnectionOptions} options
|
|
265
304
|
*/
|
|
266
|
-
connect() {
|
|
305
|
+
connect(connection) {
|
|
267
306
|
return __awaiter(this, void 0, void 0, function* () {
|
|
268
307
|
if (!this.baseSubject)
|
|
269
308
|
return Promise.reject('Subject must be given');
|
|
270
|
-
if (this.
|
|
309
|
+
if (this.natsConnection)
|
|
271
310
|
return Promise.resolve();
|
|
311
|
+
if (connection) {
|
|
312
|
+
if (connection.isClosed()) {
|
|
313
|
+
return Promise.reject('Provided connection is closed');
|
|
314
|
+
}
|
|
315
|
+
this.natsConnection = connection;
|
|
316
|
+
return Promise.resolve();
|
|
317
|
+
}
|
|
272
318
|
try {
|
|
273
319
|
return yield connect(this.connectionOptions)
|
|
274
320
|
.then((connection) => {
|
|
275
|
-
this.
|
|
321
|
+
this.natsConnection = connection;
|
|
276
322
|
return Promise.resolve();
|
|
277
323
|
})
|
|
278
324
|
.catch((error) => Promise.reject(`Failed to connect to ${this.connectionOptions.servers} with ${error}`));
|
|
@@ -288,9 +334,9 @@ export class BaseClient {
|
|
|
288
334
|
close() {
|
|
289
335
|
return __awaiter(this, void 0, void 0, function* () {
|
|
290
336
|
var _a;
|
|
291
|
-
if (this.
|
|
292
|
-
yield ((_a = this.
|
|
293
|
-
this.
|
|
337
|
+
if (this.natsConnection) {
|
|
338
|
+
yield ((_a = this.natsConnection) === null || _a === void 0 ? void 0 : _a.close().then(() => {
|
|
339
|
+
this.natsConnection = null;
|
|
294
340
|
}).catch((error) => {
|
|
295
341
|
throw new Error(`failed to close connection: ${error}`);
|
|
296
342
|
}));
|
|
@@ -617,6 +663,7 @@ export class BaseClient {
|
|
|
617
663
|
* Dispatches a request with the given subject and returns a Promise of type T
|
|
618
664
|
* @param subject The subject to send the request to
|
|
619
665
|
* @returns Promise<T> The response from the request
|
|
666
|
+
* @deprecated Use {@link request} instead.
|
|
620
667
|
*/
|
|
621
668
|
dispatchRequest(subject, payload, options) {
|
|
622
669
|
return __awaiter(this, void 0, void 0, function* () {
|
package/dist/mjs/DTOs.d.ts
CHANGED
|
@@ -876,7 +876,8 @@ export declare enum SessionState {
|
|
|
876
876
|
Breaking = "Breaking",
|
|
877
877
|
Aborting = "Aborting",
|
|
878
878
|
WaitingForUserInput = "WaitingForUserInput",
|
|
879
|
-
Loading = "Loading"
|
|
879
|
+
Loading = "Loading",
|
|
880
|
+
Restarting = "Restarting"
|
|
880
881
|
}
|
|
881
882
|
export declare class TestPlan implements ITestPlan {
|
|
882
883
|
childTestSteps?: TestStep[] | undefined;
|
|
@@ -1207,7 +1208,9 @@ export declare enum SessionEventName {
|
|
|
1207
1208
|
TestStepChanged = "TestStepChanged",
|
|
1208
1209
|
Break = "Break",
|
|
1209
1210
|
UserInputRequested = "UserInputRequested",
|
|
1210
|
-
UserInputRequestCompleted = "UserInputRequestCompleted"
|
|
1211
|
+
UserInputRequestCompleted = "UserInputRequestCompleted",
|
|
1212
|
+
RestartInitiated = "RestartInitiated",
|
|
1213
|
+
RestartCompleted = "RestartCompleted"
|
|
1211
1214
|
}
|
|
1212
1215
|
export declare abstract class SessionEvent {
|
|
1213
1216
|
readonly eventName: SessionEventName;
|
|
@@ -1315,6 +1318,21 @@ export declare class UserInputRequestCompletedEvent extends SessionEvent {
|
|
|
1315
1318
|
static fromJS(data: any): UserInputRequestCompletedEvent;
|
|
1316
1319
|
toJSON(data?: any): any;
|
|
1317
1320
|
}
|
|
1321
|
+
export declare class RestartInitiatedEvent extends SessionEvent {
|
|
1322
|
+
oldProcessId?: number;
|
|
1323
|
+
constructor(data?: Partial<RestartInitiatedEvent>);
|
|
1324
|
+
init(_data?: any): void;
|
|
1325
|
+
static fromJS(data: any): RestartInitiatedEvent;
|
|
1326
|
+
toJSON(data?: any): any;
|
|
1327
|
+
}
|
|
1328
|
+
export declare class RestartCompletedEvent extends SessionEvent {
|
|
1329
|
+
success?: boolean;
|
|
1330
|
+
newProcessId?: number;
|
|
1331
|
+
constructor(data?: Partial<RestartCompletedEvent>);
|
|
1332
|
+
init(_data?: any): void;
|
|
1333
|
+
static fromJS(data: any): RestartCompletedEvent;
|
|
1334
|
+
toJSON(data?: any): any;
|
|
1335
|
+
}
|
|
1318
1336
|
export type ISessionEvent = SessionEvent;
|
|
1319
1337
|
export interface IOnTestPlanRun {
|
|
1320
1338
|
status?: string;
|
package/dist/mjs/DTOs.js
CHANGED
|
@@ -2143,6 +2143,7 @@ export var SessionState;
|
|
|
2143
2143
|
SessionState["Aborting"] = "Aborting";
|
|
2144
2144
|
SessionState["WaitingForUserInput"] = "WaitingForUserInput";
|
|
2145
2145
|
SessionState["Loading"] = "Loading";
|
|
2146
|
+
SessionState["Restarting"] = "Restarting";
|
|
2146
2147
|
})(SessionState || (SessionState = {}));
|
|
2147
2148
|
export class TestPlan {
|
|
2148
2149
|
constructor(data) {
|
|
@@ -2925,6 +2926,8 @@ export var SessionEventName;
|
|
|
2925
2926
|
SessionEventName["Break"] = "Break";
|
|
2926
2927
|
SessionEventName["UserInputRequested"] = "UserInputRequested";
|
|
2927
2928
|
SessionEventName["UserInputRequestCompleted"] = "UserInputRequestCompleted";
|
|
2929
|
+
SessionEventName["RestartInitiated"] = "RestartInitiated";
|
|
2930
|
+
SessionEventName["RestartCompleted"] = "RestartCompleted";
|
|
2928
2931
|
})(SessionEventName || (SessionEventName = {}));
|
|
2929
2932
|
export class SessionEvent {
|
|
2930
2933
|
constructor(eventName) {
|
|
@@ -3200,6 +3203,52 @@ export class UserInputRequestCompletedEvent extends SessionEvent {
|
|
|
3200
3203
|
return json;
|
|
3201
3204
|
}
|
|
3202
3205
|
}
|
|
3206
|
+
export class RestartInitiatedEvent extends SessionEvent {
|
|
3207
|
+
constructor(data) {
|
|
3208
|
+
super(SessionEventName.RestartInitiated);
|
|
3209
|
+
if (data) {
|
|
3210
|
+
Object.assign(this, data);
|
|
3211
|
+
}
|
|
3212
|
+
}
|
|
3213
|
+
init(_data) {
|
|
3214
|
+
const data = ensureObject(_data);
|
|
3215
|
+
this.oldProcessId = data['OldProcessId'];
|
|
3216
|
+
}
|
|
3217
|
+
static fromJS(data) {
|
|
3218
|
+
const result = new RestartInitiatedEvent();
|
|
3219
|
+
result.init(data);
|
|
3220
|
+
return result;
|
|
3221
|
+
}
|
|
3222
|
+
toJSON(data) {
|
|
3223
|
+
const json = ensureObject(data);
|
|
3224
|
+
json['OldProcessId'] = this.oldProcessId;
|
|
3225
|
+
return json;
|
|
3226
|
+
}
|
|
3227
|
+
}
|
|
3228
|
+
export class RestartCompletedEvent extends SessionEvent {
|
|
3229
|
+
constructor(data) {
|
|
3230
|
+
super(SessionEventName.RestartCompleted);
|
|
3231
|
+
if (data) {
|
|
3232
|
+
Object.assign(this, data);
|
|
3233
|
+
}
|
|
3234
|
+
}
|
|
3235
|
+
init(_data) {
|
|
3236
|
+
const data = ensureObject(_data);
|
|
3237
|
+
this.success = data['Success'];
|
|
3238
|
+
this.newProcessId = data['NewProcessId'];
|
|
3239
|
+
}
|
|
3240
|
+
static fromJS(data) {
|
|
3241
|
+
const result = new RestartCompletedEvent();
|
|
3242
|
+
result.init(data);
|
|
3243
|
+
return result;
|
|
3244
|
+
}
|
|
3245
|
+
toJSON(data) {
|
|
3246
|
+
const json = ensureObject(data);
|
|
3247
|
+
json['Success'] = this.success;
|
|
3248
|
+
json['NewProcessId'] = this.newProcessId;
|
|
3249
|
+
return json;
|
|
3250
|
+
}
|
|
3251
|
+
}
|
|
3203
3252
|
export class OnTestPlanRun {
|
|
3204
3253
|
constructor(data) {
|
|
3205
3254
|
if (data) {
|
|
@@ -58,6 +58,12 @@ export declare class RunnerClient extends BaseClient {
|
|
|
58
58
|
* @returns {{Promise<void>}}
|
|
59
59
|
*/
|
|
60
60
|
shutdownSession(sessionId: string, force?: boolean): Promise<void>;
|
|
61
|
+
/**
|
|
62
|
+
* Restart a session
|
|
63
|
+
* @param sessionId the ID of the session to restart
|
|
64
|
+
* @returns {{Promise<void>}}
|
|
65
|
+
*/
|
|
66
|
+
restartSession(sessionId: string): Promise<void>;
|
|
61
67
|
/**
|
|
62
68
|
* Start a session
|
|
63
69
|
* @returns {{Promise<Session>}}
|
package/dist/mjs/RunnerClient.js
CHANGED
|
@@ -171,6 +171,16 @@ export class RunnerClient extends BaseClient {
|
|
|
171
171
|
.catch(this.error())
|
|
172
172
|
: Promise.reject('sessionId is not defined');
|
|
173
173
|
}
|
|
174
|
+
/**
|
|
175
|
+
* Restart a session
|
|
176
|
+
* @param sessionId the ID of the session to restart
|
|
177
|
+
* @returns {{Promise<void>}}
|
|
178
|
+
*/
|
|
179
|
+
restartSession(sessionId) {
|
|
180
|
+
return (sessionId === null || sessionId === void 0 ? void 0 : sessionId.length) > 0
|
|
181
|
+
? this.request('RestartSession', { SessionId: sessionId }).then(this.success()).catch(this.error())
|
|
182
|
+
: Promise.reject('sessionId is not defined');
|
|
183
|
+
}
|
|
174
184
|
/**
|
|
175
185
|
* Start a session
|
|
176
186
|
* @returns {{Promise<Session>}}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BreakEvent, BreakPoints, CommonContext, CommonSettings, DataGridControl, GetTestPlanReferenceResponse, HeartbeatEvent, Image, Interaction, ListItemType, LogList, MetricsConfiguration, OnTestPlanRun, OnTestStepRun, Result, RunStatus, SaveTestPlanToRepositoryResponse, SessionEventName, SessionStateChangedEvent, SessionTimeoutEvent, Setting, SettingsChangedEvent, StartingEvent, StartedEvent, StoppedEvent, StoppingEvent, TestPlan, TestPlanChangedEvent, TestPlanReferenceChangedEvent, TestPlanSettingsChangedEvent, TestStepChangedEvent, TestStepType, TestStepValidationError, TypeCacheInvalidatedEvent, UserInputRequestCompletedEvent, UserInputRequestedEvent, WatchDog, EditStatus, } from './DTOs';
|
|
1
|
+
import { BreakEvent, BreakPoints, CommonContext, CommonSettings, DataGridControl, GetTestPlanReferenceResponse, HeartbeatEvent, Image, Interaction, ListItemType, LogList, MetricsConfiguration, OnTestPlanRun, OnTestStepRun, Result, RunStatus, SaveTestPlanToRepositoryResponse, SessionEventName, SessionStateChangedEvent, SessionTimeoutEvent, Setting, SettingsChangedEvent, StartingEvent, StartedEvent, StoppedEvent, StoppingEvent, TestPlan, TestPlanChangedEvent, TestPlanReferenceChangedEvent, TestPlanSettingsChangedEvent, TestStepChangedEvent, TestStepType, TestStepValidationError, TypeCacheInvalidatedEvent, UserInputRequestCompletedEvent, UserInputRequestedEvent, RestartInitiatedEvent, RestartCompletedEvent, WatchDog, EditStatus, } from './DTOs';
|
|
2
2
|
import { BaseClient } from './BaseClient';
|
|
3
3
|
import { jsonCodec } from './encoders';
|
|
4
4
|
import { NIL } from 'uuid';
|
|
@@ -808,4 +808,6 @@ SessionClient.sessionEventFactories = {
|
|
|
808
808
|
[SessionEventName.Break]: payload => BreakEvent.fromJS(payload),
|
|
809
809
|
[SessionEventName.UserInputRequested]: payload => UserInputRequestedEvent.fromJS(payload),
|
|
810
810
|
[SessionEventName.UserInputRequestCompleted]: payload => UserInputRequestCompletedEvent.fromJS(payload),
|
|
811
|
+
[SessionEventName.RestartInitiated]: payload => RestartInitiatedEvent.fromJS(payload),
|
|
812
|
+
[SessionEventName.RestartCompleted]: payload => RestartCompletedEvent.fromJS(payload),
|
|
811
813
|
};
|