arangojs 7.8.0 → 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +264 -3
- package/CONTRIBUTING.md +1 -1
- package/MIGRATING.md +126 -2
- package/README.md +7 -13
- package/analyzer.d.ts +531 -253
- package/analyzer.d.ts.map +1 -1
- package/analyzer.js +9 -8
- package/analyzer.js.map +1 -1
- package/aql.d.ts +122 -139
- package/aql.d.ts.map +1 -1
- package/aql.js +146 -148
- package/aql.js.map +1 -1
- package/collection.d.ts +311 -310
- package/collection.d.ts.map +1 -1
- package/collection.js +163 -96
- package/collection.js.map +1 -1
- package/connection.d.ts +65 -52
- package/connection.d.ts.map +1 -1
- package/connection.js +142 -140
- package/connection.js.map +1 -1
- package/cursor.d.ts +108 -26
- package/cursor.d.ts.map +1 -1
- package/cursor.js +24 -23
- package/cursor.js.map +1 -1
- package/database.d.ts +298 -330
- package/database.d.ts.map +1 -1
- package/database.js +178 -252
- package/database.js.map +1 -1
- package/documents.d.ts +3 -4
- package/documents.d.ts.map +1 -1
- package/documents.js +0 -1
- package/documents.js.map +1 -1
- package/error.d.ts +3 -6
- package/error.d.ts.map +1 -1
- package/error.js +5 -7
- package/error.js.map +1 -1
- package/foxx-manifest.d.ts +7 -8
- package/foxx-manifest.d.ts.map +1 -1
- package/foxx-manifest.js +1 -1
- package/foxx-manifest.js.map +1 -1
- package/graph.d.ts +38 -56
- package/graph.d.ts.map +1 -1
- package/graph.js +59 -63
- package/graph.js.map +1 -1
- package/index.d.ts +6 -8
- package/index.d.ts.map +1 -1
- package/index.js +1 -6
- package/index.js.map +1 -1
- package/indexes.d.ts +348 -127
- package/indexes.d.ts.map +1 -1
- package/indexes.js +1 -3
- package/indexes.js.map +1 -1
- package/lib/blob.d.ts +0 -2
- package/lib/blob.d.ts.map +1 -1
- package/lib/blob.js +0 -1
- package/lib/blob.js.map +1 -1
- package/lib/btoa.d.ts +1 -3
- package/lib/btoa.d.ts.map +1 -1
- package/lib/btoa.js +3 -5
- package/lib/btoa.js.map +1 -1
- package/lib/btoa.web.d.ts +1 -3
- package/lib/btoa.web.d.ts.map +1 -1
- package/lib/btoa.web.js +4 -6
- package/lib/btoa.web.js.map +1 -1
- package/lib/codes.d.ts +2 -2
- package/lib/codes.d.ts.map +1 -1
- package/lib/codes.js +3 -3
- package/lib/codes.js.map +1 -1
- package/lib/errback.d.ts +0 -2
- package/lib/errback.d.ts.map +1 -1
- package/lib/errback.js.map +1 -1
- package/lib/joinPath.d.ts +0 -2
- package/lib/joinPath.d.ts.map +1 -1
- package/lib/joinPath.js +0 -2
- package/lib/joinPath.js.map +1 -1
- package/lib/joinPath.web.d.ts +1 -3
- package/lib/joinPath.web.d.ts.map +1 -1
- package/lib/joinPath.web.js +7 -4
- package/lib/joinPath.web.js.map +1 -1
- package/lib/multipart.d.ts +0 -4
- package/lib/multipart.d.ts.map +1 -1
- package/lib/multipart.js +16 -37
- package/lib/multipart.js.map +1 -1
- package/lib/multipart.web.d.ts +0 -2
- package/lib/multipart.web.d.ts.map +1 -1
- package/lib/multipart.web.js +0 -2
- package/lib/multipart.web.js.map +1 -1
- package/lib/normalizeUrl.d.ts +0 -2
- package/lib/normalizeUrl.d.ts.map +1 -1
- package/lib/normalizeUrl.js +0 -2
- package/lib/normalizeUrl.js.map +1 -1
- package/lib/omit.d.ts +1 -3
- package/lib/omit.d.ts.map +1 -1
- package/lib/omit.js +1 -2
- package/lib/omit.js.map +1 -1
- package/lib/querystringify.d.ts +4 -0
- package/lib/querystringify.d.ts.map +1 -0
- package/lib/querystringify.js +20 -0
- package/lib/querystringify.js.map +1 -0
- package/lib/querystringify.web.d.ts +2 -0
- package/lib/querystringify.web.d.ts.map +1 -0
- package/lib/querystringify.web.js +30 -0
- package/lib/querystringify.web.js.map +1 -0
- package/lib/request.d.ts +0 -1
- package/lib/request.d.ts.map +1 -1
- package/lib/request.js +6 -3
- package/lib/request.js.map +1 -1
- package/lib/request.node.d.ts +2 -8
- package/lib/request.node.d.ts.map +1 -1
- package/lib/request.node.js +16 -7
- package/lib/request.node.js.map +1 -1
- package/lib/request.web.d.ts +2 -3
- package/lib/request.web.d.ts.map +1 -1
- package/lib/request.web.js +26 -29
- package/lib/request.web.js.map +1 -1
- package/lib/xhr.d.ts +1 -3
- package/lib/xhr.d.ts.map +1 -1
- package/lib/xhr.js +0 -2
- package/lib/xhr.js.map +1 -1
- package/package.json +5 -6
- package/route.d.ts +1 -2
- package/route.d.ts.map +1 -1
- package/route.js +1 -2
- package/route.js.map +1 -1
- package/transaction.d.ts +31 -6
- package/transaction.d.ts.map +1 -1
- package/transaction.js +13 -6
- package/transaction.js.map +1 -1
- package/view.d.ts +237 -181
- package/view.d.ts.map +1 -1
- package/view.js +17 -25
- package/view.js.map +1 -1
- package/web.js +1 -1
- package/web.js.map +1 -1
- package/lib/error.d.ts +0 -18
- package/lib/error.d.ts.map +0 -1
- package/lib/error.js +0 -18
- package/lib/error.js.map +0 -1
package/connection.js
CHANGED
|
@@ -1,31 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Connection = exports.isArangoConnection = void 0;
|
|
4
|
-
const querystring_1 = require("querystring");
|
|
5
4
|
const x3_linkedlist_1 = require("x3-linkedlist");
|
|
6
5
|
const error_1 = require("./error");
|
|
7
6
|
const btoa_1 = require("./lib/btoa");
|
|
8
7
|
const codes_1 = require("./lib/codes");
|
|
9
8
|
const normalizeUrl_1 = require("./lib/normalizeUrl");
|
|
9
|
+
const querystringify_1 = require("./lib/querystringify");
|
|
10
10
|
const request_1 = require("./lib/request");
|
|
11
11
|
const MIME_JSON = /\/(json|javascript)(\W|$)/;
|
|
12
12
|
const LEADER_ENDPOINT_HEADER = "x-arango-endpoint";
|
|
13
|
-
function clean(obj) {
|
|
14
|
-
const result = {};
|
|
15
|
-
for (const key of Object.keys(obj)) {
|
|
16
|
-
const value = obj[key];
|
|
17
|
-
if (value === undefined)
|
|
18
|
-
continue;
|
|
19
|
-
result[key] = value;
|
|
20
|
-
}
|
|
21
|
-
return result;
|
|
22
|
-
}
|
|
23
13
|
function isBearerAuth(auth) {
|
|
24
14
|
return auth.hasOwnProperty("token");
|
|
25
15
|
}
|
|
26
16
|
/**
|
|
27
17
|
* @internal
|
|
28
|
-
* @hidden
|
|
29
18
|
*/
|
|
30
19
|
function generateStackTrace() {
|
|
31
20
|
let err = new Error();
|
|
@@ -45,7 +34,6 @@ function generateStackTrace() {
|
|
|
45
34
|
* @param connection - A value that might be a connection.
|
|
46
35
|
*
|
|
47
36
|
* @internal
|
|
48
|
-
* @hidden
|
|
49
37
|
*/
|
|
50
38
|
function isArangoConnection(connection) {
|
|
51
39
|
return Boolean(connection && connection.isArangoConnection);
|
|
@@ -55,7 +43,6 @@ exports.isArangoConnection = isArangoConnection;
|
|
|
55
43
|
* Represents a connection pool shared by one or more databases.
|
|
56
44
|
*
|
|
57
45
|
* @internal
|
|
58
|
-
* @hidden
|
|
59
46
|
*/
|
|
60
47
|
class Connection {
|
|
61
48
|
/**
|
|
@@ -65,23 +52,21 @@ class Connection {
|
|
|
65
52
|
*
|
|
66
53
|
* @param config - An object with configuration options.
|
|
67
54
|
*
|
|
68
|
-
* @hidden
|
|
69
55
|
*/
|
|
70
56
|
constructor(config = {}) {
|
|
71
|
-
var _a, _b, _c;
|
|
72
57
|
this._activeTasks = 0;
|
|
73
|
-
this._arangoVersion =
|
|
58
|
+
this._arangoVersion = 30900;
|
|
74
59
|
this._queue = new x3_linkedlist_1.LinkedList();
|
|
75
60
|
this._databases = new Map();
|
|
76
61
|
this._hosts = [];
|
|
77
|
-
this.
|
|
62
|
+
this._hostUrls = [];
|
|
78
63
|
this._transactionId = null;
|
|
79
64
|
this._queueTimes = new x3_linkedlist_1.LinkedList();
|
|
80
65
|
const URLS = config.url
|
|
81
66
|
? Array.isArray(config.url)
|
|
82
67
|
? config.url
|
|
83
68
|
: [config.url]
|
|
84
|
-
: ["http://
|
|
69
|
+
: ["http://127.0.0.1:8529"];
|
|
85
70
|
const MAX_SOCKETS = 3 * (config.loadBalancingStrategy === "ROUND_ROBIN" ? URLS.length : 1);
|
|
86
71
|
if (config.arangoVersion !== undefined) {
|
|
87
72
|
this._arangoVersion = config.arangoVersion;
|
|
@@ -98,20 +83,18 @@ class Connection {
|
|
|
98
83
|
};
|
|
99
84
|
this._maxTasks = this._agentOptions.maxSockets;
|
|
100
85
|
this._headers = { ...config.headers };
|
|
101
|
-
this._loadBalancingStrategy =
|
|
102
|
-
this._useFailOver = this._loadBalancingStrategy !== "ROUND_ROBIN";
|
|
86
|
+
this._loadBalancingStrategy = config.loadBalancingStrategy ?? "NONE";
|
|
103
87
|
this._precaptureStackTraces = Boolean(config.precaptureStackTraces);
|
|
104
|
-
this._responseQueueTimeSamples =
|
|
88
|
+
this._responseQueueTimeSamples = config.responseQueueTimeSamples ?? 10;
|
|
89
|
+
this._retryOnConflict = config.retryOnConflict ?? 0;
|
|
105
90
|
if (this._responseQueueTimeSamples < 0) {
|
|
106
91
|
this._responseQueueTimeSamples = Infinity;
|
|
107
92
|
}
|
|
108
93
|
if (config.maxRetries === false) {
|
|
109
|
-
this.
|
|
110
|
-
this._maxRetries = 0;
|
|
94
|
+
this._maxRetries = false;
|
|
111
95
|
}
|
|
112
96
|
else {
|
|
113
|
-
this.
|
|
114
|
-
this._maxRetries = (_c = config.maxRetries) !== null && _c !== void 0 ? _c : 0;
|
|
97
|
+
this._maxRetries = Number(config.maxRetries ?? 0);
|
|
115
98
|
}
|
|
116
99
|
this.addToHostList(URLS);
|
|
117
100
|
if (config.auth) {
|
|
@@ -123,12 +106,14 @@ class Connection {
|
|
|
123
106
|
}
|
|
124
107
|
}
|
|
125
108
|
if (this._loadBalancingStrategy === "ONE_RANDOM") {
|
|
126
|
-
this.
|
|
127
|
-
|
|
109
|
+
this._activeHostUrl =
|
|
110
|
+
this._hostUrls[Math.floor(Math.random() * this._hostUrls.length)];
|
|
111
|
+
this._activeDirtyHostUrl =
|
|
112
|
+
this._hostUrls[Math.floor(Math.random() * this._hostUrls.length)];
|
|
128
113
|
}
|
|
129
114
|
else {
|
|
130
|
-
this.
|
|
131
|
-
this.
|
|
115
|
+
this._activeHostUrl = this._hostUrls[0];
|
|
116
|
+
this._activeDirtyHostUrl = this._hostUrls[0];
|
|
132
117
|
}
|
|
133
118
|
}
|
|
134
119
|
/**
|
|
@@ -141,7 +126,7 @@ class Connection {
|
|
|
141
126
|
}
|
|
142
127
|
get queueTime() {
|
|
143
128
|
return {
|
|
144
|
-
getLatest: () =>
|
|
129
|
+
getLatest: () => this._queueTimes.last?.value[1],
|
|
145
130
|
getValues: () => Array.from(this._queueTimes.values()),
|
|
146
131
|
getAvg: () => {
|
|
147
132
|
let avg = 0;
|
|
@@ -156,40 +141,109 @@ class Connection {
|
|
|
156
141
|
if (!this._queue.length || this._activeTasks >= this._maxTasks)
|
|
157
142
|
return;
|
|
158
143
|
const task = this._queue.shift();
|
|
159
|
-
let
|
|
160
|
-
if (task.
|
|
161
|
-
|
|
144
|
+
let hostUrl = this._activeHostUrl;
|
|
145
|
+
if (task.hostUrl !== undefined) {
|
|
146
|
+
hostUrl = task.hostUrl;
|
|
162
147
|
}
|
|
163
148
|
else if (task.allowDirtyRead) {
|
|
164
|
-
|
|
165
|
-
this.
|
|
149
|
+
hostUrl = this._activeDirtyHostUrl;
|
|
150
|
+
this._activeDirtyHostUrl =
|
|
151
|
+
this._hostUrls[(this._hostUrls.indexOf(this._activeDirtyHostUrl) + 1) %
|
|
152
|
+
this._hostUrls.length];
|
|
166
153
|
task.options.headers["x-arango-allow-dirty-read"] = "true";
|
|
167
154
|
}
|
|
168
155
|
else if (this._loadBalancingStrategy === "ROUND_ROBIN") {
|
|
169
|
-
this.
|
|
156
|
+
this._activeHostUrl =
|
|
157
|
+
this._hostUrls[(this._hostUrls.indexOf(this._activeHostUrl) + 1) %
|
|
158
|
+
this._hostUrls.length];
|
|
170
159
|
}
|
|
171
160
|
this._activeTasks += 1;
|
|
172
161
|
const callback = (err, res) => {
|
|
173
162
|
this._activeTasks -= 1;
|
|
163
|
+
if (!err && res) {
|
|
164
|
+
if (res.statusCode === 503 && res.headers[LEADER_ENDPOINT_HEADER]) {
|
|
165
|
+
const url = res.headers[LEADER_ENDPOINT_HEADER];
|
|
166
|
+
const [cleanUrl] = this.addToHostList(url);
|
|
167
|
+
task.hostUrl = cleanUrl;
|
|
168
|
+
if (this._activeHostUrl === hostUrl) {
|
|
169
|
+
this._activeHostUrl = cleanUrl;
|
|
170
|
+
}
|
|
171
|
+
this._queue.push(task);
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
res.arangojsHostUrl = hostUrl;
|
|
175
|
+
const contentType = res.headers["content-type"];
|
|
176
|
+
const queueTime = res.headers["x-arango-queue-time-seconds"];
|
|
177
|
+
if (queueTime) {
|
|
178
|
+
this._queueTimes.push([Date.now(), Number(queueTime)]);
|
|
179
|
+
while (this._responseQueueTimeSamples < this._queueTimes.length) {
|
|
180
|
+
this._queueTimes.shift();
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
let parsedBody = undefined;
|
|
184
|
+
if (res.body.length && contentType && contentType.match(MIME_JSON)) {
|
|
185
|
+
try {
|
|
186
|
+
parsedBody = res.body;
|
|
187
|
+
parsedBody = JSON.parse(parsedBody);
|
|
188
|
+
}
|
|
189
|
+
catch (e) {
|
|
190
|
+
if (!task.options.expectBinary) {
|
|
191
|
+
if (typeof parsedBody !== "string") {
|
|
192
|
+
parsedBody = res.body.toString("utf-8");
|
|
193
|
+
}
|
|
194
|
+
e.res = res;
|
|
195
|
+
if (task.stack) {
|
|
196
|
+
e.stack += task.stack();
|
|
197
|
+
}
|
|
198
|
+
callback(e);
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
else if (res.body && !task.options.expectBinary) {
|
|
204
|
+
parsedBody = res.body.toString("utf-8");
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
parsedBody = res.body;
|
|
208
|
+
}
|
|
209
|
+
if ((0, error_1.isArangoErrorResponse)(parsedBody)) {
|
|
210
|
+
res.body = parsedBody;
|
|
211
|
+
err = new error_1.ArangoError(res);
|
|
212
|
+
}
|
|
213
|
+
else if (res.statusCode && res.statusCode >= 400) {
|
|
214
|
+
res.body = parsedBody;
|
|
215
|
+
err = new error_1.HttpError(res);
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
if (!task.options.expectBinary)
|
|
219
|
+
res.body = parsedBody;
|
|
220
|
+
task.resolve(task.transform ? task.transform(res) : res);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
174
224
|
if (err) {
|
|
175
225
|
if (!task.allowDirtyRead &&
|
|
176
226
|
this._hosts.length > 1 &&
|
|
177
|
-
this.
|
|
178
|
-
this.
|
|
179
|
-
this.
|
|
227
|
+
this._activeHostUrl === hostUrl &&
|
|
228
|
+
this._loadBalancingStrategy !== "ROUND_ROBIN") {
|
|
229
|
+
this._activeHostUrl =
|
|
230
|
+
this._hostUrls[(this._hostUrls.indexOf(this._activeHostUrl) + 1) %
|
|
231
|
+
this._hostUrls.length];
|
|
180
232
|
}
|
|
181
|
-
if (error_1.isArangoError(err) &&
|
|
233
|
+
if ((0, error_1.isArangoError)(err) &&
|
|
182
234
|
err.errorNum === codes_1.ERROR_ARANGO_CONFLICT &&
|
|
183
235
|
task.retryOnConflict > 0) {
|
|
184
236
|
task.retryOnConflict -= 1;
|
|
185
237
|
this._queue.push(task);
|
|
186
238
|
}
|
|
187
|
-
else if (
|
|
188
|
-
this._shouldRetry &&
|
|
189
|
-
task.retries < (this._maxRetries || this._hosts.length - 1) &&
|
|
190
|
-
error_1.isSystemError(err) &&
|
|
239
|
+
else if ((((0, error_1.isSystemError)(err) &&
|
|
191
240
|
err.syscall === "connect" &&
|
|
192
|
-
err.code === "ECONNREFUSED")
|
|
241
|
+
err.code === "ECONNREFUSED") ||
|
|
242
|
+
((0, error_1.isArangoError)(err) &&
|
|
243
|
+
err.errorNum === codes_1.ERROR_ARANGO_MAINTENANCE_MODE)) &&
|
|
244
|
+
task.hostUrl === undefined &&
|
|
245
|
+
this._maxRetries !== false &&
|
|
246
|
+
task.retries < (this._maxRetries || this._hosts.length - 1)) {
|
|
193
247
|
task.retries += 1;
|
|
194
248
|
this._queue.push(task);
|
|
195
249
|
}
|
|
@@ -200,27 +254,10 @@ class Connection {
|
|
|
200
254
|
task.reject(err);
|
|
201
255
|
}
|
|
202
256
|
}
|
|
203
|
-
else {
|
|
204
|
-
const response = res;
|
|
205
|
-
if (response.statusCode === 503 &&
|
|
206
|
-
response.headers[LEADER_ENDPOINT_HEADER]) {
|
|
207
|
-
const url = response.headers[LEADER_ENDPOINT_HEADER];
|
|
208
|
-
const [index] = this.addToHostList(url);
|
|
209
|
-
task.host = index;
|
|
210
|
-
if (this._activeHost === host) {
|
|
211
|
-
this._activeHost = index;
|
|
212
|
-
}
|
|
213
|
-
this._queue.push(task);
|
|
214
|
-
}
|
|
215
|
-
else {
|
|
216
|
-
response.arangojsHostId = host;
|
|
217
|
-
task.resolve(response);
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
257
|
this._runQueue();
|
|
221
258
|
};
|
|
222
259
|
try {
|
|
223
|
-
this._hosts[
|
|
260
|
+
this._hosts[this._hostUrls.indexOf(hostUrl)](task.options, callback);
|
|
224
261
|
}
|
|
225
262
|
catch (e) {
|
|
226
263
|
callback(e);
|
|
@@ -233,7 +270,7 @@ class Connection {
|
|
|
233
270
|
if (typeof qs === "string")
|
|
234
271
|
search = `?${qs}`;
|
|
235
272
|
else
|
|
236
|
-
search = `?${
|
|
273
|
+
search = `?${(0, querystringify_1.querystringify)(qs)}`;
|
|
237
274
|
}
|
|
238
275
|
return search ? { pathname, search } : { pathname };
|
|
239
276
|
}
|
|
@@ -241,7 +278,7 @@ class Connection {
|
|
|
241
278
|
this.setHeader("authorization", `Bearer ${auth.token}`);
|
|
242
279
|
}
|
|
243
280
|
setBasicAuth(auth) {
|
|
244
|
-
this.setHeader("authorization", `Basic ${btoa_1.
|
|
281
|
+
this.setHeader("authorization", `Basic ${(0, btoa_1.base64Encode)(`${auth.username}:${auth.password}`)}`);
|
|
245
282
|
}
|
|
246
283
|
setResponseQueueTimeSamples(responseQueueTimeSamples) {
|
|
247
284
|
if (responseQueueTimeSamples < 0) {
|
|
@@ -263,21 +300,40 @@ class Connection {
|
|
|
263
300
|
this._databases.set(databaseName, database);
|
|
264
301
|
return database;
|
|
265
302
|
}
|
|
303
|
+
/**
|
|
304
|
+
* @internal
|
|
305
|
+
*
|
|
306
|
+
* Replaces the host list with the given URLs.
|
|
307
|
+
*
|
|
308
|
+
* See {@link Connection#acquireHostList}.
|
|
309
|
+
*
|
|
310
|
+
* @param urls - URLs to use as host list.
|
|
311
|
+
*/
|
|
312
|
+
setHostList(urls) {
|
|
313
|
+
const cleanUrls = urls.map((url) => (0, normalizeUrl_1.normalizeUrl)(url));
|
|
314
|
+
this._hosts.splice(0, this._hosts.length, ...cleanUrls.map((url) => {
|
|
315
|
+
const i = this._hostUrls.indexOf(url);
|
|
316
|
+
if (i !== -1)
|
|
317
|
+
return this._hosts[i];
|
|
318
|
+
return (0, request_1.createRequest)(url, this._agentOptions, this._agent);
|
|
319
|
+
}));
|
|
320
|
+
this._hostUrls.splice(0, this._hostUrls.length, ...cleanUrls);
|
|
321
|
+
}
|
|
266
322
|
/**
|
|
267
323
|
* @internal
|
|
268
324
|
*
|
|
269
325
|
* Adds the given URL or URLs to the host list.
|
|
270
326
|
*
|
|
271
|
-
* See {@link Connection
|
|
327
|
+
* See {@link Connection#acquireHostList}.
|
|
272
328
|
*
|
|
273
329
|
* @param urls - URL or URLs to add.
|
|
274
330
|
*/
|
|
275
331
|
addToHostList(urls) {
|
|
276
|
-
const cleanUrls = (Array.isArray(urls) ? urls : [urls]).map((url) => normalizeUrl_1.normalizeUrl(url));
|
|
277
|
-
const newUrls = cleanUrls.filter((url) => this.
|
|
278
|
-
this.
|
|
279
|
-
this._hosts.push(...newUrls.map((url) => request_1.createRequest(url, this._agentOptions, this._agent)));
|
|
280
|
-
return cleanUrls
|
|
332
|
+
const cleanUrls = (Array.isArray(urls) ? urls : [urls]).map((url) => (0, normalizeUrl_1.normalizeUrl)(url));
|
|
333
|
+
const newUrls = cleanUrls.filter((url) => this._hostUrls.indexOf(url) === -1);
|
|
334
|
+
this._hostUrls.push(...newUrls);
|
|
335
|
+
this._hosts.push(...newUrls.map((url) => (0, request_1.createRequest)(url, this._agentOptions, this._agent)));
|
|
336
|
+
return cleanUrls;
|
|
281
337
|
}
|
|
282
338
|
/**
|
|
283
339
|
* @internal
|
|
@@ -288,7 +344,7 @@ class Connection {
|
|
|
288
344
|
* within the transaction if possible. Setting the ID manually may cause
|
|
289
345
|
* unexpected behavior.
|
|
290
346
|
*
|
|
291
|
-
* See also {@link Connection
|
|
347
|
+
* See also {@link Connection#clearTransactionId}.
|
|
292
348
|
*
|
|
293
349
|
* @param transactionId - ID of the active transaction.
|
|
294
350
|
*/
|
|
@@ -325,7 +381,7 @@ class Connection {
|
|
|
325
381
|
*
|
|
326
382
|
* Closes all open connections.
|
|
327
383
|
*
|
|
328
|
-
* See {@link Database
|
|
384
|
+
* See {@link database.Database#close}.
|
|
329
385
|
*/
|
|
330
386
|
close() {
|
|
331
387
|
for (const host of this._hosts) {
|
|
@@ -338,7 +394,7 @@ class Connection {
|
|
|
338
394
|
*
|
|
339
395
|
* Waits for propagation.
|
|
340
396
|
*
|
|
341
|
-
* See {@link Database
|
|
397
|
+
* See {@link database.Database#waitForPropagation}.
|
|
342
398
|
*
|
|
343
399
|
* @param request - Request to perform against each coordinator.
|
|
344
400
|
* @param timeout - Maximum number of milliseconds to wait for propagation.
|
|
@@ -347,16 +403,17 @@ class Connection {
|
|
|
347
403
|
const numHosts = this._hosts.length;
|
|
348
404
|
const propagated = [];
|
|
349
405
|
const started = Date.now();
|
|
350
|
-
let
|
|
406
|
+
let index = 0;
|
|
351
407
|
while (true) {
|
|
352
408
|
if (propagated.length === numHosts) {
|
|
353
409
|
return;
|
|
354
410
|
}
|
|
355
|
-
while (propagated.includes(
|
|
356
|
-
|
|
411
|
+
while (propagated.includes(this._hostUrls[index])) {
|
|
412
|
+
index = (index + 1) % numHosts;
|
|
357
413
|
}
|
|
414
|
+
const hostUrl = this._hostUrls[index];
|
|
358
415
|
try {
|
|
359
|
-
await this.request({ ...request,
|
|
416
|
+
await this.request({ ...request, hostUrl });
|
|
360
417
|
}
|
|
361
418
|
catch (e) {
|
|
362
419
|
if (started + timeout < Date.now()) {
|
|
@@ -365,8 +422,8 @@ class Connection {
|
|
|
365
422
|
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
366
423
|
continue;
|
|
367
424
|
}
|
|
368
|
-
if (!propagated.includes(
|
|
369
|
-
propagated.push(
|
|
425
|
+
if (!propagated.includes(hostUrl)) {
|
|
426
|
+
propagated.push(hostUrl);
|
|
370
427
|
}
|
|
371
428
|
}
|
|
372
429
|
}
|
|
@@ -375,7 +432,7 @@ class Connection {
|
|
|
375
432
|
*
|
|
376
433
|
* Performs a request using the arangojs connection pool.
|
|
377
434
|
*/
|
|
378
|
-
request({
|
|
435
|
+
request({ hostUrl, method = "GET", body, expectBinary = false, isBinary = false, allowDirtyRead = false, retryOnConflict = this._retryOnConflict, timeout = 0, headers, ...urlInfo }, transform) {
|
|
379
436
|
return new Promise((resolve, reject) => {
|
|
380
437
|
let contentType = "text/plain";
|
|
381
438
|
if (isBinary) {
|
|
@@ -400,7 +457,7 @@ class Connection {
|
|
|
400
457
|
}
|
|
401
458
|
const task = {
|
|
402
459
|
retries: 0,
|
|
403
|
-
|
|
460
|
+
hostUrl,
|
|
404
461
|
allowDirtyRead,
|
|
405
462
|
retryOnConflict,
|
|
406
463
|
options: {
|
|
@@ -412,63 +469,8 @@ class Connection {
|
|
|
412
469
|
body,
|
|
413
470
|
},
|
|
414
471
|
reject,
|
|
415
|
-
resolve
|
|
416
|
-
|
|
417
|
-
const queueTime = res.headers["x-arango-queue-time-seconds"];
|
|
418
|
-
if (queueTime) {
|
|
419
|
-
this._queueTimes.push([Date.now(), Number(queueTime)]);
|
|
420
|
-
while (this._responseQueueTimeSamples < this._queueTimes.length) {
|
|
421
|
-
this._queueTimes.shift();
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
let parsedBody = undefined;
|
|
425
|
-
if (res.body.length && contentType && contentType.match(MIME_JSON)) {
|
|
426
|
-
try {
|
|
427
|
-
parsedBody = res.body;
|
|
428
|
-
parsedBody = JSON.parse(parsedBody);
|
|
429
|
-
}
|
|
430
|
-
catch (e) {
|
|
431
|
-
if (!expectBinary) {
|
|
432
|
-
if (typeof parsedBody !== "string") {
|
|
433
|
-
parsedBody = res.body.toString("utf-8");
|
|
434
|
-
}
|
|
435
|
-
e.response = res;
|
|
436
|
-
if (task.stack) {
|
|
437
|
-
e.stack += task.stack();
|
|
438
|
-
}
|
|
439
|
-
reject(e);
|
|
440
|
-
return;
|
|
441
|
-
}
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
else if (res.body && !expectBinary) {
|
|
445
|
-
parsedBody = res.body.toString("utf-8");
|
|
446
|
-
}
|
|
447
|
-
else {
|
|
448
|
-
parsedBody = res.body;
|
|
449
|
-
}
|
|
450
|
-
if (error_1.isArangoErrorResponse(parsedBody)) {
|
|
451
|
-
res.body = parsedBody;
|
|
452
|
-
const err = new error_1.ArangoError(res);
|
|
453
|
-
if (task.stack) {
|
|
454
|
-
err.stack += task.stack();
|
|
455
|
-
}
|
|
456
|
-
reject(err);
|
|
457
|
-
}
|
|
458
|
-
else if (res.statusCode && res.statusCode >= 400) {
|
|
459
|
-
res.body = parsedBody;
|
|
460
|
-
const err = new error_1.HttpError(res);
|
|
461
|
-
if (task.stack) {
|
|
462
|
-
err.stack += task.stack();
|
|
463
|
-
}
|
|
464
|
-
reject(err);
|
|
465
|
-
}
|
|
466
|
-
else {
|
|
467
|
-
if (!expectBinary)
|
|
468
|
-
res.body = parsedBody;
|
|
469
|
-
resolve(transform ? transform(res) : res);
|
|
470
|
-
}
|
|
471
|
-
},
|
|
472
|
+
resolve,
|
|
473
|
+
transform,
|
|
472
474
|
};
|
|
473
475
|
if (this._precaptureStackTraces) {
|
|
474
476
|
if (typeof Error.captureStackTrace === "function") {
|