@algolia/client-common 5.0.0-alpha.7 → 5.0.0-alpha.71

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