@algolia/client-common 5.0.0-alpha.9 → 5.0.0-alpha.90

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 (42) hide show
  1. package/dist/{client-common.cjs.js → client-common.cjs} +139 -200
  2. package/dist/client-common.esm.node.js +139 -199
  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/errors.d.ts +37 -20
  20. package/dist/src/transporter/errors.d.ts.map +1 -1
  21. package/dist/src/transporter/helpers.d.ts +8 -8
  22. package/dist/src/transporter/helpers.d.ts.map +1 -1
  23. package/dist/src/transporter/index.d.ts +6 -6
  24. package/dist/src/transporter/responses.d.ts +4 -4
  25. package/dist/src/transporter/stackTrace.d.ts +3 -3
  26. package/dist/src/types/cache.d.ts +46 -46
  27. package/dist/src/types/cache.d.ts.map +1 -1
  28. package/dist/src/types/createClient.d.ts +11 -11
  29. package/dist/src/types/createClient.d.ts.map +1 -1
  30. package/dist/src/types/createIterablePromise.d.ts +35 -35
  31. package/dist/src/types/createIterablePromise.d.ts.map +1 -1
  32. package/dist/src/types/host.d.ts +32 -32
  33. package/dist/src/types/host.d.ts.map +1 -1
  34. package/dist/src/types/index.d.ts +6 -6
  35. package/dist/src/types/requester.d.ts +65 -65
  36. package/dist/src/types/requester.d.ts.map +1 -1
  37. package/dist/src/types/transporter.d.ts +127 -127
  38. package/dist/src/types/transporter.d.ts.map +1 -1
  39. package/package.json +11 -8
  40. package/src/createEchoRequester.ts +2 -2
  41. package/src/transporter/errors.ts +38 -2
  42. 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,53 +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
