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

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