@algolia/client-common 5.0.0-alpha.8 → 5.0.0-alpha.81

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.
Files changed (44) hide show
  1. package/dist/{client-common.cjs.js → client-common.cjs} +140 -199
  2. package/dist/client-common.esm.node.js +140 -198
  3. package/dist/index.d.ts +9 -9
  4. package/dist/src/cache/createBrowserLocalStorageCache.d.ts +2 -2
  5. package/dist/src/cache/createFallbackableCache.d.ts +2 -2
  6. package/dist/src/cache/createMemoryCache.d.ts +2 -2
  7. package/dist/src/cache/createNullCache.d.ts +2 -2
  8. package/dist/src/cache/index.d.ts +4 -4
  9. package/dist/src/constants.d.ts +6 -6
  10. package/dist/src/createAlgoliaAgent.d.ts +2 -2
  11. package/dist/src/createAuth.d.ts +5 -5
  12. package/dist/src/createEchoRequester.d.ts +6 -6
  13. package/dist/src/createEchoRequester.d.ts.map +1 -1
  14. package/dist/src/createIterablePromise.d.ts +12 -12
  15. package/dist/src/getAlgoliaAgent.d.ts +7 -7
  16. package/dist/src/getAlgoliaAgent.d.ts.map +1 -1
  17. package/dist/src/transporter/createStatefulHost.d.ts +2 -2
  18. package/dist/src/transporter/createTransporter.d.ts +2 -2
  19. package/dist/src/transporter/createTransporter.d.ts.map +1 -1
  20. package/dist/src/transporter/errors.d.ts +37 -20
  21. package/dist/src/transporter/errors.d.ts.map +1 -1
  22. package/dist/src/transporter/helpers.d.ts +8 -8
  23. package/dist/src/transporter/helpers.d.ts.map +1 -1
  24. package/dist/src/transporter/index.d.ts +6 -6
  25. package/dist/src/transporter/responses.d.ts +4 -4
  26. package/dist/src/transporter/stackTrace.d.ts +3 -3
  27. package/dist/src/types/cache.d.ts +46 -46
  28. package/dist/src/types/cache.d.ts.map +1 -1
  29. package/dist/src/types/createClient.d.ts +11 -11
  30. package/dist/src/types/createClient.d.ts.map +1 -1
  31. package/dist/src/types/createIterablePromise.d.ts +35 -35
  32. package/dist/src/types/createIterablePromise.d.ts.map +1 -1
  33. package/dist/src/types/host.d.ts +32 -32
  34. package/dist/src/types/host.d.ts.map +1 -1
  35. package/dist/src/types/index.d.ts +6 -6
  36. package/dist/src/types/requester.d.ts +65 -65
  37. package/dist/src/types/requester.d.ts.map +1 -1
  38. package/dist/src/types/transporter.d.ts +127 -127
  39. package/dist/src/types/transporter.d.ts.map +1 -1
  40. package/package.json +9 -8
  41. package/src/createEchoRequester.ts +2 -2
  42. package/src/transporter/createTransporter.ts +4 -1
  43. package/src/transporter/errors.ts +38 -2
  44. package/src/transporter/helpers.ts +14 -6
@@ -1,7 +1,5 @@
1
1
  'use strict';
