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