@algolia/client-common 5.0.0-alpha.3 → 5.0.0-alpha.31
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/client-common.cjs.js +58 -144
- package/dist/client-common.esm.node.js +58 -142
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/src/cache/createBrowserLocalStorageCache.d.ts.map +1 -1
- package/dist/src/cache/createFallbackableCache.d.ts.map +1 -1
- package/dist/src/cache/createMemoryCache.d.ts.map +1 -1
- package/dist/src/cache/createNullCache.d.ts.map +1 -1
- package/dist/src/cache/index.d.ts.map +1 -1
- package/dist/src/constants.d.ts.map +1 -1
- package/dist/src/createAlgoliaAgent.d.ts.map +1 -1
- package/dist/src/createAuth.d.ts.map +1 -1
- package/dist/src/createEchoRequester.d.ts.map +1 -1
- package/dist/src/createIterablePromise.d.ts +13 -0
- package/dist/src/createIterablePromise.d.ts.map +1 -0
- package/dist/src/getAlgoliaAgent.d.ts.map +1 -1
- package/dist/src/transporter/createStatefulHost.d.ts.map +1 -1
- package/dist/src/transporter/createTransporter.d.ts.map +1 -1
- package/dist/src/transporter/errors.d.ts.map +1 -1
- package/dist/src/transporter/helpers.d.ts.map +1 -1
- package/dist/src/transporter/index.d.ts.map +1 -1
- package/dist/src/transporter/responses.d.ts.map +1 -1
- package/dist/src/transporter/stackTrace.d.ts.map +1 -1
- package/dist/src/types/{Cache.d.ts → cache.d.ts} +1 -1
- package/dist/src/types/cache.d.ts.map +1 -0
- package/dist/src/types/{CreateClient.d.ts → createClient.d.ts} +2 -2
- package/dist/src/types/createClient.d.ts.map +1 -0
- package/dist/src/types/createIterablePromise.d.ts +36 -0
- package/dist/src/types/createIterablePromise.d.ts.map +1 -0
- package/dist/src/types/{Host.d.ts → host.d.ts} +1 -1
- package/dist/src/types/host.d.ts.map +1 -0
- package/dist/src/types/index.d.ts +6 -6
- package/dist/src/types/index.d.ts.map +1 -1
- package/dist/src/types/{Requester.d.ts → requester.d.ts} +2 -2
- package/dist/src/types/requester.d.ts.map +1 -0
- package/dist/src/types/{Transporter.d.ts → transporter.d.ts} +4 -4
- package/dist/src/types/transporter.d.ts.map +1 -0
- package/index.ts +1 -1
- package/package.json +9 -8
- package/src/__tests__/create-iterable-promise.test.ts +238 -0
- package/src/createEchoRequester.ts +1 -1
- package/src/createIterablePromise.ts +47 -0
- package/src/transporter/createTransporter.ts +4 -1
- package/src/transporter/helpers.ts +2 -2
- package/src/types/{Cache.ts → cache.ts} +0 -0
- package/src/types/{CreateClient.ts → createClient.ts} +1 -1
- package/src/types/createIterablePromise.ts +40 -0
- package/src/types/{Host.ts → host.ts} +0 -0
- package/src/types/index.ts +6 -6
- package/src/types/{Requester.ts → requester.ts} +1 -1
- package/src/types/{Transporter.ts → transporter.ts} +3 -3
- package/dist/src/createRetryablePromise.d.ts +0 -14
- package/dist/src/createRetryablePromise.d.ts.map +0 -1
- package/dist/src/types/Cache.d.ts.map +0 -1
- package/dist/src/types/CreateClient.d.ts.map +0 -1
- package/dist/src/types/CreateRetryablePromise.d.ts +0 -19
- package/dist/src/types/CreateRetryablePromise.d.ts.map +0 -1
- package/dist/src/types/Host.d.ts.map +0 -1
- package/dist/src/types/Requester.d.ts.map +0 -1
- package/dist/src/types/Transporter.d.ts.map +0 -1
- package/src/__tests__/create-retryable-promise.test.ts +0 -86
- package/src/createRetryablePromise.ts +0 -52
- package/src/types/CreateRetryablePromise.ts +0 -21
|
@@ -7,11 +7,9 @@ function createAuth(appId, apiKey, authMode = 'WithinHeaders') {
|
|
|
7
7
|
headers() {
|
|
8
8
|
return authMode === 'WithinHeaders' ? credentials : {};
|
|
9
9
|
},
|
|
10
|
-
|
|
11
10
|
queryParameters() {
|
|
12
11
|
return authMode === 'WithinQueryParameters' ? credentials : {};
|
|
13
12
|
}
|
|
14
|
-
|
|
15
13
|
};
|
|
16
14
|
}
|
|
17
15
|
|
|
@@ -22,15 +20,12 @@ function getUrlParams({
|
|
|
22
20
|
}) {
|
|
23
21
|
const algoliaAgent = urlSearchParams.get('x-algolia-agent') || '';
|
|
24
22
|
const searchParams = {};
|
|
25
|
-
|
|
26
23
|
for (const [k, v] of urlSearchParams) {
|
|
27
24
|
if (k === 'x-algolia-agent') {
|
|
28
25
|
continue;
|
|
29
26
|
}
|
|
30
|
-
|
|
31
27
|
searchParams[k] = v;
|
|
32
28
|
}
|
|
33
|
-
|
|
34
29
|
return {
|
|
35
30
|
host,
|
|
36
31
|
algoliaAgent,
|
|
@@ -38,7 +33,6 @@ function getUrlParams({
|
|
|
38
33
|
path: pathname
|
|
39
34
|
};
|
|
40
35
|
}
|
|
41
|
-
|
|
42
36
|
function createEchoRequester({
|
|
43
37
|
getURL,
|
|
44
38
|
status = 200
|
|
@@ -50,11 +44,12 @@ function createEchoRequester({
|
|
|
50
44
|
algoliaAgent,
|
|
51
45
|
path
|
|
52
46
|
} = getUrlParams(getURL(request.url));
|
|
53
|
-
const content = {
|
|
47
|
+
const content = {
|
|
48
|
+
...request,
|
|
54
49
|
data: request.data ? JSON.parse(request.data) : undefined,
|
|
55
50
|
path,
|
|
56
51
|
host,
|
|
57
|
-
algoliaAgent:
|
|
52
|
+
algoliaAgent: encodeURIComponent(algoliaAgent),
|
|
58
53
|
searchParams
|
|
59
54
|
};
|
|
60
55
|
return Promise.resolve({
|
|
@@ -63,73 +58,64 @@ function createEchoRequester({
|
|
|
63
58
|
status
|
|
64
59
|
});
|
|
65
60
|
}
|
|
66
|
-
|
|
67
61
|
return {
|
|
68
62
|
send
|
|
69
63
|
};
|
|
70
64
|
}
|
|
71
65
|
|
|
72
|
-
const DEFAULT_MAX_RETRIES = 50;
|
|
73
|
-
const DEFAULT_TIMEOUT = retryCount => Math.min(retryCount * 200, 5000);
|
|
74
66
|
/**
|
|
75
|
-
*
|
|
67
|
+
* Helper: Returns the promise of a given `func` to iterate on, based on a given `validate` condition.
|
|
76
68
|
*
|
|
77
|
-
* @param
|
|
78
|
-
* @param
|
|
79
|
-
* @param
|
|
80
|
-
* @param
|
|
81
|
-
* @param
|
|
69
|
+
* @param createIterator - The createIterator options.
|
|
70
|
+
* @param createIterator.func - The function to run, which returns a promise.
|
|
71
|
+
* @param createIterator.validate - The validator function. It receives the resolved return of `func`.
|
|
72
|
+
* @param createIterator.aggregator - The function that runs right after the `func` method has been executed, allows you to do anything with the response before `validate`.
|
|
73
|
+
* @param createIterator.error - The `validate` condition to throw an error, and its message.
|
|
74
|
+
* @param createIterator.timeout - The function to decide how long to wait between iterations.
|
|
82
75
|
*/
|
|
83
|
-
|
|
84
|
-
function createRetryablePromise({
|
|
76
|
+
function createIterablePromise({
|
|
85
77
|
func,
|
|
86
78
|
validate,
|
|
87
|
-
|
|
88
|
-
|
|
79
|
+
aggregator,
|
|
80
|
+
error,
|
|
81
|
+
timeout = () => 0
|
|
89
82
|
}) {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
const retry = () => {
|
|
83
|
+
const retry = previousResponse => {
|
|
93
84
|
return new Promise((resolve, reject) => {
|
|
94
|
-
func().then(response => {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
if (isValid) {
|
|
98
|
-
resolve(response);
|
|
99
|
-
} else if (retryCount + 1 >= maxRetries) {
|
|
100
|
-
reject(new Error(`The maximum number of retries exceeded. (${retryCount + 1}/${maxRetries})`));
|
|
101
|
-
} else {
|
|
102
|
-
retryCount += 1;
|
|
103
|
-
setTimeout(() => {
|
|
104
|
-
retry().then(resolve).catch(reject);
|
|
105
|
-
}, timeout(retryCount));
|
|
85
|
+
func(previousResponse).then(response => {
|
|
86
|
+
if (aggregator) {
|
|
87
|
+
aggregator(response);
|
|
106
88
|
}
|
|
107
|
-
|
|
108
|
-
|
|
89
|
+
if (validate(response)) {
|
|
90
|
+
return resolve(response);
|
|
91
|
+
}
|
|
92
|
+
if (error && error.validate(response)) {
|
|
93
|
+
return reject(new Error(error.message(response)));
|
|
94
|
+
}
|
|
95
|
+
return setTimeout(() => {
|
|
96
|
+
retry(response).then(resolve).catch(reject);
|
|
97
|
+
}, timeout());
|
|
98
|
+
}).catch(err => {
|
|
99
|
+
reject(err);
|
|
109
100
|
});
|
|
110
101
|
});
|
|
111
102
|
};
|
|
112
|
-
|
|
113
103
|
return retry();
|
|
114
104
|
}
|
|
115
105
|
|
|
116
106
|
function createBrowserLocalStorageCache(options) {
|
|
117
|
-
let storage;
|
|
118
|
-
|
|
107
|
+
let storage;
|
|
108
|
+
// We've changed the namespace to avoid conflicts with v4, as this version is a huge breaking change
|
|
119
109
|
const namespaceKey = `algolia-client-js-${options.key}`;
|
|
120
|
-
|
|
121
110
|
function getStorage() {
|
|
122
111
|
if (storage === undefined) {
|
|
123
112
|
storage = options.localStorage || window.localStorage;
|
|
124
113
|
}
|
|
125
|
-
|
|
126
114
|
return storage;
|
|
127
115
|
}
|
|
128
|
-
|
|
129
116
|
function getNamespace() {
|
|
130
117
|
return JSON.parse(getStorage().getItem(namespaceKey) || '{}');
|
|
131
118
|
}
|
|
132
|
-
|
|
133
119
|
return {
|
|
134
120
|
get(key, defaultValue, events = {
|
|
135
121
|
miss: () => Promise.resolve()
|
|
@@ -142,7 +128,6 @@ function createBrowserLocalStorageCache(options) {
|
|
|
142
128
|
return Promise.all([value, exists || events.miss(value)]);
|
|
143
129
|
}).then(([value]) => value);
|
|
144
130
|
},
|
|
145
|
-
|
|
146
131
|
set(key, value) {
|
|
147
132
|
return Promise.resolve().then(() => {
|
|
148
133
|
const namespace = getNamespace();
|
|
@@ -151,7 +136,6 @@ function createBrowserLocalStorageCache(options) {
|
|
|
151
136
|
return value;
|
|
152
137
|
});
|
|
153
138
|
},
|
|
154
|
-
|
|
155
139
|
delete(key) {
|
|
156
140
|
return Promise.resolve().then(() => {
|
|
157
141
|
const namespace = getNamespace();
|
|
@@ -159,13 +143,11 @@ function createBrowserLocalStorageCache(options) {
|
|
|
159
143
|
getStorage().setItem(namespaceKey, JSON.stringify(namespace));
|
|
160
144
|
});
|
|
161
145
|
},
|
|
162
|
-
|
|
163
146
|
clear() {
|
|
164
147
|
return Promise.resolve().then(() => {
|
|
165
148
|
getStorage().removeItem(namespaceKey);
|
|
166
149
|
});
|
|
167
150
|
}
|
|
168
|
-
|
|
169
151
|
};
|
|
170
152
|
}
|
|
171
153
|
|
|
@@ -177,30 +159,24 @@ function createNullCache() {
|
|
|
177
159
|
const value = defaultValue();
|
|
178
160
|
return value.then(result => Promise.all([result, events.miss(result)])).then(([result]) => result);
|
|
179
161
|
},
|
|
180
|
-
|
|
181
162
|
set(_key, value) {
|
|
182
163
|
return Promise.resolve(value);
|
|
183
164
|
},
|
|
184
|
-
|
|
185
165
|
delete(_key) {
|
|
186
166
|
return Promise.resolve();
|
|
187
167
|
},
|
|
188
|
-
|
|
189
168
|
clear() {
|
|
190
169
|
return Promise.resolve();
|
|
191
170
|
}
|
|
192
|
-
|
|
193
171
|
};
|
|
194
172
|
}
|
|
195
173
|
|
|
196
174
|
function createFallbackableCache(options) {
|
|
197
175
|
const caches = [...options.caches];
|
|
198
176
|
const current = caches.shift();
|
|
199
|
-
|
|
200
177
|
if (current === undefined) {
|
|
201
178
|
return createNullCache();
|
|
202
179
|
}
|
|
203
|
-
|
|
204
180
|
return {
|
|
205
181
|
get(key, defaultValue, events = {
|
|
206
182
|
miss: () => Promise.resolve()
|
|
@@ -211,7 +187,6 @@ function createFallbackableCache(options) {
|
|
|
211
187
|
}).get(key, defaultValue, events);
|
|
212
188
|
});
|
|
213
189
|
},
|
|
214
|
-
|
|
215
190
|
set(key, value) {
|
|
216
191
|
return current.set(key, value).catch(() => {
|
|
217
192
|
return createFallbackableCache({
|
|
@@ -219,7 +194,6 @@ function createFallbackableCache(options) {
|
|
|
219
194
|
}).set(key, value);
|
|
220
195
|
});
|
|
221
196
|
},
|
|
222
|
-
|
|
223
197
|
delete(key) {
|
|
224
198
|
return current.delete(key).catch(() => {
|
|
225
199
|
return createFallbackableCache({
|
|
@@ -227,7 +201,6 @@ function createFallbackableCache(options) {
|
|
|
227
201
|
}).delete(key);
|
|
228
202
|
});
|
|
229
203
|
},
|
|
230
|
-
|
|
231
204
|
clear() {
|
|
232
205
|
return current.clear().catch(() => {
|
|
233
206
|
return createFallbackableCache({
|
|
@@ -235,7 +208,6 @@ function createFallbackableCache(options) {
|
|
|
235
208
|
}).clear();
|
|
236
209
|
});
|
|
237
210
|
}
|
|
238
|
-
|
|
239
211
|
};
|
|
240
212
|
}
|
|
241
213
|
|
|
@@ -248,30 +220,24 @@ function createMemoryCache(options = {
|
|
|
248
220
|
miss: () => Promise.resolve()
|
|
249
221
|
}) {
|
|
250
222
|
const keyAsString = JSON.stringify(key);
|
|
251
|
-
|
|
252
223
|
if (keyAsString in cache) {
|
|
253
224
|
return Promise.resolve(options.serializable ? JSON.parse(cache[keyAsString]) : cache[keyAsString]);
|
|
254
225
|
}
|
|
255
|
-
|
|
256
226
|
const promise = defaultValue();
|
|
257
227
|
return promise.then(value => events.miss(value)).then(() => promise);
|
|
258
228
|
},
|
|
259
|
-
|
|
260
229
|
set(key, value) {
|
|
261
230
|
cache[JSON.stringify(key)] = options.serializable ? JSON.stringify(value) : value;
|
|
262
231
|
return Promise.resolve(value);
|
|
263
232
|
},
|
|
264
|
-
|
|
265
233
|
delete(key) {
|
|
266
234
|
delete cache[JSON.stringify(key)];
|
|
267
235
|
return Promise.resolve();
|
|
268
236
|
},
|
|
269
|
-
|
|
270
237
|
clear() {
|
|
271
238
|
cache = {};
|
|
272
239
|
return Promise.resolve();
|
|
273
240
|
}
|
|
274
|
-
|
|
275
241
|
};
|
|
276
242
|
}
|
|
277
243
|
|
|
@@ -280,16 +246,14 @@ function createMemoryCache(options = {
|
|
|
280
246
|
const EXPIRATION_DELAY = 2 * 60 * 1000;
|
|
281
247
|
function createStatefulHost(host, status = 'up') {
|
|
282
248
|
const lastUpdate = Date.now();
|
|
283
|
-
|
|
284
249
|
function isUp() {
|
|
285
250
|
return status === 'up' || Date.now() - lastUpdate > EXPIRATION_DELAY;
|
|
286
251
|
}
|
|
287
|
-
|
|
288
252
|
function isTimedOut() {
|
|
289
253
|
return status === 'timed out' && Date.now() - lastUpdate <= EXPIRATION_DELAY;
|
|
290
254
|
}
|
|
291
|
-
|
|
292
|
-
|
|
255
|
+
return {
|
|
256
|
+
...host,
|
|
293
257
|
status,
|
|
294
258
|
lastUpdate,
|
|
295
259
|
isUp,
|
|
@@ -308,92 +272,74 @@ function _defineProperty(obj, key, value) {
|
|
|
308
272
|
} else {
|
|
309
273
|
obj[key] = value;
|
|
310
274
|
}
|
|
311
|
-
|
|
312
275
|
return obj;
|
|
313
276
|
}
|
|
314
277
|
|
|
315
278
|
class AlgoliaError extends Error {
|
|
316
279
|
constructor(message, name) {
|
|
317
280
|
super(message);
|
|
318
|
-
|
|
319
281
|
_defineProperty(this, "name", 'AlgoliaError');
|
|
320
|
-
|
|
321
282
|
if (name) {
|
|
322
283
|
this.name = name;
|
|
323
284
|
}
|
|
324
285
|
}
|
|
325
|
-
|
|
326
286
|
}
|
|
327
287
|
class ErrorWithStackTrace extends AlgoliaError {
|
|
328
288
|
constructor(message, stackTrace, name) {
|
|
329
|
-
super(message, name);
|
|
330
|
-
|
|
289
|
+
super(message, name);
|
|
290
|
+
// the array and object should be frozen to reflect the stackTrace at the time of the error
|
|
331
291
|
_defineProperty(this, "stackTrace", void 0);
|
|
332
|
-
|
|
333
292
|
this.stackTrace = stackTrace;
|
|
334
293
|
}
|
|
335
|
-
|
|
336
294
|
}
|
|
337
295
|
class RetryError extends ErrorWithStackTrace {
|
|
338
296
|
constructor(stackTrace) {
|
|
339
297
|
super('Unreachable hosts - your application id may be incorrect. If the error persists, contact support@algolia.com.', stackTrace, 'RetryError');
|
|
340
298
|
}
|
|
341
|
-
|
|
342
299
|
}
|
|
343
300
|
class ApiError extends ErrorWithStackTrace {
|
|
344
301
|
constructor(message, status, stackTrace) {
|
|
345
302
|
super(message, stackTrace, 'ApiError');
|
|
346
|
-
|
|
347
303
|
_defineProperty(this, "status", void 0);
|
|
348
|
-
|
|
349
304
|
this.status = status;
|
|
350
305
|
}
|
|
351
|
-
|
|
352
306
|
}
|
|
353
307
|
class DeserializationError extends AlgoliaError {
|
|
354
308
|
constructor(message, response) {
|
|
355
309
|
super(message, 'DeserializationError');
|
|
356
|
-
|
|
357
310
|
_defineProperty(this, "response", void 0);
|
|
358
|
-
|
|
359
311
|
this.response = response;
|
|
360
312
|
}
|
|
361
|
-
|
|
362
313
|
}
|
|
363
314
|
|
|
364
315
|
function shuffle(array) {
|
|
365
316
|
const shuffledArray = array;
|
|
366
|
-
|
|
367
317
|
for (let c = array.length - 1; c > 0; c--) {
|
|
368
318
|
const b = Math.floor(Math.random() * (c + 1));
|
|
369
319
|
const a = array[c];
|
|
370
320
|
shuffledArray[c] = array[b];
|
|
371
321
|
shuffledArray[b] = a;
|
|
372
322
|
}
|
|
373
|
-
|
|
374
323
|
return shuffledArray;
|
|
375
324
|
}
|
|
376
325
|
function serializeUrl(host, path, queryParameters) {
|
|
377
326
|
const queryParametersAsString = serializeQueryParameters(queryParameters);
|
|
378
327
|
let url = `${host.protocol}://${host.url}/${path.charAt(0) === '/' ? path.substr(1) : path}`;
|
|
379
|
-
|
|
380
328
|
if (queryParametersAsString.length) {
|
|
381
329
|
url += `?${queryParametersAsString}`;
|
|
382
330
|
}
|
|
383
|
-
|
|
384
331
|
return url;
|
|
385
332
|
}
|
|
386
333
|
function serializeQueryParameters(parameters) {
|
|
387
334
|
const isObjectOrArray = value => Object.prototype.toString.call(value) === '[object Object]' || Object.prototype.toString.call(value) === '[object Array]';
|
|
388
|
-
|
|
389
|
-
return Object.keys(parameters).map(key => `${key}=${isObjectOrArray(parameters[key]) ? JSON.stringify(parameters[key]) : parameters[key]}`).join('&');
|
|
335
|
+
return Object.keys(parameters).map(key => `${key}=${encodeURIComponent(isObjectOrArray(parameters[key]) ? JSON.stringify(parameters[key]) : parameters[key])}`).join('&');
|
|
390
336
|
}
|
|
391
337
|
function serializeData(request, requestOptions) {
|
|
392
338
|
if (request.method === 'GET' || request.data === undefined && requestOptions.data === undefined) {
|
|
393
339
|
return undefined;
|
|
394
340
|
}
|
|
395
|
-
|
|
396
|
-
|
|
341
|
+
const data = Array.isArray(request.data) ? request.data : {
|
|
342
|
+
...request.data,
|
|
397
343
|
...requestOptions.data
|
|
398
344
|
};
|
|
399
345
|
return JSON.stringify(data);
|
|
@@ -424,12 +370,11 @@ function deserializeFailure({
|
|
|
424
370
|
status
|
|
425
371
|
}, stackFrame) {
|
|
426
372
|
let message = content;
|
|
427
|
-
|
|
428
373
|
try {
|
|
429
374
|
message = JSON.parse(content).message;
|
|
430
|
-
} catch (e) {
|
|
375
|
+
} catch (e) {
|
|
376
|
+
// ..
|
|
431
377
|
}
|
|
432
|
-
|
|
433
378
|
return new ApiError(message, status, stackFrame);
|
|
434
379
|
}
|
|
435
380
|
|
|
@@ -461,9 +406,12 @@ function stackFrameWithoutCredentials(stackFrame) {
|
|
|
461
406
|
const modifiedHeaders = stackFrame.request.headers['x-algolia-api-key'] ? {
|
|
462
407
|
'x-algolia-api-key': '*****'
|
|
463
408
|
} : {};
|
|
464
|
-
return {
|
|
465
|
-
|
|
466
|
-
|
|
409
|
+
return {
|
|
410
|
+
...stackFrame,
|
|
411
|
+
request: {
|
|
412
|
+
...stackFrame.request,
|
|
413
|
+
headers: {
|
|
414
|
+
...stackFrame.request.headers,
|
|
467
415
|
...modifiedHeaders
|
|
468
416
|
}
|
|
469
417
|
}
|
|
@@ -488,13 +436,12 @@ function createTransporter({
|
|
|
488
436
|
});
|
|
489
437
|
}));
|
|
490
438
|
const hostsUp = statefulHosts.filter(host => host.isUp());
|
|
491
|
-
const hostsTimedOut = statefulHosts.filter(host => host.isTimedOut());
|
|
492
|
-
|
|
439
|
+
const hostsTimedOut = statefulHosts.filter(host => host.isTimedOut());
|
|
440
|
+
// Note, we put the hosts that previously timed out on the end of the list.
|
|
493
441
|
const hostsAvailable = [...hostsUp, ...hostsTimedOut];
|
|
494
442
|
const compatibleHostsAvailable = hostsAvailable.length > 0 ? hostsAvailable : compatibleHosts;
|
|
495
443
|
return {
|
|
496
444
|
hosts: compatibleHostsAvailable,
|
|
497
|
-
|
|
498
445
|
getTimeout(timeoutsCount, baseTimeout) {
|
|
499
446
|
/**
|
|
500
447
|
* Imagine that you have 4 hosts, if timeouts will increase
|
|
@@ -510,29 +457,28 @@ function createTransporter({
|
|
|
510
457
|
const timeoutMultiplier = hostsTimedOut.length === 0 && timeoutsCount === 0 ? 1 : hostsTimedOut.length + 3 + timeoutsCount;
|
|
511
458
|
return timeoutMultiplier * baseTimeout;
|
|
512
459
|
}
|
|
513
|
-
|
|
514
460
|
};
|
|
515
461
|
}
|
|
516
|
-
|
|
517
462
|
async function retryableRequest(request, requestOptions, isRead = true) {
|
|
518
463
|
const stackTrace = [];
|
|
519
464
|
/**
|
|
520
465
|
* First we prepare the payload that do not depend from hosts.
|
|
521
466
|
*/
|
|
522
|
-
|
|
523
467
|
const data = serializeData(request, requestOptions);
|
|
524
|
-
const headers = serializeHeaders(baseHeaders, request.headers, requestOptions.headers);
|
|
525
|
-
|
|
526
|
-
const dataQueryParameters = request.method === 'GET' ? {
|
|
468
|
+
const headers = serializeHeaders(baseHeaders, request.headers, requestOptions.headers);
|
|
469
|
+
// On `GET`, the data is proxied to query parameters.
|
|
470
|
+
const dataQueryParameters = request.method === 'GET' ? {
|
|
471
|
+
...request.data,
|
|
527
472
|
...requestOptions.data
|
|
528
473
|
} : {};
|
|
529
474
|
const queryParameters = {
|
|
530
|
-
'x-algolia-agent': algoliaAgent.value,
|
|
531
475
|
...baseQueryParameters,
|
|
532
476
|
...request.queryParameters,
|
|
533
477
|
...dataQueryParameters
|
|
534
478
|
};
|
|
535
|
-
|
|
479
|
+
if (algoliaAgent.value) {
|
|
480
|
+
queryParameters['x-algolia-agent'] = algoliaAgent.value;
|
|
481
|
+
}
|
|
536
482
|
if (requestOptions && requestOptions.queryParameters) {
|
|
537
483
|
for (const key of Object.keys(requestOptions.queryParameters)) {
|
|
538
484
|
// We want to keep `undefined` and `null` values,
|
|
@@ -545,25 +491,19 @@ function createTransporter({
|
|
|
545
491
|
}
|
|
546
492
|
}
|
|
547
493
|
}
|
|
548
|
-
|
|
549
494
|
let timeoutsCount = 0;
|
|
550
|
-
|
|
551
495
|
const retry = async (retryableHosts, getTimeout) => {
|
|
552
496
|
/**
|
|
553
497
|
* We iterate on each host, until there is no host left.
|
|
554
498
|
*/
|
|
555
499
|
const host = retryableHosts.pop();
|
|
556
|
-
|
|
557
500
|
if (host === undefined) {
|
|
558
501
|
throw new RetryError(stackTraceWithoutCredentials(stackTrace));
|
|
559
502
|
}
|
|
560
|
-
|
|
561
503
|
let responseTimeout = requestOptions.timeout;
|
|
562
|
-
|
|
563
504
|
if (responseTimeout === undefined) {
|
|
564
505
|
responseTimeout = isRead ? timeouts.read : timeouts.write;
|
|
565
506
|
}
|
|
566
|
-
|
|
567
507
|
const payload = {
|
|
568
508
|
data,
|
|
569
509
|
headers,
|
|
@@ -577,7 +517,6 @@ function createTransporter({
|
|
|
577
517
|
* can have information about onRetry and onFailure
|
|
578
518
|
* decisions.
|
|
579
519
|
*/
|
|
580
|
-
|
|
581
520
|
const pushToStackTrace = response => {
|
|
582
521
|
const stackFrame = {
|
|
583
522
|
request: payload,
|
|
@@ -588,12 +527,10 @@ function createTransporter({
|
|
|
588
527
|
stackTrace.push(stackFrame);
|
|
589
528
|
return stackFrame;
|
|
590
529
|
};
|
|
591
|
-
|
|
592
530
|
const response = await requester.send(payload);
|
|
593
|
-
|
|
594
531
|
if (isRetryable(response)) {
|
|
595
|
-
const stackFrame = pushToStackTrace(response);
|
|
596
|
-
|
|
532
|
+
const stackFrame = pushToStackTrace(response);
|
|
533
|
+
// If response is a timeout, we increase the number of timeouts so we can increase the timeout later.
|
|
597
534
|
if (response.isTimedOut) {
|
|
598
535
|
timeoutsCount++;
|
|
599
536
|
}
|
|
@@ -603,23 +540,18 @@ function createTransporter({
|
|
|
603
540
|
* when a retry error does not happen.
|
|
604
541
|
*/
|
|
605
542
|
// eslint-disable-next-line no-console -- this will be fixed by exposing a `logger` to the transporter
|
|
606
|
-
|
|
607
|
-
|
|
608
543
|
console.log('Retryable failure', stackFrameWithoutCredentials(stackFrame));
|
|
609
544
|
/**
|
|
610
545
|
* We also store the state of the host in failure cases. If the host, is
|
|
611
546
|
* down it will remain down for the next 2 minutes. In a timeout situation,
|
|
612
547
|
* this host will be added end of the list of hosts on the next request.
|
|
613
548
|
*/
|
|
614
|
-
|
|
615
549
|
await hostsCache.set(host, createStatefulHost(host, response.isTimedOut ? 'timed out' : 'down'));
|
|
616
550
|
return retry(retryableHosts, getTimeout);
|
|
617
551
|
}
|
|
618
|
-
|
|
619
552
|
if (isSuccess(response)) {
|
|
620
553
|
return deserializeSuccess(response);
|
|
621
554
|
}
|
|
622
|
-
|
|
623
555
|
pushToStackTrace(response);
|
|
624
556
|
throw deserializeFailure(response, stackTrace);
|
|
625
557
|
};
|
|
@@ -631,20 +563,16 @@ function createTransporter({
|
|
|
631
563
|
* 2. We also get from the retryable options a timeout multiplier that is tailored
|
|
632
564
|
* for the current context.
|
|
633
565
|
*/
|
|
634
|
-
|
|
635
|
-
|
|
636
566
|
const compatibleHosts = hosts.filter(host => host.accept === 'readWrite' || (isRead ? host.accept === 'read' : host.accept === 'write'));
|
|
637
567
|
const options = await createRetryableOptions(compatibleHosts);
|
|
638
568
|
return retry([...options.hosts].reverse(), options.getTimeout);
|
|
639
569
|
}
|
|
640
|
-
|
|
641
570
|
function createRequest(request, requestOptions = {}) {
|
|
642
571
|
/**
|
|
643
572
|
* A read request is either a `GET` request, or a request that we make
|
|
644
573
|
* via the `read` transporter (e.g. `search`).
|
|
645
574
|
*/
|
|
646
575
|
const isRead = request.useReadTransporter || request.method === 'GET';
|
|
647
|
-
|
|
648
576
|
if (!isRead) {
|
|
649
577
|
/**
|
|
650
578
|
* On write requests, no cache mechanisms are applied, and we
|
|
@@ -652,7 +580,6 @@ function createTransporter({
|
|
|
652
580
|
*/
|
|
653
581
|
return retryableRequest(request, requestOptions, isRead);
|
|
654
582
|
}
|
|
655
|
-
|
|
656
583
|
const createRetryableRequest = () => {
|
|
657
584
|
/**
|
|
658
585
|
* Then, we prepare a function factory that contains the construction of
|
|
@@ -666,14 +593,11 @@ function createTransporter({
|
|
|
666
593
|
* request is "cacheable" - should be cached. Note that, once again,
|
|
667
594
|
* the user can force this option.
|
|
668
595
|
*/
|
|
669
|
-
|
|
670
|
-
|
|
671
596
|
const cacheable = requestOptions.cacheable || request.cacheable;
|
|
672
597
|
/**
|
|
673
598
|
* If is not "cacheable", we immediately trigger the retryable request, no
|
|
674
599
|
* need to check cache implementations.
|
|
675
600
|
*/
|
|
676
|
-
|
|
677
601
|
if (cacheable !== true) {
|
|
678
602
|
return createRetryableRequest();
|
|
679
603
|
}
|
|
@@ -682,8 +606,6 @@ function createTransporter({
|
|
|
682
606
|
* the cache implementations if this request is on progress or if the
|
|
683
607
|
* response already exists on the cache.
|
|
684
608
|
*/
|
|
685
|
-
|
|
686
|
-
|
|
687
609
|
const key = {
|
|
688
610
|
request,
|
|
689
611
|
requestOptions,
|
|
@@ -696,7 +618,6 @@ function createTransporter({
|
|
|
696
618
|
* With the computed key, we first ask the responses cache
|
|
697
619
|
* implementation if this request was been resolved before.
|
|
698
620
|
*/
|
|
699
|
-
|
|
700
621
|
return responsesCache.get(key, () => {
|
|
701
622
|
/**
|
|
702
623
|
* If the request has never resolved before, we actually ask if there
|
|
@@ -718,7 +639,6 @@ function createTransporter({
|
|
|
718
639
|
miss: response => responsesCache.set(key, response)
|
|
719
640
|
});
|
|
720
641
|
}
|
|
721
|
-
|
|
722
642
|
return {
|
|
723
643
|
hostsCache,
|
|
724
644
|
requester,
|
|
@@ -736,17 +656,13 @@ function createTransporter({
|
|
|
736
656
|
function createAlgoliaAgent(version) {
|
|
737
657
|
const algoliaAgent = {
|
|
738
658
|
value: `Algolia for JavaScript (${version})`,
|
|
739
|
-
|
|
740
659
|
add(options) {
|
|
741
660
|
const addedAlgoliaAgent = `; ${options.segment}${options.version !== undefined ? ` (${options.version})` : ''}`;
|
|
742
|
-
|
|
743
661
|
if (algoliaAgent.value.indexOf(addedAlgoliaAgent) === -1) {
|
|
744
662
|
algoliaAgent.value = `${algoliaAgent.value}${addedAlgoliaAgent}`;
|
|
745
663
|
}
|
|
746
|
-
|
|
747
664
|
return algoliaAgent;
|
|
748
665
|
}
|
|
749
|
-
|
|
750
666
|
};
|
|
751
667
|
return algoliaAgent;
|
|
752
668
|
}
|
|
@@ -771,4 +687,4 @@ const DEFAULT_CONNECT_TIMEOUT_NODE = 2000;
|
|
|
771
687
|
const DEFAULT_READ_TIMEOUT_NODE = 5000;
|
|
772
688
|
const DEFAULT_WRITE_TIMEOUT_NODE = 30000;
|
|
773
689
|
|
|
774
|
-
export { AlgoliaError, ApiError, DEFAULT_CONNECT_TIMEOUT_BROWSER, DEFAULT_CONNECT_TIMEOUT_NODE,
|
|
690
|
+
export { AlgoliaError, ApiError, DEFAULT_CONNECT_TIMEOUT_BROWSER, DEFAULT_CONNECT_TIMEOUT_NODE, DEFAULT_READ_TIMEOUT_BROWSER, DEFAULT_READ_TIMEOUT_NODE, DEFAULT_WRITE_TIMEOUT_BROWSER, DEFAULT_WRITE_TIMEOUT_NODE, DeserializationError, ErrorWithStackTrace, RetryError, createAlgoliaAgent, createAuth, createBrowserLocalStorageCache, createEchoRequester, createFallbackableCache, createIterablePromise, createMemoryCache, createNullCache, createStatefulHost, createTransporter, deserializeFailure, deserializeSuccess, getAlgoliaAgent, isNetworkError, isRetryable, isSuccess, serializeData, serializeHeaders, serializeQueryParameters, serializeUrl, shuffle, stackFrameWithoutCredentials, stackTraceWithoutCredentials };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export * from './src/createAuth';
|
|
2
2
|
export * from './src/createEchoRequester';
|
|
3
|
-
export * from './src/
|
|
3
|
+
export * from './src/createIterablePromise';
|
|
4
4
|
export * from './src/cache';
|
|
5
5
|
export * from './src/transporter';
|
|
6
6
|
export * from './src/createAlgoliaAgent';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createBrowserLocalStorageCache.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"createBrowserLocalStorageCache.d.ts","sourceRoot":"","sources":["../../../src/cache/createBrowserLocalStorageCache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,0BAA0B,EAAE,KAAK,EAAe,MAAM,UAAU,CAAC;AAE/E,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,0BAA0B,GAClC,KAAK,CAqEP"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createFallbackableCache.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"createFallbackableCache.d.ts","sourceRoot":"","sources":["../../../src/cache/createFallbackableCache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,KAAK,EAAe,MAAM,UAAU,CAAC;AAI7E,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,wBAAwB,GAChC,KAAK,CA8CP"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createMemoryCache.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"createMemoryCache.d.ts","sourceRoot":"","sources":["../../../src/cache/createMemoryCache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAe,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAEvE,wBAAgB,iBAAiB,CAC/B,OAAO,GAAE,kBAA2C,GACnD,KAAK,CAmDP"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createNullCache.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"createNullCache.d.ts","sourceRoot":"","sources":["../../../src/cache/createNullCache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAe,MAAM,UAAU,CAAC;AAEnD,wBAAgB,eAAe,IAAI,KAAK,CA+BvC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cache/index.ts"],"names":[],"mappings":"AAAA,cAAc,kCAAkC,CAAC;AACjD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,+BAA+B,OAAO,CAAC;AACpD,eAAO,MAAM,4BAA4B,OAAO,CAAC;AACjD,eAAO,MAAM,6BAA6B,QAAQ,CAAC;AAEnD,eAAO,MAAM,4BAA4B,OAAO,CAAC;AACjD,eAAO,MAAM,yBAAyB,OAAO,CAAC;AAC9C,eAAO,MAAM,0BAA0B,QAAQ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createAlgoliaAgent.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"createAlgoliaAgent.d.ts","sourceRoot":"","sources":["../../src/createAlgoliaAgent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAuB,YAAY,EAAE,MAAM,SAAS,CAAC;AAEjE,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,CAiBhE"}
|