2
2
 
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
3
  function createAuth(appId, apiKey, authMode = 'WithinHeaders') {
6
4
  const credentials = {
7
5
  'x-algolia-api-key': apiKey,
@@ -11,11 +9,9 @@ function createAuth(appId, apiKey, authMode = 'WithinHeaders') {
11
9
  headers() {
12
10
  return authMode === 'WithinHeaders' ? credentials : {};
13
11
  },
14
-
15
12
  queryParameters() {
16
13
  return authMode === 'WithinQueryParameters' ? credentials : {};
17
14
  }
18
-
19
15
  };
20
16
  }
21
17
 
@@ -26,15 +22,12 @@ function getUrlParams({
26
22
  }) {
27
23
  const algoliaAgent = urlSearchParams.get('x-algolia-agent') || '';
28
24
  const searchParams = {};
29
-
30
25
  for (const [k, v] of urlSearchParams) {
31
26
  if (k === 'x-algolia-agent') {
32
27
  continue;
33
28
  }
34
-
35
29
  searchParams[k] = v;
36
30
  }
37
-
38
31
  return {
39
32
  host,
40
33
  algoliaAgent,
@@ -42,7 +35,6 @@ function getUrlParams({
42
35
  path: pathname
43
36
  };
44
37
  }
45
-
46
38
  function createEchoRequester({
47
39
  getURL,
48
40
  status = 200
@@ -54,11 +46,12 @@ function createEchoRequester({
54
46
  algoliaAgent,
55
47
  path
56
48
  } = getUrlParams(getURL(request.url));
57
- const content = { ...request,
49
+ const content = {
50
+ ...request,
58
51
  data: request.data ? JSON.parse(request.data) : undefined,
59
52
  path,
60
53
  host,
61
- algoliaAgent: encodeURI(algoliaAgent),
54
+ algoliaAgent: encodeURIComponent(algoliaAgent),
62
55
  searchParams
63
56
  };
64
57
  return Promise.resolve({
@@ -67,21 +60,20 @@ function createEchoRequester({
67
60
  status
68
61
  });
69
62
  }
70
-
71
63
  return {
72
64
  send
73
65
  };
74
66
  }
75
67
 
76
- /**
77
- * Helper: Returns the promise of a given `func` to iterate on, based on a given `validate` condition.
78
- *
79
- * @param createIterator - The createIterator options.
80
- * @param createIterator.func - The function to run, which returns a promise.
81
- * @param createIterator.validate - The validator function. It receives the resolved return of `func`.
82
- * @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`.
83
- * @param createIterator.error - The `validate` condition to throw an error, and its message.
84
- * @param createIterator.timeout - The function to decide how long to wait between iterations.
68
+ /**
69
+ * Helper: Returns the promise of a given `func` to iterate on, based on a given `validate` condition.
70
+ *
71
+ * @param createIterator - The createIterator options.
72
+ * @param createIterator.func - The function to run, which returns a promise.
73
+ * @param createIterator.validate - The validator function. It receives the resolved return of `func`.
74
+ * @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`.
75
+ * @param createIterator.error - The `validate` condition to throw an error, and its message.
76
+ * @param createIterator.timeout - The function to decide how long to wait between iterations.
85
77
  */
86
78
  function createIterablePromise({
87
79
  func,
@@ -96,15 +88,12 @@ function createIterablePromise({
96
88
  if (aggregator) {
97
89
  aggregator(response);
98
90
  }
99
-
100
91
  if (validate(response)) {
101
92
  return resolve(response);
102
93
  }
103
-
104
94
  if (error && error.validate(response)) {
105
95
  return reject(new Error(error.message(response)));
106
96
  }
107
-
108
97
  return setTimeout(() => {
109
98
  retry(response).then(resolve).catch(reject);
110
99
  }, timeout());
@@ -113,27 +102,22 @@ function createIterablePromise({
113
102
  });
114
103
  });
115
104
  };
116
-
117
105
  return retry();
118
106
  }
119
107
 
120
108
  function createBrowserLocalStorageCache(options) {
121
- let storage; // We've changed the namespace to avoid conflicts with v4, as this version is a huge breaking change
122
-
109
+ let storage;
110
+ // We've changed the namespace to avoid conflicts with v4, as this version is a huge breaking change
123
111
  const namespaceKey = `algolia-client-js-${options.key}`;
124
-
125
112
  function getStorage() {
126
113
  if (storage === undefined) {
127
114
  storage = options.localStorage || window.localStorage;
128
115
  }
129
-
130
116
  return storage;
131
117
  }
132
-
133
118
  function getNamespace() {
134
119
  return JSON.parse(getStorage().getItem(namespaceKey) || '{}');
135
120
  }
136
-
137
121
  return {
138
122
  get(key, defaultValue, events = {
139
123
  miss: () => Promise.resolve()
@@ -146,7 +130,6 @@ function createBrowserLocalStorageCache(options) {
146
130
  return Promise.all([value, exists || events.miss(value)]);
147
131
  }).then(([value]) => value);
148
132
  },
149
-
150
133
  set(key, value) {
151
134
  return Promise.resolve().then(() => {
152
135
  const namespace = getNamespace();
@@ -155,7 +138,6 @@ function createBrowserLocalStorageCache(options) {
155
138
  return value;
156
139
  });
157
140
  },
158
-
159
141
  delete(key) {
160
142
  return Promise.resolve().then(() => {
161
143
  const namespace = getNamespace();
@@ -163,13 +145,11 @@ function createBrowserLocalStorageCache(options) {
163
145
  getStorage().setItem(namespaceKey, JSON.stringify(namespace));
164
146
  });
165
147
  },
166
-
167
148
  clear() {
168
149
  return Promise.resolve().then(() => {
169
150
  getStorage().removeItem(namespaceKey);
170
151
  });
171
152
  }
172
-
173
153
  };
174
154
  }
175
155
 
@@ -181,30 +161,24 @@ function createNullCache() {
181
161
  const value = defaultValue();
182
162
  return value.then(result => Promise.all([result, events.miss(result)])).then(([result]) => result);
183
163
  },
184
-
185
164
  set(_key, value) {
186
165
  return Promise.resolve(value);
187
166
  },
188
-
189
167
  delete(_key) {
190
168
  return Promise.resolve();
191
169
  },
192
-
193
170
  clear() {
194
171
  return Promise.resolve();
195
172
  }
196
-
197
173
  };
198
174
  }
199
175
 
200
176
  function createFallbackableCache(options) {
201
177
  const caches = [...options.caches];
202
178
  const current = caches.shift();
203
-
204
179
  if (current === undefined) {
205
180
  return createNullCache();
206
181
  }
207
-
208
182
  return {
209
183
  get(key, defaultValue, events = {
210
184
  miss: () => Promise.resolve()
@@ -215,7 +189,6 @@ function createFallbackableCache(options) {
215
189
  }).get(key, defaultValue, events);
216
190
  });
217
191
  },
218
-
219
192
  set(key, value) {
220
193
  return current.set(key, value).catch(() => {
221
194
  return createFallbackableCache({
@@ -223,7 +196,6 @@ function createFallbackableCache(options) {
223
196
  }).set(key, value);
224
197
  });
225
198
  },
226
-
227
199
  delete(key) {
228
200
  return current.delete(key).catch(() => {
229
201
  return createFallbackableCache({
@@ -231,7 +203,6 @@ function createFallbackableCache(options) {
231
203
  }).delete(key);
232
204
  });
233
205
  },
234
-
235
206
  clear() {
236
207
  return current.clear().catch(() => {
237
208
  return createFallbackableCache({
@@ -239,7 +210,6 @@ function createFallbackableCache(options) {
239
210
  }).clear();
240
211
  });
241
212
  }
242
-
243
213
  };
244
214
  }
245
215
 
@@ -252,30 +222,24 @@ function createMemoryCache(options = {
252
222
  miss: () => Promise.resolve()
253
223
  }) {
254
224
  const keyAsString = JSON.stringify(key);
255
-
256
225
  if (keyAsString in cache) {
257
226
  return Promise.resolve(options.serializable ? JSON.parse(cache[keyAsString]) : cache[keyAsString]);
258
227
  }
259
-
260
228
  const promise = defaultValue();
261
229
  return promise.then(value => events.miss(value)).then(() => promise);
262
230
  },
263
-
264
231
  set(key, value) {
265
232
  cache[JSON.stringify(key)] = options.serializable ? JSON.stringify(value) : value;
266
233
  return Promise.resolve(value);
267
234
  },
268
-
269
235
  delete(key) {
270
236
  delete cache[JSON.stringify(key)];
271
237
  return Promise.resolve();
272
238
  },
273
-
274
239
  clear() {
275
240
  cache = {};
276
241
  return Promise.resolve();
277
242
  }
278
-
279
243
  };
280
244
  }
281
245
 
@@ -284,16 +248,14 @@ function createMemoryCache(options = {
284
248
  const EXPIRATION_DELAY = 2 * 60 * 1000;
285
249
  function createStatefulHost(host, status = 'up') {
286
250
  const lastUpdate = Date.now();
287
-
288
251
  function isUp() {
289
252
  return status === 'up' || Date.now() - lastUpdate > EXPIRATION_DELAY;
290
253
  }
291
-
292
254
  function isTimedOut() {
293
255
  return status === 'timed out' && Date.now() - lastUpdate <= EXPIRATION_DELAY;
294
256
  }
295
-
296
- return { ...host,
257
+ return {
258
+ ...host,
297
259
  status,
298
260
  lastUpdate,
299
261
  isUp,
@@ -302,6 +264,7 @@ function createStatefulHost(host, status = 'up') {
302
264
  }
303
265
 
304
266
  function _defineProperty(obj, key, value) {
267
+ key = _toPropertyKey(key);
305
268
  if (key in obj) {
306
269
  Object.defineProperty(obj, key, {
307
270
  value: value,
@@ -312,92 +275,96 @@ function _defineProperty(obj, key, value) {
312
275
  } else {
313
276
  obj[key] = value;
314
277
  }
315
-
316
278
  return obj;
317
279
  }
280
+ function _toPrimitive(input, hint) {
281
+ if (typeof input !== "object" || input === null) return input;
282
+ var prim = input[Symbol.toPrimitive];
283
+ if (prim !== undefined) {
284
+ var res = prim.call(input, hint || "default");
285
+ if (typeof res !== "object") return res;
286
+ throw new TypeError("@@toPrimitive must return a primitive value.");
287
+ }
288
+ return (hint === "string" ? String : Number)(input);
289
+ }
290
+ function _toPropertyKey(arg) {
291
+ var key = _toPrimitive(arg, "string");
292
+ return typeof key === "symbol" ? key : String(key);
293
+ }
318
294
 
319
295
  class AlgoliaError extends Error {
320
296
  constructor(message, name) {
321
297
  super(message);
322
-
323
298
  _defineProperty(this, "name", 'AlgoliaError');
324
-
325
299
  if (name) {
326
300
  this.name = name;
327
301
  }
328
302
  }
329
-
330
303
  }
331
304
  class ErrorWithStackTrace extends AlgoliaError {
332
305
  constructor(message, stackTrace, name) {
333
- super(message, name); // the array and object should be frozen to reflect the stackTrace at the time of the error
334
-
306
+ super(message, name);
307
+ // the array and object should be frozen to reflect the stackTrace at the time of the error
335
308
  _defineProperty(this, "stackTrace", void 0);
336
-
337
309
  this.stackTrace = stackTrace;
338
310
  }
339
-
340
311
  }
341
312
  class RetryError extends ErrorWithStackTrace {
342
313
  constructor(stackTrace) {
343
314
  super('Unreachable hosts - your application id may be incorrect. If the error persists, contact support@algolia.com.', stackTrace, 'RetryError');
344
315
  }
345
-
346
316
  }
347
317
  class ApiError extends ErrorWithStackTrace {
348
- constructor(message, status, stackTrace) {
349
- super(message, stackTrace, 'ApiError');
350
-
318
+ constructor(message, status, stackTrace, name = 'ApiError') {
319
+ super(message, stackTrace, name);
351
320
  _defineProperty(this, "status", void 0);
352
-
353
321
  this.status = status;
354
322
  }
355
-
356
323
  }
357
324
  class DeserializationError extends AlgoliaError {
358
325
  constructor(message, response) {
359
326
  super(message, 'DeserializationError');
360
-
361
327
  _defineProperty(this, "response", void 0);
362
-
363
328
  this.response = response;
364
329
  }
365
-
330
+ }
331
+ // DetailedApiError is only used by the ingestion client to return more informative error, other clients will use ApiClient.
332
+ class DetailedApiError extends ApiError {
333
+ constructor(message, status, error, stackTrace) {
334
+ super(message, status, stackTrace, 'DetailedApiError');
335
+ _defineProperty(this, "error", void 0);
336
+ this.error = error;
337
+ }
366
338
  }
367
339
 
368
340
  function shuffle(array) {
369
341
  const shuffledArray = array;
370
-
371
342
  for (let c = array.length - 1; c > 0; c--) {
372
343
  const b = Math.floor(Math.random() * (c + 1));
373
344
  const a = array[c];
374
345
  shuffledArray[c] = array[b];
375
346
  shuffledArray[b] = a;
376
347
  }
377
-
378
348
  return shuffledArray;
379
349
  }
380
350
  function serializeUrl(host, path, queryParameters) {
381
351
  const queryParametersAsString = serializeQueryParameters(queryParameters);
382
352
  let url = `${host.protocol}://${host.url}/${path.charAt(0) === '/' ? path.substr(1) : path}`;
383
-
384
353
  if (queryParametersAsString.length) {
385
354
  url += `?${queryParametersAsString}`;
386
355
  }
387
-
388
356
  return url;
389
357
  }
390
358
  function serializeQueryParameters(parameters) {
391
359
  const isObjectOrArray = value => Object.prototype.toString.call(value) === '[object Object]' || Object.prototype.toString.call(value) === '[object Array]';
392
-
393
- return Object.keys(parameters).map(key => `${key}=${isObjectOrArray(parameters[key]) ? JSON.stringify(parameters[key]) : parameters[key]}`).join('&');
360
+ return Object.keys(parameters).map(key => `${key}=${encodeURIComponent(isObjectOrArray(parameters[key]) ? JSON.stringify(parameters[key]) : parameters[key])}`).join('&');
394
361
  }
395
362
  function serializeData(request, requestOptions) {
396
363
  if (request.method === 'GET' || request.data === undefined && requestOptions.data === undefined) {
397
364
  return undefined;
398
365
  }
399
-
400
- const data = Array.isArray(request.data) ? request.data : { ...request.data,
366
+ const data = Array.isArray(request.data) ? request.data : {
367
+ ...request.data,
401
368
  ...requestOptions.data
402
369
  };
403
370
  return JSON.stringify(data);
@@ -427,14 +394,16 @@ function deserializeFailure({
427
394
  content,
428
395
  status
429
396
  }, stackFrame) {
430
- let message = content;
431
-
432
397
  try {
433
- message = JSON.parse(content).message;
434
- } catch (e) {// ..
398
+ const parsed = JSON.parse(content);
399
+ if ('error' in parsed) {
400
+ return new DetailedApiError(parsed.message, status, parsed.error, stackFrame);
401
+ }
402
+ return new ApiError(parsed.message, status, stackFrame);
403
+ } catch (e) {
404
+ // ..
435
405
  }
436
-
437
- return new ApiError(message, status, stackFrame);
406
+ return new ApiError(content, status, stackFrame);
438
407
  }
439
408
 
440
409
  function isNetworkError({
@@ -465,9 +434,12 @@ function stackFrameWithoutCredentials(stackFrame) {
465
434
  const modifiedHeaders = stackFrame.request.headers['x-algolia-api-key'] ? {
466
435
  'x-algolia-api-key': '*****'
467
436
  } : {};
468
- return { ...stackFrame,
469
- request: { ...stackFrame.request,
470
- headers: { ...stackFrame.request.headers,
437
+ return {
438
+ ...stackFrame,
439
+ request: {
440
+ ...stackFrame.request,
441
+ headers: {
442
+ ...stackFrame.request.headers,
471
443
  ...modifiedHeaders
472
444
  }
473
445
  }
@@ -492,51 +464,49 @@ function createTransporter({
492
464
  });
493
465
  }));
494
466
  const hostsUp = statefulHosts.filter(host => host.isUp());
495
- const hostsTimedOut = statefulHosts.filter(host => host.isTimedOut()); // Note, we put the hosts that previously timed out on the end of the list.
496
-
467
+ const hostsTimedOut = statefulHosts.filter(host => host.isTimedOut());
468
+ // Note, we put the hosts that previously timed out on the end of the list.
497
469
  const hostsAvailable = [...hostsUp, ...hostsTimedOut];
498
470
  const compatibleHostsAvailable = hostsAvailable.length > 0 ? hostsAvailable : compatibleHosts;
499
471
  return {
500
472
  hosts: compatibleHostsAvailable,
501
-
502
473
  getTimeout(timeoutsCount, baseTimeout) {
503
- /**
504
- * Imagine that you have 4 hosts, if timeouts will increase
505
- * on the following way: 1 (timed out) > 4 (timed out) > 5 (200).
506
- *
507
- * Note that, the very next request, we start from the previous timeout.
508
- *
509
- * 5 (timed out) > 6 (timed out) > 7 ...
510
- *
511
- * This strategy may need to be reviewed, but is the strategy on the our
512
- * current v3 version.
474
+ /**
475
+ * Imagine that you have 4 hosts, if timeouts will increase
476
+ * on the following way: 1 (timed out) > 4 (timed out) > 5 (200).
477
+ *
478
+ * Note that, the very next request, we start from the previous timeout.
479
+ *
480
+ * 5 (timed out) > 6 (timed out) > 7 ...
481
+ *
482
+ * This strategy may need to be reviewed, but is the strategy on the our
483
+ * current v3 version.
513
484
  */
514
485
  const timeoutMultiplier = hostsTimedOut.length === 0 && timeoutsCount === 0 ? 1 : hostsTimedOut.length + 3 + timeoutsCount;
515
486
  return timeoutMultiplier * baseTimeout;
516
487
  }
517
-
518
488
  };
519
489
  }
520
-
521
490
  async function retryableRequest(request, requestOptions, isRead = true) {
522
491
  const stackTrace = [];
523
- /**
524
- * First we prepare the payload that do not depend from hosts.
492
+ /**
493
+ * First we prepare the payload that do not depend from hosts.
525
494
  */
526
-
527
495
  const data = serializeData(request, requestOptions);
528
- const headers = serializeHeaders(baseHeaders, request.headers, requestOptions.headers); // On `GET`, the data is proxied to query parameters.
529
-
530
- const dataQueryParameters = request.method === 'GET' ? { ...request.data,
496
+ const headers = serializeHeaders(baseHeaders, request.headers, requestOptions.headers);
497
+ // On `GET`, the data is proxied to query parameters.
498
+ const dataQueryParameters = request.method === 'GET' ? {
499
+ ...request.data,
531
500
  ...requestOptions.data
532
501
  } : {};
533
502
  const queryParameters = {
534
- 'x-algolia-agent': algoliaAgent.value,
535
503
  ...baseQueryParameters,
536
504
  ...request.queryParameters,
537
505
  ...dataQueryParameters
538
506
  };
539
-
507
+ if (algoliaAgent.value) {
508
+ queryParameters['x-algolia-agent'] = algoliaAgent.value;
509
+ }
540
510
  if (requestOptions && requestOptions.queryParameters) {
541
511
  for (const key of Object.keys(requestOptions.queryParameters)) {
542
512
  // We want to keep `undefined` and `null` values,
@@ -549,25 +519,19 @@ function createTransporter({
549
519
  }
550
520
  }
551
521
  }
552
-
553
522
  let timeoutsCount = 0;
554
-
555
523
  const retry = async (retryableHosts, getTimeout) => {
556
- /**
557
- * We iterate on each host, until there is no host left.
524
+ /**
525
+ * We iterate on each host, until there is no host left.
558
526
  */
559
527
  const host = retryableHosts.pop();
560
-
561
528
  if (host === undefined) {
562
529
  throw new RetryError(stackTraceWithoutCredentials(stackTrace));
563
530
  }
564
-
565
531
  let responseTimeout = requestOptions.timeout;
566
-
567
532
  if (responseTimeout === undefined) {
568
533
  responseTimeout = isRead ? timeouts.read : timeouts.write;
569
534
  }
570
-
571
535
  const payload = {
572
536
  data,
573
537
  headers,
@@ -576,12 +540,11 @@ function createTransporter({
576
540
  connectTimeout: getTimeout(timeoutsCount, timeouts.connect),
577
541
  responseTimeout: getTimeout(timeoutsCount, responseTimeout)
578
542
  };
579
- /**
580
- * The stackFrame is pushed to the stackTrace so we
581
- * can have information about onRetry and onFailure
582
- * decisions.
543
+ /**
544
+ * The stackFrame is pushed to the stackTrace so we
545
+ * can have information about onRetry and onFailure
546
+ * decisions.
583
547
  */
584
-
585
548
  const pushToStackTrace = response => {
586
549
  const stackFrame = {
587
550
  request: payload,
@@ -592,102 +555,85 @@ function createTransporter({
592
555
  stackTrace.push(stackFrame);
593
556
  return stackFrame;
594
557
  };
595
-
596
558
  const response = await requester.send(payload);
597
-
598
559
  if (isRetryable(response)) {
599
- const stackFrame = pushToStackTrace(response); // If response is a timeout, we increase the number of timeouts so we can increase the timeout later.
600
-
560
+ const stackFrame = pushToStackTrace(response);
561
+ // If response is a timeout, we increase the number of timeouts so we can increase the timeout later.
601
562
  if (response.isTimedOut) {
602
563
  timeoutsCount++;
603
564
  }
604
- /**
605
- * Failures are individually sent to the logger, allowing
606
- * the end user to debug / store stack frames even
607
- * when a retry error does not happen.
565
+ /**
566
+ * Failures are individually sent to the logger, allowing
567
+ * the end user to debug / store stack frames even
568
+ * when a retry error does not happen.
608
569
  */
609
570
  // eslint-disable-next-line no-console -- this will be fixed by exposing a `logger` to the transporter
610
-
611
-
612
571
  console.log('Retryable failure', stackFrameWithoutCredentials(stackFrame));
613
- /**
614
- * We also store the state of the host in failure cases. If the host, is
615
- * down it will remain down for the next 2 minutes. In a timeout situation,
616
- * this host will be added end of the list of hosts on the next request.
572
+ /**
573
+ * We also store the state of the host in failure cases. If the host, is
574
+ * down it will remain down for the next 2 minutes. In a timeout situation,
575
+ * this host will be added end of the list of hosts on the next request.
617
576
  */
618
-
619
577
  await hostsCache.set(host, createStatefulHost(host, response.isTimedOut ? 'timed out' : 'down'));
620
578
  return retry(retryableHosts, getTimeout);
621
579
  }
622
-
623
580
  if (isSuccess(response)) {
624
581
  return deserializeSuccess(response);
625
582
  }
626
-
627
583
  pushToStackTrace(response);
628
584
  throw deserializeFailure(response, stackTrace);
629
585
  };
630
- /**
631
- * Finally, for each retryable host perform request until we got a non
632
- * retryable response. Some notes here:
633
- *
634
- * 1. The reverse here is applied so we can apply a `pop` later on => more performant.
635
- * 2. We also get from the retryable options a timeout multiplier that is tailored
636
- * for the current context.
586
+ /**
587
+ * Finally, for each retryable host perform request until we got a non
588
+ * retryable response. Some notes here:
589
+ *
590
+ * 1. The reverse here is applied so we can apply a `pop` later on => more performant.
591
+ * 2. We also get from the retryable options a timeout multiplier that is tailored
592
+ * for the current context.
637
593
  */
638
-
639
-
640
594
  const compatibleHosts = hosts.filter(host => host.accept === 'readWrite' || (isRead ? host.accept === 'read' : host.accept === 'write'));
641
595
  const options = await createRetryableOptions(compatibleHosts);
642
596
  return retry([...options.hosts].reverse(), options.getTimeout);
643
597
  }
644
-
645
598
  function createRequest(request, requestOptions = {}) {
646
- /**
647
- * A read request is either a `GET` request, or a request that we make
648
- * via the `read` transporter (e.g. `search`).
599
+ /**
600
+ * A read request is either a `GET` request, or a request that we make
601
+ * via the `read` transporter (e.g. `search`).
649
602
  */
650
603
  const isRead = request.useReadTransporter || request.method === 'GET';
651
-
652
604
  if (!isRead) {
653
- /**
654
- * On write requests, no cache mechanisms are applied, and we
655
- * proxy the request immediately to the requester.
605
+ /**
606
+ * On write requests, no cache mechanisms are applied, and we
607
+ * proxy the request immediately to the requester.
656
608
  */
657
609
  return retryableRequest(request, requestOptions, isRead);
658
610
  }
659
-
660
611
  const createRetryableRequest = () => {
661
- /**
662
- * Then, we prepare a function factory that contains the construction of
663
- * the retryable request. At this point, we may *not* perform the actual
664
- * request. But we want to have the function factory ready.
612
+ /**
613
+ * Then, we prepare a function factory that contains the construction of
614
+ * the retryable request. At this point, we may *not* perform the actual
615
+ * request. But we want to have the function factory ready.
665
616
  */
666
617
  return retryableRequest(request, requestOptions);
667
618
  };
668
- /**
669
- * Once we have the function factory ready, we need to determine of the
670
- * request is "cacheable" - should be cached. Note that, once again,
671
- * the user can force this option.
619
+ /**
620
+ * Once we have the function factory ready, we need to determine of the
621
+ * request is "cacheable" - should be cached. Note that, once again,
622
+ * the user can force this option.
672
623
  */
673
-
674
-
675
624
  const cacheable = requestOptions.cacheable || request.cacheable;
676
- /**
677
- * If is not "cacheable", we immediately trigger the retryable request, no
678
- * need to check cache implementations.
625
+ /**
626
+ * If is not "cacheable", we immediately trigger the retryable request, no
627
+ * need to check cache implementations.
679
628
  */
680
-
681
629
  if (cacheable !== true) {
682
630
  return createRetryableRequest();
683
631
  }
684
- /**
685
- * If the request is "cacheable", we need to first compute the key to ask
686
- * the cache implementations if this request is on progress or if the
687
- * response already exists on the cache.
632
+ /**
633
+ * If the request is "cacheable", we need to first compute the key to ask
634
+ * the cache implementations if this request is on progress or if the
635
+ * response already exists on the cache.
688
636
  */
689
-
690
-
691
637
  const key = {
692
638
  request,
693
639
  requestOptions,
@@ -696,33 +642,31 @@ function createTransporter({
696
642
  headers: baseHeaders
697
643
  }
698
644
  };
699
- /**
700
- * With the computed key, we first ask the responses cache
701
- * implementation if this request was been resolved before.
645
+ /**
646
+ * With the computed key, we first ask the responses cache
647
+ * implementation if this request was been resolved before.
702
648
  */
703
-
704
649
  return responsesCache.get(key, () => {
705
- /**
706
- * If the request has never resolved before, we actually ask if there
707
- * is a current request with the same key on progress.
650
+ /**
651
+ * If the request has never resolved before, we actually ask if there
652
+ * is a current request with the same key on progress.
708
653
  */
709
654
  return requestsCache.get(key, () =>
710
- /**
711
- * Finally, if there is no request in progress with the same key,
712
- * this `createRetryableRequest()` will actually trigger the
713
- * retryable request.
655
+ /**
656
+ * Finally, if there is no request in progress with the same key,
657
+ * this `createRetryableRequest()` will actually trigger the
658
+ * retryable request.
714
659
  */
715
660
  requestsCache.set(key, createRetryableRequest()).then(response => Promise.all([requestsCache.delete(key), response]), err => Promise.all([requestsCache.delete(key), Promise.reject(err)])).then(([_, response]) => response));
716
661
  }, {
717
- /**
718
- * Of course, once we get this response back from the server, we
719
- * tell response cache to actually store the received response
720
- * to be used later.
662
+ /**
663
+ * Of course, once we get this response back from the server, we
664
+ * tell response cache to actually store the received response
665
+ * to be used later.
721
666
  */
722
667
  miss: response => responsesCache.set(key, response)
723
668
  });
724
669
  }
725
-
726
670
  return {
727
671
  hostsCache,
728
672
  requester,
@@ -740,17 +684,13 @@ function createTransporter({
740
684
  function createAlgoliaAgent(version) {
741
685
  const algoliaAgent = {
742
686
  value: `Algolia for JavaScript (${version})`,
743
-
744
687
  add(options) {
745
688
  const addedAlgoliaAgent = `; ${options.segment}${options.version !== undefined ? ` (${options.version})` : ''}`;
746
-
747
689
  if (algoliaAgent.value.indexOf(addedAlgoliaAgent) === -1) {
748
690
  algoliaAgent.value = `${algoliaAgent.value}${addedAlgoliaAgent}`;
749
691
  }
750
-
751
692
  return algoliaAgent;
752
693
  }
753
-
754
694
  };
755
695
  return algoliaAgent;
756
696
  }
@@ -784,6 +724,7 @@ exports.DEFAULT_READ_TIMEOUT_NODE = DEFAULT_READ_TIMEOUT_NODE;
784
724
  exports.DEFAULT_WRITE_TIMEOUT_BROWSER = DEFAULT_WRITE_TIMEOUT_BROWSER;
785
725
  exports.DEFAULT_WRITE_TIMEOUT_NODE = DEFAULT_WRITE_TIMEOUT_NODE;
786
726
  exports.DeserializationError = DeserializationError;
727
+ exports.DetailedApiError = DetailedApiError;
787
728
  exports.ErrorWithStackTrace = ErrorWithStackTrace;
788
729
  exports.RetryError = RetryError;
789
730
  exports.createAlgoliaAgent = createAlgoliaAgent;