- const queryParameters = { ...baseQueryParameters,
502
+ const queryParameters = {
503
+ ...baseQueryParameters,
534
504
  ...request.queryParameters,
535
505
  ...dataQueryParameters
536
506
  };
537
-
538
507
  if (algoliaAgent.value) {
539
508
  queryParameters['x-algolia-agent'] = algoliaAgent.value;
540
509
  }
541
-
542
510
  if (requestOptions && requestOptions.queryParameters) {
543
511
  for (const key of Object.keys(requestOptions.queryParameters)) {
544
512
  // We want to keep `undefined` and `null` values,
@@ -551,25 +519,19 @@ function createTransporter({
551
519
  }
552
520
  }
553
521
  }
554
-
555
522
  let timeoutsCount = 0;
556
-
557
523
  const retry = async (retryableHosts, getTimeout) => {
558
- /**
559
- * We iterate on each host, until there is no host left.
524
+ /**
525
+ * We iterate on each host, until there is no host left.
560
526
  */
561
527
  const host = retryableHosts.pop();
562
-
563
528
  if (host === undefined) {
564
529
  throw new RetryError(stackTraceWithoutCredentials(stackTrace));
565
530
  }
566
-
567
531
  let responseTimeout = requestOptions.timeout;
568
-
569
532
  if (responseTimeout === undefined) {
570
533
  responseTimeout = isRead ? timeouts.read : timeouts.write;
571
534
  }
572
-
573
535
  const payload = {
574
536
  data,
575
537
  headers,
@@ -578,12 +540,11 @@ function createTransporter({
578
540
  connectTimeout: getTimeout(timeoutsCount, timeouts.connect),
579
541
  responseTimeout: getTimeout(timeoutsCount, responseTimeout)
580
542
  };
581
- /**
582
- * The stackFrame is pushed to the stackTrace so we
583
- * can have information about onRetry and onFailure
584
- * decisions.
543
+ /**
544
+ * The stackFrame is pushed to the stackTrace so we
545
+ * can have information about onRetry and onFailure
546
+ * decisions.
585
547
  */
586
-
587
548
  const pushToStackTrace = response => {
588
549
  const stackFrame = {
589
550
  request: payload,
@@ -594,102 +555,85 @@ function createTransporter({
594
555
  stackTrace.push(stackFrame);
595
556
  return stackFrame;
596
557
  };
597
-
598
558
  const response = await requester.send(payload);
599
-
600
559
  if (isRetryable(response)) {
601
- const stackFrame = pushToStackTrace(response); // If response is a timeout, we increase the number of timeouts so we can increase the timeout later.
602
-
560
+ const stackFrame = pushToStackTrace(response);
561
+ // If response is a timeout, we increase the number of timeouts so we can increase the timeout later.
603
562
  if (response.isTimedOut) {
604
563
  timeoutsCount++;
605
564
  }
606
- /**
607
- * Failures are individually sent to the logger, allowing
608
- * the end user to debug / store stack frames even
609
- * 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.
610
569
  */
611
570
  // eslint-disable-next-line no-console -- this will be fixed by exposing a `logger` to the transporter
612
-
613
-
614
571
  console.log('Retryable failure', stackFrameWithoutCredentials(stackFrame));
615
- /**
616
- * We also store the state of the host in failure cases. If the host, is
617
- * down it will remain down for the next 2 minutes. In a timeout situation,
618
- * 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.
619
576
  */
620
-
621
577
  await hostsCache.set(host, createStatefulHost(host, response.isTimedOut ? 'timed out' : 'down'));
622
578
  return retry(retryableHosts, getTimeout);
623
579
  }
624
-
625
580
  if (isSuccess(response)) {
626
581
  return deserializeSuccess(response);
627
582
  }
628
-
629
583
  pushToStackTrace(response);
630
584
  throw deserializeFailure(response, stackTrace);
631
585
  };
632
- /**
633
- * Finally, for each retryable host perform request until we got a non
634
- * retryable response. Some notes here:
635
- *
636
- * 1. The reverse here is applied so we can apply a `pop` later on => more performant.
637
- * 2. We also get from the retryable options a timeout multiplier that is tailored
638
- * 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.
639
593
  */
640
-
641
-
642
594
  const compatibleHosts = hosts.filter(host => host.accept === 'readWrite' || (isRead ? host.accept === 'read' : host.accept === 'write'));
643
595
  const options = await createRetryableOptions(compatibleHosts);
644
596
  return retry([...options.hosts].reverse(), options.getTimeout);
645
597
  }
646
-
647
598
  function createRequest(request, requestOptions = {}) {
648
- /**
649
- * A read request is either a `GET` request, or a request that we make
650
- * 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`).
651
602
  */
652
603
  const isRead = request.useReadTransporter || request.method === 'GET';
653
-
654
604
  if (!isRead) {
655
- /**
656
- * On write requests, no cache mechanisms are applied, and we
657
- * 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.
658
608
  */
659
609
  return retryableRequest(request, requestOptions, isRead);
660
610
  }
661
-
662
611
  const createRetryableRequest = () => {
663
- /**
664
- * Then, we prepare a function factory that contains the construction of
665
- * the retryable request. At this point, we may *not* perform the actual
666
- * 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.
667
616
  */
668
617
  return retryableRequest(request, requestOptions);
669
618
  };
670
- /**
671
- * Once we have the function factory ready, we need to determine of the
672
- * request is "cacheable" - should be cached. Note that, once again,
673
- * 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.
674
623
  */
675
-
676
-
677
624
  const cacheable = requestOptions.cacheable || request.cacheable;
678
- /**
679
- * If is not "cacheable", we immediately trigger the retryable request, no
680
- * need to check cache implementations.
625
+ /**
626
+ * If is not "cacheable", we immediately trigger the retryable request, no
627
+ * need to check cache implementations.
681
628
  */
682
-
683
629
  if (cacheable !== true) {
684
630
  return createRetryableRequest();
685
631
  }
686
- /**
687
- * If the request is "cacheable", we need to first compute the key to ask
688
- * the cache implementations if this request is on progress or if the
689
- * 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.
690
636
  */
691
-
692
-
693
637
  const key = {
694
638
  request,
695
639
  requestOptions,
@@ -698,33 +642,31 @@ function createTransporter({
698
642
  headers: baseHeaders
699
643
  }
700
644
  };
701
- /**
702
- * With the computed key, we first ask the responses cache
703
- * 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.
704
648
  */
705
-
706
649
  return responsesCache.get(key, () => {
707
- /**
708
- * If the request has never resolved before, we actually ask if there
709
- * 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.
710
653
  */
711
654
  return requestsCache.get(key, () =>
712
- /**
713
- * Finally, if there is no request in progress with the same key,
714
- * this `createRetryableRequest()` will actually trigger the
715
- * 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.
716
659
  */
717
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));
718
661
  }, {
719
- /**
720
- * Of course, once we get this response back from the server, we
721
- * tell response cache to actually store the received response
722
- * 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.
723
666
  */
724
667
  miss: response => responsesCache.set(key, response)
725
668
  });
726
669
  }
727
-
728
670
  return {
729
671
  hostsCache,
730
672
  requester,
@@ -742,17 +684,13 @@ function createTransporter({
742
684
  function createAlgoliaAgent(version) {
743
685
  const algoliaAgent = {
744
686
  value: `Algolia for JavaScript (${version})`,
745
-
746
687
  add(options) {
747
688
  const addedAlgoliaAgent = `; ${options.segment}${options.version !== undefined ? ` (${options.version})` : ''}`;
748
-
749
689
  if (algoliaAgent.value.indexOf(addedAlgoliaAgent) === -1) {
750
690
  algoliaAgent.value = `${algoliaAgent.value}${addedAlgoliaAgent}`;
751
691
  }
752
-
753
692
  return algoliaAgent;
754
693
  }
755
-
756
694
  };
757
695
  return algoliaAgent;
758
696
  }
@@ -786,6 +724,7 @@ exports.DEFAULT_READ_TIMEOUT_NODE = DEFAULT_READ_TIMEOUT_NODE;
786
724
  exports.DEFAULT_WRITE_TIMEOUT_BROWSER = DEFAULT_WRITE_TIMEOUT_BROWSER;
787
725
  exports.DEFAULT_WRITE_TIMEOUT_NODE = DEFAULT_WRITE_TIMEOUT_NODE;
788
726
  exports.DeserializationError = DeserializationError;
727
+ exports.DetailedApiError = DetailedApiError;
789
728
  exports.ErrorWithStackTrace = ErrorWithStackTrace;
790
729
  exports.RetryError = RetryError;
791
730
  exports.createAlgoliaAgent = createAlgoliaAgent;