@opentap/runner-client 2.3.2-alpha.1.5 → 2.3.2-alpha.1.7
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/lib/BaseClient.d.ts +1 -1
- package/lib/BaseClient.js +51 -35
- package/package.json +1 -1
package/lib/BaseClient.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ComponentSettingsBase, ComponentSettingsIdentifier, ComponentSettingsListItem, DataGridControl, ErrorResponse, FileParameter, FileResponse, ListItemType, ProfileGroup, RepositoryPackageReference, RepositorySettingsPackageDefinition, SettingsTapPackage } from './DTOs';
|
|
2
2
|
import { ConnectionOptions, Subscription, SubscriptionOptions, PublishOptions } from 'nats.ws';
|
|
3
3
|
interface BaseClientRequestOptions {
|
|
4
|
-
|
|
4
|
+
publishOptions?: PublishOptions;
|
|
5
5
|
rawResponse?: boolean;
|
|
6
6
|
fullSubject?: boolean;
|
|
7
7
|
timeout?: number;
|
package/lib/BaseClient.js
CHANGED
|
@@ -99,7 +99,7 @@ var BaseClient = /** @class */ (function () {
|
|
|
99
99
|
configurable: true
|
|
100
100
|
});
|
|
101
101
|
BaseClient.prototype.withTimeout = function (promise, timeout) {
|
|
102
|
-
return Promise.race([promise, new Promise(function (_, reject) { return setTimeout(function () { return reject(new Error(
|
|
102
|
+
return Promise.race([promise, new Promise(function (_, reject) { return setTimeout(function () { return reject(new Error(ErrorCode.Timeout)); }, timeout); })]);
|
|
103
103
|
};
|
|
104
104
|
/**
|
|
105
105
|
* Send a request to the nats server.
|
|
@@ -109,10 +109,11 @@ var BaseClient = /** @class */ (function () {
|
|
|
109
109
|
* @returns Promise of an object
|
|
110
110
|
*/
|
|
111
111
|
BaseClient.prototype.request = function (subject, payload, options) {
|
|
112
|
+
var _a, _b, _c;
|
|
112
113
|
return __awaiter(this, void 0, void 0, function () {
|
|
113
|
-
var data, headers, replySubject,
|
|
114
|
+
var data, headers, timeout, replySubject, chunkSize, requestId, opts, fileDescriptor, chunkNumber, getChunk, subscription, responsePromise, chunk, i;
|
|
114
115
|
var _this = this;
|
|
115
|
-
return __generator(this, function (
|
|
116
|
+
return __generator(this, function (_d) {
|
|
116
117
|
// Prepend the base subject if the given subject does not start with that
|
|
117
118
|
if (!(options === null || options === void 0 ? void 0 : options.fullSubject)) {
|
|
118
119
|
subject = "".concat(this.baseSubject, ".Request.").concat(subject);
|
|
@@ -123,55 +124,73 @@ var BaseClient = /** @class */ (function () {
|
|
|
123
124
|
return [2 /*return*/, Promise.reject("".concat(subject, ": Connection has been closed! Please reconnect!"))];
|
|
124
125
|
data = this.encode(payload);
|
|
125
126
|
headers = this.buildHeaders();
|
|
127
|
+
timeout = (options === null || options === void 0 ? void 0 : options.timeout) || this.timeout;
|
|
126
128
|
replySubject = crypto.randomUUID();
|
|
127
|
-
|
|
128
|
-
|
|
129
|
+
chunkSize = ((_c = (_b = (_a = this.connection) === null || _a === void 0 ? void 0 : _a.info) === null || _b === void 0 ? void 0 : _b.max_payload) !== null && _c !== void 0 ? _c : 512000) - 2000;
|
|
130
|
+
// The Session and the Client need to agree on the chunk size. Put it in a header.
|
|
131
|
+
headers.append('ChunkSize', chunkSize.toString());
|
|
129
132
|
requestId = crypto.randomUUID();
|
|
130
133
|
headers.append('RequestId', requestId);
|
|
131
|
-
opts = __assign(__assign({}, options === null || options === void 0 ? void 0 : options.
|
|
132
|
-
fileDescriptor = new FileDescriptor(data.length,
|
|
134
|
+
opts = __assign(__assign({}, options === null || options === void 0 ? void 0 : options.publishOptions), { headers: headers, reply: replySubject });
|
|
135
|
+
fileDescriptor = new FileDescriptor(data.length, chunkSize);
|
|
133
136
|
chunkNumber = 1;
|
|
134
137
|
headers.set('ChunkNumber', chunkNumber.toString());
|
|
135
|
-
subscription = this.connection.subscribe(replySubject);
|
|
136
138
|
getChunk = function (chunk) {
|
|
137
139
|
var offset = chunk * fileDescriptor.chunkSize;
|
|
138
140
|
return data.slice(offset, offset + fileDescriptor.chunkSize);
|
|
139
141
|
};
|
|
140
|
-
|
|
142
|
+
subscription = this.connection.subscribe(replySubject, { timeout: timeout });
|
|
141
143
|
responsePromise = new Promise(function (resolve, reject) {
|
|
142
144
|
var messages = [];
|
|
143
145
|
subscription.callback = function (error, message) {
|
|
144
146
|
var _a;
|
|
145
147
|
if (error) {
|
|
148
|
+
subscription.unsubscribe();
|
|
149
|
+
console.log('error:', error);
|
|
146
150
|
reject(error);
|
|
147
151
|
}
|
|
152
|
+
// Put all the response chunks in an array in the order they are received
|
|
148
153
|
messages.push(message);
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
var finalMessageNumber = (_a = finalMessage.headers) === null || _a === void 0 ? void 0 : _a.get('ChunkNumber');
|
|
153
|
-
if (!finalMessageNumber) {
|
|
154
|
-
return reject('Response is not a valid chunk.');
|
|
155
|
-
}
|
|
156
|
-
if (parseInt(finalMessageNumber) !== messages.length) {
|
|
157
|
-
return reject("Expected {finalMessageNumber} chunks, but received ".concat(messages.length, ". ") +
|
|
158
|
-
"The connection may have been interrupted.");
|
|
159
|
-
}
|
|
160
|
-
// Concatenate the payloads
|
|
161
|
-
var dataArrays = messages.map(function (m) { return m.data; });
|
|
162
|
-
var totalSize = dataArrays.reduce(function (total, current) { return total + current.length; }, 0);
|
|
163
|
-
var flattenedArray_1 = new Uint8Array(totalSize);
|
|
164
|
-
var k_1 = 0;
|
|
165
|
-
dataArrays.map(function (m) {
|
|
166
|
-
for (var i = 0; i < m.length; i++) {
|
|
167
|
-
flattenedArray_1[k_1++] = m[i];
|
|
168
|
-
}
|
|
169
|
-
});
|
|
170
|
-
return resolve(flattenedArray_1);
|
|
154
|
+
// If the chunk has a size equal to the chunkSize, we should expect another message
|
|
155
|
+
if (message.data.length === chunkSize) {
|
|
156
|
+
return;
|
|
171
157
|
}
|
|
158
|
+
// If the chunk has a length smaller than the chunkSize, the message is complete
|
|
159
|
+
// If the final message was received, we can safely unsubscribe
|
|
160
|
+
subscription.unsubscribe();
|
|
161
|
+
// Check if the number of the final message is equal to the number of
|
|
162
|
+
// messages we received. If this is not the case, we dropped a chunk,
|
|
163
|
+
// likely due to a network error. In this case, the entire message is invalid.
|
|
164
|
+
var finalMessage = message;
|
|
165
|
+
var finalMessageNumber = (_a = finalMessage.headers) === null || _a === void 0 ? void 0 : _a.get('ChunkNumber');
|
|
166
|
+
if (!finalMessageNumber) {
|
|
167
|
+
return reject('Response is not a valid chunk.');
|
|
168
|
+
}
|
|
169
|
+
if (parseInt(finalMessageNumber) !== messages.length) {
|
|
170
|
+
return reject("Expected {finalMessageNumber} chunks, but received ".concat(messages.length, ". ") +
|
|
171
|
+
"The connection may have been interrupted.");
|
|
172
|
+
}
|
|
173
|
+
// Concatenate the payloads
|
|
174
|
+
// When there are many chunks, doing a single allocation
|
|
175
|
+
// is significantly faster than concatenating arrays in sequence
|
|
176
|
+
var dataArrays = messages.map(function (m) { return m.data; });
|
|
177
|
+
var flattenedSize = dataArrays.reduce(function (sum, array) { return sum + array.length; }, 0);
|
|
178
|
+
var flattenedArray = new Uint8Array(flattenedSize);
|
|
179
|
+
var k = 0;
|
|
180
|
+
dataArrays.map(function (m) {
|
|
181
|
+
for (var i = 0; i < m.length; i++) {
|
|
182
|
+
flattenedArray[k++] = m[i];
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
return resolve(flattenedArray);
|
|
172
186
|
};
|
|
173
187
|
})
|
|
174
188
|
.then(function (byteArray) {
|
|
189
|
+
if (byteArray.length === 0) {
|
|
190
|
+
return Promise.resolve(undefined);
|
|
191
|
+
}
|
|
192
|
+
var jsonCodec = JSONCodec();
|
|
193
|
+
// If a raw response is requested, we should avoid decoding the bytes.
|
|
175
194
|
var response = (options === null || options === void 0 ? void 0 : options.rawResponse) ? byteArray : jsonCodec.decode(byteArray);
|
|
176
195
|
return _this.isErrorResponse(response) ? Promise.reject(ErrorResponse.fromJS(response)) : Promise.resolve(response);
|
|
177
196
|
})
|
|
@@ -194,10 +213,7 @@ var BaseClient = /** @class */ (function () {
|
|
|
194
213
|
this.connection.publish(subject, Empty, opts);
|
|
195
214
|
}
|
|
196
215
|
// Now that we have sent the terminating chunk, the result should arrive on our promise.
|
|
197
|
-
|
|
198
|
-
return [2 /*return*/, this.withTimeout(responsePromise, options.timeout)];
|
|
199
|
-
}
|
|
200
|
-
return [2 /*return*/, responsePromise];
|
|
216
|
+
return [2 /*return*/, this.withTimeout(responsePromise, timeout)];
|
|
201
217
|
});
|
|
202
218
|
});
|
|
203
219
|
};
|